ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/Development/ray/src/rt/RcontribSimulManager.cpp
(Generate patch)

Comparing ray/src/rt/RcontribSimulManager.cpp (file contents):
Revision 2.10 by greg, Tue Dec 10 00:38:59 2024 UTC vs.
Revision 2.17 by greg, Thu Oct 23 16:33:39 2025 UTC

# Line 52 | Line 52 | struct RowAssignment {
52          uint32                  ac;             // accumulation count
53   };
54  
55 < // Get format identifier
56 < const char *
57 < formstr(int f)
58 < {
59 <        switch (f) {
60 <        case 'a': return("ascii");
61 <        case 'f': return("float");
62 <        case 'd': return("double");
63 <        case 'c': return(NCSAMP==3 ? COLRFMT : SPECFMT);
64 <        }
65 <        return("unknown");
66 < }
55 > static const char       ROW_DONE[] = "ROW FINISHED\n";
56  
57 < // Our default data share function
58 < RdataShare *
70 < defDataShare(const char *name, RCOutputOp op, size_t siz)
71 < {
72 <        return new RdataShareMap(name, RSDOflags[op], siz);
73 < }
74 <
75 < // Allocate rcontrib accumulator
76 < RcontribMod *
57 > // allocate rcontrib accumulator
58 > static RcontribMod *
59   NewRcMod(const char *prms, const char *binexpr, int ncbins)
60   {
61 +        if (binexpr && !*binexpr) binexpr = NULL;
62          if (!prms) prms = "";
63          if ((ncbins > 1) & !binexpr) {
64                  error(USER, "missing bin expression");
# Line 87 | Line 70 | NewRcMod(const char *prms, const char *binexpr, int nc
70                                                  sizeof(DCOLORV)*(NCSAMP*ncbins-1) +
71                                                  strlen(prms)+1);
72  
73 <        if (binexpr) {                          // check bin expression
73 >        if (binexpr) {                          // get/check bin expression
74                  mp->binv = eparse(const_cast<char *>(binexpr));
75                  if (mp->binv->type == NUM) {    // constant expression (0)?
76 <                        if ((int)(evalue(mp->binv) + .5) > 0) {
77 <                                sprintf(errmsg, "illegal positive constant for bin (%s)",
76 >                        if ((int)evalue(mp->binv) != 0) {
77 >                                sprintf(errmsg, "illegal non-zero constant for bin (%s)",
78                                                  binexpr);
79                                  error(USER, errmsg);
80                          }
# Line 110 | Line 93 | NewRcMod(const char *prms, const char *binexpr, int nc
93          return mp;
94   }
95  
96 < // Free an RcontribMod
96 > // Free an RcontribMod (public for RcontribSimulManager constructor)
97   void
98   FreeRcMod(void *p)
99   {
# Line 120 | Line 103 | FreeRcMod(void *p)
103          efree(p);
104   }
105  
106 + // Get format identifier
107 + const char *
108 + formstr(int f)
109 + {
110 +        switch (f) {
111 +        case 'a': return("ascii");
112 +        case 'f': return("float");
113 +        case 'd': return("double");
114 +        case 'c': return(NCSAMP==3 ? COLRFMT : SPECFMT);
115 +        }
116 +        return("unknown");
117 + }
118 +
119 + // Standard file data share function
120 + RdataShare *
121 + fileDataShare(const char *name, RCOutputOp op, size_t siz)
122 + {
123 +        return new RdataShareFile(name, RSDOflags[op], siz);
124 + }
125 +
126 + // Memory-mapped data share function
127 + RdataShare *
128 + mapDataShare(const char *name, RCOutputOp op, size_t siz)
129 + {
130 +        return new RdataShareMap(name, RSDOflags[op], siz);
131 + }
132 +
133   // Set output format ('f', 'd', or 'c')
134   bool
135   RcontribSimulManager::SetDataFormat(int ty)
# Line 182 | Line 192 | RcontribSimulManager::RctCall(RAY *r, void *cd)
192          raycontrib(contr, r, PRIMARY);          // compute coefficient
193          if (rcp->HasFlag(RCcontrib))
194                  smultscolor(contr, r->rcol);    // -> value contribution
195 +
196          for (int i = 0; i < NCSAMP; i++)
197                  *dvp++ += contr[i];             // accumulate color/spectrum
198          return 1;
# Line 214 | Line 225 | RcontribSimulManager::AddModifier(const char *modn, co
225                  error(WARNING, "ignoring bad call to AddModifier()");
226                  return false;
227          }
228 +        if (*outspec == '!') {
229 +                error(USER, "command output not supported by RcontribSimulManager");
230 +                return false;
231 +        }
232          if (!nChan) {                           // initial call?
233                  if ((xres < 0) | (yres <= 0)) {
234                          error(USER, "xres, yres must be set before first modifier");
# Line 223 | Line 238 | RcontribSimulManager::AddModifier(const char *modn, co
238                          return false;
239                  nChan = NCSAMP;
240          } else if (nChan != NCSAMP) {
241 <                error(USER, "number of spectral channels must be fixed");
241 >                error(USER, "# spectral channels must be fixed in AddModifier()");
242                  return false;
243          }
244          if (Ready()) {
# Line 319 | Line 334 | RcontribSimulManager::AddModFile(const char *modfn, co
334          }
335          char            mod[MAXSTR];
336          while (fgetword(mod, sizeof(mod), fp))
337 <                if (!AddModifier(mod, outspec, prms, binval, bincnt))
337 >                if (!AddModifier(mod, outspec, prms, binval, bincnt)) {
338 >                        fclose(fp);
339                          return false;
340 +                }
341          fclose(fp);
342          return true;
343   }
# Line 329 | Line 346 | RcontribSimulManager::AddModFile(const char *modfn, co
346   static int
347   checkModExists(const LUENT *lp, void *p)
348   {
349 <        if (modifier(lp->key) != OVOID)
349 >        OBJECT  mod = modifier(lp->key);
350 >
351 >        if ((mod != OVOID) & (mod < nsceneobjs))
352                  return 1;
353  
354          sprintf(errmsg, "tracked modifier '%s' not found in main scene", lp->key);
# Line 342 | Line 361 | int
361   RcontribSimulManager::PrepOutput()
362   {
363          if (!outList || !RtraceSimulManager::Ready()) {
364 <                error(INTERNAL, "PrepOutput() called before octree & modifiers assigned");
364 >                error(INTERNAL, "PrepOutput() called before octree & modifiers set");
365                  return -1;
366          }
367          if (!cdsF) {
368 <                error(INTERNAL, "missing RdataShare constructor call (*cdsF)");
368 >                error(INTERNAL, "missing RdataShare constructor call (cdsF)");
369                  return -1;
370          }
371          if (lu_doall(&modLUT, checkModExists, NULL) < 0)
372                  return -1;
373  
374 +        outList->nRows = yres * (xres + !xres); // all outputs have same #rows
375          int     remWarnings = 20;
376          for (RcontribOutput *op = outList; op; op = op->next) {
377                  if (op->rData) {
378                          error(INTERNAL, "output channel already open in PrepOutput()");
379                          return -1;
380                  }
381 <                op->nRows = yres * (xres + !xres);
381 >                op->nRows = outList->nRows;
382                  op->rData = (*cdsF)(op->ofname, outOp,
383                                          GetHeadLen()+1024 + op->nRows*op->rowBytes);
384                  freeqstr(op->ofname); op->ofname = NULL;
# Line 368 | Line 388 | RcontribSimulManager::PrepOutput()
388                                  return -1;
389                          if (rd >= op->nRows) {
390                                  if (remWarnings >= 0) {
391 <                                        sprintf(errmsg, "recovered output '%s' already done",
391 >                                        sprintf(errmsg, "recovered output '%s' is complete",
392                                                          op->GetName());
393 <                                        error(WARNING, remWarnings ? errmsg : "etc...");
374 <                                        remWarnings--;
393 >                                        error(WARNING, --remWarnings ? errmsg : "etc...");
394                                  }
395                                  rd = op->nRows;
396                          }
# Line 597 | Line 616 | putModContrib(const LUENT *lp, void *p)
616                  }
617                  } break;
618          default:
619 <                error(CONSISTENCY, "unsupported output type in sendModContrib()");
619 >                error(CONSISTENCY, "unsupported output type in putModContrib()");
620                  return -1;
621          }
622                                                  // clear for next tally
# Line 616 | Line 635 | RcontribSimulManager::ComputeRecord(const FVECT orig_d
635                  return 0;
636          }
637          if (nkids > 0) {                        // in parent process?
638 <                int     k = GetChild();         // updates output rows
639 <                if (k < 0) return -1;           // can't really happen
638 >                int     k = GetChild(false);    // updates output rows
639 >                if (k < 0) return -1;           // someone died?
640                  RowAssignment   rass;
641                  rass.row = kidRow[k] = rInPos++;
642                  rass.ac = accum;
# Line 662 | Line 681 | RcontribSimulManager::GetChild(bool forceWait)
681                  return -1;
682                                                  // take inventory
683          int     pn, n = 0;
684 <        fd_set  writeset, errset;
685 <        FD_ZERO(&writeset); FD_ZERO(&errset);
684 >        fd_set  readset, errset;
685 >        FD_ZERO(&readset); FD_ZERO(&errset);
686          for (pn = nkids; pn--; ) {
687                  if (kidRow[pn] < 0) {           // child already ready?
688                          if (forceWait) continue;
689                          return pn;              // good enough
690                  }
691 <                FD_SET(kid[pn].w, &writeset);   // will check on this one
692 <                FD_SET(kid[pn].w, &errset);
693 <                if (kid[pn].w >= n)
694 <                        n = kid[pn].w + 1;
691 >                FD_SET(kid[pn].r, &readset);    // will check on this one
692 >                FD_SET(kid[pn].r, &errset);
693 >                if (kid[pn].r >= n)
694 >                        n = kid[pn].r + 1;
695          }
696          if (!n)                                 // every child is idle?
697                  return -1;
698                                                  // wait on "busy" child(ren)
699 <        while ((n = select(n, NULL, &writeset, &errset, NULL)) <= 0)
699 >        while ((n = select(n, &readset, NULL, &errset, NULL)) <= 0)
700                  if (errno != EINTR) {
701                          error(SYSTEM, "select call failed in GetChild()");
702                          return -1;
703                  }
704 +        char    buf[sizeof(ROW_DONE)] = "X";
705          pn = -1;                                // get flags set by select
706          for (n = nkids; n--; )
707                  if (kidRow[n] >= 0 &&
708 <                                FD_ISSET(kid[n].w, &writeset) |
709 <                                FD_ISSET(kid[n].w, &errset)) {
708 >                                FD_ISSET(kid[n].r, &readset) |
709 >                                FD_ISSET(kid[n].r, &errset)) {
710 >                                                // check for error
711 >                        if (FD_ISSET(kid[n].r, &errset) ||
712 >                                        read(kid[n].r, buf, sizeof(ROW_DONE)) <= 0 ||
713 >                                        memcmp(buf, ROW_DONE, sizeof(ROW_DONE)))
714 >                                return -1;
715                                                  // update output row counts
716 <                        if (!FD_ISSET(kid[n].w, &errset))
717 <                                UpdateRowsDone(kidRow[n]);
693 <                        kidRow[n] = -1;         // flag it available
716 >                        UpdateRowsDone(kidRow[n]);
717 >                        kidRow[n] = -1;         // flag child available
718                          pn = n;
719                  }
720          return pn;
# Line 728 | Line 752 | RcontribSimulManager::RunChild()
752                          error(CONSISTENCY, "bad accumulator count in child");
753                          exit(1);
754                  }
755 <                if (rass.ac > accum)
756 <                        vecList = (FVECT *)erealloc(vecList,
757 <                                                sizeof(FVECT)*2*rass.ac);
755 >                if (rass.ac > accum) {
756 >                        efree(vecList);
757 >                        vecList = (FVECT *)emalloc(sizeof(FVECT)*2*rass.ac);
758 >                }
759                  accum = rass.ac;
760                  rInPos = rass.row;
761  
# Line 740 | Line 765 | RcontribSimulManager::RunChild()
765  
766                  if (ComputeRecord(vecList) <= 0)
767                          exit(1);
768 +                                                // signal this row is done
769 +                if (write(1, ROW_DONE, sizeof(ROW_DONE)) != sizeof(ROW_DONE))
770 +                        exit(1);
771          }
772          if (nr) {
773                  error(SYSTEM, "read error in child process");
# Line 765 | Line 793 | RcontribSimulManager::StartKids(int n2go)
793          fflush(stdout);                         // shouldn't use, anyway
794          while (nkids < n2go) {
795                  kid[nkids] = sp_inactive;
768                kid[nkids].w = dup(1);
769                kid[nkids].flags |= PF_FILT_OUT;
796                  int     rv = open_process(&kid[nkids], NULL);
797                  if (!rv) {                      // in child process?
798 <                        while (nkids-- > 0)
798 >                        while (nkids-- > 0) {
799 >                                close(kid[nkids].r);
800                                  close(kid[nkids].w);
801 +                        }
802                          free(kid); free(kidRow);
803                          kid = NULL; kidRow = NULL;
804                          RunChild();             // should never return

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)