ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/pabopto2xml.c
(Generate patch)

Comparing ray/src/cv/pabopto2xml.c (file contents):
Revision 2.15 by greg, Sun Sep 23 16:45:20 2012 UTC vs.
Revision 2.16 by greg, Sun Oct 14 22:31:20 2012 UTC

# Line 8 | Line 8 | static const char RCSid[] = "$Id$";
8   *      G.Ward
9   */
10  
11 + #ifndef _WIN32
12 + #include <unistd.h>
13 + #include <sys/wait.h>
14 + #include <sys/mman.h>
15 + #endif
16   #define _USE_MATH_DEFINES
17   #include <stdio.h>
18   #include <stdlib.h>
# Line 95 | Line 100 | int                    pctcull = -1;
100   #else
101   int                     pctcull = 90;
102   #endif
103 +                                /* number of processes to run */
104 + int                     nprocs = 1;
105 +                                /* number of children (-1 in child) */
106 + int                     nchild = 0;
107 +
108                                  /* sampling order (set by data density) */
109   int                     samp_order = 0;
110  
# Line 645 | Line 655 | thetaphi(const FVECT v)
655   }
656   #endif
657  
658 < /* Compute (and insert) migration along directed edge */
658 > /* Create a new migration holder (sharing memory for multiprocessing) */
659   static MIGRATION *
660 < make_migration(RBFNODE *from_rbf, RBFNODE *to_rbf, int creat_only)
660 > new_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
661   {
662 +        size_t          memlen = sizeof(MIGRATION) +
663 +                                sizeof(float)*(from_rbf->nrbf*to_rbf->nrbf - 1);
664 +        MIGRATION       *newmig;
665 + #ifdef _WIN32
666 +        newmig = (MIGRATION *)malloc(memlen);
667 + #else
668 +        if (nprocs <= 1) {                      /* single process? */
669 +                newmig = (MIGRATION *)malloc(memlen);
670 +        } else {                                /* else need to share memory */
671 +                newmig = (MIGRATION *)mmap(NULL, memlen, PROT_READ|PROT_WRITE,
672 +                                                MAP_ANON|MAP_SHARED, -1, 0);
673 +                if ((void *)newmig == MAP_FAILED)
674 +                        newmig = NULL;
675 +        }
676 + #endif
677 +        if (newmig == NULL) {
678 +                fprintf(stderr, "%s: cannot allocate new migration\n", progname);
679 +                exit(1);
680 +        }
681 +        newmig->rbfv[0] = from_rbf;
682 +        newmig->rbfv[1] = to_rbf;
683 +                                                /* insert in edge lists */
684 +        newmig->enxt[0] = from_rbf->ejl;
685 +        from_rbf->ejl = newmig;
686 +        newmig->enxt[1] = to_rbf->ejl;
687 +        to_rbf->ejl = newmig;
688 +        newmig->next = mig_list;                /* push onto global list */
689 +        return(mig_list = newmig);
690 + }
691 +
692 + #ifdef _WIN32
693 + #define await_children(n)       (void)(n)
694 + #define run_subprocess()        0
695 + #define end_subprocess()        (void)0
696 + #else
697 +
698 + /* Wait for the specified number of child processes to complete */
699 + static void
700 + await_children(int n)
701 + {
702 +        if (n > nchild)
703 +                n = nchild;
704 +        while (n-- > 0) {
705 +                int     status;
706 +                if (wait(&status) < 0) {
707 +                        fprintf(stderr, "%s: missing child(ren)!\n", progname);
708 +                        nchild = 0;
709 +                        break;
710 +                }
711 +                --nchild;
712 +                if (status) {
713 +                        if ((status = WEXITSTATUS(status)))
714 +                                exit(status);
715 +                        fprintf(stderr, "%s: subprocess died\n", progname);
716 +                        exit(1);
717 +                }
718 +        }
719 + }
720 +
721 + /* Start child process if multiprocessing selected */
722 + static pid_t
723 + run_subprocess(void)
724 + {
725 +        int     status;
726 +        pid_t   pid;
727 +
728 +        if (nprocs <= 1)                        /* any children requested? */
729 +                return(0);
730 +        await_children(nchild + 1 - nprocs);    /* free up child process */
731 +        if ((pid = fork())) {
732 +                if (pid < 0) {
733 +                        fprintf(stderr, "%s: cannot fork subprocess\n",
734 +                                        progname);
735 +                        exit(1);
736 +                }
737 +                ++nchild;                       /* subprocess started */
738 +                return(pid);
739 +        }
740 +        nchild = -1;
741 +        return(0);                              /* put child to work */
742 + }
743 +
744 + /* If we are in subprocess, call exit */
745 + #define end_subprocess()        if (nchild < 0) _exit(0); else
746 +
747 + #endif  /* ! _WIN32 */
748 +
749 + /* Compute and insert migration along directed edge (may fork child) */
750 + static MIGRATION *
751 + create_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
752 + {
753          const double    end_thresh = 0.02/(from_rbf->nrbf*to_rbf->nrbf);
754          float           *pmtx;
755          MIGRATION       *newmig;
# Line 659 | Line 760 | make_migration(RBFNODE *from_rbf, RBFNODE *to_rbf, int
760          for (newmig = from_rbf->ejl; newmig != NULL;
761                          newmig = nextedge(from_rbf,newmig))
762                  if (newmig->rbfv[1] == to_rbf)
763 <                        return(creat_only ? (MIGRATION *)NULL : newmig);
763 >                        return(NULL);
764                                                  /* else allocate */
765 +        newmig = new_migration(from_rbf, to_rbf);
766 +        if (run_subprocess())
767 +                return(newmig);                 /* child continues */
768          pmtx = price_routes(from_rbf, to_rbf);
665        newmig = (MIGRATION *)malloc(sizeof(MIGRATION) + sizeof(float) *
666                                        (from_rbf->nrbf*to_rbf->nrbf - 1));
769          src_rem = (double *)malloc(sizeof(double)*from_rbf->nrbf);
770          dst_rem = (double *)malloc(sizeof(double)*to_rbf->nrbf);
771 <        if ((newmig == NULL) | (src_rem == NULL) | (dst_rem == NULL)) {
772 <                fputs("Out of memory in make_migration()\n", stderr);
771 >        if ((src_rem == NULL) | (dst_rem == NULL)) {
772 >                fputs("Out of memory in create_migration()\n", stderr);
773                  exit(1);
774          }
775   #ifdef DEBUG
776 <        {
777 <                fprintf(stderr, "Building path from (theta,phi) %s ",
778 <                                thetaphi(from_rbf->invec));
779 <                fprintf(stderr, "to %s", thetaphi(to_rbf->invec));
678 <        }
776 >        fprintf(stderr, "Building path from (theta,phi) %s ",
777 >                        thetaphi(from_rbf->invec));
778 >        fprintf(stderr, "to %s", thetaphi(to_rbf->invec));
779 >        /* if (nchild) */ fputc('\n', stderr);
780   #endif
680        newmig->next = NULL;
681        newmig->rbfv[0] = from_rbf;
682        newmig->rbfv[1] = to_rbf;
683        newmig->enxt[0] = newmig->enxt[1] = NULL;
684        memset(newmig->mtx, 0, sizeof(float)*from_rbf->nrbf*to_rbf->nrbf);
781                                                  /* starting quantities */
782 +        memset(newmig->mtx, 0, sizeof(float)*from_rbf->nrbf*to_rbf->nrbf);
783          for (i = from_rbf->nrbf; i--; )
784                  src_rem[i] = rbf_volume(&from_rbf->rbfa[i]) / from_rbf->vtotal;
785          for (i = to_rbf->nrbf; i--; )
# Line 691 | Line 788 | make_migration(RBFNODE *from_rbf, RBFNODE *to_rbf, int
788          while (total_rem > end_thresh) {
789                  total_rem -= migration_step(newmig, src_rem, dst_rem, pmtx);
790   #ifdef DEBUG
791 <                /* fputc('.', stderr); */
792 <                fprintf(stderr, "\n%.9f remaining...", total_rem);
791 >                if (!nchild)
792 >                        /* fputc('.', stderr); */
793 >                        fprintf(stderr, "%.9f remaining...\r", total_rem);
794   #endif
795          }
796   #ifdef DEBUG
797 <        fputs("done.\n", stderr);
797 >        if (!nchild) fputs("done.\n", stderr);
798   #endif
799  
800          free(pmtx);                             /* free working arrays */
# Line 710 | Line 808 | make_migration(RBFNODE *from_rbf, RBFNODE *to_rbf, int
808              for (j = to_rbf->nrbf; j--; )
809                  newmig->mtx[mtx_ndx(newmig,i,j)] *= nf;
810          }
811 <                                                /* insert in edge lists */
812 <        newmig->enxt[0] = from_rbf->ejl;
715 <        from_rbf->ejl = newmig;
716 <        newmig->enxt[1] = to_rbf->ejl;
717 <        to_rbf->ejl = newmig;
718 <        newmig->next = mig_list;
719 <        return(mig_list = newmig);
811 >        end_subprocess();                       /* exit here if subprocess */
812 >        return(newmig);
813   }
814  
815   /* Get triangle surface orientation (unnormalized) */
# Line 844 | Line 937 | mesh_from_edge(MIGRATION *edge)
937                  tvert[0] = find_chull_vert(edge->rbfv[0], edge->rbfv[1]);
938                  if (tvert[0] != NULL) {
939                          if (tvert[0] > edge->rbfv[0])
940 <                                ej0 = make_migration(edge->rbfv[0], tvert[0], 1);
940 >                                ej0 = create_migration(edge->rbfv[0], tvert[0]);
941                          else
942 <                                ej0 = make_migration(tvert[0], edge->rbfv[0], 1);
942 >                                ej0 = create_migration(tvert[0], edge->rbfv[0]);
943                          if (tvert[0] > edge->rbfv[1])
944 <                                ej1 = make_migration(edge->rbfv[1], tvert[0], 1);
944 >                                ej1 = create_migration(edge->rbfv[1], tvert[0]);
945                          else
946 <                                ej1 = make_migration(tvert[0], edge->rbfv[1], 1);
946 >                                ej1 = create_migration(tvert[0], edge->rbfv[1]);
947                          mesh_from_edge(ej0);
948                          mesh_from_edge(ej1);
949                  }
# Line 858 | Line 951 | mesh_from_edge(MIGRATION *edge)
951                  tvert[1] = find_chull_vert(edge->rbfv[1], edge->rbfv[0]);
952                  if (tvert[1] != NULL) {
953                          if (tvert[1] > edge->rbfv[0])
954 <                                ej0 = make_migration(edge->rbfv[0], tvert[1], 1);
954 >                                ej0 = create_migration(edge->rbfv[0], tvert[1]);
955                          else
956 <                                ej0 = make_migration(tvert[1], edge->rbfv[0], 1);
956 >                                ej0 = create_migration(tvert[1], edge->rbfv[0]);
957                          if (tvert[1] > edge->rbfv[1])
958 <                                ej1 = make_migration(edge->rbfv[1], tvert[1], 1);
958 >                                ej1 = create_migration(edge->rbfv[1], tvert[1]);
959                          else
960 <                                ej1 = make_migration(tvert[1], edge->rbfv[1], 1);
960 >                                ej1 = create_migration(tvert[1], edge->rbfv[1]);
961                          mesh_from_edge(ej0);
962                          mesh_from_edge(ej1);
963                  }
# Line 978 | Line 1071 | build_mesh()
1071          if (single_plane_incident) {
1072                  for (rbf0 = dsf_list; rbf0 != NULL; rbf0 = rbf0->next)
1073                          if (rbf0->next != NULL)
1074 <                                make_migration(rbf0, rbf0->next, 1);
1074 >                                create_migration(rbf0, rbf0->next);
1075 >                await_children(nchild);
1076                  return;
1077          }
1078                                                  /* start w/ shortest edge */
# Line 998 | Line 1092 | build_mesh()
1092          }
1093                                                  /* build mesh from this edge */
1094          if (shrt_edj[0] < shrt_edj[1])
1095 <                mesh_from_edge(make_migration(shrt_edj[0], shrt_edj[1], 0));
1095 >                mesh_from_edge(create_migration(shrt_edj[0], shrt_edj[1]));
1096          else
1097 <                mesh_from_edge(make_migration(shrt_edj[1], shrt_edj[0], 0));
1097 >                mesh_from_edge(create_migration(shrt_edj[1], shrt_edj[0]));
1098 >                                                /* complete migrations */
1099 >        await_children(nchild);
1100                                                  /* draw edge list into grid */
1101          draw_edges();
1102   }
# Line 1388 | Line 1484 | interp_isotropic()
1484                  fflush(stdout);
1485                  ofp = popen(cmd, "w");
1486                  if (ofp == NULL) {
1487 <                        fputs("Cannot create pipe for rttree_reduce\n", stderr);
1487 >                        fprintf(stderr, "%s: cannot create pipe to rttree_reduce\n",
1488 >                                        progname);
1489                          exit(1);
1490                  }
1491          } else
# Line 1415 | Line 1512 | interp_isotropic()
1512          }
1513          if (pctcull >= 0) {                     /* finish output */
1514                  if (pclose(ofp)) {
1515 <                        fprintf(stderr, "Error running '%s'\n", cmd);
1515 >                        fprintf(stderr, "%s: error running '%s'\n",
1516 >                                        progname, cmd);
1517                          exit(1);
1518                  }
1519          } else {
# Line 1446 | Line 1544 | interp_anisotropic()
1544                  fflush(stdout);
1545                  ofp = popen(cmd, "w");
1546                  if (ofp == NULL) {
1547 <                        fputs("Cannot create pipe for rttree_reduce\n", stderr);
1547 >                        fprintf(stderr, "%s: cannot create pipe to rttree_reduce\n",
1548 >                                        progname);
1549                          exit(1);
1550                  }
1551          } else
# Line 1474 | Line 1573 | interp_anisotropic()
1573              }
1574          if (pctcull >= 0) {                     /* finish output */
1575                  if (pclose(ofp)) {
1576 <                        fprintf(stderr, "Error running '%s'\n", cmd);
1576 >                        fprintf(stderr, "%s: error running '%s'\n",
1577 >                                        progname, cmd);
1578                          exit(1);
1579                  }
1580          } else
# Line 1490 | Line 1590 | main(int argc, char *argv[])
1590          double          bsdf;
1591          int             i;
1592  
1593 <        progname = argv[0];
1594 <        if (argc > 2 && !strcmp(argv[1], "-t")) {
1595 <                pctcull = atoi(argv[2]);
1593 >        progname = argv[0];                     /* get options */
1594 >        while (argc > 2 && argv[1][0] == '-') {
1595 >                switch (argv[1][1]) {
1596 >                case 'n':
1597 >                        nprocs = atoi(argv[2]);
1598 >                        break;
1599 >                case 't':
1600 >                        pctcull = atoi(argv[2]);
1601 >                        break;
1602 >                default:
1603 >                        goto userr;
1604 >                }
1605                  argv += 2; argc -= 2;
1606          }
1607 <        if (argc < 3) {
1608 <                fprintf(stderr,
1609 <                "Usage: %s [-t pctcull] meas1.dat meas2.dat .. > bsdf.xml\n",
1607 >        if (argc < 3)
1608 >                goto userr;
1609 > #ifdef _WIN32
1610 >        if (nprocs > 1) {
1611 >                fprintf(stderr, "%s: multiprocessing not supported\n",
1612                                  progname);
1613                  return(1);
1614          }
1615 + #endif
1616          for (i = 1; i < argc; i++) {            /* compile measurements */
1617                  if (!load_pabopto_meas(argv[i]))
1618                          return(1);
# Line 1516 | Line 1628 | main(int argc, char *argv[])
1628                  interp_anisotropic();
1629          /* xml_epilogue();                              /* finish XML output */
1630          return(0);
1631 + userr:
1632 +        fprintf(stderr,
1633 +        "Usage: %s [-n nprocs][-t pctcull] meas1.dat meas2.dat .. > bsdf.xml\n",
1634 +                                progname);
1635 +        return(1);
1636   }
1637   #else
1638   /* Test main produces a Radiance model from the given input file */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines