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.12 by greg, Thu Oct 16 18:36:23 2025 UTC vs.
Revision 2.23 by greg, Tue Nov 11 02:08:52 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 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 +        if (op == RCOrecover && access(name, R_OK|W_OK) < 0) {
124 +                sprintf(errmsg, "cannot recover from '%s'", name);
125 +                error(SYSTEM, errmsg);
126 +                return NULL;
127 +        }
128 +        RdataShare *    rds = new RdataShareFile(name, RSDOflags[op],
129 +                                                 siz*(op != RCOforce));
130 +                                                
131 +        if (!rds || (op == RCOforce && rds->Resize(siz) < siz)) {
132 +                delete rds;
133 +                sprintf(errmsg, "cannot create %lu byte output file '%s'",
134 +                                        (unsigned long)siz, name);
135 +                error(SYSTEM, errmsg);
136 +                return NULL;
137 +        }
138 +        return rds;
139 + }
140 +
141 + // Memory-mapped data share function
142 + RdataShare *
143 + mapDataShare(const char *name, RCOutputOp op, size_t siz)
144 + {
145 +        if (op == RCOrecover && access(name, R_OK|W_OK) < 0) {
146 +                sprintf(errmsg, "cannot recover from '%s'", name);
147 +                error(SYSTEM, errmsg);
148 +                return NULL;
149 +        }
150 +        RdataShare *    rds = new RdataShareMap(name, RSDOflags[op],
151 +                                                 siz*(op != RCOforce));
152 +
153 +        if (!rds || (op == RCOforce && rds->Resize(siz) < siz)) {
154 +                delete rds;
155 +                sprintf(errmsg, "cannot create %lu byte output map '%s'",
156 +                                        (unsigned long)siz, name);
157 +                error(SYSTEM, errmsg);
158 +                return NULL;
159 +        }
160 +        return rds;
161 + }
162 +
163   // Set output format ('f', 'd', or 'c')
164   bool
165   RcontribSimulManager::SetDataFormat(int ty)
# Line 163 | Line 203 | RcontribSimulManager::RctCall(RAY *r, void *cd)
203          if (!mp)
204                  return 0;               // not in our modifier list
205  
206 <        int                     bi = 0; // get bin index
206 >        int     i;                      // pre-emptive check for zero
207 >        if (rcp->HasFlag(RCcontrib)) {
208 >                for (i = NCSAMP; i--; )
209 >                        if (r->rcoef[i]*r->rcol[i] > FTINY)
210 >                                break;
211 >                if (i < 0)
212 >                        return 0;       // zero contribution
213 >        } else if (sintens(r->rcoef) <= FTINY)
214 >                return 0;               // zero coefficient
215 >
216 >        int     bi = 0;                 // get bin index
217          if (mp->binv) {
218                  worldfunc(RCCONTEXT, r);
219                  set_eparams(mp->params);
# Line 183 | Line 233 | RcontribSimulManager::RctCall(RAY *r, void *cd)
233          if (rcp->HasFlag(RCcontrib))
234                  smultscolor(contr, r->rcol);    // -> value contribution
235  
236 <        for (int i = 0; i < NCSAMP; i++)
236 >        for (i = 0; i < NCSAMP; i++)
237                  *dvp++ += contr[i];             // accumulate color/spectrum
238          return 1;
239   }
# Line 377 | Line 427 | RcontribSimulManager::PrepOutput()
427                          if (rd < 0)
428                                  return -1;
429                          if (rd >= op->nRows) {
430 <                                if (remWarnings >= 0) {
430 >                                if (remWarnings > 0) {
431                                          sprintf(errmsg, "recovered output '%s' is complete",
432                                                          op->GetName());
433                                          error(WARNING, --remWarnings ? errmsg : "etc...");
# Line 394 | Line 444 | RcontribSimulManager::PrepOutput()
444          }
445          rowsDone.NewBitMap(outList->nRows);     // create row completion map
446          rowsDone.ClearBits(0, rInPos, true);
447 <        return rInPos;
447 >        return nrDone = rInPos;
448   }
449  
450   // Create header in open write-only channel
# Line 429 | Line 479 | RcontribOutput::NewHeader(const RcontribSimulManager *
479          sprintf(hdr+begData, "%s%d\n", NCOMPSTR, NCSAMP);
480          begData += strlen(hdr+begData);
481          if (NCSAMP > 3) {
482 <                sprintf(hdr+begData, "%s %f %f %f %f\n", WLSPLTSTR,
482 >                sprintf(hdr+begData, "%s %g %g %g %g\n", WLSPLTSTR,
483                                  WLPART[0], WLPART[1], WLPART[2], WLPART[3]);
484                  begData += strlen(hdr+begData);
485          }
# Line 514 | Line 564 | RcontribOutput::CheckHeader(const RcontribSimulManager
564                  return -1;
565          }
566                                                  // check #columns
567 <        if (((cp = findArgs(hdr, "NCOLS=", begData)) && atoi(cp)*esiz != rowBytes) ||
568 <                        !rcp->xres | (rowBytes > esiz)) {
569 <                sprintf(errmsg, "expected NCOLS=%d in '%s'",
520 <                                int(rowBytes/esiz), GetName());
567 >        if ((cp = findArgs(hdr, "NCOLS=", begData)) ? (atoi(cp)*esiz != rowBytes)
568 >                                                    : (!rcp->xres | (rowBytes > esiz))) {
569 >                sprintf(errmsg, "expected NCOLS=%d in '%s'", int(rowBytes/esiz), GetName());
570                  error(USER, errmsg);
571                  return -1;
572          }
# Line 559 | Line 608 | RcontribSimulManager::ResetRow(int r)
608                          return false;
609  
610          rowsDone.ClearBits(r, rInPos-r, false);
611 <        rInPos = r;
611 >        nrDone = rInPos = r;
612          return true;
613   }
614  
# Line 606 | Line 655 | putModContrib(const LUENT *lp, void *p)
655                  }
656                  } break;
657          default:
658 <                error(CONSISTENCY, "unsupported output type in sendModContrib()");
658 >                error(CONSISTENCY, "unsupported output type in putModContrib()");
659                  return -1;
660          }
661                                                  // clear for next tally
# Line 625 | Line 674 | RcontribSimulManager::ComputeRecord(const FVECT orig_d
674                  return 0;
675          }
676          if (nkids > 0) {                        // in parent process?
677 <                int     k = GetChild();         // updates output rows
678 <                if (k < 0) return -1;           // can't really happen
677 >                int     k = GetChild(false);    // updates output rows
678 >                if (k < 0) return -1;           // someone died?
679                  RowAssignment   rass;
680                  rass.row = kidRow[k] = rInPos++;
681                  rass.ac = accum;
# Line 671 | Line 720 | RcontribSimulManager::GetChild(bool forceWait)
720                  return -1;
721                                                  // take inventory
722          int     pn, n = 0;
723 <        fd_set  writeset, errset;
724 <        FD_ZERO(&writeset); FD_ZERO(&errset);
723 >        fd_set  readset, errset;
724 >        FD_ZERO(&readset); FD_ZERO(&errset);
725          for (pn = nkids; pn--; ) {
726                  if (kidRow[pn] < 0) {           // child already ready?
727                          if (forceWait) continue;
728                          return pn;              // good enough
729                  }
730 <                FD_SET(kid[pn].w, &writeset);   // will check on this one
731 <                FD_SET(kid[pn].w, &errset);
732 <                if (kid[pn].w >= n)
733 <                        n = kid[pn].w + 1;
730 >                FD_SET(kid[pn].r, &readset);    // will check on this one
731 >                FD_SET(kid[pn].r, &errset);
732 >                if (kid[pn].r >= n)
733 >                        n = kid[pn].r + 1;
734          }
735          if (!n)                                 // every child is idle?
736                  return -1;
737                                                  // wait on "busy" child(ren)
738 <        while ((n = select(n, NULL, &writeset, &errset, NULL)) <= 0)
738 >        while ((n = select(n, &readset, NULL, &errset, NULL)) <= 0)
739                  if (errno != EINTR) {
740                          error(SYSTEM, "select call failed in GetChild()");
741                          return -1;
742                  }
743 +        char    buf[sizeof(ROW_DONE)] = "X";
744          pn = -1;                                // get flags set by select
745          for (n = nkids; n--; )
746                  if (kidRow[n] >= 0 &&
747 <                                FD_ISSET(kid[n].w, &writeset) |
748 <                                FD_ISSET(kid[n].w, &errset)) {
747 >                                FD_ISSET(kid[n].r, &readset) |
748 >                                FD_ISSET(kid[n].r, &errset)) {
749 >                                                // check for error
750 >                        if (FD_ISSET(kid[n].r, &errset) ||
751 >                                        read(kid[n].r, buf, sizeof(ROW_DONE)) <= 0 ||
752 >                                        memcmp(buf, ROW_DONE, sizeof(ROW_DONE)))
753 >                                return -1;
754                                                  // update output row counts
755 <                        if (!FD_ISSET(kid[n].w, &errset))
756 <                                UpdateRowsDone(kidRow[n]);
702 <                        kidRow[n] = -1;         // flag it available
755 >                        UpdateRowsDone(kidRow[n]);
756 >                        kidRow[n] = -1;         // flag child available
757                          pn = n;
758                  }
759          return pn;
# Line 713 | Line 767 | RcontribSimulManager::UpdateRowsDone(int r)
767                  error(WARNING, "redundant call to UpdateRowsDone()");
768                  return false;
769          }
770 <        int     nDone = GetRowFinished();
771 <        if (nDone <= r)
770 >        GetRowFinished();
771 >        if (nrDone <= r)
772                  return true;                    // nothing to update, yet
773          for (RcontribOutput *op = outList; op; op = op->next)
774 <                if (!op->SetRowsDone(nDone))
774 >                if (!op->SetRowsDone(nrDone))
775                          return false;
776          return true;                            // up-to-date
777   }
# Line 737 | Line 791 | RcontribSimulManager::RunChild()
791                          error(CONSISTENCY, "bad accumulator count in child");
792                          exit(1);
793                  }
794 <                if (rass.ac > accum)
795 <                        vecList = (FVECT *)erealloc(vecList,
796 <                                                sizeof(FVECT)*2*rass.ac);
794 >                if (rass.ac > accum) {
795 >                        efree(vecList);
796 >                        vecList = (FVECT *)emalloc(sizeof(FVECT)*2*rass.ac);
797 >                }
798                  accum = rass.ac;
799                  rInPos = rass.row;
800  
# Line 749 | Line 804 | RcontribSimulManager::RunChild()
804  
805                  if (ComputeRecord(vecList) <= 0)
806                          exit(1);
807 +                                                // signal this row is done
808 +                if (write(1, ROW_DONE, sizeof(ROW_DONE)) != sizeof(ROW_DONE))
809 +                        exit(1);
810          }
811          if (nr) {
812                  error(SYSTEM, "read error in child process");
# Line 774 | Line 832 | RcontribSimulManager::StartKids(int n2go)
832          fflush(stdout);                         // shouldn't use, anyway
833          while (nkids < n2go) {
834                  kid[nkids] = sp_inactive;
777                kid[nkids].w = dup(1);
778                kid[nkids].flags |= PF_FILT_OUT;
835                  int     rv = open_process(&kid[nkids], NULL);
836                  if (!rv) {                      // in child process?
837 <                        while (nkids-- > 0)
837 >                        while (nkids-- > 0) {
838 >                                close(kid[nkids].r);
839                                  close(kid[nkids].w);
840 +                        }
841                          free(kid); free(kidRow);
842                          kid = NULL; kidRow = NULL;
843                          RunChild();             // should never return

Diff Legend

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