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

Comparing ray/src/util/pvsum.c (file contents):
Revision 2.1 by greg, Thu Mar 27 01:26:55 2025 UTC vs.
Revision 2.5 by greg, Fri Jun 6 18:26:22 2025 UTC

# Line 11 | Line 11 | static const char RCSid[] = "$Id$";
11   #include "resolu.h"
12   #include "platform.h"
13   #include "paths.h"
14 + #include "random.h"
15   #include "rmatrix.h"
16   #if !defined(_WIN32) && !defined(_WIN64)
17   #include <sys/mman.h>
18 + #include <sys/wait.h>
19   #endif
20  
21   int     nprocs = 1;                     /* # of calculation processes (Unix) */
# Line 67 | Line 69 | iheadline(char *s, void *p)
69                  ncomp = ncompval(s);
70                  return(1);
71          }
70        if (isexpos(s)) {
71                if (fabs(1. - exposval(s)) > 0.04)
72                        fputs("Warning - ignoring EXPOSURE setting\n", stderr);
73                return(1);
74        }
72          if (formatval(fmt, s)) {
73                  for (in_type = DTend; --in_type > DTfromHeader; )
74                          if (!strcmp(fmt, cm_fmt_id[in_type]))
# Line 154 | Line 151 | get_iotypes(void)
151   int
152   checkline(char *s, void *p)
153   {
154 <        int     *xyres = (int *)p;
155 <        char    fmt[MAXFMTLEN];
154 >        static int      exposWarned = 0;
155 >        int             *xyres = (int *)p;
156 >        char            fmt[MAXFMTLEN];
157  
158          if (!strncmp(s, "NCOLS=", 6)) {
159                  xyres[0] = atoi(s+6);
# Line 175 | Line 173 | checkline(char *s, void *p)
173                  return(1);
174          }
175          if (isexpos(s)) {
176 <                if (fabs(1. - exposval(s)) > 0.04)
177 <                        fputs("Warning - ignoring EXPOSURE setting\n", stderr);
176 >                if (!exposWarned && fabs(1. - exposval(s)) > 0.04) {
177 >                        fputs("Warning - ignoring EXPOSURE setting(s)\n",
178 >                                        stderr);
179 >                        exposWarned++;
180 >                }
181                  return(1);
182          }
183          if (formatval(fmt, s)) {
# Line 227 | Line 228 | open_output(char *ospec, int fno)
228          if (!ospec) {
229                  ospec = "<stdout>";
230                  fp = stdout;
230                SET_FILE_BINARY(fp);
231          } else if (ospec[0] == '!') {
232                  if (!(fp = popen(ospec+1, "w"))) {
233                          fprintf(stderr, "Cannot start: %s\n", ospec);
234                          return(NULL);
235                  }
236 <                SET_FILE_BINARY(fp);
237 <        } else if (!(fp = fopen(ospec, "wb"))) {
236 >        } else if (!(fp = fopen(ospec, "w"))) {
237                  fprintf(stderr, "%s: cannot open for writing\n", ospec);
238                  return(NULL);
239          }
240 +        SET_FILE_BINARY(fp);
241          newheader("RADIANCE", fp);
242 <        fputnow(fp);
242 >        if (cmtx->info)                 /* prepend matrix metadata */
243 >                fputs(cmtx->info, fp);
244 >        else
245 >                fputnow(fp);
246          if (fno >= 0)
247                  fprintf(fp, "FRAME=%d\n", fno);
248          switch (out_type) {
# Line 377 | Line 380 | writerr:
380          return(0);
381   }
382  
383 + /* allocate a scrambled index array of the specified length */
384 + int *
385 + scramble(int n)
386 + {
387 +        int     *scarr = (int *)malloc(sizeof(int)*n);
388 +        int     i;
389 +
390 +        if (!scarr) {
391 +                fprintf(stderr, "Out of memory in scramble(%d)\n", n);
392 +                exit(1);
393 +        }
394 +        for (i = n; i--; )
395 +                scarr[i] = i;
396 +                                        /* perform Fisher-Yates shuffle */
397 +        for (i = 0; i < n-1; i++) {
398 +                int     ix = irandom(n-i) + i;
399 +                int     ndx = scarr[i];
400 +                scarr[i] = scarr[ix];
401 +                scarr[ix] = ndx;
402 +        }
403 +        return(scarr);
404 + }
405 +
406   /* run calculation on multiple processes, using memory maps and fork() */
407   int
408   multi_process(void)
# Line 389 | Line 415 | multi_process(void)
415          int     odd = 0;
416          char    fbuf[512];
417          float   *osum;
418 +        int     *syarr;
419          int     c;
420                                          /* sanity check */
421          if (sizeof(float) != sizeof(COLORV)) {
# Line 409 | Line 436 | multi_process(void)
436                                  xres, yres, ncomp);
437                  return(0);
438          }
439 +        srandom(113*coff + 5669);       /* randomize row access for this process */
440 +        syarr = scramble(yres);
441                                          /* run through our unique set of columns */
442          for (c = coff; c < cmtx->ncols; c += nprocs) {
443                  FILE    *fout;
# Line 419 | Line 448 | multi_process(void)
448                  while (rc-- > 0) {      /* map & sum each input file */
449                          const int       r = odd ? rc : cmtx->nrows-1 - rc;
450                          const rmx_dtype *cval = rmx_val(cmtx, r, c);
451 <                        long            dstart, n;
451 >                        long            dstart;
452                          size_t          maplen;
453                          void            *imap;
454                          FILE            *finp;
455                          float           *dst;
456 <                        int             i;
456 >                        int             i, x;
457                          for (i = ncomp; i--; )
458                                  if (cval[i] != 0) break;
459                          if (i < 0)      /* this coefficient is zero, skip */
# Line 446 | Line 475 | multi_process(void)
475                          maplen = dstart + yres*xres*i;
476                          imap = mmap(NULL, maplen, PROT_READ,
477                                          MAP_FILE|MAP_SHARED, fileno(finp), 0);
478 <                        fclose(finp);           /* will load from map */
478 >                        fclose(finp);           /* will read from map (randomly) */
479                          if (imap == MAP_FAILED) {
480                                  fprintf(stderr, "%s: unable to map input file\n", fbuf);
481                                  return(0);
482                          }
483 <                        dst = osum;             /* -> weighted image sum */
484 <                        if (in_type == DTfloat) {
485 <                            const float *fvp = (float *)((char *)imap + dstart);
486 <                            for (n = (long)yres*xres; n-- > 0;
487 <                                                        dst += ncomp, fvp += ncomp)
488 <                                for (i = ncomp; i--; )
489 <                                    dst[i] += cval[i]*fvp[i];
490 <                        } else {
462 <                            const COLRV *cvp = (COLRV *)((char *)imap + dstart);
463 <                            for (n = (long)yres*xres; n-- > 0;
464 <                                                        dst += ncomp, cvp += ncomp+1) {
465 <                                const rmx_dtype fe = cxponent[cvp[ncomp]];
466 <                                for (i = ncomp; i--; )
467 <                                    dst[i] += cval[i]*(cvp[i]+(rmx_dtype).5)*fe;
483 >                        if (in_type == DTfloat)
484 >                            for (y = yres; y-- > 0; ) {
485 >                                const float     *fvp = (float *)((char *)imap + dstart) +
486 >                                                        (size_t)ncomp*xres*syarr[y];
487 >                                dst = osum + (size_t)ncomp*xres*syarr[y];
488 >                                for (x = xres; x-- > 0; dst += ncomp, fvp += ncomp)
489 >                                    for (i = ncomp; i--; )
490 >                                        dst[i] += cval[i]*fvp[i];
491                              }
492 <                        }
492 >                        else
493 >                            for (y = yres; y-- > 0; ) {
494 >                                const COLRV     *cvp = (COLRV *)((char *)imap + dstart) +
495 >                                                        (ncomp+1L)*xres*syarr[y];
496 >                                dst = osum + (size_t)ncomp*xres*syarr[y];
497 >                                for (x = xres; x-- > 0; dst += ncomp, cvp += ncomp+1) {
498 >                                    const rmx_dtype     fe = cxponent[cvp[ncomp]];
499 >                                    for (i = ncomp; i--; )
500 >                                        dst[i] += cval[i]*(cvp[i]+(rmx_dtype).5)*fe;
501 >                                }
502 >                            }
503                          munmap(imap, maplen);
504 <                }                       /* write out accumulated column result */
504 >                }                       /* write accumulated column picture/matrix */
505                  sprintf(fbuf, out_spec, c);
506                  fout = open_output(fbuf, c);
507                  if (!fout)
# Line 492 | Line 525 | multi_process(void)
525                  odd = !odd;             /* go back & forth to milk page cache */
526          }
527          free(osum);
528 <        if (coff)                       /* children return here... */
528 >        free(syarr);
529 >        if (coff)                       /* child processes return here... */
530                  return(1);
531          c = 0;                          /* ...but parent waits for children */
532          while (++coff < nprocs) {
# Line 544 | Line 578 | badopt:                        fprintf(stderr, "%s: bad option: %s\n", argv
578          if ((argc-a < 1) | (argc-a > 2) || argv[a][0] == '-')
579                  goto userr;
580          in_spec = argv[a];
581 <        cmtx = rmx_load(argv[a+1], RMPnone);    /* may load from stdin */
581 >        cmtx = rmx_load(argv[a+1]);     /* loads from stdin if a+1==argc */
582          if (cmtx == NULL)
583                  return(1);              /* error reported */
584 +        if (nprocs > cmtx->ncols)
585 +                nprocs = cmtx->ncols;
586   #if defined(_WIN32) || defined(_WIN64)
587          if (nprocs > 1) {
588                  fprintf(stderr, "%s: warning - Windows only allows -N 1\n", argv[0]);
589                  nprocs = 1;
590          }
591   #else
556        if (nprocs > cmtx->ncols)
557                nprocs = cmtx->ncols;
592          if ((nprocs > 1) & !out_spec) {
593                  fprintf(stderr, "%s: multi-processing result cannot go to stdout\n",
594                                  argv[0]);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines