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

Comparing ray/src/cv/bsdfmesh.c (file contents):
Revision 2.1 by greg, Fri Oct 19 04:14:29 2012 UTC vs.
Revision 2.2 by greg, Sat Oct 20 07:02:00 2012 UTC

# Line 23 | Line 23 | int                    nprocs = 1;
23                                  /* number of children (-1 in child) */
24   static int              nchild = 0;
25  
26 + /* Create a new migration holder (sharing memory for multiprocessing) */
27 + static MIGRATION *
28 + new_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
29 + {
30 +        size_t          memlen = sizeof(MIGRATION) +
31 +                                sizeof(float)*(from_rbf->nrbf*to_rbf->nrbf - 1);
32 +        MIGRATION       *newmig;
33 + #ifdef _WIN32
34 +        if (nprocs > 1)
35 +                fprintf(stderr, "%s: warning - multiprocessing not supported\n",
36 +                                progname);
37 +        nprocs = 1;
38 +        newmig = (MIGRATION *)malloc(memlen);
39 + #else
40 +        if (nprocs <= 1) {                      /* single process? */
41 +                newmig = (MIGRATION *)malloc(memlen);
42 +        } else {                                /* else need to share memory */
43 +                newmig = (MIGRATION *)mmap(NULL, memlen, PROT_READ|PROT_WRITE,
44 +                                                MAP_ANON|MAP_SHARED, -1, 0);
45 +                if ((void *)newmig == MAP_FAILED)
46 +                        newmig = NULL;
47 +        }
48 + #endif
49 +        if (newmig == NULL) {
50 +                fprintf(stderr, "%s: cannot allocate new migration\n", progname);
51 +                exit(1);
52 +        }
53 +        newmig->rbfv[0] = from_rbf;
54 +        newmig->rbfv[1] = to_rbf;
55 +                                                /* insert in edge lists */
56 +        newmig->enxt[0] = from_rbf->ejl;
57 +        from_rbf->ejl = newmig;
58 +        newmig->enxt[1] = to_rbf->ejl;
59 +        to_rbf->ejl = newmig;
60 +        newmig->next = mig_list;                /* push onto global list */
61 +        return(mig_list = newmig);
62 + }
63 +
64 + #ifdef _WIN32
65 + #define await_children(n)       (void)(n)
66 + #define run_subprocess()        0
67 + #define end_subprocess()        (void)0
68 + #else
69 +
70 + /* Wait for the specified number of child processes to complete */
71 + static void
72 + await_children(int n)
73 + {
74 +        int     exit_status = 0;
75 +
76 +        if (n > nchild)
77 +                n = nchild;
78 +        while (n-- > 0) {
79 +                int     status;
80 +                if (wait(&status) < 0) {
81 +                        fprintf(stderr, "%s: missing child(ren)!\n", progname);
82 +                        nchild = 0;
83 +                        break;
84 +                }
85 +                --nchild;
86 +                if (status) {                   /* something wrong */
87 +                        if ((status = WEXITSTATUS(status)))
88 +                                exit_status = status;
89 +                        else
90 +                                exit_status += !exit_status;
91 +                        fprintf(stderr, "%s: subprocess died\n", progname);
92 +                        n = nchild;             /* wait for the rest */
93 +                }
94 +        }
95 +        if (exit_status)
96 +                exit(exit_status);
97 + }
98 +
99 + /* Start child process if multiprocessing selected */
100 + static pid_t
101 + run_subprocess(void)
102 + {
103 +        int     status;
104 +        pid_t   pid;
105 +
106 +        if (nprocs <= 1)                        /* any children requested? */
107 +                return(0);
108 +        await_children(nchild + 1 - nprocs);    /* free up child process */
109 +        if ((pid = fork())) {
110 +                if (pid < 0) {
111 +                        fprintf(stderr, "%s: cannot fork subprocess\n",
112 +                                        progname);
113 +                        exit(1);
114 +                }
115 +                ++nchild;                       /* subprocess started */
116 +                return(pid);
117 +        }
118 +        nchild = -1;
119 +        return(0);                              /* put child to work */
120 + }
121 +
122 + /* If we are in subprocess, call exit */
123 + #define end_subprocess()        if (nchild < 0) _exit(0); else
124 +
125 + #endif  /* ! _WIN32 */
126 +
127   /* Compute (and allocate) migration price matrix for optimization */
128   static float *
129   price_routes(const RBFNODE *from_rbf, const RBFNODE *to_rbf)
# Line 106 | Line 207 | static double
207   migration_step(MIGRATION *mig, double *src_rem, double *dst_rem, const float *pmtx)
208   {
209          const double    maxamt = .1;
210 <        const double    minamt = maxamt*.0001;
210 >        const double    minamt = maxamt*5e-6;
211          static double   *src_cost = NULL;
212          static int      n_alloc = 0;
213          struct {
# Line 136 | Line 237 | migration_step(MIGRATION *mig, double *src_rem, double
237          for (cur.s = mtx_nrows(mig); cur.s--; ) {
238              const float *price = pmtx + cur.s*mtx_ncols(mig);
239              double      cost_others = 0;
240 <            if (src_rem[cur.s] < minamt)
240 >            if (src_rem[cur.s] <= minamt)
241                      continue;
242              cur.d = -1;                         /* examine cheapest dest. */
243              for (i = mtx_ncols(mig); i--; )
# Line 164 | Line 265 | migration_step(MIGRATION *mig, double *src_rem, double
265          if ((best.s < 0) | (best.d < 0))
266                  return(.0);
267                                                  /* make the actual move */
268 <        mig->mtx[mtx_ndx(mig,best.s,best.d)] += best.amt;
268 >        mtx_coef(mig,best.s,best.d) += best.amt;
269          src_rem[best.s] -= best.amt;
270          dst_rem[best.d] -= best.amt;
271          return(best.amt);
# Line 185 | Line 286 | thetaphi(const FVECT v)
286   }
287   #endif
288  
188 /* Create a new migration holder (sharing memory for multiprocessing) */
189 static MIGRATION *
190 new_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
191 {
192        size_t          memlen = sizeof(MIGRATION) +
193                                sizeof(float)*(from_rbf->nrbf*to_rbf->nrbf - 1);
194        MIGRATION       *newmig;
195 #ifdef _WIN32
196        if (nprocs > 1)
197                fprintf(stderr, "%s: warning - multiprocessing not supported\n",
198                                progname);
199        nprocs = 1;
200        newmig = (MIGRATION *)malloc(memlen);
201 #else
202        if (nprocs <= 1) {                      /* single process? */
203                newmig = (MIGRATION *)malloc(memlen);
204        } else {                                /* else need to share memory */
205                newmig = (MIGRATION *)mmap(NULL, memlen, PROT_READ|PROT_WRITE,
206                                                MAP_ANON|MAP_SHARED, -1, 0);
207                if ((void *)newmig == MAP_FAILED)
208                        newmig = NULL;
209        }
210 #endif
211        if (newmig == NULL) {
212                fprintf(stderr, "%s: cannot allocate new migration\n", progname);
213                exit(1);
214        }
215        newmig->rbfv[0] = from_rbf;
216        newmig->rbfv[1] = to_rbf;
217                                                /* insert in edge lists */
218        newmig->enxt[0] = from_rbf->ejl;
219        from_rbf->ejl = newmig;
220        newmig->enxt[1] = to_rbf->ejl;
221        to_rbf->ejl = newmig;
222        newmig->next = mig_list;                /* push onto global list */
223        return(mig_list = newmig);
224 }
225
226 #ifdef _WIN32
227 #define await_children(n)       (void)(n)
228 #define run_subprocess()        0
229 #define end_subprocess()        (void)0
230 #else
231
232 /* Wait for the specified number of child processes to complete */
233 static void
234 await_children(int n)
235 {
236        int     exit_status = 0;
237
238        if (n > nchild)
239                n = nchild;
240        while (n-- > 0) {
241                int     status;
242                if (wait(&status) < 0) {
243                        fprintf(stderr, "%s: missing child(ren)!\n", progname);
244                        nchild = 0;
245                        break;
246                }
247                --nchild;
248                if (status) {                   /* something wrong */
249                        if ((status = WEXITSTATUS(status)))
250                                exit_status = status;
251                        else
252                                exit_status += !exit_status;
253                        fprintf(stderr, "%s: subprocess died\n", progname);
254                        n = nchild;             /* wait for the rest */
255                }
256        }
257        if (exit_status)
258                exit(exit_status);
259 }
260
261 /* Start child process if multiprocessing selected */
262 static pid_t
263 run_subprocess(void)
264 {
265        int     status;
266        pid_t   pid;
267
268        if (nprocs <= 1)                        /* any children requested? */
269                return(0);
270        await_children(nchild + 1 - nprocs);    /* free up child process */
271        if ((pid = fork())) {
272                if (pid < 0) {
273                        fprintf(stderr, "%s: cannot fork subprocess\n",
274                                        progname);
275                        exit(1);
276                }
277                ++nchild;                       /* subprocess started */
278                return(pid);
279        }
280        nchild = -1;
281        return(0);                              /* put child to work */
282 }
283
284 /* If we are in subprocess, call exit */
285 #define end_subprocess()        if (nchild < 0) _exit(0); else
286
287 #endif  /* ! _WIN32 */
288
289   /* Compute and insert migration along directed edge (may fork child) */
290   static MIGRATION *
291   create_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
292   {
293 <        const double    end_thresh = 0.1/(from_rbf->nrbf*to_rbf->nrbf);
294 <        const double    check_thresh = 0.01;
295 <        const double    rel_thresh = 5e-6;
293 >        const double    end_thresh = 5e-6;
294          float           *pmtx;
295          MIGRATION       *newmig;
296          double          *src_rem, *dst_rem;
# Line 318 | Line 316 | create_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
316   #ifdef DEBUG
317          fprintf(stderr, "Building path from (theta,phi) %s ",
318                          thetaphi(from_rbf->invec));
319 <        fprintf(stderr, "to %s", thetaphi(to_rbf->invec));
320 <        /* if (nchild) */ fputc('\n', stderr);
319 >        fprintf(stderr, "to %s with %d x %d matrix\n",
320 >                        thetaphi(to_rbf->invec),
321 >                        from_rbf->nrbf, to_rbf->nrbf);
322   #endif
323                                                  /* starting quantities */
324          memset(newmig->mtx, 0, sizeof(float)*from_rbf->nrbf*to_rbf->nrbf);
# Line 332 | Line 331 | create_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
331                  total_rem -= move_amt;
332   #ifdef DEBUG
333                  if (!nchild)
334 <                        /* fputc('.', stderr); */
336 <                        fprintf(stderr, "%.9f remaining...\r", total_rem);
334 >                        fprintf(stderr, "\r%.9f remaining...", total_rem);
335   #endif
336 <        } while (total_rem > end_thresh && (total_rem > check_thresh) |
339 <                                        (move_amt > rel_thresh*total_rem));
336 >        } while ((total_rem > end_thresh) & (move_amt > 0));
337   #ifdef DEBUG
338 <        if (!nchild) fputs("\ndone.\n", stderr);
338 >        if (!nchild) fputs("done.\n", stderr);
339          else fprintf(stderr, "finished with %.9f remaining\n", total_rem);
340   #endif
341          for (i = from_rbf->nrbf; i--; ) {       /* normalize final matrix */
# Line 347 | Line 344 | create_migration(RBFNODE *from_rbf, RBFNODE *to_rbf)
344              if (nf <= FTINY) continue;
345              nf = from_rbf->vtotal / nf;
346              for (j = to_rbf->nrbf; j--; )
347 <                newmig->mtx[mtx_ndx(newmig,i,j)] *= nf;
347 >                mtx_coef(newmig,i,j) *= nf;
348          }
349          end_subprocess();                       /* exit here if subprocess */
350          free(pmtx);                             /* free working arrays */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines