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

Comparing ray/src/rt/RtraceSimulManager.cpp (file contents):
Revision 2.5 by greg, Tue Mar 12 16:54:51 2024 UTC vs.
Revision 2.7 by greg, Wed May 1 20:28:53 2024 UTC

# Line 13 | Line 13 | static const char RCSid[] = "$Id$";
13   #include "RtraceSimulManager.h"
14   #include "source.h"
15  
16 extern int      castonly;       // doing ray-casting only?
17
16   // Load octree and prepare renderer
17   bool
18   RadSimulManager::LoadOctree(const char *octn)
# Line 22 | Line 20 | RadSimulManager::LoadOctree(const char *octn)
20          if (octname) {          // already running?
21                  if (octn && !strcmp(octn, octname))
22                          return true;
23 <                Cleanup(false);
23 >                Cleanup();
24          }
25          if (!octn)
26                  return false;
# Line 35 | Line 33 | RadSimulManager::LoadOctree(const char *octn)
33   int
34   RadSimulManager::GetNCores()
35   {
36 <        return sysconf(_NPROCESSORS_ONLN);
36 >        return sysconf(_SC_NPROCESSORS_ONLN);
37   }
38  
39   // Set number of computation threads (0 => #cores)
40   int
41   RadSimulManager::SetThreadCount(int nt)
42   {
43 <        if (nt <= 0) nt = GetNCores();
43 >        if (!Ready())
44 >                return 0;
45  
46 <        return nThreads = nt;
46 >        if (nt <= 0) nt = castonly ? 1 : GetNCores();
47 >
48 >        if (nt == 1)
49 >                ray_pclose(ray_pnprocs);
50 >        else if (nt < ray_pnprocs)
51 >                ray_pclose(ray_pnprocs - nt);
52 >        else if (nt > ray_pnprocs)
53 >                ray_popen(nt - ray_pnprocs);
54 >
55 >        return NThreads();
56   }
57  
58   // Assign ray to subthread (fails if NThreads()<2)
59   bool
60   RadSimulManager::SplitRay(RAY *r)
61   {
62 <        if (NThreads() < 2 || ThreadsAvailable() < 1)
62 >        if (!ray_pnprocs || ThreadsAvailable() < 1)
63                  return false;
64  
65 <        int     rv = ray_psend(r);
58 <        if (rv < 0)
59 <                nThreads = 1;   // someone died
60 <        return (rv > 0);
65 >        return (ray_psend(r) > 0);
66   }
67  
68   // Process a ray (in subthread), optional result
69   bool
70   RadSimulManager::ProcessRay(RAY *r)
71   {
72 <        if (!r || !Ready()) return false;
73 <        if (NThreads() < 2) {   // single-threaded mode?
72 >        if (!Ready()) return false;
73 >
74 >        if (!ray_pnprocs) {     // single-threaded mode?
75                  samplendx++;
76                  rayvalue(r);
77                  return true;
78          }
79 <        if (ThreadsAvailable() >= 1) {
80 <                SplitRay(r);    // queue not yet full
79 >        int     rv = ray_pqueue(r);
80 >        if (rv < 0) {
81 >                error(WARNING, "ray tracing process(es) died");
82                  return false;
83          }
84 <        RAY     toDo = *r;
78 <        if (!WaitResult(r))     // need a free thread
79 <                return false;
80 <
81 <        return SplitRay(&toDo); // queue up new ray & return old
84 >        return (rv > 0);
85   }
86  
87   // Wait for next result (or fail)
88   bool
89   RadSimulManager::WaitResult(RAY *r)
90   {
91 <        int     rv = ray_presult(r, 0);
92 <        if (rv < 0)
93 <                nThreads = 1;   // someone died
94 <        return (rv > 0);
91 >        if (!ray_pnprocs)
92 >                return false;
93 >
94 >        return (ray_presult(r, 0) > 0);
95   }
96  
97   // Close octree, free data, return status
98   int
99   RadSimulManager::Cleanup(bool everything)
100   {
101 <        if (NThreads() > 1)
101 >        if (!ray_pnprocs)
102                  ray_pdone(everything);
103          else
104                  ray_done(everything);
# Line 106 | Line 109 | RadSimulManager::Cleanup(bool everything)
109   int
110   RadSimulManager::ThreadsAvailable() const
111   {
112 <        if (NThreads() == 1) return 1;
112 >        if (!ray_pnprocs) return 1;
113 >
114          return ray_pnidle;
115   }
116  
117   // Global pointer to simulation manager for trace call-back (only one)
118   static const RtraceSimulManager *       ourRTsimMan = NULL;
119  
120 < void    // static call-back
120 > // Call-back for trace output
121 > void
122   RtraceSimulManager::RTracer(RAY *r)
123   {
124          (*ourRTsimMan->traceCall)(r, ourRTsimMan->tcData);
125   }
126  
127 + // Call-back for FIFO output
128 + int
129 + RtraceSimulManager::Rfifout(RAY *r)
130 + {
131 +        return (*ourRTsimMan->cookedCall)(r, ourRTsimMan->ccData);
132 + }
133 +
134   // Check for changes to render flags & adjust accordingly
135   bool
136   RtraceSimulManager::UpdateMode()
# Line 143 | Line 155 | RtraceSimulManager::UpdateMode()
155          if (misMatch & RTdoFIFO && FlushQueue() < 0)
156                  return false;
157          curFlags = rtFlags;
158 <                                // update trace callback
159 <        if (traceCall) {
148 <                if (ourRTsimMan && ourRTsimMan != this)
149 <                        error(WARNING, "Competing top-level simulation managers?");
150 <                ourRTsimMan = this;
158 >                                // update callbacks
159 >        if (traceCall)
160                  trace = RTracer;
161 <        } else if (ourRTsimMan == this) {
161 >        else if (trace == RTracer)
162                  trace = NULL;
163 +        if (rtFlags & RTdoFIFO)
164 +                ray_fifo_out = Rfifout;
165 +        else if (ray_fifo_out == Rfifout)
166 +                ray_fifo_out = NULL;
167 +        if ((trace != RTracer) & (ray_fifo_out != Rfifout)) {
168                  ourRTsimMan = NULL;
169 +        } else if (ourRTsimMan != this) {
170 +                if (ourRTsimMan)
171 +                        error(WARNING, "Competing top-level simulation managers?");
172 +                ourRTsimMan = this;
173          }
174          return true;
175   }
176  
177   extern "C" int  m_normal(OBJREC *m, RAY *r);
178  
179 < /* compute irradiance rather than radiance */
179 > // compute irradiance rather than radiance
180   static void
181   rayirrad(RAY *r)
182   {
# Line 175 | Line 193 | rayirrad(RAY *r)
193          r->revf = rayirrad;
194   }
195  
196 < /* compute first ray intersection only */
196 > // compute first ray intersection only
197   static void
198   raycast(RAY *r)
199   {
# Line 188 | Line 206 | raycast(RAY *r)
206          }
207   }
208  
191 // Add a ray result to FIFO, flushing what we can
192 int
193 RtraceSimulManager::QueueResult(const RAY &ra)
194 {
195        return 0;       // UNIMPLEMENTED
196 }
197
209   // Add ray bundle to queue w/ optional 1st ray ID
210   int
211   RtraceSimulManager::EnqueueBundle(const FVECT orig_direc[], int n, RNUMBER rID0)
# Line 227 | Line 238 | RtraceSimulManager::EnqueueBundle(const FVECT orig_dir
238                  if (d > 0) {            // direction vector is valid?
239                          if (curFlags & RTlimDist)
240                                  res.rmax = d;
241 <                        if ((sendRes &= ProcessRay(&res)) &&
242 <                                        rtFlags & RTdoFIFO && NThreads() > 1) {
232 <                                if (QueueResult(res) < 0)
241 >                        if (((curFlags&RTdoFIFO) != 0) & (ray_pnprocs > 0)) {
242 >                                if (ray_fifo_in(&res) < 0)
243                                          return -1;
244                                  sendRes = false;
245 <                        }
245 >                        } else
246 >                                sendRes &= ProcessRay(&res);
247                  } else if (ThreadsAvailable() < NThreads() &&
248                                  FlushQueue() < 0)
249                          return -1;
250 <
251 <                if (sendRes)            // may be dummy ray
252 <                        (*cookedCall)(&res, ccData);
250 >                                        // may be dummy ray
251 >                if (sendRes && (*cookedCall)(&res, ccData) < 0)
252 >                        return -1;
253                  nqueued++;
254          }
255          return nqueued;
# Line 248 | Line 259 | RtraceSimulManager::EnqueueBundle(const FVECT orig_dir
259   int
260   RtraceSimulManager::FlushQueue()
261   {
262 +        if (curFlags & RTdoFIFO) {
263 +                if (ray_pnprocs)
264 +                        return ray_fifo_flush();
265 +                return 0;
266 +        }
267          int     nsent = 0;
268          RAY     res;
269  
270          while (WaitResult(&res)) {
271                  if (!cookedCall) continue;
272 <                if (rtFlags & RTdoFIFO) {
273 <                        int     ns = QueueResult(res);
274 <                        if (ns < 0) return ns;
259 <                        nsent += ns;
260 <                } else {
261 <                        (*cookedCall)(&res, ccData);
262 <                        nsent++;
263 <                }
272 >                int     rv = (*cookedCall)(&res, ccData);
273 >                if (rv < 0) return -1;
274 >                nsent += rv;
275          }
276          return nsent;
277   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines