23 |
|
#include "pmapdiag.h" |
24 |
|
#include "rcontrib.h" |
25 |
|
#include "otypes.h" |
26 |
+ |
#include "otspecial.h" |
27 |
|
#if NIX |
28 |
|
#include <sys/mman.h> |
29 |
|
#include <sys/wait.h> |
173 |
|
|
174 |
|
|
175 |
|
|
176 |
+ |
|
177 |
+ |
|
178 |
+ |
|
179 |
|
void distribPhotonContrib (PhotonMap* pm, unsigned numProc) |
180 |
|
{ |
181 |
|
EmissionMap emap; |
197 |
|
if (!nsources) |
198 |
|
error(USER, "no light sources in distribPhotonContrib"); |
199 |
|
|
196 |
– |
if (nsources > MAXMODLIST) |
197 |
– |
error(USER, "too many light sources in distribPhotonContrib"); |
198 |
– |
|
200 |
|
/* Allocate photon flux per light source; this differs for every |
201 |
|
* source as all sources contribute the same number of distributed |
202 |
|
* photons (srcDistribTarget), hence the number of photons emitted per |
228 |
|
if (!pm -> distribTarget) |
229 |
|
error(INTERNAL, "no photons to distribute in distribPhotonContrib"); |
230 |
|
|
231 |
< |
/* Get photon ports if specified */ |
232 |
< |
if (ambincl == 1) |
232 |
< |
getPhotonPorts(); |
231 |
> |
/* Get photon ports from modifier list */ |
232 |
> |
getPhotonPorts(photonPortList); |
233 |
|
|
234 |
|
/* Get photon sensor modifiers */ |
235 |
|
getPhotonSensors(photonSensorList); |
358 |
|
|
359 |
|
/* Seed RNGs from PID for decorellated photon distribution */ |
360 |
|
pmapSeed(randSeed + proc, partState); |
361 |
< |
pmapSeed(randSeed + proc, emitState); |
362 |
< |
pmapSeed(randSeed + proc, cntState); |
363 |
< |
pmapSeed(randSeed + proc, mediumState); |
364 |
< |
pmapSeed(randSeed + proc, scatterState); |
365 |
< |
pmapSeed(randSeed + proc, rouletteState); |
361 |
> |
pmapSeed(randSeed + (proc + 1) % numProc, emitState); |
362 |
> |
pmapSeed(randSeed + (proc + 2) % numProc, cntState); |
363 |
> |
pmapSeed(randSeed + (proc + 3) % numProc, mediumState); |
364 |
> |
pmapSeed(randSeed + (proc + 4) % numProc, scatterState); |
365 |
> |
pmapSeed(randSeed + (proc + 5) % numProc, rouletteState); |
366 |
> |
|
367 |
> |
#ifdef PMAP_SIGUSR |
368 |
> |
double partNumEmit; |
369 |
> |
unsigned long partEmitCnt; |
370 |
> |
double srcPhotonFlux, avgPhotonFlux; |
371 |
> |
unsigned portCnt, passCnt, prePassCnt; |
372 |
> |
float srcPreDistrib; |
373 |
> |
double srcNumEmit; /* # to emit from source */ |
374 |
> |
unsigned long srcNumDistrib; /* # stored */ |
375 |
> |
|
376 |
> |
void sigUsrDiags() |
377 |
> |
/* Loop diags via SIGUSR1 */ |
378 |
> |
{ |
379 |
> |
sprintf(errmsg, |
380 |
> |
"********************* Proc %d Diags *********************\n" |
381 |
> |
"srcIdx = %d (%s)\nportCnt = %d (%s)\npassCnt = %d\n" |
382 |
> |
"srcFlux = %f\nsrcPhotonFlux = %f\navgPhotonFlux = %f\n" |
383 |
> |
"partNumEmit = %f\npartEmitCnt = %lu\n\n", |
384 |
> |
proc, srcIdx, findmaterial(source [srcIdx].so) -> oname, |
385 |
> |
portCnt, photonPorts [portCnt].so -> oname, |
386 |
> |
passCnt, srcFlux [srcIdx], srcPhotonFlux, avgPhotonFlux, |
387 |
> |
partNumEmit, partEmitCnt); |
388 |
> |
eputs(errmsg); |
389 |
> |
fflush(stderr); |
390 |
> |
} |
391 |
> |
#endif |
392 |
|
|
393 |
+ |
#ifdef PMAP_SIGUSR |
394 |
+ |
signal(SIGUSR1, sigUsrDiags); |
395 |
+ |
#endif |
396 |
+ |
|
397 |
+ |
#ifdef DEBUG_PMAP |
398 |
+ |
/* Output child process PID after random delay to prevent corrupted |
399 |
+ |
* console output due to race condition */ |
400 |
+ |
usleep(1e6 * pmapRandom(rouletteState)); |
401 |
+ |
fprintf(stderr, "Proc %d: PID = %d " |
402 |
+ |
"(waiting 10 sec to attach debugger...)\n", |
403 |
+ |
proc, getpid()); |
404 |
+ |
/* Allow time for debugger to attach to child process */ |
405 |
+ |
sleep(10); |
406 |
+ |
#endif |
407 |
+ |
|
408 |
|
/* ============================================================= |
409 |
|
* 2-PASS PHOTON DISTRIBUTION |
410 |
|
* Pass 1 (pre): emit fraction of target photon count |
411 |
|
* Pass 2 (main): based on outcome of pass 1, estimate remaining |
412 |
|
* number of photons to emit to approximate target |
413 |
|
* count |
414 |
< |
* ============================================================= */ |
414 |
> |
* ============================================================= */ |
415 |
|
for (srcIdx = 0; srcIdx < nsources; srcIdx++) { |
416 |
+ |
#ifndef PMAP_SIGUSR |
417 |
|
unsigned portCnt, passCnt = 0, prePassCnt = 0; |
418 |
|
float srcPreDistrib = preDistrib; |
419 |
|
double srcNumEmit = 0; /* # to emit from source */ |
420 |
|
unsigned long srcNumDistrib = pm -> numPhotons; /* # stored */ |
421 |
+ |
#else |
422 |
+ |
passCnt = prePassCnt = 0; |
423 |
+ |
srcPreDistrib = preDistrib; |
424 |
+ |
srcNumEmit = 0; /* # to emit from source */ |
425 |
+ |
srcNumDistrib = pm -> numPhotons; /* # stored */ |
426 |
+ |
#endif |
427 |
|
|
428 |
|
if (srcFlux [srcIdx] < FTINY) |
429 |
|
continue; |
431 |
|
while (passCnt < 2) { |
432 |
|
if (!passCnt) { |
433 |
|
/* INIT PASS 1 */ |
434 |
< |
if (++prePassCnt > maxPreDistrib && !proc) { |
434 |
> |
if (++prePassCnt > maxPreDistrib) { |
435 |
|
/* Warn if no photons contributed after sufficient |
436 |
|
* iterations; only output from subprocess 0 to reduce |
437 |
|
* console clutter */ |
438 |
< |
sprintf(errmsg, |
439 |
< |
"source %s: too many prepasses, skipped", |
440 |
< |
source [srcIdx].so -> oname); |
441 |
< |
error(WARNING, errmsg); |
438 |
> |
if (!proc) { |
439 |
> |
sprintf(errmsg, |
440 |
> |
"source %s: too many prepasses, skipped", |
441 |
> |
source [srcIdx].so -> oname); |
442 |
> |
error(WARNING, errmsg); |
443 |
> |
} |
444 |
> |
|
445 |
|
break; |
446 |
|
} |
447 |
|
|
450 |
|
} |
451 |
|
else { |
452 |
|
/* INIT PASS 2 */ |
453 |
+ |
#ifndef PMAP_SIGUSR |
454 |
|
double srcPhotonFlux, avgPhotonFlux; |
455 |
+ |
#endif |
456 |
|
|
457 |
|
/* Based on the outcome of the predistribution we can now |
458 |
|
* figure out how many more photons we have to emit from |
474 |
|
srcPhotonFlux = srcFlux [srcIdx] / srcNumEmit; |
475 |
|
avgPhotonFlux = photonFluxSum / (srcIdx + 1); |
476 |
|
|
477 |
< |
if (avgPhotonFlux > 0 && |
477 |
> |
if (avgPhotonFlux > FTINY && |
478 |
|
srcPhotonFlux / avgPhotonFlux < FTINY) { |
479 |
|
/* Skip source if its photon flux is grossly below the |
480 |
|
* running average, indicating negligible contributions |
481 |
|
* at the expense of excessive distribution time; only |
482 |
|
* output from subproc 0 to reduce console clutter */ |
483 |
< |
sprintf(errmsg, |
484 |
< |
"source %s: itsy bitsy photon flux, skipped", |
485 |
< |
source [srcIdx].so -> oname); |
486 |
< |
error(WARNING, errmsg); |
487 |
< |
srcNumEmit = 0; |
483 |
> |
if (!proc) { |
484 |
> |
sprintf(errmsg, |
485 |
> |
"source %s: itsy bitsy photon flux, skipped", |
486 |
> |
source [srcIdx].so -> oname); |
487 |
> |
error(WARNING, errmsg); |
488 |
> |
} |
489 |
> |
|
490 |
> |
srcNumEmit = 0; /* Or just break??? */ |
491 |
|
} |
492 |
|
|
493 |
|
/* Update sum of photon flux per light source */ |
528 |
|
|
529 |
|
for (emap.partitionCnt = 0; emap.partitionCnt < emap.numPartitions; |
530 |
|
emap.partitionCnt++) { |
531 |
+ |
#ifndef PMAP_SIGUSR |
532 |
|
double partNumEmit; |
533 |
|
unsigned long partEmitCnt; |
534 |
+ |
#endif |
535 |
|
|
536 |
|
/* Get photon origin within current source partishunn |
537 |
|
* and build emission map */ |
628 |
|
pm -> numPhotons); |
629 |
|
eputs(errmsg); |
630 |
|
fflush(stderr); |
631 |
+ |
#endif |
632 |
+ |
|
633 |
+ |
#ifdef PMAP_SIGUSR |
634 |
+ |
signal(SIGUSR1, SIG_DFL); |
635 |
|
#endif |
636 |
|
|
637 |
|
#if NIX |