Compare commits

...
6 Commits
Author SHA1 Message Date
wyj 2d01c2c101 Doc: Adopt CSV CIE 1931 blackbody reference 2026-09-12 15:29:36 -04:00
wyj ce9c4bc16f Test: Refresh reference images for CSV blackbody reference 2026-09-12 15:29:36 -04:00
wyj d2a901cab1 Feat: Add CSV CIE 1931 blackbody LUT backend
Replace the in-tree Wyman analytic CIE fit with a repository CIE 1931
2-degree LUT derived from the 360-830 nm, 1 nm-linear CSV reference. The
GRBBLUT3 table stores 1024 uniform log(T) XYZ nodes over
[670.146556, 101408.88] K with four-point cubic Lagrange interpolation, and
the same CSV reference supplies a three-term Rayleigh-Jeans form above the
table and an inverse-temperature/log-XYZ crossover with channel-specific
endpoint forms below it. The loader validates the header and payload
checksum and rejects legacy formats and runtime generation.

Initialize the backend in the renderer, frame test, and PSF capture tool so
the new default is active wherever colors are produced.
2026-09-12 15:29:33 -04:00
wyj 2fc2b43e8d Doc: Record production PSF chunk geometry
Preserve the protected full-catalog dummy run, its initial harness failure, input and output hashes, distribution quantiles, and the resulting sparse-tile scheduling conclusions.
2026-09-11 23:28:02 -04:00
wyj d02ecb2181 Feat: Add dummy PSF chunk diagnostics
Reuse production catalog mapping and per-worker chunk boundaries to report triangle and spatial distributions without initializing HIP or writing image outputs. Include a protected full-catalog runner and build documentation.
2026-09-11 23:27:42 -04:00
wyj 776f9b7247 Test: Add adaptive HIP tile replay selection
Add a bounded per-chunk center-tile selector to the real-event replay prototype and retain the paired timing, mixed-boundary, CPU, HIP, and sandbox-failure evidence.
2026-09-11 23:27:24 -04:00
58 changed files with 2258 additions and 83 deletions

No files matched your search

+10 -2
View File
@@ -29,7 +29,7 @@ else
IMAGE_EXT := ppm
endif
COMMON_SOURCES := $(filter-out src/main.c src/spacetime_minkowski.c src/spacetime_schwarzschild.c,$(wildcard src/*.c))
COMMON_SOURCES := $(filter-out src/main.c src/dummy_psf.c src/spacetime_minkowski.c src/spacetime_schwarzschild.c,$(wildcard src/*.c))
PROVIDER_SOURCE := src/spacetime_$(SPACETIME).c
BUILD_DIR := build/$(BUILD_TYPE)
TARGET_BASENAME := $(SPACETIME)_sky
@@ -56,8 +56,11 @@ RENDER_LINKER := $(CC)
else ifeq ($(PSF_BACKEND),hip)
RENDER_LINKER := $(HIPCC)
BUILD_CPPFLAGS += -DPSF_BACKEND_HIP
else ifeq ($(PSF_BACKEND),dummy)
RENDER_LINKER := $(CC)
BUILD_CPPFLAGS += -DPSF_BACKEND_DUMMY
else
$(error Unknown PSF_BACKEND '$(PSF_BACKEND)'; choose cpu or hip)
$(error Unknown PSF_BACKEND '$(PSF_BACKEND)'; choose cpu, hip, or dummy)
endif
ifeq ($(SPACETIME),minkowski)
@@ -80,10 +83,15 @@ endif
ifeq ($(PSF_BACKEND),hip)
TARGET := $(BUILD_DIR)/$(TARGET_BASENAME)_hip
else ifeq ($(PSF_BACKEND),dummy)
TARGET := $(BUILD_DIR)/$(TARGET_BASENAME)_dummy
else
TARGET := $(BUILD_DIR)/$(TARGET_BASENAME)
endif
RENDER_SOURCES := $(COMMON_SOURCES) $(PROVIDER_SOURCE) src/main.c
ifeq ($(PSF_BACKEND),dummy)
RENDER_SOURCES += src/dummy_psf.c
endif
RENDER_OBJECTS := $(patsubst %.c,$(OBJECT_DIR)/$(HDR_BUILD_TAG)/%.o,$(RENDER_SOURCES))
ifeq ($(PSF_BACKEND),hip)
HIP_PSF_OBJECT := $(OBJECT_DIR)/$(HDR_BUILD_TAG)/src/hip_psf.o
+471
View File
@@ -0,0 +1,471 @@
360,0.000129900000,0.0000039170000,0.000606100000
361,0.000145847000,0.0000043935810,0.000680879200
362,0.000163802100,0.0000049296040,0.000765145600
363,0.000184003700,0.0000055321360,0.000860012400
364,0.000206690200,0.0000062082450,0.000966592800
365,0.000232100000,0.0000069650000,0.001086000000
366,0.000260728000,0.0000078132190,0.001220586000
367,0.000293075000,0.0000087673360,0.001372729000
368,0.000329388000,0.0000098398440,0.001543579000
369,0.000369914000,0.0000110432300,0.001734286000
370,0.000414900000,0.0000123900000,0.001946000000
371,0.000464158700,0.0000138864100,0.002177777000
372,0.000518986000,0.0000155572800,0.002435809000
373,0.000581854000,0.0000174429600,0.002731953000
374,0.000655234700,0.0000195837500,0.003078064000
375,0.000741600000,0.0000220200000,0.003486000000
376,0.000845029600,0.0000248396500,0.003975227000
377,0.000964526800,0.0000280412600,0.004540880000
378,0.001094949000,0.0000315310400,0.005158320000
379,0.001231154000,0.0000352152100,0.005802907000
380,0.001368000000,0.0000390000000,0.006450001000
381,0.001502050000,0.0000428264000,0.007083216000
382,0.001642328000,0.0000469146000,0.007745488000
383,0.001802382000,0.0000515896000,0.008501152000
384,0.001995757000,0.0000571764000,0.009414544000
385,0.002236000000,0.0000640000000,0.010549990000
386,0.002535385000,0.0000723442100,0.011965800000
387,0.002892603000,0.0000822122400,0.013655870000
388,0.003300829000,0.0000935081600,0.015588050000
389,0.003753236000,0.0001061361000,0.017730150000
390,0.004243000000,0.0001200000000,0.020050010000
391,0.004762389000,0.0001349840000,0.022511360000
392,0.005330048000,0.0001514920000,0.025202880000
393,0.005978712000,0.0001702080000,0.028279720000
394,0.006741117000,0.0001918160000,0.031897040000
395,0.007650000000,0.0002170000000,0.036210000000
396,0.008751373000,0.0002469067000,0.041437710000
397,0.010028880000,0.0002812400000,0.047503720000
398,0.011421700000,0.0003185200000,0.054119880000
399,0.012869010000,0.0003572667000,0.060998030000
400,0.014310000000,0.0003960000000,0.067850010000
401,0.015704430000,0.0004337147000,0.074486320000
402,0.017147440000,0.0004730240000,0.081361560000
403,0.018781220000,0.0005178760000,0.089153640000
404,0.020748010000,0.0005722187000,0.098540480000
405,0.023190000000,0.0006400000000,0.110200000000
406,0.026207360000,0.0007245600000,0.124613300000
407,0.029782480000,0.0008255000000,0.141701700000
408,0.033880920000,0.0009411600000,0.161303500000
409,0.038468240000,0.0010698800000,0.183256800000
410,0.043510000000,0.0012100000000,0.207400000000
411,0.048995600000,0.0013620910000,0.233692100000
412,0.055022600000,0.0015307520000,0.262611400000
413,0.061718800000,0.0017203680000,0.294774600000
414,0.069212000000,0.0019353230000,0.330798500000
415,0.077630000000,0.0021800000000,0.371300000000
416,0.086958110000,0.0024548000000,0.416209100000
417,0.097176720000,0.0027640000000,0.465464200000
418,0.108406300000,0.0031178000000,0.519694800000
419,0.120767200000,0.0035264000000,0.579530300000
420,0.134380000000,0.0040000000000,0.645600000000
421,0.149358200000,0.0045462400000,0.718483800000
422,0.165395700000,0.0051593200000,0.796713300000
423,0.181983100000,0.0058292800000,0.877845900000
424,0.198611000000,0.0065461600000,0.959439000000
425,0.214770000000,0.0073000000000,1.039050100000
426,0.230186800000,0.0080865070000,1.115367300000
427,0.244879700000,0.0089087200000,1.188497100000
428,0.258777300000,0.0097676800000,1.258123300000
429,0.271807900000,0.0106644300000,1.323929600000
430,0.283900000000,0.0116000000000,1.385600000000
431,0.294943800000,0.0125731700000,1.442635200000
432,0.304896500000,0.0135827200000,1.494803500000
433,0.313787300000,0.0146296800000,1.542190300000
434,0.321645400000,0.0157150900000,1.584880700000
435,0.328500000000,0.0168400000000,1.622960000000
436,0.334351300000,0.0180073600000,1.656404800000
437,0.339210100000,0.0192144800000,1.685295900000
438,0.343121300000,0.0204539200000,1.709874500000
439,0.346129600000,0.0217182400000,1.730382100000
440,0.348280000000,0.0230000000000,1.747060000000
441,0.349599900000,0.0242946100000,1.760044600000
442,0.350147400000,0.0256102400000,1.769623300000
443,0.350013000000,0.0269585700000,1.776263700000
444,0.349287000000,0.0283512500000,1.780433400000
445,0.348060000000,0.0298000000000,1.782600000000
446,0.346373300000,0.0313108300000,1.782968200000
447,0.344262400000,0.0328836800000,1.781699800000
448,0.341808800000,0.0345211200000,1.779198200000
449,0.339094100000,0.0362257100000,1.775867100000
450,0.336200000000,0.0380000000000,1.772110000000
451,0.333197700000,0.0398466700000,1.768258900000
452,0.330041100000,0.0417680000000,1.764039000000
453,0.326635700000,0.0437660000000,1.758943800000
454,0.322886800000,0.0458426700000,1.752466300000
455,0.318700000000,0.0480000000000,1.744100000000
456,0.314025100000,0.0502436800000,1.733559500000
457,0.308884000000,0.0525730400000,1.720858100000
458,0.303290400000,0.0549805600000,1.705936900000
459,0.297257900000,0.0574587200000,1.688737200000
460,0.290800000000,0.0600000000000,1.669200000000
461,0.283970100000,0.0626019700000,1.647528700000
462,0.276721400000,0.0652775200000,1.623412700000
463,0.268917800000,0.0680420800000,1.596022300000
464,0.260422700000,0.0709110900000,1.564528000000
465,0.251100000000,0.0739000000000,1.528100000000
466,0.240847500000,0.0770160000000,1.486111400000
467,0.229851200000,0.0802664000000,1.439521500000
468,0.218407200000,0.0836668000000,1.389879900000
469,0.206811500000,0.0872328000000,1.338736200000
470,0.195360000000,0.0909800000000,1.287640000000
471,0.184213600000,0.0949175500000,1.237422300000
472,0.173327300000,0.0990458400000,1.187824300000
473,0.162688100000,0.1033674000000,1.138761100000
474,0.152283300000,0.1078846000000,1.090148000000
475,0.142100000000,0.1126000000000,1.041900000000
476,0.132178600000,0.1175320000000,0.994197600000
477,0.122569600000,0.1226744000000,0.947347300000
478,0.113275200000,0.1279928000000,0.901453100000
479,0.104297900000,0.1334528000000,0.856619300000
480,0.095640000000,0.1390200000000,0.812950100000
481,0.087299550000,0.1446764000000,0.770517300000
482,0.079308040000,0.1504693000000,0.729444800000
483,0.071717760000,0.1564619000000,0.689913600000
484,0.064580990000,0.1627177000000,0.652104900000
485,0.057950010000,0.1693000000000,0.616200000000
486,0.051862110000,0.1762431000000,0.582328600000
487,0.046281520000,0.1835581000000,0.550416200000
488,0.041150880000,0.1912735000000,0.520337600000
489,0.036412830000,0.1994180000000,0.491967300000
490,0.032010000000,0.2080200000000,0.465180000000
491,0.027917200000,0.2171199000000,0.439924600000
492,0.024144400000,0.2267345000000,0.416183600000
493,0.020687000000,0.2368571000000,0.393882200000
494,0.017540400000,0.2474812000000,0.372945900000
495,0.014700000000,0.2586000000000,0.353300000000
496,0.012161790000,0.2701849000000,0.334857800000
497,0.009919960000,0.2822939000000,0.317552100000
498,0.007967240000,0.2950505000000,0.301337500000
499,0.006296346000,0.3085780000000,0.286168600000
500,0.004900000000,0.3230000000000,0.272000000000
501,0.003777173000,0.3384021000000,0.258817100000
502,0.002945320000,0.3546858000000,0.246483800000
503,0.002424880000,0.3716986000000,0.234771800000
504,0.002236293000,0.3892875000000,0.223453300000
505,0.002400000000,0.4073000000000,0.212300000000
506,0.002925520000,0.4256299000000,0.201169200000
507,0.003836560000,0.4443096000000,0.190119600000
508,0.005174840000,0.4633944000000,0.179225400000
509,0.006982080000,0.4829395000000,0.168560800000
510,0.009300000000,0.5030000000000,0.158200000000
511,0.012149490000,0.5235693000000,0.148138300000
512,0.015535880000,0.5445120000000,0.138375800000
513,0.019477520000,0.5656900000000,0.128994200000
514,0.023992770000,0.5869653000000,0.120075100000
515,0.029100000000,0.6082000000000,0.111700000000
516,0.034814850000,0.6293456000000,0.103904800000
517,0.041120160000,0.6503068000000,0.096667480000
518,0.047985040000,0.6708752000000,0.089982720000
519,0.055378610000,0.6908424000000,0.083845310000
520,0.063270000000,0.7100000000000,0.078249990000
521,0.071635010000,0.7281852000000,0.073208990000
522,0.080462240000,0.7454636000000,0.068678160000
523,0.089739960000,0.7619694000000,0.064567840000
524,0.099456450000,0.7778368000000,0.060788350000
525,0.109600000000,0.7932000000000,0.057250010000
526,0.120167400000,0.8081104000000,0.053904350000
527,0.131114500000,0.8224962000000,0.050746640000
528,0.142367900000,0.8363068000000,0.047752760000
529,0.153854200000,0.8494916000000,0.044898590000
530,0.165500000000,0.8620000000000,0.042160000000
531,0.177257100000,0.8738108000000,0.039507280000
532,0.189140000000,0.8849624000000,0.036935640000
533,0.201169400000,0.8954936000000,0.034458360000
534,0.213365800000,0.9054432000000,0.032088720000
535,0.225749900000,0.9148501000000,0.029840000000
536,0.238320900000,0.9237348000000,0.027711810000
537,0.251066800000,0.9320924000000,0.025694440000
538,0.263992200000,0.9399226000000,0.023787160000
539,0.277101700000,0.9472252000000,0.021989250000
540,0.290400000000,0.9540000000000,0.020300000000
541,0.303891200000,0.9602561000000,0.018718050000
542,0.317572600000,0.9660074000000,0.017240360000
543,0.331438400000,0.9712606000000,0.015863640000
544,0.345482800000,0.9760225000000,0.014584610000
545,0.359700000000,0.9803000000000,0.013400000000
546,0.374083900000,0.9840924000000,0.012307230000
547,0.388639600000,0.9874182000000,0.011301880000
548,0.403378400000,0.9903128000000,0.010377920000
549,0.418311500000,0.9928116000000,0.009529306000
550,0.433449900000,0.9949501000000,0.008749999000
551,0.448795300000,0.9967108000000,0.008035200000
552,0.464336000000,0.9980983000000,0.007381600000
553,0.480064000000,0.9991120000000,0.006785400000
554,0.495971300000,0.9997482000000,0.006242800000
555,0.512050100000,1.0000000000000,0.005749999000
556,0.528295900000,0.9998567000000,0.005303600000
557,0.544691600000,0.9993046000000,0.004899800000
558,0.561209400000,0.9983255000000,0.004534200000
559,0.577821500000,0.9968987000000,0.004202400000
560,0.594500000000,0.9950000000000,0.003900000000
561,0.611220900000,0.9926005000000,0.003623200000
562,0.627975800000,0.9897426000000,0.003370600000
563,0.644760200000,0.9864444000000,0.003141400000
564,0.661569700000,0.9827241000000,0.002934800000
565,0.678400000000,0.9786000000000,0.002749999000
566,0.695239200000,0.9740837000000,0.002585200000
567,0.712058600000,0.9691712000000,0.002438600000
568,0.728828400000,0.9638568000000,0.002309400000
569,0.745518800000,0.9581349000000,0.002196800000
570,0.762100000000,0.9520000000000,0.002100000000
571,0.778543200000,0.9454504000000,0.002017733000
572,0.794825600000,0.9384992000000,0.001948200000
573,0.810926400000,0.9311628000000,0.001889800000
574,0.826824800000,0.9234576000000,0.001840933000
575,0.842500000000,0.9154000000000,0.001800000000
576,0.857932500000,0.9070064000000,0.001766267000
577,0.873081600000,0.8982772000000,0.001737800000
578,0.887894400000,0.8892048000000,0.001711200000
579,0.902318100000,0.8797816000000,0.001683067000
580,0.916300000000,0.8700000000000,0.001650001000
581,0.929799500000,0.8598613000000,0.001610133000
582,0.942798400000,0.8493920000000,0.001564400000
583,0.955277600000,0.8386220000000,0.001513600000
584,0.967217900000,0.8275813000000,0.001458533000
585,0.978600000000,0.8163000000000,0.001400000000
586,0.989385600000,0.8047947000000,0.001336667000
587,0.999548800000,0.7930820000000,0.001270000000
588,1.009089200000,0.7811920000000,0.001205000000
589,1.018006400000,0.7691547000000,0.001146667000
590,1.026300000000,0.7570000000000,0.001100000000
591,1.033982700000,0.7447541000000,0.001068800000
592,1.040986000000,0.7324224000000,0.001049400000
593,1.047188000000,0.7200036000000,0.001035600000
594,1.052466700000,0.7074965000000,0.001021200000
595,1.056700000000,0.6949000000000,0.001000000000
596,1.059794400000,0.6822192000000,0.000968640000
597,1.061799200000,0.6694716000000,0.000929920000
598,1.062806800000,0.6566744000000,0.000886880000
599,1.062909600000,0.6438448000000,0.000842560000
600,1.062200000000,0.6310000000000,0.000800000000
601,1.060735200000,0.6181555000000,0.000760960000
602,1.058443600000,0.6053144000000,0.000723680000
603,1.055224400000,0.5924756000000,0.000685920000
604,1.050976800000,0.5796379000000,0.000645440000
605,1.045600000000,0.5668000000000,0.000600000000
606,1.039036900000,0.5539611000000,0.000547866700
607,1.031360800000,0.5411372000000,0.000491600000
608,1.022666200000,0.5283528000000,0.000435400000
609,1.013047700000,0.5156323000000,0.000383466700
610,1.002600000000,0.5030000000000,0.000340000000
611,0.991367500000,0.4904688000000,0.000307253300
612,0.979331400000,0.4780304000000,0.000283160000
613,0.966491600000,0.4656776000000,0.000265440000
614,0.952847900000,0.4534032000000,0.000251813300
615,0.938400000000,0.4412000000000,0.000240000000
616,0.923194000000,0.4290800000000,0.000229546700
617,0.907244000000,0.4170360000000,0.000220640000
618,0.890502000000,0.4050320000000,0.000211960000
619,0.872920000000,0.3930320000000,0.000202186700
620,0.854449900000,0.3810000000000,0.000190000000
621,0.835084000000,0.3689184000000,0.000174213300
622,0.814946000000,0.3568272000000,0.000155640000
623,0.794186000000,0.3447768000000,0.000135960000
624,0.772954000000,0.3328176000000,0.000116853300
625,0.751400000000,0.3210000000000,0.000100000000
626,0.729583600000,0.3093381000000,0.000086133330
627,0.707588800000,0.2978504000000,0.000074600000
628,0.685602200000,0.2865936000000,0.000065000000
629,0.663810400000,0.2756245000000,0.000056933330
630,0.642400000000,0.2650000000000,0.000049999990
631,0.621514900000,0.2547632000000,0.000044160000
632,0.601113800000,0.2448896000000,0.000039480000
633,0.581105200000,0.2353344000000,0.000035720000
634,0.561397700000,0.2260528000000,0.000032640000
635,0.541900000000,0.2170000000000,0.000030000000
636,0.522599500000,0.2081616000000,0.000027653330
637,0.503546400000,0.1995488000000,0.000025560000
638,0.484743600000,0.1911552000000,0.000023640000
639,0.466193900000,0.1829744000000,0.000021813330
640,0.447900000000,0.1750000000000,0.000020000000
641,0.429861300000,0.1672235000000,0.000018133330
642,0.412098000000,0.1596464000000,0.000016200000
643,0.394644000000,0.1522776000000,0.000014200000
644,0.377533300000,0.1451259000000,0.000012133330
645,0.360800000000,0.1382000000000,0.000010000000
646,0.344456300000,0.1315003000000,0.000007733333
647,0.328516800000,0.1250248000000,0.000005400000
648,0.313019200000,0.1187792000000,0.000003200000
649,0.298001100000,0.1127691000000,0.000001333333
650,0.283500000000,0.1070000000000,0.000000000000
651,0.269544800000,0.1014762000000,0.000000000000
652,0.256118400000,0.0961886400000,0.000000000000
653,0.243189600000,0.0911229600000,0.000000000000
654,0.230727200000,0.0862648500000,0.000000000000
655,0.218700000000,0.0816000000000,0.000000000000
656,0.207097100000,0.0771206400000,0.000000000000
657,0.195923200000,0.0728255200000,0.000000000000
658,0.185170800000,0.0687100800000,0.000000000000
659,0.174832300000,0.0647697600000,0.000000000000
660,0.164900000000,0.0610000000000,0.000000000000
661,0.155366700000,0.0573962100000,0.000000000000
662,0.146230000000,0.0539550400000,0.000000000000
663,0.137490000000,0.0506737600000,0.000000000000
664,0.129146700000,0.0475496500000,0.000000000000
665,0.121200000000,0.0445800000000,0.000000000000
666,0.113639700000,0.0417587200000,0.000000000000
667,0.106465000000,0.0390849600000,0.000000000000
668,0.099690440000,0.0365638400000,0.000000000000
669,0.093330610000,0.0342004800000,0.000000000000
670,0.087400000000,0.0320000000000,0.000000000000
671,0.081900960000,0.0299626100000,0.000000000000
672,0.076804280000,0.0280766400000,0.000000000000
673,0.072077120000,0.0263293600000,0.000000000000
674,0.067686640000,0.0247080500000,0.000000000000
675,0.063600000000,0.0232000000000,0.000000000000
676,0.059806850000,0.0218007700000,0.000000000000
677,0.056282160000,0.0205011200000,0.000000000000
678,0.052971040000,0.0192810800000,0.000000000000
679,0.049818610000,0.0181206900000,0.000000000000
680,0.046770000000,0.0170000000000,0.000000000000
681,0.043784050000,0.0159037900000,0.000000000000
682,0.040875360000,0.0148371800000,0.000000000000
683,0.038072640000,0.0138106800000,0.000000000000
684,0.035404610000,0.0128347800000,0.000000000000
685,0.032900000000,0.0119200000000,0.000000000000
686,0.030564190000,0.0110683100000,0.000000000000
687,0.028380560000,0.0102733900000,0.000000000000
688,0.026344840000,0.0095333110000,0.000000000000
689,0.024452750000,0.0088461570000,0.000000000000
690,0.022700000000,0.0082100000000,0.000000000000
691,0.021084290000,0.0076237810000,0.000000000000
692,0.019599880000,0.0070854240000,0.000000000000
693,0.018237320000,0.0065914760000,0.000000000000
694,0.016987170000,0.0061384850000,0.000000000000
695,0.015840000000,0.0057230000000,0.000000000000
696,0.014790640000,0.0053430590000,0.000000000000
697,0.013831320000,0.0049957960000,0.000000000000
698,0.012948680000,0.0046764040000,0.000000000000
699,0.012129200000,0.0043800750000,0.000000000000
700,0.011359160000,0.0041020000000,0.000000000000
701,0.010629350000,0.0038384530000,0.000000000000
702,0.009938846000,0.0035890990000,0.000000000000
703,0.009288422000,0.0033542190000,0.000000000000
704,0.008678854000,0.0031340930000,0.000000000000
705,0.008110916000,0.0029290000000,0.000000000000
706,0.007582388000,0.0027381390000,0.000000000000
707,0.007088746000,0.0025598760000,0.000000000000
708,0.006627313000,0.0023932440000,0.000000000000
709,0.006195408000,0.0022372750000,0.000000000000
710,0.005790346000,0.0020910000000,0.000000000000
711,0.005409826000,0.0019535870000,0.000000000000
712,0.005052583000,0.0018245800000,0.000000000000
713,0.004717512000,0.0017035800000,0.000000000000
714,0.004403507000,0.0015901870000,0.000000000000
715,0.004109457000,0.0014840000000,0.000000000000
716,0.003833913000,0.0013844960000,0.000000000000
717,0.003575748000,0.0012912680000,0.000000000000
718,0.003334342000,0.0012040920000,0.000000000000
719,0.003109075000,0.0011227440000,0.000000000000
720,0.002899327000,0.0010470000000,0.000000000000
721,0.002704348000,0.0009765896000,0.000000000000
722,0.002523020000,0.0009111088000,0.000000000000
723,0.002354168000,0.0008501332000,0.000000000000
724,0.002196616000,0.0007932384000,0.000000000000
725,0.002049190000,0.0007400000000,0.000000000000
726,0.001910960000,0.0006900827000,0.000000000000
727,0.001781438000,0.0006433100000,0.000000000000
728,0.001660110000,0.0005994960000,0.000000000000
729,0.001546459000,0.0005584547000,0.000000000000
730,0.001439971000,0.0005200000000,0.000000000000
731,0.001340042000,0.0004839136000,0.000000000000
732,0.001246275000,0.0004500528000,0.000000000000
733,0.001158471000,0.0004183452000,0.000000000000
734,0.001076430000,0.0003887184000,0.000000000000
735,0.000999949300,0.0003611000000,0.000000000000
736,0.000928735800,0.0003353835000,0.000000000000
737,0.000862433200,0.0003114404000,0.000000000000
738,0.000800750300,0.0002891656000,0.000000000000
739,0.000743396000,0.0002684539000,0.000000000000
740,0.000690078600,0.0002492000000,0.000000000000
741,0.000640515600,0.0002313019000,0.000000000000
742,0.000594502100,0.0002146856000,0.000000000000
743,0.000551864600,0.0001992884000,0.000000000000
744,0.000512429000,0.0001850475000,0.000000000000
745,0.000476021300,0.0001719000000,0.000000000000
746,0.000442453600,0.0001597781000,0.000000000000
747,0.000411511700,0.0001486044000,0.000000000000
748,0.000382981400,0.0001383016000,0.000000000000
749,0.000356649100,0.0001287925000,0.000000000000
750,0.000332301100,0.0001200000000,0.000000000000
751,0.000309758600,0.0001118595000,0.000000000000
752,0.000288887100,0.0001043224000,0.000000000000
753,0.000269539400,0.0000973356000,0.000000000000
754,0.000251568200,0.0000908458700,0.000000000000
755,0.000234826100,0.0000848000000,0.000000000000
756,0.000219171000,0.0000791466700,0.000000000000
757,0.000204525800,0.0000738580000,0.000000000000
758,0.000190840500,0.0000689160000,0.000000000000
759,0.000178065400,0.0000643026700,0.000000000000
760,0.000166150500,0.0000600000000,0.000000000000
761,0.000155023600,0.0000559818700,0.000000000000
762,0.000144621900,0.0000522256000,0.000000000000
763,0.000134909800,0.0000487184000,0.000000000000
764,0.000125852000,0.0000454474700,0.000000000000
765,0.000117413000,0.0000424000000,0.000000000000
766,0.000109551500,0.0000395610400,0.000000000000
767,0.000102224500,0.0000369151200,0.000000000000
768,0.000095394450,0.0000344486800,0.000000000000
769,0.000089023900,0.0000321481600,0.000000000000
770,0.000083075270,0.0000300000000,0.000000000000
771,0.000077512690,0.0000279912500,0.000000000000
772,0.000072313040,0.0000261135600,0.000000000000
773,0.000067457780,0.0000243602400,0.000000000000
774,0.000062928440,0.0000227246100,0.000000000000
775,0.000058706520,0.0000212000000,0.000000000000
776,0.000054770280,0.0000197785500,0.000000000000
777,0.000051099180,0.0000184528500,0.000000000000
778,0.000047676540,0.0000172168700,0.000000000000
779,0.000044485670,0.0000160645900,0.000000000000
780,0.000041509940,0.0000149900000,0.000000000000
781,0.000038733240,0.0000139872800,0.000000000000
782,0.000036142030,0.0000130515500,0.000000000000
783,0.000033723520,0.0000121781800,0.000000000000
784,0.000031464870,0.0000113625400,0.000000000000
785,0.000029353260,0.0000106000000,0.000000000000
786,0.000027375730,0.0000098858770,0.000000000000
787,0.000025524330,0.0000092173040,0.000000000000
788,0.000023793760,0.0000085923620,0.000000000000
789,0.000022178700,0.0000080091330,0.000000000000
790,0.000020673830,0.0000074657000,0.000000000000
791,0.000019272260,0.0000069595670,0.000000000000
792,0.000017966400,0.0000064879950,0.000000000000
793,0.000016749910,0.0000060486990,0.000000000000
794,0.000015616480,0.0000056393960,0.000000000000
795,0.000014559770,0.0000052578000,0.000000000000
796,0.000013573870,0.0000049017710,0.000000000000
797,0.000012654360,0.0000045697200,0.000000000000
798,0.000011797230,0.0000042601940,0.000000000000
799,0.000010998440,0.0000039717390,0.000000000000
800,0.000010253980,0.0000037029000,0.000000000000
801,0.000009559646,0.0000034521630,0.000000000000
802,0.000008912044,0.0000032183020,0.000000000000
803,0.000008308358,0.0000030003000,0.000000000000
804,0.000007745769,0.0000027971390,0.000000000000
805,0.000007221456,0.0000026078000,0.000000000000
806,0.000006732475,0.0000024312200,0.000000000000
807,0.000006276423,0.0000022665310,0.000000000000
808,0.000005851304,0.0000021130130,0.000000000000
809,0.000005455118,0.0000019699430,0.000000000000
810,0.000005085868,0.0000018366000,0.000000000000
811,0.000004741466,0.0000017122300,0.000000000000
812,0.000004420236,0.0000015962280,0.000000000000
813,0.000004120783,0.0000014880900,0.000000000000
814,0.000003841716,0.0000013873140,0.000000000000
815,0.000003581652,0.0000012934000,0.000000000000
816,0.000003339127,0.0000012058200,0.000000000000
817,0.000003112949,0.0000011241430,0.000000000000
818,0.000002902121,0.0000010480090,0.000000000000
819,0.000002705645,0.0000009770578,0.000000000000
820,0.000002522525,0.0000009109300,0.000000000000
821,0.000002351726,0.0000008492513,0.000000000000
822,0.000002192415,0.0000007917212,0.000000000000
823,0.000002043902,0.0000007380904,0.000000000000
824,0.000001905497,0.0000006881098,0.000000000000
825,0.000001776509,0.0000006415300,0.000000000000
826,0.000001656215,0.0000005980895,0.000000000000
827,0.000001544022,0.0000005575746,0.000000000000
828,0.000001439440,0.0000005198080,0.000000000000
829,0.000001341977,0.0000004846123,0.000000000000
830,0.000001251141,0.0000004518100,0.000000000000
1 360 0.000129900000 0.0000039170000 0.000606100000
2 361 0.000145847000 0.0000043935810 0.000680879200
3 362 0.000163802100 0.0000049296040 0.000765145600
4 363 0.000184003700 0.0000055321360 0.000860012400
5 364 0.000206690200 0.0000062082450 0.000966592800
6 365 0.000232100000 0.0000069650000 0.001086000000
7 366 0.000260728000 0.0000078132190 0.001220586000
8 367 0.000293075000 0.0000087673360 0.001372729000
9 368 0.000329388000 0.0000098398440 0.001543579000
10 369 0.000369914000 0.0000110432300 0.001734286000
11 370 0.000414900000 0.0000123900000 0.001946000000
12 371 0.000464158700 0.0000138864100 0.002177777000
13 372 0.000518986000 0.0000155572800 0.002435809000
14 373 0.000581854000 0.0000174429600 0.002731953000
15 374 0.000655234700 0.0000195837500 0.003078064000
16 375 0.000741600000 0.0000220200000 0.003486000000
17 376 0.000845029600 0.0000248396500 0.003975227000
18 377 0.000964526800 0.0000280412600 0.004540880000
19 378 0.001094949000 0.0000315310400 0.005158320000
20 379 0.001231154000 0.0000352152100 0.005802907000
21 380 0.001368000000 0.0000390000000 0.006450001000
22 381 0.001502050000 0.0000428264000 0.007083216000
23 382 0.001642328000 0.0000469146000 0.007745488000
24 383 0.001802382000 0.0000515896000 0.008501152000
25 384 0.001995757000 0.0000571764000 0.009414544000
26 385 0.002236000000 0.0000640000000 0.010549990000
27 386 0.002535385000 0.0000723442100 0.011965800000
28 387 0.002892603000 0.0000822122400 0.013655870000
29 388 0.003300829000 0.0000935081600 0.015588050000
30 389 0.003753236000 0.0001061361000 0.017730150000
31 390 0.004243000000 0.0001200000000 0.020050010000
32 391 0.004762389000 0.0001349840000 0.022511360000
33 392 0.005330048000 0.0001514920000 0.025202880000
34 393 0.005978712000 0.0001702080000 0.028279720000
35 394 0.006741117000 0.0001918160000 0.031897040000
36 395 0.007650000000 0.0002170000000 0.036210000000
37 396 0.008751373000 0.0002469067000 0.041437710000
38 397 0.010028880000 0.0002812400000 0.047503720000
39 398 0.011421700000 0.0003185200000 0.054119880000
40 399 0.012869010000 0.0003572667000 0.060998030000
41 400 0.014310000000 0.0003960000000 0.067850010000
42 401 0.015704430000 0.0004337147000 0.074486320000
43 402 0.017147440000 0.0004730240000 0.081361560000
44 403 0.018781220000 0.0005178760000 0.089153640000
45 404 0.020748010000 0.0005722187000 0.098540480000
46 405 0.023190000000 0.0006400000000 0.110200000000
47 406 0.026207360000 0.0007245600000 0.124613300000
48 407 0.029782480000 0.0008255000000 0.141701700000
49 408 0.033880920000 0.0009411600000 0.161303500000
50 409 0.038468240000 0.0010698800000 0.183256800000
51 410 0.043510000000 0.0012100000000 0.207400000000
52 411 0.048995600000 0.0013620910000 0.233692100000
53 412 0.055022600000 0.0015307520000 0.262611400000
54 413 0.061718800000 0.0017203680000 0.294774600000
55 414 0.069212000000 0.0019353230000 0.330798500000
56 415 0.077630000000 0.0021800000000 0.371300000000
57 416 0.086958110000 0.0024548000000 0.416209100000
58 417 0.097176720000 0.0027640000000 0.465464200000
59 418 0.108406300000 0.0031178000000 0.519694800000
60 419 0.120767200000 0.0035264000000 0.579530300000
61 420 0.134380000000 0.0040000000000 0.645600000000
62 421 0.149358200000 0.0045462400000 0.718483800000
63 422 0.165395700000 0.0051593200000 0.796713300000
64 423 0.181983100000 0.0058292800000 0.877845900000
65 424 0.198611000000 0.0065461600000 0.959439000000
66 425 0.214770000000 0.0073000000000 1.039050100000
67 426 0.230186800000 0.0080865070000 1.115367300000
68 427 0.244879700000 0.0089087200000 1.188497100000
69 428 0.258777300000 0.0097676800000 1.258123300000
70 429 0.271807900000 0.0106644300000 1.323929600000
71 430 0.283900000000 0.0116000000000 1.385600000000
72 431 0.294943800000 0.0125731700000 1.442635200000
73 432 0.304896500000 0.0135827200000 1.494803500000
74 433 0.313787300000 0.0146296800000 1.542190300000
75 434 0.321645400000 0.0157150900000 1.584880700000
76 435 0.328500000000 0.0168400000000 1.622960000000
77 436 0.334351300000 0.0180073600000 1.656404800000
78 437 0.339210100000 0.0192144800000 1.685295900000
79 438 0.343121300000 0.0204539200000 1.709874500000
80 439 0.346129600000 0.0217182400000 1.730382100000
81 440 0.348280000000 0.0230000000000 1.747060000000
82 441 0.349599900000 0.0242946100000 1.760044600000
83 442 0.350147400000 0.0256102400000 1.769623300000
84 443 0.350013000000 0.0269585700000 1.776263700000
85 444 0.349287000000 0.0283512500000 1.780433400000
86 445 0.348060000000 0.0298000000000 1.782600000000
87 446 0.346373300000 0.0313108300000 1.782968200000
88 447 0.344262400000 0.0328836800000 1.781699800000
89 448 0.341808800000 0.0345211200000 1.779198200000
90 449 0.339094100000 0.0362257100000 1.775867100000
91 450 0.336200000000 0.0380000000000 1.772110000000
92 451 0.333197700000 0.0398466700000 1.768258900000
93 452 0.330041100000 0.0417680000000 1.764039000000
94 453 0.326635700000 0.0437660000000 1.758943800000
95 454 0.322886800000 0.0458426700000 1.752466300000
96 455 0.318700000000 0.0480000000000 1.744100000000
97 456 0.314025100000 0.0502436800000 1.733559500000
98 457 0.308884000000 0.0525730400000 1.720858100000
99 458 0.303290400000 0.0549805600000 1.705936900000
100 459 0.297257900000 0.0574587200000 1.688737200000
101 460 0.290800000000 0.0600000000000 1.669200000000
102 461 0.283970100000 0.0626019700000 1.647528700000
103 462 0.276721400000 0.0652775200000 1.623412700000
104 463 0.268917800000 0.0680420800000 1.596022300000
105 464 0.260422700000 0.0709110900000 1.564528000000
106 465 0.251100000000 0.0739000000000 1.528100000000
107 466 0.240847500000 0.0770160000000 1.486111400000
108 467 0.229851200000 0.0802664000000 1.439521500000
109 468 0.218407200000 0.0836668000000 1.389879900000
110 469 0.206811500000 0.0872328000000 1.338736200000
111 470 0.195360000000 0.0909800000000 1.287640000000
112 471 0.184213600000 0.0949175500000 1.237422300000
113 472 0.173327300000 0.0990458400000 1.187824300000
114 473 0.162688100000 0.1033674000000 1.138761100000
115 474 0.152283300000 0.1078846000000 1.090148000000
116 475 0.142100000000 0.1126000000000 1.041900000000
117 476 0.132178600000 0.1175320000000 0.994197600000
118 477 0.122569600000 0.1226744000000 0.947347300000
119 478 0.113275200000 0.1279928000000 0.901453100000
120 479 0.104297900000 0.1334528000000 0.856619300000
121 480 0.095640000000 0.1390200000000 0.812950100000
122 481 0.087299550000 0.1446764000000 0.770517300000
123 482 0.079308040000 0.1504693000000 0.729444800000
124 483 0.071717760000 0.1564619000000 0.689913600000
125 484 0.064580990000 0.1627177000000 0.652104900000
126 485 0.057950010000 0.1693000000000 0.616200000000
127 486 0.051862110000 0.1762431000000 0.582328600000
128 487 0.046281520000 0.1835581000000 0.550416200000
129 488 0.041150880000 0.1912735000000 0.520337600000
130 489 0.036412830000 0.1994180000000 0.491967300000
131 490 0.032010000000 0.2080200000000 0.465180000000
132 491 0.027917200000 0.2171199000000 0.439924600000
133 492 0.024144400000 0.2267345000000 0.416183600000
134 493 0.020687000000 0.2368571000000 0.393882200000
135 494 0.017540400000 0.2474812000000 0.372945900000
136 495 0.014700000000 0.2586000000000 0.353300000000
137 496 0.012161790000 0.2701849000000 0.334857800000
138 497 0.009919960000 0.2822939000000 0.317552100000
139 498 0.007967240000 0.2950505000000 0.301337500000
140 499 0.006296346000 0.3085780000000 0.286168600000
141 500 0.004900000000 0.3230000000000 0.272000000000
142 501 0.003777173000 0.3384021000000 0.258817100000
143 502 0.002945320000 0.3546858000000 0.246483800000
144 503 0.002424880000 0.3716986000000 0.234771800000
145 504 0.002236293000 0.3892875000000 0.223453300000
146 505 0.002400000000 0.4073000000000 0.212300000000
147 506 0.002925520000 0.4256299000000 0.201169200000
148 507 0.003836560000 0.4443096000000 0.190119600000
149 508 0.005174840000 0.4633944000000 0.179225400000
150 509 0.006982080000 0.4829395000000 0.168560800000
151 510 0.009300000000 0.5030000000000 0.158200000000
152 511 0.012149490000 0.5235693000000 0.148138300000
153 512 0.015535880000 0.5445120000000 0.138375800000
154 513 0.019477520000 0.5656900000000 0.128994200000
155 514 0.023992770000 0.5869653000000 0.120075100000
156 515 0.029100000000 0.6082000000000 0.111700000000
157 516 0.034814850000 0.6293456000000 0.103904800000
158 517 0.041120160000 0.6503068000000 0.096667480000
159 518 0.047985040000 0.6708752000000 0.089982720000
160 519 0.055378610000 0.6908424000000 0.083845310000
161 520 0.063270000000 0.7100000000000 0.078249990000
162 521 0.071635010000 0.7281852000000 0.073208990000
163 522 0.080462240000 0.7454636000000 0.068678160000
164 523 0.089739960000 0.7619694000000 0.064567840000
165 524 0.099456450000 0.7778368000000 0.060788350000
166 525 0.109600000000 0.7932000000000 0.057250010000
167 526 0.120167400000 0.8081104000000 0.053904350000
168 527 0.131114500000 0.8224962000000 0.050746640000
169 528 0.142367900000 0.8363068000000 0.047752760000
170 529 0.153854200000 0.8494916000000 0.044898590000
171 530 0.165500000000 0.8620000000000 0.042160000000
172 531 0.177257100000 0.8738108000000 0.039507280000
173 532 0.189140000000 0.8849624000000 0.036935640000
174 533 0.201169400000 0.8954936000000 0.034458360000
175 534 0.213365800000 0.9054432000000 0.032088720000
176 535 0.225749900000 0.9148501000000 0.029840000000
177 536 0.238320900000 0.9237348000000 0.027711810000
178 537 0.251066800000 0.9320924000000 0.025694440000
179 538 0.263992200000 0.9399226000000 0.023787160000
180 539 0.277101700000 0.9472252000000 0.021989250000
181 540 0.290400000000 0.9540000000000 0.020300000000
182 541 0.303891200000 0.9602561000000 0.018718050000
183 542 0.317572600000 0.9660074000000 0.017240360000
184 543 0.331438400000 0.9712606000000 0.015863640000
185 544 0.345482800000 0.9760225000000 0.014584610000
186 545 0.359700000000 0.9803000000000 0.013400000000
187 546 0.374083900000 0.9840924000000 0.012307230000
188 547 0.388639600000 0.9874182000000 0.011301880000
189 548 0.403378400000 0.9903128000000 0.010377920000
190 549 0.418311500000 0.9928116000000 0.009529306000
191 550 0.433449900000 0.9949501000000 0.008749999000
192 551 0.448795300000 0.9967108000000 0.008035200000
193 552 0.464336000000 0.9980983000000 0.007381600000
194 553 0.480064000000 0.9991120000000 0.006785400000
195 554 0.495971300000 0.9997482000000 0.006242800000
196 555 0.512050100000 1.0000000000000 0.005749999000
197 556 0.528295900000 0.9998567000000 0.005303600000
198 557 0.544691600000 0.9993046000000 0.004899800000
199 558 0.561209400000 0.9983255000000 0.004534200000
200 559 0.577821500000 0.9968987000000 0.004202400000
201 560 0.594500000000 0.9950000000000 0.003900000000
202 561 0.611220900000 0.9926005000000 0.003623200000
203 562 0.627975800000 0.9897426000000 0.003370600000
204 563 0.644760200000 0.9864444000000 0.003141400000
205 564 0.661569700000 0.9827241000000 0.002934800000
206 565 0.678400000000 0.9786000000000 0.002749999000
207 566 0.695239200000 0.9740837000000 0.002585200000
208 567 0.712058600000 0.9691712000000 0.002438600000
209 568 0.728828400000 0.9638568000000 0.002309400000
210 569 0.745518800000 0.9581349000000 0.002196800000
211 570 0.762100000000 0.9520000000000 0.002100000000
212 571 0.778543200000 0.9454504000000 0.002017733000
213 572 0.794825600000 0.9384992000000 0.001948200000
214 573 0.810926400000 0.9311628000000 0.001889800000
215 574 0.826824800000 0.9234576000000 0.001840933000
216 575 0.842500000000 0.9154000000000 0.001800000000
217 576 0.857932500000 0.9070064000000 0.001766267000
218 577 0.873081600000 0.8982772000000 0.001737800000
219 578 0.887894400000 0.8892048000000 0.001711200000
220 579 0.902318100000 0.8797816000000 0.001683067000
221 580 0.916300000000 0.8700000000000 0.001650001000
222 581 0.929799500000 0.8598613000000 0.001610133000
223 582 0.942798400000 0.8493920000000 0.001564400000
224 583 0.955277600000 0.8386220000000 0.001513600000
225 584 0.967217900000 0.8275813000000 0.001458533000
226 585 0.978600000000 0.8163000000000 0.001400000000
227 586 0.989385600000 0.8047947000000 0.001336667000
228 587 0.999548800000 0.7930820000000 0.001270000000
229 588 1.009089200000 0.7811920000000 0.001205000000
230 589 1.018006400000 0.7691547000000 0.001146667000
231 590 1.026300000000 0.7570000000000 0.001100000000
232 591 1.033982700000 0.7447541000000 0.001068800000
233 592 1.040986000000 0.7324224000000 0.001049400000
234 593 1.047188000000 0.7200036000000 0.001035600000
235 594 1.052466700000 0.7074965000000 0.001021200000
236 595 1.056700000000 0.6949000000000 0.001000000000
237 596 1.059794400000 0.6822192000000 0.000968640000
238 597 1.061799200000 0.6694716000000 0.000929920000
239 598 1.062806800000 0.6566744000000 0.000886880000
240 599 1.062909600000 0.6438448000000 0.000842560000
241 600 1.062200000000 0.6310000000000 0.000800000000
242 601 1.060735200000 0.6181555000000 0.000760960000
243 602 1.058443600000 0.6053144000000 0.000723680000
244 603 1.055224400000 0.5924756000000 0.000685920000
245 604 1.050976800000 0.5796379000000 0.000645440000
246 605 1.045600000000 0.5668000000000 0.000600000000
247 606 1.039036900000 0.5539611000000 0.000547866700
248 607 1.031360800000 0.5411372000000 0.000491600000
249 608 1.022666200000 0.5283528000000 0.000435400000
250 609 1.013047700000 0.5156323000000 0.000383466700
251 610 1.002600000000 0.5030000000000 0.000340000000
252 611 0.991367500000 0.4904688000000 0.000307253300
253 612 0.979331400000 0.4780304000000 0.000283160000
254 613 0.966491600000 0.4656776000000 0.000265440000
255 614 0.952847900000 0.4534032000000 0.000251813300
256 615 0.938400000000 0.4412000000000 0.000240000000
257 616 0.923194000000 0.4290800000000 0.000229546700
258 617 0.907244000000 0.4170360000000 0.000220640000
259 618 0.890502000000 0.4050320000000 0.000211960000
260 619 0.872920000000 0.3930320000000 0.000202186700
261 620 0.854449900000 0.3810000000000 0.000190000000
262 621 0.835084000000 0.3689184000000 0.000174213300
263 622 0.814946000000 0.3568272000000 0.000155640000
264 623 0.794186000000 0.3447768000000 0.000135960000
265 624 0.772954000000 0.3328176000000 0.000116853300
266 625 0.751400000000 0.3210000000000 0.000100000000
267 626 0.729583600000 0.3093381000000 0.000086133330
268 627 0.707588800000 0.2978504000000 0.000074600000
269 628 0.685602200000 0.2865936000000 0.000065000000
270 629 0.663810400000 0.2756245000000 0.000056933330
271 630 0.642400000000 0.2650000000000 0.000049999990
272 631 0.621514900000 0.2547632000000 0.000044160000
273 632 0.601113800000 0.2448896000000 0.000039480000
274 633 0.581105200000 0.2353344000000 0.000035720000
275 634 0.561397700000 0.2260528000000 0.000032640000
276 635 0.541900000000 0.2170000000000 0.000030000000
277 636 0.522599500000 0.2081616000000 0.000027653330
278 637 0.503546400000 0.1995488000000 0.000025560000
279 638 0.484743600000 0.1911552000000 0.000023640000
280 639 0.466193900000 0.1829744000000 0.000021813330
281 640 0.447900000000 0.1750000000000 0.000020000000
282 641 0.429861300000 0.1672235000000 0.000018133330
283 642 0.412098000000 0.1596464000000 0.000016200000
284 643 0.394644000000 0.1522776000000 0.000014200000
285 644 0.377533300000 0.1451259000000 0.000012133330
286 645 0.360800000000 0.1382000000000 0.000010000000
287 646 0.344456300000 0.1315003000000 0.000007733333
288 647 0.328516800000 0.1250248000000 0.000005400000
289 648 0.313019200000 0.1187792000000 0.000003200000
290 649 0.298001100000 0.1127691000000 0.000001333333
291 650 0.283500000000 0.1070000000000 0.000000000000
292 651 0.269544800000 0.1014762000000 0.000000000000
293 652 0.256118400000 0.0961886400000 0.000000000000
294 653 0.243189600000 0.0911229600000 0.000000000000
295 654 0.230727200000 0.0862648500000 0.000000000000
296 655 0.218700000000 0.0816000000000 0.000000000000
297 656 0.207097100000 0.0771206400000 0.000000000000
298 657 0.195923200000 0.0728255200000 0.000000000000
299 658 0.185170800000 0.0687100800000 0.000000000000
300 659 0.174832300000 0.0647697600000 0.000000000000
301 660 0.164900000000 0.0610000000000 0.000000000000
302 661 0.155366700000 0.0573962100000 0.000000000000
303 662 0.146230000000 0.0539550400000 0.000000000000
304 663 0.137490000000 0.0506737600000 0.000000000000
305 664 0.129146700000 0.0475496500000 0.000000000000
306 665 0.121200000000 0.0445800000000 0.000000000000
307 666 0.113639700000 0.0417587200000 0.000000000000
308 667 0.106465000000 0.0390849600000 0.000000000000
309 668 0.099690440000 0.0365638400000 0.000000000000
310 669 0.093330610000 0.0342004800000 0.000000000000
311 670 0.087400000000 0.0320000000000 0.000000000000
312 671 0.081900960000 0.0299626100000 0.000000000000
313 672 0.076804280000 0.0280766400000 0.000000000000
314 673 0.072077120000 0.0263293600000 0.000000000000
315 674 0.067686640000 0.0247080500000 0.000000000000
316 675 0.063600000000 0.0232000000000 0.000000000000
317 676 0.059806850000 0.0218007700000 0.000000000000
318 677 0.056282160000 0.0205011200000 0.000000000000
319 678 0.052971040000 0.0192810800000 0.000000000000
320 679 0.049818610000 0.0181206900000 0.000000000000
321 680 0.046770000000 0.0170000000000 0.000000000000
322 681 0.043784050000 0.0159037900000 0.000000000000
323 682 0.040875360000 0.0148371800000 0.000000000000
324 683 0.038072640000 0.0138106800000 0.000000000000
325 684 0.035404610000 0.0128347800000 0.000000000000
326 685 0.032900000000 0.0119200000000 0.000000000000
327 686 0.030564190000 0.0110683100000 0.000000000000
328 687 0.028380560000 0.0102733900000 0.000000000000
329 688 0.026344840000 0.0095333110000 0.000000000000
330 689 0.024452750000 0.0088461570000 0.000000000000
331 690 0.022700000000 0.0082100000000 0.000000000000
332 691 0.021084290000 0.0076237810000 0.000000000000
333 692 0.019599880000 0.0070854240000 0.000000000000
334 693 0.018237320000 0.0065914760000 0.000000000000
335 694 0.016987170000 0.0061384850000 0.000000000000
336 695 0.015840000000 0.0057230000000 0.000000000000
337 696 0.014790640000 0.0053430590000 0.000000000000
338 697 0.013831320000 0.0049957960000 0.000000000000
339 698 0.012948680000 0.0046764040000 0.000000000000
340 699 0.012129200000 0.0043800750000 0.000000000000
341 700 0.011359160000 0.0041020000000 0.000000000000
342 701 0.010629350000 0.0038384530000 0.000000000000
343 702 0.009938846000 0.0035890990000 0.000000000000
344 703 0.009288422000 0.0033542190000 0.000000000000
345 704 0.008678854000 0.0031340930000 0.000000000000
346 705 0.008110916000 0.0029290000000 0.000000000000
347 706 0.007582388000 0.0027381390000 0.000000000000
348 707 0.007088746000 0.0025598760000 0.000000000000
349 708 0.006627313000 0.0023932440000 0.000000000000
350 709 0.006195408000 0.0022372750000 0.000000000000
351 710 0.005790346000 0.0020910000000 0.000000000000
352 711 0.005409826000 0.0019535870000 0.000000000000
353 712 0.005052583000 0.0018245800000 0.000000000000
354 713 0.004717512000 0.0017035800000 0.000000000000
355 714 0.004403507000 0.0015901870000 0.000000000000
356 715 0.004109457000 0.0014840000000 0.000000000000
357 716 0.003833913000 0.0013844960000 0.000000000000
358 717 0.003575748000 0.0012912680000 0.000000000000
359 718 0.003334342000 0.0012040920000 0.000000000000
360 719 0.003109075000 0.0011227440000 0.000000000000
361 720 0.002899327000 0.0010470000000 0.000000000000
362 721 0.002704348000 0.0009765896000 0.000000000000
363 722 0.002523020000 0.0009111088000 0.000000000000
364 723 0.002354168000 0.0008501332000 0.000000000000
365 724 0.002196616000 0.0007932384000 0.000000000000
366 725 0.002049190000 0.0007400000000 0.000000000000
367 726 0.001910960000 0.0006900827000 0.000000000000
368 727 0.001781438000 0.0006433100000 0.000000000000
369 728 0.001660110000 0.0005994960000 0.000000000000
370 729 0.001546459000 0.0005584547000 0.000000000000
371 730 0.001439971000 0.0005200000000 0.000000000000
372 731 0.001340042000 0.0004839136000 0.000000000000
373 732 0.001246275000 0.0004500528000 0.000000000000
374 733 0.001158471000 0.0004183452000 0.000000000000
375 734 0.001076430000 0.0003887184000 0.000000000000
376 735 0.000999949300 0.0003611000000 0.000000000000
377 736 0.000928735800 0.0003353835000 0.000000000000
378 737 0.000862433200 0.0003114404000 0.000000000000
379 738 0.000800750300 0.0002891656000 0.000000000000
380 739 0.000743396000 0.0002684539000 0.000000000000
381 740 0.000690078600 0.0002492000000 0.000000000000
382 741 0.000640515600 0.0002313019000 0.000000000000
383 742 0.000594502100 0.0002146856000 0.000000000000
384 743 0.000551864600 0.0001992884000 0.000000000000
385 744 0.000512429000 0.0001850475000 0.000000000000
386 745 0.000476021300 0.0001719000000 0.000000000000
387 746 0.000442453600 0.0001597781000 0.000000000000
388 747 0.000411511700 0.0001486044000 0.000000000000
389 748 0.000382981400 0.0001383016000 0.000000000000
390 749 0.000356649100 0.0001287925000 0.000000000000
391 750 0.000332301100 0.0001200000000 0.000000000000
392 751 0.000309758600 0.0001118595000 0.000000000000
393 752 0.000288887100 0.0001043224000 0.000000000000
394 753 0.000269539400 0.0000973356000 0.000000000000
395 754 0.000251568200 0.0000908458700 0.000000000000
396 755 0.000234826100 0.0000848000000 0.000000000000
397 756 0.000219171000 0.0000791466700 0.000000000000
398 757 0.000204525800 0.0000738580000 0.000000000000
399 758 0.000190840500 0.0000689160000 0.000000000000
400 759 0.000178065400 0.0000643026700 0.000000000000
401 760 0.000166150500 0.0000600000000 0.000000000000
402 761 0.000155023600 0.0000559818700 0.000000000000
403 762 0.000144621900 0.0000522256000 0.000000000000
404 763 0.000134909800 0.0000487184000 0.000000000000
405 764 0.000125852000 0.0000454474700 0.000000000000
406 765 0.000117413000 0.0000424000000 0.000000000000
407 766 0.000109551500 0.0000395610400 0.000000000000
408 767 0.000102224500 0.0000369151200 0.000000000000
409 768 0.000095394450 0.0000344486800 0.000000000000
410 769 0.000089023900 0.0000321481600 0.000000000000
411 770 0.000083075270 0.0000300000000 0.000000000000
412 771 0.000077512690 0.0000279912500 0.000000000000
413 772 0.000072313040 0.0000261135600 0.000000000000
414 773 0.000067457780 0.0000243602400 0.000000000000
415 774 0.000062928440 0.0000227246100 0.000000000000
416 775 0.000058706520 0.0000212000000 0.000000000000
417 776 0.000054770280 0.0000197785500 0.000000000000
418 777 0.000051099180 0.0000184528500 0.000000000000
419 778 0.000047676540 0.0000172168700 0.000000000000
420 779 0.000044485670 0.0000160645900 0.000000000000
421 780 0.000041509940 0.0000149900000 0.000000000000
422 781 0.000038733240 0.0000139872800 0.000000000000
423 782 0.000036142030 0.0000130515500 0.000000000000
424 783 0.000033723520 0.0000121781800 0.000000000000
425 784 0.000031464870 0.0000113625400 0.000000000000
426 785 0.000029353260 0.0000106000000 0.000000000000
427 786 0.000027375730 0.0000098858770 0.000000000000
428 787 0.000025524330 0.0000092173040 0.000000000000
429 788 0.000023793760 0.0000085923620 0.000000000000
430 789 0.000022178700 0.0000080091330 0.000000000000
431 790 0.000020673830 0.0000074657000 0.000000000000
432 791 0.000019272260 0.0000069595670 0.000000000000
433 792 0.000017966400 0.0000064879950 0.000000000000
434 793 0.000016749910 0.0000060486990 0.000000000000
435 794 0.000015616480 0.0000056393960 0.000000000000
436 795 0.000014559770 0.0000052578000 0.000000000000
437 796 0.000013573870 0.0000049017710 0.000000000000
438 797 0.000012654360 0.0000045697200 0.000000000000
439 798 0.000011797230 0.0000042601940 0.000000000000
440 799 0.000010998440 0.0000039717390 0.000000000000
441 800 0.000010253980 0.0000037029000 0.000000000000
442 801 0.000009559646 0.0000034521630 0.000000000000
443 802 0.000008912044 0.0000032183020 0.000000000000
444 803 0.000008308358 0.0000030003000 0.000000000000
445 804 0.000007745769 0.0000027971390 0.000000000000
446 805 0.000007221456 0.0000026078000 0.000000000000
447 806 0.000006732475 0.0000024312200 0.000000000000
448 807 0.000006276423 0.0000022665310 0.000000000000
449 808 0.000005851304 0.0000021130130 0.000000000000
450 809 0.000005455118 0.0000019699430 0.000000000000
451 810 0.000005085868 0.0000018366000 0.000000000000
452 811 0.000004741466 0.0000017122300 0.000000000000
453 812 0.000004420236 0.0000015962280 0.000000000000
454 813 0.000004120783 0.0000014880900 0.000000000000
455 814 0.000003841716 0.0000013873140 0.000000000000
456 815 0.000003581652 0.0000012934000 0.000000000000
457 816 0.000003339127 0.0000012058200 0.000000000000
458 817 0.000003112949 0.0000011241430 0.000000000000
459 818 0.000002902121 0.0000010480090 0.000000000000
460 819 0.000002705645 0.0000009770578 0.000000000000
461 820 0.000002522525 0.0000009109300 0.000000000000
462 821 0.000002351726 0.0000008492513 0.000000000000
463 822 0.000002192415 0.0000007917212 0.000000000000
464 823 0.000002043902 0.0000007380904 0.000000000000
465 824 0.000001905497 0.0000006881098 0.000000000000
466 825 0.000001776509 0.0000006415300 0.000000000000
467 826 0.000001656215 0.0000005980895 0.000000000000
468 827 0.000001544022 0.0000005575746 0.000000000000
469 828 0.000001439440 0.0000005198080 0.000000000000
470 829 0.000001341977 0.0000004846123 0.000000000000
471 830 0.000001251141 0.0000004518100 0.000000000000
+40
View File
@@ -0,0 +1,40 @@
# CIE 1931 blackbody LUT
`cie1931_2deg_xyz_1024.grbblut` is the sole repository LUT. It contains 1,024
XYZ nodes uniformly spaced in `log(T)` over `[670.146556, 101408.88] K`.
Wolfram integrates the Planck spectrum against the piecewise-linear 1 nm data
in `assets/CIE_xyz_1931_2deg.csv` at 40-digit working precision and rounds each
stored value once to little-endian IEEE binary64.
The 160-byte `GRBBLUT3` header records the CIE 1931 2-degree, 360--830 nm,
1 nm-linear reference definition, node count, temperature limits, physical
constants, generator description, and payload FNV-1a checksum. The C loader
validates the header, exact payload size, and checksum, and rejects trailing
bytes. Runtime table generation and the former `GRBBLUT1`/`GRBBLUT2` formats are
not supported. The evaluator uses four-point cubic Lagrange interpolation in
`log(T)`.
- file size: 24,736 bytes
- payload FNV-1a: `0e39867b0e70a809`
- file SHA-256:
`850446663212fe488c88fca3ac2f54d6f8119a04801dda84fc1a62acdec37d63`
- all 1,023 interval midpoints versus independent Gauss-16 integration:
max XYZ-channel relative `5.4633e-5`, no negative XYZ
The LUT interpolation acceptance limit is `1e-4`. A separate `5e-4` overall
relative error budget accounts for the estimated error of linearly
interpolating the 1 nm CIE samples; the LUT's much smaller internal error must
not be mistaken for physical-reference accuracy.
Outside the stored range, the same CSV reference supplies both models. Above
101408.88 K the evaluator uses three integrated Rayleigh--Jeans terms
`A T+B+C/T` (maximum validated XYZ-channel relative error `1.6635e-5`
through `10*Tmax`). Below 670.146556 K it uses a six-segment, degree-eight
inverse-temperature/log-XYZ Chebyshev--Lobatto crossover down to 4.097321 K
and channel-specific endpoint forms below that. Their maximum sampled XYZ
relative errors are `8.16e-5` and `6.69e-5`.
The Wolfram generation/validation scripts that produced this table, together
with the bounded performance and accuracy evidence, are preserved on the
experiment branch `codex/blackbody-cost-experiment` (tag
`blackbody-cost-experiment-2026-09-12`) and are not part of the mainline tree.
Binary file not shown.
@@ -0,0 +1 @@
__pycache__/
@@ -0,0 +1,84 @@
# Production chunk geometry diagnostic (2026-09-11)
## Scope
This run measures the event stream that the production HIP sink would receive
for the supplied Schwarzschild Galactic-center render. `PSF_BACKEND=dummy`
keeps the real imported lens map, all-sky prefetch, OpenMP dynamic triangle
scheduling, inverse mapping, redshift/color/flux work, PSF cache eligibility,
and 16,384-event per-worker chunk boundaries. It does not initialize HIP,
allocate a full HDR framebuffer, splat pixels, or write PNG/FITS output.
The run used repository revision `11e703e33dffb1ff168ba11dd922e68b448116b9`
plus the uncommitted dummy-backend work. The complete stdout/stderr, executable
and input hashes, process resource use, and protected-output hashes are in
[`full_catalog.log`](full_catalog.log). An initial harness-only failure before
the renderer started is retained as
[`full_catalog_missing_time.log`](full_catalog_missing_time.log).
## Build and run
```sh
make -j1 PSF_BACKEND=dummy SPACETIME=schwarzschild ENABLE_HDR=1 backend
python3 benchmarks/dummy_psf_chunks_2026-09-11/run.py
```
The runner fixes `OMP_NUM_THREADS=16` and `OMP_DYNAMIC=FALSE`, uses a 600-second
timeout and a process lock, refuses to overwrite its log, and hashes both the
named PNG and companion FITS before and after the run. Its renderer arguments
are exactly the user-supplied command except that the `_hip` executable is
replaced by `_dummy`; the exact expanded command is the first line of the log.
Inputs and protected outputs:
- lens map SHA-256:
`905f960aea2d276f9586c79fba545a72cf742311e9e7e18faea293835c68bf28`
- existing PNG SHA-256 before/after:
`3e01feb911e60acce545a6a86870ca05f96250022e874eb8097bec88a8879bfd`
- existing FITS SHA-256 before/after:
`2408e62dcc22f147da284d87af9a2b0fdd0050eda2dabc23b6ec2554b2f1d38e`
Both protected files retained the same size and nanosecond mtime as well as the
same hash. No HIP backend was run.
## Result
The catalog prefetch loaded 343,363,141 stars for 130,882 lens triangles. The
producer classified 598,264,924 cache events, with zero direct fallbacks,
wing-clipped events, or min-Y discards. Sixteen workers produced 36,524 chunks:
36,508 full chunks and one final partial chunk per worker.
| full-chunk metric | min | p10 | p25 | p50 | p75 | p90 | p99 | max |
|---|---:|---:|---:|---:|---:|---:|---:|---:|
| event-producing triangles | 1 | 1 | 1 | 2 | 3 | 10 | 31 | 59 |
| occupied 32px center tiles | 1 | 1 | 1 | 1 | 2 | 5 | 30 | 45 |
| event bbox diagonal (px) | 0.199 | 0.742 | 3.250 | 12.651 | 57.018 | 429.306 | 3759.261 | 3834.557 |
| triangle-centroid bbox diagonal (px) | 0 | 0 | 0 | 9.618 | 49.477 | 424.149 | 3744.061 | 3824.075 |
| maximum successive centroid jump (px) | 0 | 0 | 0 | 8.724 | 25.157 | 144.000 | 3744.034 | 3792.034 |
All 36,508 full chunks satisfy the replay prototype's current selector:
`events >= 8192 && events / occupied_32px_tiles >= 32`.
Catalog prefetch took 55.469 s. Producer classification and chunk accounting
took 232.340 s; total process wall time was 288.872 s. These are diagnostic CPU
costs and do not estimate HIP tile-kernel speed.
## Interpretation and limits
The measured production event order strongly supports the hypothesis that a
full worker chunk is usually filled by very few image-plane triangles: the
median is two and 75% contain at most three. Center-tile occupancy is even more
concentrated. This is favorable for a tile16 path because the same output pixels
receive many contributions that can be reduced before the final double HDR
write.
The rare tail matters: p99 chunks can contain a few clusters separated by
nearly the full 4K image width. “Few triangles” therefore does not imply one
small contiguous bounding rectangle. A production implementation should use a
sparse occupied-tile list, retain the atomic fallback, and measure the complete
streaming sink including binning and synchronization.
This is one Schwarzschild Galactic-center frame with one 16-worker dynamic
schedule. Worker-to-triangle assignment is nondeterministic, so exact quantiles
may vary between runs. The result establishes event geometry for this input; it
does not by itself establish single-BH/BBH universality or a HIP speedup.
@@ -0,0 +1,235 @@
COMMAND OMP_NUM_THREADS=16 OMP_DYNAMIC=FALSE /home/wyj/Code/C/GR_4d_raytracing/build/Release/schwarzschild_sky_dummy --verbose --psf-relative-tail 1e-8 --psf-min-y 0 --max-cache-psf-flux 1e8 --all-sky-catalog assets/2mass/processed/all_sky --exposure 1e13 --psf-fwhm-pixels 2.7 --psf-moffat-beta 4.5 --catalog-load-workers 4 --hdr-output --lens-map-input output/lens/schwarzschild_galactic_center_R100_45deg_16_4_4k_.grlens --output output/imgs/2mass_galactic_center_schwarzschild_R100_4k_1e13_beta4.5_16_4-full-gpu.png
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 c71a843a6064cd730b4694c5fe4e61249a995106526da0fdca97bc625c7db470
LENS_SHA256 905f960aea2d276f9586c79fba545a72cf742311e9e7e18faea293835c68bf28
PROTECTED_BEFORE output/imgs/2mass_galactic_center_schwarzschild_R100_4k_1e13_beta4.5_16_4-full-gpu.png sha256=3e01feb911e60acce545a6a86870ca05f96250022e874eb8097bec88a8879bfd size=13072572 mtime_ns=1788744728751407011
PROTECTED_BEFORE output/imgs/2mass_galactic_center_schwarzschild_R100_4k_1e13_beta4.5_16_4-full-gpu_HDR.fits sha256=2408e62dcc22f147da284d87af9a2b0fdd0050eda2dabc23b6ec2554b2f1d38e size=99535680 mtime_ns=1788744726380022561
Dummy PSF backend: --output and --hdr-output are accepted for command parity but no image files will be written.
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.678 s
Frame 0: finding and prefetching catalog tiles...
Catalog prefetch: 64440 requested, 64440 newly loaded (343363141 stars), 0 unavailable in 55.469 s; 4 loader workers
Frame 0: catalog prefetch finished (64440 candidate tiles).
Frame 0: splatting 130882 lens triangles...
Frame 0: splat worker 2/16 started.
Frame 0: splat worker 1/16 started.
Frame 0: splat worker 4/16 started.
Frame 0: splat worker 3/16 started.
Frame 0: splat worker 5/16 started.
Frame 0: splat worker 10/16 started.
Frame 0: splat worker 7/16 started.
Frame 0: splat worker 8/16 started.
Frame 0: splat worker 13/16 started.
Frame 0: splat worker 11/16 started.
Frame 0: splat worker 6/16 started.
Frame 0: splat worker 12/16 started.
Frame 0: splat worker 9/16 started.
Frame 0: splat worker 14/16 started.
Frame 0: splat worker 16/16 started.
Frame 0: splat worker 15/16 started.
Frame 0: splat worker 1/16 reached 8 local triangles.
Frame 0: splat worker 6/16 reached 8 local triangles.
Frame 0: splat worker 10/16 reached 8 local triangles.
Frame 0: splat worker 14/16 reached 8 local triangles.
Frame 0: splat worker 12/16 reached 8 local triangles.
Frame 0: splat worker 2/16 reached 8 local triangles.
Frame 0: splat worker 5/16 reached 8 local triangles.
Frame 0: splat worker 3/16 reached 8 local triangles.
Frame 0: splat worker 7/16 reached 8 local triangles.
Frame 0: splat worker 15/16 reached 8 local triangles.
Frame 0: splat worker 8/16 reached 8 local triangles.
Frame 0: splat worker 4/16 reached 8 local triangles.
Frame 0: splat worker 11/16 reached 8 local triangles.
Frame 0: splat worker 13/16 reached 8 local triangles.
Frame 0: splat worker 9/16 reached 8 local triangles.
Frame 0: splat worker 16/16 reached 8 local triangles.
Frame 0: splat worker 12/16 reached 16 local triangles.
Frame 0: splat worker 4/16 reached 16 local triangles.
Frame 0: splat worker 14/16 reached 16 local triangles.
Frame 0: splat worker 6/16 reached 16 local triangles.
Frame 0: splat worker 1/16 reached 16 local triangles.
Frame 0: splat worker 8/16 reached 16 local triangles.
Frame 0: splat worker 3/16 reached 16 local triangles.
Frame 0: splat worker 7/16 reached 16 local triangles.
Frame 0: splat worker 2/16 reached 16 local triangles.
Frame 0: splat worker 15/16 reached 16 local triangles.
Frame 0: splat worker 5/16 reached 16 local triangles.
Frame 0: splat worker 11/16 reached 16 local triangles.
Frame 0: splat worker 13/16 reached 16 local triangles.
Frame 0: splat worker 9/16 reached 16 local triangles.
Frame 0: splat worker 16/16 reached 16 local triangles.
Frame 0: splat worker 12/16 reached 32 local triangles.
Frame 0: splat worker 4/16 reached 32 local triangles.
Frame 0: splat worker 7/16 reached 32 local triangles.
Frame 0: splat worker 6/16 reached 32 local triangles.
Frame 0: splat worker 8/16 reached 32 local triangles.
Frame 0: splat worker 2/16 reached 32 local triangles.
Frame 0: splat worker 3/16 reached 32 local triangles.
Frame 0: splat worker 11/16 reached 32 local triangles.
Frame 0: splat worker 9/16 reached 32 local triangles.
Frame 0: splat worker 1/16 reached 32 local triangles.
Frame 0: splat worker 15/16 reached 32 local triangles.
Frame 0: splat worker 16/16 reached 32 local triangles.
Frame 0: splat worker 14/16 reached 32 local triangles.
Frame 0: splat worker 5/16 reached 32 local triangles.
Frame 0: splat worker 13/16 reached 32 local triangles.
Frame 0: splat worker 10/16 reached 16 local triangles.
Frame 0: splat worker 10/16 reached 32 local triangles.
Frame 0: splat worker 4/16 reached 64 local triangles.
Frame 0: splat worker 6/16 reached 64 local triangles.
Frame 0: splat worker 8/16 reached 64 local triangles.
Frame 0: splat worker 2/16 reached 64 local triangles.
Frame 0: splat worker 3/16 reached 64 local triangles.
Frame 0: splat worker 12/16 reached 64 local triangles.
Frame 0: splat worker 11/16 reached 64 local triangles.
Frame 0: splat worker 15/16 reached 64 local triangles.
Frame 0: splat worker 16/16 reached 64 local triangles.
Frame 0: splat worker 14/16 reached 64 local triangles.
Frame 0: splat worker 5/16 reached 64 local triangles.
Frame 0: splat worker 9/16 reached 64 local triangles.
Frame 0: splat worker 1/16 reached 64 local triangles.
Frame 0: splat worker 7/16 reached 64 local triangles.
Frame 0: splat worker 13/16 reached 64 local triangles.
Frame 0: splat worker 10/16 reached 64 local triangles.
Frame 0: splat worker 4/16 reached 128 local triangles.
Frame 0: splat worker 12/16 reached 128 local triangles.
Frame 0: splat worker 11/16 reached 128 local triangles.
Frame 0: splat worker 6/16 reached 128 local triangles.
Frame 0: splat worker 15/16 reached 128 local triangles.
Frame 0: splat worker 2/16 reached 128 local triangles.
Frame 0: splat worker 5/16 reached 128 local triangles.
Frame 0: splat worker 8/16 reached 128 local triangles.
Frame 0: splat worker 3/16 reached 128 local triangles.
Frame 0: splat worker 16/16 reached 128 local triangles.
Frame 0: splat worker 14/16 reached 128 local triangles.
Frame 0: splat worker 7/16 reached 128 local triangles.
Frame 0: splat worker 1/16 reached 128 local triangles.
Frame 0: splat worker 13/16 reached 128 local triangles.
Frame 0: splat worker 9/16 reached 128 local triangles.
Frame 0: splat worker 10/16 reached 128 local triangles.
Frame 0: splat worker 13/16 reached 256 local triangles.
Frame 0: splat worker 15/16 reached 256 local triangles.
Frame 0: splat worker 16/16 reached 256 local triangles.
Frame 0: splat worker 8/16 reached 256 local triangles.
Frame 0: splat worker 11/16 reached 256 local triangles.
Frame 0: splat worker 6/16 reached 256 local triangles.
Frame 0: splat worker 5/16 reached 256 local triangles.
Frame 0: splat worker 3/16 reached 256 local triangles.
Frame 0: splat worker 1/16 reached 256 local triangles.
Frame 0: splat worker 2/16 reached 256 local triangles.
Frame 0: splat worker 7/16 reached 256 local triangles.
Frame 0: splat worker 4/16 reached 256 local triangles.
Frame 0: splat worker 12/16 reached 256 local triangles.
Frame 0: splat worker 10/16 reached 256 local triangles.
Frame 0: splat worker 14/16 reached 256 local triangles.
Frame 0: splat worker 9/16 reached 256 local triangles.
Frame 0: splat worker 8/16 reached 512 local triangles.
Frame 0: splat worker 12/16 reached 512 local triangles.
Frame 0: splat worker 16/16 reached 512 local triangles.
Frame 0: splat worker 5/16 reached 512 local triangles.
Frame 0: splat worker 13/16 reached 512 local triangles.
Frame 0: splat worker 3/16 reached 512 local triangles.
Frame 0: splat worker 7/16 reached 512 local triangles.
Frame 0: splat worker 11/16 reached 512 local triangles.
Frame 0: splat worker 1/16 reached 512 local triangles.
Frame 0: splat worker 15/16 reached 512 local triangles.
Frame 0: splat worker 2/16 reached 512 local triangles.
Frame 0: splat worker 10/16 reached 512 local triangles.
Frame 0: splat worker 4/16 reached 512 local triangles.
Frame 0: splat worker 6/16 reached 512 local triangles.
Frame 0: splat worker 14/16 reached 512 local triangles.
Frame 0: splat worker 9/16 reached 512 local triangles.
Frame 0: splat worker 8/16 reached 1024 local triangles.
Frame 0: splat worker 7/16 reached 1024 local triangles.
Frame 0: splat worker 12/16 reached 1024 local triangles.
Frame 0: splat worker 3/16 reached 1024 local triangles.
Frame 0: splat worker 16/16 reached 1024 local triangles.
Frame 0: splat worker 11/16 reached 1024 local triangles.
Frame 0: splat worker 5/16 reached 1024 local triangles.
Frame 0: splat worker 14/16 reached 1024 local triangles.
Frame 0: splat worker 15/16 reached 1024 local triangles.
Frame 0: splat worker 4/16 reached 1024 local triangles.
Frame 0: splat worker 9/16 reached 1024 local triangles.
Frame 0: splat worker 13/16 reached 1024 local triangles.
Frame 0: splat worker 6/16 reached 1024 local triangles.
Frame 0: splat worker 1/16 reached 1024 local triangles.
Frame 0: splat worker 10/16 reached 1024 local triangles.
Frame 0: splat worker 2/16 reached 1024 local triangles.
Frame 0: splat worker 8/16 reached 2048 local triangles.
Frame 0: splat worker 12/16 reached 2048 local triangles.
Frame 0: splat worker 16/16 reached 2048 local triangles.
Frame 0: splat worker 14/16 reached 2048 local triangles.
Frame 0: splat worker 7/16 reached 2048 local triangles.
Frame 0: splat worker 3/16 reached 2048 local triangles.
Frame 0: splat worker 4/16 reached 2048 local triangles.
Frame 0: splat worker 1/16 reached 2048 local triangles.
Frame 0: splat worker 11/16 reached 2048 local triangles.
Frame 0: splat worker 5/16 reached 2048 local triangles.
Frame 0: splat worker 13/16 reached 2048 local triangles.
Frame 0: splat worker 15/16 reached 2048 local triangles.
Frame 0: splat worker 6/16 reached 2048 local triangles.
Frame 0: splat worker 2/16 reached 2048 local triangles.
Frame 0: splat worker 9/16 reached 2048 local triangles.
Frame 0: splat worker 10/16 reached 2048 local triangles.
Frame 0: splat worker 3/16 reached 4096 local triangles.
Frame 0: splat worker 7/16 reached 4096 local triangles.
Frame 0: splat worker 16/16 reached 4096 local triangles.
Frame 0: splat worker 14/16 reached 4096 local triangles.
Frame 0: splat worker 9/16 reached 4096 local triangles.
Frame 0: splat worker 4/16 reached 4096 local triangles.
Frame 0: splat worker 6/16 reached 4096 local triangles.
Frame 0: splat worker 8/16 reached 4096 local triangles.
Frame 0: splat worker 13/16 reached 4096 local triangles.
Frame 0: splat worker 5/16 reached 4096 local triangles.
Frame 0: splat worker 10/16 reached 4096 local triangles.
Frame 0: splat worker 15/16 reached 4096 local triangles.
Frame 0: splat worker 11/16 reached 4096 local triangles.
Frame 0: splat worker 12/16 reached 4096 local triangles.
Frame 0: splat worker 1/16 reached 4096 local triangles.
Frame 0: splat worker 2/16 reached 4096 local triangles.
Frame 0: splat worker 3/16 reached 8192 local triangles.
Frame 0: splat worker 7/16 reached 8192 local triangles.
Frame 0: splat worker 16/16 reached 8192 local triangles.
Frame 0: splat worker 13/16 reached 8192 local triangles.
Frame 0: splat worker 9/16 reached 8192 local triangles.
Frame 0: splat worker 4/16 reached 8192 local triangles.
Frame 0: splat worker 8/16 reached 8192 local triangles.
Frame 0: splat worker 2/16 finished after 7916 local triangles.
Frame 0: splat worker 8/16 finished after 8212 local triangles.
Frame 0: splat worker 6/16 finished after 8150 local triangles.
Frame 0: splat worker 1/16 finished after 7784 local triangles.
Frame 0: splat worker 4/16 finished after 8227 local triangles.
Frame 0: splat worker 15/16 finished after 7878 local triangles.
Frame 0: splat worker 14/16 finished after 8186 local triangles.
Frame 0: splat worker 11/16 finished after 7962 local triangles.
Frame 0: splat worker 9/16 finished after 8276 local triangles.
Frame 0: splat worker 16/16 finished after 8477 local triangles.
Frame 0: splat worker 3/16 finished after 8967 local triangles.
Frame 0: splat worker 7/16 finished after 8576 local triangles.
Frame 0: splat worker 10/16 finished after 7772 local triangles.
Frame 0: splat worker 13/16 finished after 8295 local triangles.
Frame 0: splat worker 12/16 finished after 8013 local triangles.
Frame 0: splat worker 5/16 finished after 8191 local triangles.
Dummy PSF diagnostic only: no HDR or image was accumulated/written.
Dummy PSF chunks: total=36524 full=36508 partial=16 events=598264924 capacity=16384 selector_tile=32px
Dummy PSF all events: min=263.000 p10=16384.000 p25=16384.000 p50=16384.000 p75=16384.000 p90=16384.000 p99=16384.000 max=16384.000
Dummy PSF all distinct_triangles: min=1.000 p10=1.000 p25=1.000 p50=2.000 p75=4.000 p90=10.000 p99=31.000 max=59.000
Dummy PSF all occupied_32px_tiles: min=1.000 p10=1.000 p25=1.000 p50=1.000 p75=2.000 p90=5.000 p99=30.000 max=45.000
Dummy PSF all event_bbox_diagonal_px: min=0.199 p10=0.743 p25=3.252 p50=12.667 p75=57.123 p90=432.049 p99=3759.261 max=3834.557
Dummy PSF all triangle_centroid_bbox_diagonal_px: min=0.000 p10=0.000 p25=0.000 p50=9.621 p75=49.817 p90=425.680 p99=3744.061 max=3824.075
Dummy PSF all maximum_successive_triangle_jump_px: min=0.000 p10=0.000 p25=0.000 p50=8.750 p75=25.157 p90=144.000 p99=3744.034 max=3792.034
Dummy PSF all adaptive criterion: 36516/36524 chunks tile16-eligible (events>=8192 and events/occupied_32px_tiles>=32)
Dummy PSF full events: min=16384.000 p10=16384.000 p25=16384.000 p50=16384.000 p75=16384.000 p90=16384.000 p99=16384.000 max=16384.000
Dummy PSF full distinct_triangles: min=1.000 p10=1.000 p25=1.000 p50=2.000 p75=3.000 p90=10.000 p99=31.000 max=59.000
Dummy PSF full occupied_32px_tiles: min=1.000 p10=1.000 p25=1.000 p50=1.000 p75=2.000 p90=5.000 p99=30.000 max=45.000
Dummy PSF full event_bbox_diagonal_px: min=0.199 p10=0.742 p25=3.250 p50=12.651 p75=57.018 p90=429.306 p99=3759.261 max=3834.557
Dummy PSF full triangle_centroid_bbox_diagonal_px: min=0.000 p10=0.000 p25=0.000 p50=9.618 p75=49.477 p90=424.149 p99=3744.061 max=3824.075
Dummy PSF full maximum_successive_triangle_jump_px: min=0.000 p10=0.000 p25=0.000 p50=8.724 p75=25.157 p90=144.000 p99=3744.034 max=3792.034
Dummy PSF full adaptive criterion: 36508/36508 chunks tile16-eligible (events>=8192 and events/occupied_32px_tiles>=32)
Dummy PSF producers: 16 workers; classification/chunk wall 232.340 s
Frame 0: catalog classification finished in 232.3 s; reporting chunk statistics...
Dummy PSF classified 598264924 images from 343363141 catalog stars; no HDR, PNG, or PPM was written.
PSF splats: cached 598264924, cached wing-clipped 0, direct fallbacks 0, discarded below min-Y 0
PROCESS_WALL 288.871615309 EXIT 0
PROCESS_USER 3815.986955000 PROCESS_SYSTEM 12.140569000 MAX_RSS_KIB 13769936
PROTECTED_AFTER output/imgs/2mass_galactic_center_schwarzschild_R100_4k_1e13_beta4.5_16_4-full-gpu.png sha256=3e01feb911e60acce545a6a86870ca05f96250022e874eb8097bec88a8879bfd size=13072572 mtime_ns=1788744728751407011 unchanged=yes
PROTECTED_AFTER output/imgs/2mass_galactic_center_schwarzschild_R100_4k_1e13_beta4.5_16_4-full-gpu_HDR.fits sha256=2408e62dcc22f147da284d87af9a2b0fdd0050eda2dabc23b6ec2554b2f1d38e size=99535680 mtime_ns=1788744726380022561 unchanged=yes
@@ -0,0 +1,6 @@
COMMAND OMP_NUM_THREADS=16 OMP_DYNAMIC=FALSE /usr/bin/time -v /home/wyj/Code/C/GR_4d_raytracing/build/Release/schwarzschild_sky_dummy --verbose --psf-relative-tail 1e-8 --psf-min-y 0 --max-cache-psf-flux 1e8 --all-sky-catalog assets/2mass/processed/all_sky --exposure 1e13 --psf-fwhm-pixels 2.7 --psf-moffat-beta 4.5 --catalog-load-workers 4 --hdr-output --lens-map-input output/lens/schwarzschild_galactic_center_R100_45deg_16_4_4k_.grlens --output output/imgs/2mass_galactic_center_schwarzschild_R100_4k_1e13_beta4.5_16_4-full-gpu.png
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 c71a843a6064cd730b4694c5fe4e61249a995106526da0fdca97bc625c7db470
LENS_SHA256 905f960aea2d276f9586c79fba545a72cf742311e9e7e18faea293835c68bf28
PROTECTED_BEFORE output/imgs/2mass_galactic_center_schwarzschild_R100_4k_1e13_beta4.5_16_4-full-gpu.png sha256=3e01feb911e60acce545a6a86870ca05f96250022e874eb8097bec88a8879bfd size=13072572 mtime_ns=1788744728751407011
PROTECTED_BEFORE output/imgs/2mass_galactic_center_schwarzschild_R100_4k_1e13_beta4.5_16_4-full-gpu_HDR.fits sha256=2408e62dcc22f147da284d87af9a2b0fdd0050eda2dabc23b6ec2554b2f1d38e size=99535680 mtime_ns=1788744726380022561
@@ -0,0 +1,99 @@
#!/usr/bin/env python3
"""Run the fixed full-catalog dummy diagnostic once without touching images."""
import fcntl
import hashlib
import os
from pathlib import Path
import resource
import shlex
import signal
import subprocess
import time
ROOT = Path(__file__).resolve().parents[2]
LOG = Path(__file__).with_name("full_catalog.log")
BINARY = ROOT / "build/Release/schwarzschild_sky_dummy"
LENS = ROOT / "output/lens/schwarzschild_galactic_center_R100_45deg_16_4_4k_.grlens"
PNG = ROOT / "output/imgs/2mass_galactic_center_schwarzschild_R100_4k_1e13_beta4.5_16_4-full-gpu.png"
FITS = ROOT / "output/imgs/2mass_galactic_center_schwarzschild_R100_4k_1e13_beta4.5_16_4-full-gpu_HDR.fits"
def digest(path):
return hashlib.sha256(path.read_bytes()).hexdigest()
def main():
if LOG.exists():
raise RuntimeError(f"refusing to overwrite {LOG}")
for path in (BINARY, LENS, PNG, FITS):
if not path.is_file():
raise RuntimeError(f"required file is missing: {path}")
protected_before = {
path: (digest(path), path.stat().st_size, path.stat().st_mtime_ns)
for path in (PNG, FITS)
}
command = [
str(BINARY), "--verbose",
"--psf-relative-tail", "1e-8", "--psf-min-y", "0",
"--max-cache-psf-flux", "1e8",
"--all-sky-catalog", "assets/2mass/processed/all_sky",
"--exposure", "1e13", "--psf-fwhm-pixels", "2.7",
"--psf-moffat-beta", "4.5", "--catalog-load-workers", "4",
"--hdr-output", "--lens-map-input",
"output/lens/schwarzschild_galactic_center_R100_45deg_16_4_4k_.grlens",
"--output",
"output/imgs/2mass_galactic_center_schwarzschild_R100_4k_1e13_beta4.5_16_4-full-gpu.png",
]
guard = open("/tmp/gr_dummy_psf_chunks.lock", "w")
fcntl.flock(guard, fcntl.LOCK_EX | fcntl.LOCK_NB)
env = dict(os.environ, OMP_NUM_THREADS="16", OMP_DYNAMIC="FALSE")
with LOG.open("x") as out:
out.write("COMMAND OMP_NUM_THREADS=16 OMP_DYNAMIC=FALSE " +
shlex.join(command) + "\n")
out.write("GIT " + subprocess.check_output(
["git", "rev-parse", "HEAD"], cwd=ROOT, text=True))
out.write("BINARY_SHA256 " + digest(BINARY) + "\n")
out.write("LENS_SHA256 " + digest(LENS) + "\n")
for path, state in protected_before.items():
out.write(
f"PROTECTED_BEFORE {path.relative_to(ROOT)} sha256={state[0]} "
f"size={state[1]} mtime_ns={state[2]}\n")
out.flush()
start = time.monotonic()
usage_start = resource.getrusage(resource.RUSAGE_CHILDREN)
process = subprocess.Popen(command, cwd=ROOT, env=env, stdout=out,
stderr=subprocess.STDOUT,
start_new_session=True)
try:
returncode = process.wait(timeout=600)
except subprocess.TimeoutExpired:
os.killpg(process.pid, signal.SIGKILL)
process.wait()
out.write("TIMEOUT killed and reaped process group\n")
raise
out.write(
f"PROCESS_WALL {time.monotonic() - start:.9f} EXIT {returncode}\n")
usage_end = resource.getrusage(resource.RUSAGE_CHILDREN)
out.write(
f"PROCESS_USER {usage_end.ru_utime - usage_start.ru_utime:.9f} "
f"PROCESS_SYSTEM {usage_end.ru_stime - usage_start.ru_stime:.9f} "
f"MAX_RSS_KIB {usage_end.ru_maxrss}\n")
protected_after = {
path: (digest(path), path.stat().st_size, path.stat().st_mtime_ns)
for path in (PNG, FITS)
}
if protected_after != protected_before:
raise RuntimeError("a protected render output changed")
with LOG.open("a") as out:
for path, state in protected_after.items():
out.write(
f"PROTECTED_AFTER {path.relative_to(ROOT)} sha256={state[0]} "
f"size={state[1]} mtime_ns={state[2]} unchanged=yes\n")
if returncode:
raise RuntimeError(f"dummy diagnostic exited {returncode}")
print(LOG)
if __name__ == "__main__":
main()
+48
View File
@@ -13,6 +13,54 @@ RX 9070 上,65,536 个真实银心视场事件的累积回放中位数从 104.
一个通用生产默认算法;后续集成应先考虑分布选择及生产流式 producer 的端到端对照。
没有运行完整全天渲染,也没有推断新的全天加速比。
## 2026-09-11 自适应选择后续实验
在提交 `11e703e33dffb1ff168ba11dd922e68b448116b9` 之上增加了仅用于回放的
`adaptive` 模式,production sink 仍未改变。选择器逐个 16,384-event chunk 扫描
32×32 中心 tile 占用;chunk 至少有 8,192 events、且平均每个占用中心 tile 至少
32 events 时选择 tile16,否则选择现有 atomic。该阈值是基于本页固定输入提出的实验
假设,不是跨场景或跨设备参数。
选择扫描不构建 support 引用,四个样本的中位成本为 0.037--0.455 ms。tile 路径使用
独立的有界 event device buffer,不复用 production 双 staging slot,因此同一 stream 内
可以按 chunk 混合 atomic/tile;mixed fixture 实际覆盖 2 个 tile chunk、1 个 atomic chunk
和中途 direct fallback。所有额外 scratch 仍在 replay sink 创建时一次分配,未进入 renderer。
同一新 binary(SHA256
`121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151`)串行运行,
每项三次;表中为包含选择、分桶、上传、kernel、合并、下载和清理的 `replay_wall`
中位数:
| 65,536-event 输入 | paired atomic | paired tile16 | adaptive | adaptive 选择 |
| --- | ---: | ---: | ---: | ---: |
| 银心密集 | 95.018 ms | 67.354 ms | 67.834 ms | 0.177 ms |
| 同贡献分散 | 78.203 ms | 99.693 ms | 80.092 ms | 0.455 ms |
自适应路径在密集输入相对 paired atomic 快约 1.40×,距固定 tile16 中位数 0.7%;在分散
输入保留 atomic,距其 paired 中位数 2.4%。另外两个真实输入的自适应中位数为强放大
21.617 ms、普通区域 18.347 ms,分别选择 1/1 tile chunk。银心选择 4/4 tile chunks,
分散对照选择 4/4 atomic chunks。此结果支持继续研究 production 流式集成,但尚未包含
OpenMP producer 与 sink 锁竞争,也没有授权用本回放结果宣称完整全天加速。
全部 adaptive/mixed 检查通过原有 finite、double HDR 和 RGB/Y 通量阈值;最坏
`max_abs=5.96856e-11`、`max_rel=5.95958e-13`、RGB 通量相对差
`<=2.83233e-14`、Y `<=1.15036e-14`。`make -j1 test` 与 production HIP primitive
也通过。第一次在受限沙箱内运行明确失败为 `no ROCm-capable device is detected`,随后只在
获准的主机 GPU 环境执行;失败记录保留,没有删除或覆盖。
原始证据:
- 构建:[adaptive_build_host.log](hip_psf_replay_2026-09-07/adaptive_build_host.log);
- adaptive 三次:`adaptive_{center_65536,dispersed_65536,lensed_16384,ordinary_12765}_host_{0,1,2}.log`;
- paired 基线:`paired_{center,dispersed}_{atomic,16}_{0,1,2}.log`;
- mixed、CPU 与 HIP 回归:`adaptive_boundary_mixed_host_0.log`、
`adaptive_cpu_regression.log`、`adaptive_hip_primitive_host.log`;
- 受限环境失败:`adaptive_center_65536_0.log`。
每份日志均保留完整命令、45/90 s timeout、Git hash、binary hash(适用时)、程序原始输出、
process wall 和 exit status。所有性能进程均由现有独占 runner 串行执行,未与其他 renderer
或 profiler 并发。
实现入口:
- [capture_psf.c](../tests/capture_psf.c):调用真实 producer 的测试专用 consumer,捕获或诊断,不生成 HDR。
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/boundary.events 32771 adaptive mixed
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.691 s
device=AMD Radeon RX 9070 arch=gfx1201 events=32771 frame=128x96 mode=adaptive distribution=fixture-mixed-direct contributions=142133685 CPU_reference=0.271268845 create=0.036700010
complete_replay=0.060321093 replay_wall=0.023621082 select=0.000166893 bin=0.002514124 upload=0.000438220 prepare=0.000985861 accumulation=0.016374943 merge=0.000088215 download=0.000132840 cleanup=0.000163078 events_s=1387362.339 contributions_s=6017238463.474 center_tiles=26 tile_chunks=2 atomic_chunks=1 refs=829409 tasks=3275 scratch_used_peak=25249440 scratch_device_reserved=184549376 RSS_KiB=319696 max_abs=5.9685589803848416e-11 max_rel=5.9595772318269279e-13 flux_R=2.8323267191886195e-14 flux_G=-5.5281251977629701e-15 flux_B=9.6507636840237455e-15 flux_Y=1.1503592402127278e-14
PROCESS_WALL 1.117062220 EXIT 0
@@ -0,0 +1,7 @@
COMMAND OMP_NUM_THREADS=16 make -B -j1 PSF_BACKEND=hip 'HIP_CXXFLAGS=--offload-arch=gfx1201 -std=c++17 -O2 -Wall -Wextra -Wpedantic' hip-psf-replay
TIMEOUT 60s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
cc -DENABLE_PNG -DFRAME_PSF_EVENT_SINK=1 -DPSF_BACKEND_HIP -DSPACETIME_MINKOWSKI -std=c11 -march=native -pipe -Wall -Wextra -Wpedantic -O2 -DNDEBUG -fopenmp -Isrc -MMD -MP -c src/optics.c -o build/Release/obj/minkowski/standard_sink1_hip/src/optics.o
mkdir -p build/Release
hipcc --offload-arch=gfx1201 -std=c++17 -O2 -Wall -Wextra -Wpedantic -fopenmp -Isrc -x hip tests/replay_psf.hip -x none build/Release/obj/minkowski/standard_sink1_hip/src/optics.o -lm -lpng -o build/Release/replay_psf
PROCESS_WALL 1.266911305 EXIT 0
@@ -0,0 +1,7 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 adaptive
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
no ROCm-capable device is detected
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.667 s
PROCESS_WALL 1.667466220 EXIT 1
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 adaptive
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.679 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=adaptive distribution=captured contributions=432818979 CPU_reference=0.824280024 create=0.050632000
complete_replay=0.121458054 replay_wall=0.070826054 select=0.000172138 bin=0.007817984 upload=0.001097918 prepare=0.001653194 accumulation=0.051779747 merge=0.000582457 download=0.004020136 cleanup=0.000195980 events_s=925309.214 contributions_s=6111013629.616 center_tiles=35 tile_chunks=4 atomic_chunks=0 refs=2973775 tasks=11935 scratch_used_peak=35382764 scratch_device_reserved=184549376 RSS_KiB=713084 max_abs=2.7105054312137611e-19 max_rel=1.9611487209714066e-14 flux_R=-2.8081518355845397e-17 flux_G=4.7080671715585728e-17 flux_B=5.9271432925574641e-17 flux_Y=2.0330567515243999e-17
PROCESS_WALL 1.968497664 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 adaptive
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.662 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=adaptive distribution=captured contributions=432818979 CPU_reference=0.812095881 create=0.036637783
complete_replay=0.104471922 replay_wall=0.067834139 select=0.000179052 bin=0.007610083 upload=0.001078129 prepare=0.001619816 accumulation=0.051049709 merge=0.000552416 download=0.004829631 cleanup=0.000203133 events_s=966121.205 contributions_s=6380547998.522 center_tiles=35 tile_chunks=4 atomic_chunks=0 refs=2973775 tasks=11935 scratch_used_peak=35382764 scratch_device_reserved=184549376 RSS_KiB=713056 max_abs=2.7105054312137611e-19 max_rel=1.9611487209714066e-14 flux_R=-2.8081518355845397e-17 flux_G=4.7080671715585728e-17 flux_B=5.9271432925574641e-17 flux_Y=2.0330567515243999e-17
PROCESS_WALL 1.918472017 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 adaptive
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.664 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=adaptive distribution=captured contributions=432818979 CPU_reference=0.806693077 create=0.036690950
complete_replay=0.103733778 replay_wall=0.067042828 select=0.000176907 bin=0.007581234 upload=0.001075745 prepare=0.001624107 accumulation=0.051224947 merge=0.000552177 download=0.004083938 cleanup=0.000195026 events_s=977524.403 contributions_s=6455858060.497 center_tiles=35 tile_chunks=4 atomic_chunks=0 refs=2973775 tasks=11935 scratch_used_peak=35382764 scratch_device_reserved=184549376 RSS_KiB=713112 max_abs=2.7105054312137611e-19 max_rel=1.9611487209714066e-14 flux_R=-2.8081518355845397e-17 flux_G=4.7080671715585728e-17 flux_B=5.9271432925574641e-17 flux_Y=2.0330567515243999e-17
PROCESS_WALL 1.918304047 EXIT 0
@@ -0,0 +1,38 @@
COMMAND OMP_NUM_THREADS=16 make -j1 test
TIMEOUT 90s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
make SPACETIME=minkowski ENABLE_HDR=1 backend
make[1]: Entering directory '/home/wyj/Code/C/GR_4d_raytracing'
cc -O2 -DNDEBUG -fopenmp build/Release/obj/minkowski/hdr_sink1_cpu/src/catalog.o build/Release/obj/minkowski/hdr_sink1_cpu/src/frame.o build/Release/obj/minkowski/hdr_sink1_cpu/src/geodesic.o build/Release/obj/minkowski/hdr_sink1_cpu/src/lens_map.o build/Release/obj/minkowski/hdr_sink1_cpu/src/movie.o build/Release/obj/minkowski/hdr_sink1_cpu/src/observer.o build/Release/obj/minkowski/hdr_sink1_cpu/src/observer_track.o build/Release/obj/minkowski/hdr_sink1_cpu/src/optics.o build/Release/obj/minkowski/hdr_sink1_cpu/src/ray.o build/Release/obj/minkowski/hdr_sink1_cpu/src/spacetime_common.o build/Release/obj/minkowski/hdr_sink1_cpu/src/spacetime_minkowski.o build/Release/obj/minkowski/hdr_sink1_cpu/src/main.o -lm -lpng -lcfitsio -o build/Release/minkowski_sky
make[1]: Leaving directory '/home/wyj/Code/C/GR_4d_raytracing'
mkdir -p /tmp/gr_psf_event_sink_reference
OMP_NUM_THREADS=16 build/Release/minkowski_sky --catalog assets/sky_grid_5deg.csv --output /tmp/gr_psf_event_sink_reference/minkowski_ra1_dec1_640x360.png --hdr-output --width 640 --height 360 --fov-deg 30 --look-ra-deg 1 --look-dec-deg 1 --exposure 0.1 --observer-radius 30 --observer-velocity 0 0 0 --psf-fwhm-pixels 2.7 --psf-moffat-beta 4.5 --max-magnification 1e300 --max-cache-psf-flux 1 --psf-relative-tail 1e-8 --psf-min-y 0 --coarse-cell-pixels 16 --refine-max-level 0 --refine-angle-abs-deg 0.001 --refine-angle-rel 0.1 --refine-jacobian-min 1e-3 --refine-min-edge-pixels 0.5 --refine-min-area-pixels2 0.25 --catalog-load-workers 4
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.667 s
Rendered 35 images from 5654 catalog stars to /tmp/gr_psf_event_sink_reference/minkowski_ra1_dec1_640x360.png (ok)
PSF splats: cached 35, cached wing-clipped 0, direct fallbacks 0, discarded below min-Y 0
python3 scripts/fits_floatdiff.py tests/data/psf_event_sink_reference/minkowski_ra1_dec1_640x360_HDR.fits /tmp/gr_psf_event_sink_reference/minkowski_ra1_dec1_640x360_HDR.fits
floatdiff: shape=(640, 360, 3) samples=691200 mismatches=0 max_abs=0 max_rel=0 worst_sample=0
make SPACETIME=schwarzschild ENABLE_HDR=1 backend
make[1]: Entering directory '/home/wyj/Code/C/GR_4d_raytracing'
cc -O2 -DNDEBUG -fopenmp build/Release/obj/schwarzschild/hdr_sink1_cpu/src/catalog.o build/Release/obj/schwarzschild/hdr_sink1_cpu/src/frame.o build/Release/obj/schwarzschild/hdr_sink1_cpu/src/geodesic.o build/Release/obj/schwarzschild/hdr_sink1_cpu/src/lens_map.o build/Release/obj/schwarzschild/hdr_sink1_cpu/src/movie.o build/Release/obj/schwarzschild/hdr_sink1_cpu/src/observer.o build/Release/obj/schwarzschild/hdr_sink1_cpu/src/observer_track.o build/Release/obj/schwarzschild/hdr_sink1_cpu/src/optics.o build/Release/obj/schwarzschild/hdr_sink1_cpu/src/ray.o build/Release/obj/schwarzschild/hdr_sink1_cpu/src/spacetime_common.o build/Release/obj/schwarzschild/hdr_sink1_cpu/src/spacetime_schwarzschild.o build/Release/obj/schwarzschild/hdr_sink1_cpu/src/main.o -lm -lpng -lcfitsio -o build/Release/schwarzschild_sky
make[1]: Leaving directory '/home/wyj/Code/C/GR_4d_raytracing'
OMP_NUM_THREADS=16 build/Release/schwarzschild_sky --catalog assets/sky_grid_5deg.csv --output /tmp/gr_psf_event_sink_reference/schwarzschild_ra1_dec1_fov60_640x360.png --hdr-output --width 640 --height 360 --fov-deg 60 --look-ra-deg 1 --look-dec-deg 1 --exposure 0.1 --observer-radius 30 --observer-velocity 0 0 0 --psf-fwhm-pixels 2.7 --psf-moffat-beta 4.5 --max-magnification 1e300 --max-cache-psf-flux 1 --psf-relative-tail 1e-8 --psf-min-y 0 --coarse-cell-pixels 16 --refine-max-level 0 --refine-angle-abs-deg 0.001 --refine-angle-rel 0.1 --refine-jacobian-min 1e-3 --refine-min-edge-pixels 0.5 --refine-min-area-pixels2 0.25 --catalog-load-workers 4
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.665 s
Rendered 5206 images from 5654 catalog stars to /tmp/gr_psf_event_sink_reference/schwarzschild_ra1_dec1_fov60_640x360.png (ok)
PSF splats: cached 5206, cached wing-clipped 0, direct fallbacks 0, discarded below min-Y 0
python3 scripts/fits_floatdiff.py tests/data/psf_event_sink_reference/schwarzschild_ra1_dec1_fov60_640x360_HDR.fits /tmp/gr_psf_event_sink_reference/schwarzschild_ra1_dec1_fov60_640x360_HDR.fits
floatdiff: shape=(640, 360, 3) samples=691200 mismatches=0 max_abs=0 max_rel=0 worst_sample=0
./build/Release/test_observer_minkowski
coordinate-camera regression passed
./build/Release/test_observer_schwarzschild
coordinate-camera regression passed
./build/Release/test_geodesic
./build/Release/test_frame
./build/Release/test_schwarzschild
./build/Release/test_observer_track
./build/Release/test_catalog_prefetch
python3 tests/test_camera_cli.py build/Release
minkowski: CLI checks passed; single/movie PNG identical, map max error 0
schwarzschild: movie lens map identical with 1, 4 and 16 threads
schwarzschild: CLI checks passed; single/movie PNG identical, map max error 4.44e-16
PROCESS_WALL 26.018675067 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 adaptive disperse
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.682 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=adaptive distribution=synthetic-phase-preserving-dispersal contributions=432818979 CPU_reference=1.491110802 create=0.037611008
complete_replay=0.117703199 replay_wall=0.080092192 select=0.000455141 bin=0.000000000 upload=0.000191523 prepare=0.000000000 accumulation=0.075263899 merge=0.000000000 download=0.004099738 cleanup=0.000207186 events_s=818257.044 contributions_s=5404009677.272 center_tiles=26986 tile_chunks=0 atomic_chunks=4 refs=0 tasks=0 scratch_used_peak=0 scratch_device_reserved=184549376 RSS_KiB=705516 max_abs=3.3881317890172014e-21 max_rel=8.4356460581299069e-16 flux_R=1.2382136141425945e-18 flux_G=1.811942792627668e-18 flux_B=1.5829277137138293e-18 flux_Y=1.5978644712371554e-18
PROCESS_WALL 2.620178348 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 adaptive disperse
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.733 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=adaptive distribution=synthetic-phase-preserving-dispersal contributions=432818979 CPU_reference=1.488748074 create=0.038790941
complete_replay=0.121706009 replay_wall=0.082915068 select=0.000465870 bin=0.000000000 upload=0.000181281 prepare=0.000000000 accumulation=0.077964972 merge=0.000000000 download=0.004236780 cleanup=0.000192881 events_s=790399.162 contributions_s=5220028049.767 center_tiles=26986 tile_chunks=0 atomic_chunks=4 refs=0 tasks=0 scratch_used_peak=0 scratch_device_reserved=184549376 RSS_KiB=705940 max_abs=3.3881317890172014e-21 max_rel=8.4356460581299069e-16 flux_R=1.377382799700594e-18 flux_G=1.939309838343059e-18 flux_B=2.0425953472603454e-18 flux_Y=1.7396938046841301e-18
PROCESS_WALL 2.720085292 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 adaptive disperse
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.671 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=adaptive distribution=synthetic-phase-preserving-dispersal contributions=432818979 CPU_reference=1.462161779 create=0.037038088
complete_replay=0.115585089 replay_wall=0.078547001 select=0.000451088 bin=0.000000000 upload=0.000188241 prepare=0.000000000 accumulation=0.073739567 merge=0.000000000 download=0.004098460 cleanup=0.000214100 events_s=834353.944 contributions_s=5510318333.269 center_tiles=26986 tile_chunks=0 atomic_chunks=4 refs=0 tasks=0 scratch_used_peak=0 scratch_device_reserved=184549376 RSS_KiB=705560 max_abs=3.3881317890172014e-21 max_rel=8.4356460581299069e-16 flux_R=1.4160413575526434e-18 flux_G=1.6738012163520145e-18 flux_B=2.0518958448496421e-18 flux_Y=1.5923904683351809e-18
PROCESS_WALL 2.568827678 EXIT 0
@@ -0,0 +1,6 @@
COMMAND OMP_NUM_THREADS=16 build/Release/test_hip_psf
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 39cd23b6d9aef423ba97ba0085b9a411a47a49e4b66cf59197f471de419ef9b8
HIP PSF cache comparison: max_abs=2.8421709430404007e-14 max_rel=7.5319184269262976e-16
PROCESS_WALL 0.816928134 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/lensed_16384.events 16384 adaptive
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.714 s
device=AMD Radeon RX 9070 arch=gfx1201 events=16384 frame=3840x2160 mode=adaptive distribution=captured contributions=107949448 CPU_reference=0.213827133 create=0.041162014
complete_replay=0.062693119 replay_wall=0.021531105 select=0.000054836 bin=0.003102064 upload=0.000283003 prepare=0.000669003 accumulation=0.012633085 merge=0.000146866 download=0.004084578 cleanup=0.000169992 events_s=760945.617 contributions_s=5013651077.913 center_tiles=359 tile_chunks=1 atomic_chunks=0 refs=740784 tasks=5251 scratch_used_peak=31785268 scratch_device_reserved=184549376 RSS_KiB=710652 max_abs=5.3290705182007514e-15 max_rel=3.8619817275125971e-15 flux_R=-5.5779263000586243e-18 flux_G=-2.9489947183383731e-19 flux_B=4.3765760168230462e-18 flux_Y=-2.1608907287060103e-18
PROCESS_WALL 1.268419138 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/lensed_16384.events 16384 adaptive
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.667 s
device=AMD Radeon RX 9070 arch=gfx1201 events=16384 frame=3840x2160 mode=adaptive distribution=captured contributions=107949448 CPU_reference=0.214478970 create=0.036618948
complete_replay=0.058495998 replay_wall=0.021877050 select=0.000056028 bin=0.003196001 upload=0.000288010 prepare=0.000689983 accumulation=0.012602091 merge=0.000144958 download=0.004350181 cleanup=0.000192165 events_s=748912.660 contributions_s=4934369397.489 center_tiles=359 tile_chunks=1 atomic_chunks=0 refs=740784 tasks=5251 scratch_used_peak=31785268 scratch_device_reserved=184549376 RSS_KiB=710384 max_abs=5.3290705182007514e-15 max_rel=3.8619817275125971e-15 flux_R=-5.5779263000586243e-18 flux_G=-2.9489947183383731e-19 flux_B=4.3765760168230462e-18 flux_Y=-2.1608907287060103e-18
PROCESS_WALL 1.216200115 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/lensed_16384.events 16384 adaptive
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.664 s
device=AMD Radeon RX 9070 arch=gfx1201 events=16384 frame=3840x2160 mode=adaptive distribution=captured contributions=107949448 CPU_reference=0.214956999 create=0.038650990
complete_replay=0.060267925 replay_wall=0.021616936 select=0.000054121 bin=0.003103971 upload=0.000282049 prepare=0.000669956 accumulation=0.012650013 merge=0.000149012 download=0.004124364 cleanup=0.000187874 events_s=757924.259 contributions_s=4993744226.675 center_tiles=359 tile_chunks=1 atomic_chunks=0 refs=740784 tasks=5251 scratch_used_peak=31785268 scratch_device_reserved=184549376 RSS_KiB=710600 max_abs=5.3290705182007514e-15 max_rel=3.8619817275125971e-15 flux_R=-5.5779263000586243e-18 flux_G=-2.9489947183383731e-19 flux_B=4.3765760168230462e-18 flux_Y=-2.1608907287060103e-18
PROCESS_WALL 1.216335608 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/ordinary_16384.events 12765 adaptive
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.683 s
device=AMD Radeon RX 9070 arch=gfx1201 events=12765 frame=3840x2160 mode=adaptive distribution=captured contributions=84287857 CPU_reference=0.161495924 create=0.036530018
complete_replay=0.054877043 replay_wall=0.018347025 select=0.000042915 bin=0.001914978 upload=0.000241995 prepare=0.000617027 accumulation=0.009811878 merge=0.000136137 download=0.005169831 cleanup=0.000195026 events_s=695753.129 contributions_s=4594088544.521 center_tiles=8 tile_chunks=1 atomic_chunks=0 refs=575476 tasks=2331 scratch_used_peak=27265820 scratch_device_reserved=184549376 RSS_KiB=708332 max_abs=2.1371793224034263e-15 max_rel=1.6186841366251043e-14 flux_R=1.3070869891010463e-16 flux_G=2.5758793226204442e-16 flux_B=1.7069617471680846e-16 flux_Y=2.1355251009923229e-16
PROCESS_WALL 1.166123833 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/ordinary_16384.events 12765 adaptive
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.679 s
device=AMD Radeon RX 9070 arch=gfx1201 events=12765 frame=3840x2160 mode=adaptive distribution=captured contributions=84287857 CPU_reference=0.164183140 create=0.036640882
complete_replay=0.054260731 replay_wall=0.017619848 select=0.000036955 bin=0.001922131 upload=0.000246048 prepare=0.000601053 accumulation=0.010066986 merge=0.000137806 download=0.004148300 cleanup=0.000171900 events_s=724467.079 contributions_s=4783688020.331 center_tiles=8 tile_chunks=1 atomic_chunks=0 refs=575476 tasks=2331 scratch_used_peak=27265820 scratch_device_reserved=184549376 RSS_KiB=707824 max_abs=2.1371793224034263e-15 max_rel=1.6186841366251043e-14 flux_R=1.3070869891010463e-16 flux_G=2.5758793226204442e-16 flux_B=1.7069617471680846e-16 flux_Y=2.1355251009923229e-16
PROCESS_WALL 1.167055415 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/ordinary_16384.events 12765 adaptive
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.674 s
device=AMD Radeon RX 9070 arch=gfx1201 events=12765 frame=3840x2160 mode=adaptive distribution=captured contributions=84287857 CPU_reference=0.159490824 create=0.036442041
complete_replay=0.056708097 replay_wall=0.020266056 select=0.000033855 bin=0.001877069 upload=0.000234127 prepare=0.000597954 accumulation=0.010081053 merge=0.000137806 download=0.004184938 cleanup=0.000163078 events_s=629870.951 contributions_s=4159065619.239 center_tiles=8 tile_chunks=1 atomic_chunks=0 refs=575476 tasks=2331 scratch_used_peak=27265820 scratch_device_reserved=184549376 RSS_KiB=707952 max_abs=2.1371793224034263e-15 max_rel=1.6186841366251043e-14 flux_R=1.3070869891010463e-16 flux_G=2.5758793226204442e-16 flux_B=1.7069617471680846e-16 flux_Y=2.1355251009923229e-16
PROCESS_WALL 1.167496176 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 16
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.783 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=16 distribution=captured contributions=432818979 CPU_reference=0.805742979 create=0.036848068
complete_replay=0.103791952 replay_wall=0.066943884 select=0.000000000 bin=0.007535458 upload=0.001190662 prepare=0.001640081 accumulation=0.051215172 merge=0.000553846 download=0.004045417 cleanup=0.000201941 events_s=978969.193 contributions_s=6465399881.387 center_tiles=0 tile_chunks=4 atomic_chunks=0 refs=2973775 tasks=11935 scratch_used_peak=35382764 scratch_device_reserved=184549376 RSS_KiB=713288 max_abs=2.7105054312137611e-19 max_rel=1.9611487209714066e-14 flux_R=-2.8081518355845397e-17 flux_G=4.7080671715585728e-17 flux_B=5.9271432925574641e-17 flux_Y=2.0330567515243999e-17
PROCESS_WALL 2.019127664 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 16
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.668 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=16 distribution=captured contributions=432818979 CPU_reference=0.815722942 create=0.036595821
complete_replay=0.106936932 replay_wall=0.070341110 select=0.000000000 bin=0.007705212 upload=0.001186848 prepare=0.001616001 accumulation=0.051277876 merge=0.000541925 download=0.004584385 cleanup=0.000200987 events_s=931688.451 contributions_s=6153143980.638 center_tiles=0 tile_chunks=4 atomic_chunks=0 refs=2973775 tasks=11935 scratch_used_peak=35382764 scratch_device_reserved=184549376 RSS_KiB=712508 max_abs=2.7105054312137611e-19 max_rel=1.9611487209714066e-14 flux_R=-2.8081518355845397e-17 flux_G=4.7080671715585728e-17 flux_B=5.9271432925574641e-17 flux_Y=2.0330567515243999e-17
PROCESS_WALL 1.917609542 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 16
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.670 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=16 distribution=captured contributions=432818979 CPU_reference=0.802520990 create=0.037091017
complete_replay=0.104444981 replay_wall=0.067353964 select=0.000000000 bin=0.007662058 upload=0.001219988 prepare=0.001631737 accumulation=0.051412106 merge=0.000540018 download=0.004093417 cleanup=0.000197887 events_s=973008.807 contributions_s=6426035740.844 center_tiles=0 tile_chunks=4 atomic_chunks=0 refs=2973775 tasks=11935 scratch_used_peak=35382764 scratch_device_reserved=184549376 RSS_KiB=712736 max_abs=2.7105054312137611e-19 max_rel=1.9611487209714066e-14 flux_R=-2.8081518355845397e-17 flux_G=4.7080671715585728e-17 flux_B=5.9271432925574641e-17 flux_Y=2.0330567515243999e-17
PROCESS_WALL 1.917963698 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 atomic
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.687 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=atomic distribution=captured contributions=432818979 CPU_reference=0.809880018 create=0.039862156
complete_replay=0.135050297 replay_wall=0.095188141 select=0.000000000 bin=0.000000000 upload=0.000205602 prepare=0.000000000 accumulation=0.090687719 merge=0.000000000 download=0.004133141 cleanup=0.000000000 events_s=688489.127 contributions_s=4546984267.662 center_tiles=0 tile_chunks=0 atomic_chunks=4 refs=0 tasks=0 scratch_used_peak=0 scratch_device_reserved=0 RSS_KiB=705156 max_abs=1.2874900798265365e-19 max_rel=7.4131884297116165e-15 flux_R=3.5244625165286513e-17 flux_G=-1.6770129667889592e-17 flux_B=-1.4396324706080044e-17 flux_Y=2.0737623150838269e-18
PROCESS_WALL 1.967518921 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 atomic
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.671 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=atomic distribution=captured contributions=432818979 CPU_reference=0.802126169 create=0.039602995
complete_replay=0.134557009 replay_wall=0.094954014 select=0.000000000 bin=0.000000000 upload=0.000198362 prepare=0.000000000 accumulation=0.090435339 merge=0.000000000 download=0.004166579 cleanup=0.000000000 events_s=690186.727 contributions_s=4558195715.666 center_tiles=0 tile_chunks=0 atomic_chunks=4 refs=0 tasks=0 scratch_used_peak=0 scratch_device_reserved=0 RSS_KiB=705688 max_abs=1.0842021724855044e-19 max_rel=7.9583748032166079e-15 flux_R=7.6396533553465937e-18 flux_G=1.6562512796306053e-17 flux_B=1.5235277925542237e-18 flux_Y=1.2880679208252085e-17
PROCESS_WALL 1.918794264 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 atomic
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.676 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=atomic distribution=captured contributions=432818979 CPU_reference=0.799952984 create=0.039901972
complete_replay=0.134919882 replay_wall=0.095017910 select=0.000000000 bin=0.000000000 upload=0.000204603 prepare=0.000000000 accumulation=0.090419817 merge=0.000000000 download=0.004226341 cleanup=0.000000000 events_s=689722.601 contributions_s=4555130490.487 center_tiles=0 tile_chunks=0 atomic_chunks=4 refs=0 tasks=0 scratch_used_peak=0 scratch_device_reserved=0 RSS_KiB=705636 max_abs=1.2874900798265365e-19 max_rel=7.9482312095117156e-15 flux_R=-5.3427317744228327e-18 flux_G=6.0837775507051433e-17 flux_B=-9.8579921222560893e-19 flux_Y=3.5056388280753197e-17
PROCESS_WALL 1.968038807 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 16 disperse
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.662 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=16 distribution=synthetic-phase-preserving-dispersal contributions=432818979 CPU_reference=1.480471134 create=0.038483858
complete_replay=0.138176918 replay_wall=0.099693060 select=0.000000000 bin=0.035099983 upload=0.001532316 prepare=0.001661777 accumulation=0.049884081 merge=0.000493050 download=0.004275622 cleanup=0.000198841 events_s=657377.756 contributions_s=4341515641.528 center_tiles=0 tile_chunks=4 atomic_chunks=0 refs=2987132 tasks=129439 scratch_used_peak=17137368 scratch_device_reserved=184549376 RSS_KiB=716772 max_abs=6.7762635780344027e-21 max_rel=2.2452117590762424e-15 flux_R=1.0178317181173255e-18 flux_G=1.4444219523404554e-18 flux_B=2.8354584230664648e-18 flux_Y=1.3331859086679348e-18
PROCESS_WALL 2.620675482 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 16 disperse
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.672 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=16 distribution=synthetic-phase-preserving-dispersal contributions=432818979 CPU_reference=1.477596998 create=0.037245035
complete_replay=0.137820959 replay_wall=0.100575924 select=0.000000000 bin=0.035495043 upload=0.001560211 prepare=0.001640797 accumulation=0.050065994 merge=0.000494242 download=0.004161540 cleanup=0.000195980 events_s=651607.238 contributions_s=4303405448.660 center_tiles=0 tile_chunks=4 atomic_chunks=0 refs=2987132 tasks=129439 scratch_used_peak=17137368 scratch_device_reserved=184549376 RSS_KiB=716808 max_abs=6.7762635780344027e-21 max_rel=2.2452117590762424e-15 flux_R=1.0178317181173255e-18 flux_G=1.4444219523404554e-18 flux_B=2.8354584230664648e-18 flux_Y=1.3331859086679348e-18
PROCESS_WALL 2.667392709 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 16 disperse
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.675 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=16 distribution=synthetic-phase-preserving-dispersal contributions=432818979 CPU_reference=1.470952988 create=0.038564920
complete_replay=0.130317926 replay_wall=0.091753006 select=0.000000000 bin=0.034946680 upload=0.001475096 prepare=0.001478195 accumulation=0.042901754 merge=0.000442028 download=0.004153220 cleanup=0.000182867 events_s=714265.427 contributions_s=4717218519.113 center_tiles=0 tile_chunks=4 atomic_chunks=0 refs=2987132 tasks=129439 scratch_used_peak=17137368 scratch_device_reserved=184549376 RSS_KiB=714840 max_abs=6.7762635780344027e-21 max_rel=2.2452117590762424e-15 flux_R=1.0178317181173255e-18 flux_G=1.4444219523404554e-18 flux_B=2.8354584230664648e-18 flux_Y=1.3331859086679348e-18
PROCESS_WALL 2.623926037 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 atomic disperse
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.685 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=atomic distribution=synthetic-phase-preserving-dispersal contributions=432818979 CPU_reference=1.483494043 create=0.036720991
complete_replay=0.115373135 replay_wall=0.078652143 select=0.000000000 bin=0.000000000 upload=0.000209722 prepare=0.000000000 accumulation=0.074174986 merge=0.000000000 download=0.004105619 cleanup=0.000000000 events_s=833238.576 contributions_s=5502952111.139 center_tiles=0 tile_chunks=0 atomic_chunks=4 refs=0 tasks=0 scratch_used_peak=0 scratch_device_reserved=0 RSS_KiB=705688 max_abs=3.3881317890172014e-21 max_rel=8.4356460581299069e-16 flux_R=1.4264853877147901e-18 flux_G=1.7304063360850003e-18 flux_B=2.1361348632691914e-18 flux_Y=1.6331855317630113e-18
PROCESS_WALL 2.620796063 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 atomic disperse
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.669 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=atomic distribution=synthetic-phase-preserving-dispersal contributions=432818979 CPU_reference=1.474539995 create=0.037378073
complete_replay=0.115452051 replay_wall=0.078073978 select=0.000000000 bin=0.000000000 upload=0.000202122 prepare=0.000000000 accumulation=0.073547550 merge=0.000000000 download=0.004160663 cleanup=0.000000000 events_s=839408.998 contributions_s=5543703391.789 center_tiles=0 tile_chunks=0 atomic_chunks=4 refs=0 tasks=0 scratch_used_peak=0 scratch_device_reserved=0 RSS_KiB=704932 max_abs=3.3881317890172014e-21 max_rel=8.4356460581299069e-16 flux_R=1.4285334484627677e-18 flux_G=1.6416822084297311e-18 flux_B=2.2250851163298864e-18 flux_Y=1.5826745498492225e-18
PROCESS_WALL 2.620563869 EXIT 0
@@ -0,0 +1,8 @@
COMMAND OMP_NUM_THREADS=16 build/Release/replay_psf benchmarks/hip_psf_replay_2026-09-07/center_65536.events 65536 atomic disperse
TIMEOUT 45s
GIT 11e703e33dffb1ff168ba11dd922e68b448116b9
BINARY_SHA256 121b85ade12680929cf0f560e04485e2ad3d8a56ff9dcbba950a323f840c5151
PSF cache ready: 64x64 phases, radius 47 px, relative tail 1e-08, tail abs 1e-06, boundary 1e-07, build 0.666 s
device=AMD Radeon RX 9070 arch=gfx1201 events=65536 frame=3840x2160 mode=atomic distribution=synthetic-phase-preserving-dispersal contributions=432818979 CPU_reference=1.498821974 create=0.037057161
complete_replay=0.115260124 replay_wall=0.078202963 select=0.000000000 bin=0.000000000 upload=0.000203722 prepare=0.000000000 accumulation=0.073602102 merge=0.000000000 download=0.004232413 cleanup=0.000000000 events_s=838024.515 contributions_s=5534559856.636 center_tiles=0 tile_chunks=0 atomic_chunks=4 refs=0 tasks=0 scratch_used_peak=0 scratch_device_reserved=0 RSS_KiB=705384 max_abs=3.3881317890172014e-21 max_rel=8.4356460581299069e-16 flux_R=1.4138169203080735e-18 flux_G=1.5950365444592374e-18 flux_B=2.1462694853060243e-18 flux_Y=1.5465636583759892e-18
PROCESS_WALL 2.619888980 EXIT 0
+23
View File
@@ -104,6 +104,29 @@ times must not be added to GPU timings or interpreted as process CPU time.
The two upload slots bound staging memory and allow CPU production ahead of GPU
completion; copies and kernels still execute in order on one stream.
### Diagnostic dummy PSF backend
To inspect production chunk geometry without starting HIP or allocating an HDR
framebuffer, build the diagnostic-only dummy backend:
```sh
make -j1 PSF_BACKEND=dummy SPACETIME=schwarzschild ENABLE_HDR=1 backend
OMP_NUM_THREADS=16 OMP_DYNAMIC=FALSE \
./build/Release/schwarzschild_sky_dummy --lens-map-input MAP.grlens \
--all-sky-catalog CATALOG_DIR --output PROTECTED_OR_UNUSED.png [normal PSF options]
```
The dummy executable requires an imported lens map and the PSF cache; it rejects
`--psf-direct`. It runs the real OpenMP triangle scheduling, catalog query,
inverse mapping, redshift/color/flux preparation, and cache/direct/min-Y
classification, but records chunk statistics instead of accumulating pixels.
`--output` and `--hdr-output` are accepted only for command parity: neither PNG
nor FITS is created or modified. Reports separate full 16,384-event chunks from
the final partial chunk of each worker and include event-producing triangle
counts, occupied 32-pixel center tiles, bounding-box diagonals, and successive
triangle-centroid jumps. This is a scheduling diagnostic, not a rendering or
backend-performance benchmark.
With both Minkowski binaries built using `ENABLE_HDR=1`,
`python3 tests/test_hip_renderer.py build/Release/minkowski_sky build/Release/minkowski_sky_hip`
runs small CPU/HIP fallback and min-Y comparisons sequentially. Each renderer
+16
View File
@@ -26,6 +26,22 @@ production HIP 尚未替换为 tile 算法;收益与事件分布有关,不
全天加速比。未运行完整全天 catalog。测试工具与原型已于 2026-09-11 提交为
`7f5ec1a`;以下保留原执行计划作为验收依据。
同日后续实验在 replay 中增加了按 chunk 的中心 tile 密度选择器。当前 RX 9070 配对数据中,
65,536-event 银心输入的 adaptive/atomic/tile16 中位数为 67.834/95.018/67.354 ms,
同贡献分散输入为 80.092/78.203/99.693 ms;选择扫描中位成本不超过 0.455 ms。
mixed fixture 已覆盖同一 stream 内 atomic、tile 与 direct fallback 的组合。结果支持下一步
做 production 流式集成原型,但选择器和 tile sink 目前仍只在测试程序中,未改变生产默认。
随后用只计数的 `PSF_BACKEND=dummy` 跑过用户给定的 45 度 Schwarzschild 银心全天命令,
没有启动 HIP,也没有写 HDR/PNG。598,264,924 个 cache event 中有 36,508 个满
16,384-event chunk;满 chunk 的 event-producing triangle 数 p50/p75/p90/p99 为
2/3/10/31,occupied 32px center tile 数为 1/2/5/30,全部满足当前 adaptive tile16
阈值。这把“dense replay”提升成了真实 production producer 顺序的证据,支持把 adaptive
tile16 接入 production sink 作为下一步候选。限制是 16-worker dynamic schedule 会有运行间
波动,而且 p99 chunk 含相距约 3.7K px 的稀疏簇;实现必须保留稀疏 tile 列表和 atomic
fallback,不能假定单一连续小矩形。详见
[dummy chunk 全量记录](benchmarks/dummy_psf_chunks_2026-09-11/README.md)。
## 下一步执行计划(2026-09-07,原计划;有界实验已实施)
### 依据与目标
+46
View File
@@ -993,6 +993,52 @@ CPU 按完整、经 cache 限制的 support 矩形建立 tile 引用;GPU 仍
合并、清理和下载的完整成本及分布依赖,不能只引用无 atomic kernel 的单项耗时。
本轮生产 HIP 路径保持原实现,尚未进行新的完整全天渲染。
2026-09-11 的后续有界实验加入了按 chunk 的分布选择器:先统计 32px 中心 tile 占用,
再在高中心密度 chunk 使用 16×16 像素归约,其余保留 atomic。RX 9070 的配对回放中,
它在银心密集输入接近固定 tile16,同时在同贡献分散输入选择 atomic,详情见上述回放记录。
此选择器仍仅存在于测试程序;阈值来自固定样本,尚未验证 production producer/sink 锁竞争
或完整全天事件序列,因此不能成为 renderer 默认策略。
2026-09-11 又加入了 `PSF_BACKEND=dummy` 的只统计后端。它要求导入 `.grlens`,复用
production 的 OpenMP `schedule(dynamic,1)`、每 worker 16,384-event chunk,以及完整的
catalog/inverse-map/颜色/flux/cache 分类,但不分配完整 HDR,也绝不写 PNG/FITS。对银心
45 度 Schwarzschild 全天输入的一次 16-worker 全量运行中,598,264,924 个 cache event
形成 36,508 个满 chunk;满 chunk 跨越的 event-producing triangle 数为 p50=2、p75=3、
p90=10、p99=31、max=59,32px 中心 tile 占用为 p50=1、p75=2、p90=5、p99=30、
max=45。全部满 chunk 都满足当前测试选择器的 tile16 条件。
这个结果支持“真实宽视场下一个 worker 的满 chunk 通常集中在少数三角形/少数局部
tile”这一调度假设,但也揭示了稀有的远距离簇:满 chunk 的三角形质心包围盒对角线
p99 约 3744px,最大相邻三角形跳跃 p99 也约 3744px。因而不能把“少数三角形”等同于
“全 chunk 单个连续矩形”;production tile 原型仍应按稀疏 occupied-tile 列表处理,并用
真实流式端到端数据验证分桶成本。完整命令、hash、输出保护和原始记录见
[dummy chunk 统计](benchmarks/dummy_psf_chunks_2026-09-11/README.md)。
2026-09-12,黑洞渲染的黑体颜色计算改为以仓库内数值 LUT 为默认实现,取代原先
`optics.c` 中的 Wyman 解析 CIE 拟合。正常区使用仓库唯一的
`assets/blackbody/cie1931_2deg_xyz_1024.grbblut`:以 40 位精度把 Planck 谱和
`assets/CIE_xyz_1931_2deg.csv` 的 360--830 nm、1 nm 分段线性 CIE 数据积分,生成覆盖
`[670.146556,101408.88] K` 的 1024 个 `log(T)` 等距 XYZ 节点。`GRBBLUT3` header
固定标识该 reference,loader 校验 magic/version/endianness/物理常数/范围/长度与 payload
checksum,并拒绝旧的 Wyman/5 nm 表与 runtime 造表。表内使用四点三次 Lagrange 插值,
在全部 1023 个区间中点相对独立 Gauss-16 积分的最大 XYZ channel 相对误差为
`5.4633e-5`,没有负 XYZ。由 1 nm 线性插值自身约 `3.2e-4` 的最坏误差估计,正常区采用
`1e-4` LUT 内部限与 `5e-4` 整体误差预算,避免继续追逐缺乏物理意义的 `1e-6`。
两端使用同一 CSV reference 的表外模型。高温端使用连续积分得到的
`A T+B+C/T` Rayleigh--Jeans 展开,在 `[Tmax,10Tmax]` 最大 XYZ 相对误差为 `1.6635e-5`。
低温端针对 X/Y 的 830 nm 端点和 Z 的 650 nm 零端点分别展开:在 `4.097321 K` 以下使用
crossover 锚定、在 `T -> 0` 趋于极限的端点式,其上用六段八次
`1/T -> log(scaled XYZ)` Chebyshev--Lobatto 插值接到 LUT。低温端点段/过渡段的最大 XYZ
相对误差分别为 `6.69e-5`/`8.16e-5`,因而三段均满足 `1e-4` 内部限;log 输出避免把极端
低温的线性下溢误解为拟合硬下限。
最终 legacy Wyman/5 nm 与 CSV LUT 的 1920x1080 double-HDR 比较显示,每通道峰值归一化
最大绝对变化为 R `9.00e-3`、G `7.02e-3`、B `8.12e-4`;这是 reference 升级本身造成的
预期变化,而不是 LUT 插值误差。旧 Wyman/5 nm 积分实现、可切换的 integral/fixed/LUT
A/B 后端、有界性能证据与观测温度采样器保留在实验分支
`codex/blackbody-cost-experiment`(tag `blackbody-cost-experiment-2026-09-12`)。
---
+128
View File
@@ -0,0 +1,128 @@
#include "blackbody_internal.h"
#include <math.h>
void blackbody_rayleigh_jeans_xyz(double temperature_K, int terms,
double xyz[3]) {
/* CSV-derived coefficients multiply T, 1, and T^-1. */
static const double coefficients[3][3] = {
{9.75239167492079072e3, -1.3438558214879372e8,
6.31051886434512943e11},
{9.51500076632225143e3, -1.25823411343233966e8,
5.58059336995288075e11},
{2.13884044303540753e4, -3.43402928472968325e8,
1.84249991169126495e12}};
xyz[0] = xyz[1] = xyz[2] = 0.0;
if (!isfinite(temperature_K) || temperature_K <= 0.0 || terms <= 0)
return;
if (terms > 3) terms = 3;
for (int channel = 0; channel < 3; ++channel) {
xyz[channel] = coefficients[channel][0] * temperature_K;
if (terms >= 2) xyz[channel] += coefficients[channel][1];
if (terms >= 3) xyz[channel] += coefficients[channel][2] / temperature_K;
}
}
static double chebyshev_clenshaw(const double coefficients[9], double x) {
double b1 = 0.0, b2 = 0.0;
for (int degree = 8; degree >= 1; --degree) {
const double b0 = 2.0 * x * b1 - b2 + coefficients[degree];
b2 = b1;
b1 = b0;
}
return coefficients[0] + x * b1 - b2;
}
int blackbody_low_hybrid_log_xyz(double temperature_K, double log_xyz[3]) {
static const double crossover_K = 4.09732109813541501;
static const double maximum_K = 670.146556;
static const double q_over_endpoint[3] = {
17334.66117474619, 17334.66117474619, 22135.028884675903};
static const double endpoint_delta[3] = {
6.27453428003507278e-6, 6.27523604457500139e-6,
9.72024116337713046e-5};
/* The 1 nm-linear endpoint makes these polynomials exactly cubic. Z has
* zero constant term because its 649--650 nm segment ends at zero. */
static const double endpoint[3][4] = {
{1.81136495194567529e-2, 6.61028930839653126e-5,
1.48916636199141013e-8, 1.27817061855715528e-12},
{6.54117161006302892e-3, 2.38707969128581198e-5,
5.37761358258185981e-9, 4.61567454126977889e-13},
{0.0, 1.18022769903543601e-3,
2.13277824065096828e-7, 1.44529622149769957e-11}};
static const double edges[7] = {
4.09732109813541501, 9.58175285991856125, 22.4073207028704393,
52.4004353296953668, 122.540559808645089, 286.566107776330601,
670.146556};
static const double coefficients[6][3][9] = {
{
{-2.19805342404174431,-0.427989370548201992,0.0457830231212280024,-0.00653024253368962181,0.00104792258851775496,-0.000179376495463268954,0.0000320194392828742251,-6.07285820395394865e-6,1.09768907792163728e-6},
{-3.21660305217802182,-0.427989317567608284,0.0457830153418609421,-0.00653024167298543334,0.00104792254862916667,-0.000179376508222333492,0.0000320194445897039005,-6.07285961285998572e-6,1.09768936710106915e-6},
{-3.15707121695679764,-0.842260091928597102,0.0900358213706993461,-0.0130901684838339702,0.00216325774923957118,-0.000378541811375747837,0.0000677130171872672182,-0.0000125764470117522098,2.20543446698214866e-6}
},{
{-1.31770949444839666,-0.441299064080369115,0.0486743388559153732,-0.00715733212557194619,0.00118377405373184402,-0.000208808548120484381,0.0000384098393642844184,-7.51938342275489625e-6,1.39706879054438949e-6},
{-2.33625922712095605,-0.441299020893064677,0.0486743393223627113,-0.00715733306978699914,0.00118377427098721058,-0.000208808583754120261,0.0000384098442083096037,-7.51938398617148892e-6,1.39706884379154304e-6},
{-1.41692623695155927,-0.878068580096058675,0.0982372095233778281,-0.0142171838603874451,0.00222410258776171213,-0.000361979109489253779,0.000060753034151493841,-0.0000107563963609356147,1.83055417864655942e-6}
},{
{-0.3921912858481657,-0.475886418801351195,0.0565482685596524812,-0.00894861708837536552,0.00159121925979185938,-0.000301479141093084493,0.0000595321929174356658,-0.0000125546605490984269,2.48503406235378882e-6},
{-1.41074105985953395,-0.475886424111238694,0.0565482743959804094,-0.00894861785536701427,0.00159121932381919629,-0.000301479143653568406,0.0000595321922909604336,-0.0000125546602334654497,2.48503397406341601e-6},
{0.405784497738078867,-0.915430672087484161,0.0971591394650644897,-0.0129050910771596898,0.00191184765152995853,-0.000308981746742567431,0.0000538107592092635484,-0.0000103283467419743846,1.93585445253475723e-6}
},{
{0.661994617272024548,-0.581350758628830698,0.0836597467165894418,-0.0158988753362009282,0.00336718167075529186,-0.000753662101271342622,0.000174585741711791468,-0.0000433048808785784171,9.75843572764750381e-6},
{-0.356555122545496873,-0.581350782933150466,0.0836597486771623816,-0.015898875146527317,0.00336718160135198675,-0.000753662094742459443,0.000174585746021139991,-0.0000433048853568368614,9.75843776186480067e-6},
{2.25724030901313405,-0.906149909784837897,0.0947967083167351412,-0.0147236528292987198,0.00294177345982300343,-0.000664178311762264752,0.000153812749558811817,-0.0000358188260289889306,7.26093914036807359e-6}
},{
{2.24517368371397051,-1.10137638803233863,0.260109466476170278,-0.0728062330999542422,0.0205487830596007146,-0.00547019170643925872,0.00127956756145661419,-0.000220004358600067039,0.0000138071701243527944},
{1.22677135347875279,-1.10165295376793399,0.260338122908468991,-0.0729732322401341771,0.0206568819007716045,-0.00553248986531515299,0.00131198334055904886,-0.000236511389192968018,0.0000196226106014253749},
{4.22881792094750399,-1.09273677796148737,0.167321326581346532,-0.0312233937525439919,0.00516074702621717587,-0.000696731180600597722,0.000080598581477044639,-0.000015356852062622951,5.09084046909121171e-6}
},{
{6.33932556236418281,-3.07589360106486531,0.456226630959950593,-0.00444896560449986224,-0.00803034195544535392,-0.000626248357061336987,0.000421665206117149112,0.0000469192966084690651,-0.0000234956663324828471},
{5.3740651556541423,-3.15361482486290811,0.488370588919019434,-0.0119565427661776158,-0.0071239164324135692,-0.000725343801153405533,0.000461709147315171223,0.0000420002316640812232,-0.0000256745877581467219},
{6.97759542644704118,-1.7029539661084809,0.314329784196094464,-0.0805402042898634484,0.0214126542337208624,-0.00404920923437737251,0.0000432174624337086157,0.000376147060473595442,-0.00015590604333367762}
}};
if (!isfinite(temperature_K) || temperature_K <= 0.0 ||
temperature_K > maximum_K)
return -1;
if (temperature_K <= crossover_K) {
for (int channel = 0; channel < 3; ++channel) {
double polynomial = endpoint[channel][3];
for (int term = 2; term >= 0; --term)
polynomial = endpoint[channel][term] + temperature_K * polynomial;
log_xyz[channel] = -q_over_endpoint[channel] / temperature_K +
log(temperature_K * polynomial) +
endpoint_delta[channel] * temperature_K / crossover_K;
}
return 0;
}
int segment = 0;
while (segment < 5 && temperature_K >= edges[segment + 1]) ++segment;
const double inverse_center =
0.5 * (1.0 / edges[segment] + 1.0 / edges[segment + 1]);
const double inverse_half =
0.5 * (1.0 / edges[segment] - 1.0 / edges[segment + 1]);
const double x = (1.0 / temperature_K - inverse_center) / inverse_half;
for (int channel = 0; channel < 3; ++channel)
log_xyz[channel] = -q_over_endpoint[channel] / temperature_K +
chebyshev_clenshaw(coefficients[segment][channel], x);
return 0;
}
int blackbody_low_hybrid_xyz(double temperature_K, double xyz[3]) {
double log_xyz[3];
if (blackbody_low_hybrid_log_xyz(temperature_K, log_xyz)) {
xyz[0] = xyz[1] = xyz[2] = 0.0;
return -1;
}
for (int channel = 0; channel < 3; ++channel)
xyz[channel] = exp(log_xyz[channel]);
return 0;
}
LinearRgb blackbody_xyz_to_linear_rgb(const double xyz[3]) {
return (LinearRgb){
fmax(0.0, 3.24096994 * xyz[0] - 1.53738318 * xyz[1] - 0.49861076 * xyz[2]),
fmax(0.0, -0.96924364 * xyz[0] + 1.87596750 * xyz[1] + 0.04155506 * xyz[2]),
fmax(0.0, 0.05563008 * xyz[0] - 0.20397696 * xyz[1] + 1.05697151 * xyz[2])};
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef BLACKBODY_INTERNAL_H
#define BLACKBODY_INTERNAL_H
#include "optics.h"
void blackbody_rayleigh_jeans_xyz(double temperature_K, int terms,
double xyz[3]);
int blackbody_low_hybrid_log_xyz(double temperature_K, double log_xyz[3]);
int blackbody_low_hybrid_xyz(double temperature_K, double xyz[3]);
LinearRgb blackbody_xyz_to_linear_rgb(const double xyz[3]);
#endif
+175
View File
@@ -0,0 +1,175 @@
#include "blackbody_internal.h"
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
enum { BLACKBODY_LUT_VERSION_CIE1931 = 3,
BLACKBODY_LUT_ELEMENT_F64 = 1,
BLACKBODY_LUT_REFERENCE_CIE1931_1NM_LINEAR = 3 };
static const char default_table_path[] =
"assets/blackbody/cie1931_2deg_xyz_1024.grbblut";
typedef struct {
char magic[8];
uint32_t version, header_bytes, endian_marker, element_type;
uint32_t reference_type, wavelength_min_nm, wavelength_max_nm,
wavelength_step_nm;
uint64_t node_count;
double log_temperature_min, log_temperature_max;
double planck_h, planck_c, planck_k;
char generator[64];
uint64_t payload_checksum;
} BlackbodyLutHeader;
_Static_assert(sizeof(BlackbodyLutHeader) == 160,
"blackbody LUT header layout changed");
typedef struct {
double *xyz;
size_t nodes;
double log_min, log_max, index_scale;
int ready;
} BlackbodyLut;
static BlackbodyLut table;
static uint64_t fnv1a64(const void *data, size_t bytes) {
const unsigned char *p = data;
uint64_t hash = UINT64_C(14695981039346656037);
for (size_t i = 0; i < bytes; ++i) {
hash ^= p[i];
hash *= UINT64_C(1099511628211);
}
return hash;
}
static int validate_header(const BlackbodyLutHeader *h) {
return memcmp(h->magic, "GRBBLUT3", 8) == 0 &&
h->version == BLACKBODY_LUT_VERSION_CIE1931 &&
h->header_bytes == sizeof *h &&
h->endian_marker == UINT32_C(0x01020304) &&
h->element_type == BLACKBODY_LUT_ELEMENT_F64 &&
h->reference_type == BLACKBODY_LUT_REFERENCE_CIE1931_1NM_LINEAR &&
h->wavelength_min_nm == 360 && h->wavelength_max_nm == 830 &&
h->wavelength_step_nm == 1 && h->node_count >= 4 &&
h->node_count <= SIZE_MAX / (3 * sizeof(double)) &&
isfinite(h->log_temperature_min) &&
isfinite(h->log_temperature_max) &&
h->log_temperature_max > h->log_temperature_min &&
h->planck_h == 6.62607015e-34 && h->planck_c == 299792458.0 &&
h->planck_k == 1.380649e-23;
}
static int read_table(const char *path) {
FILE *file = fopen(path, "rb");
BlackbodyLutHeader h;
if (file == NULL || fread(&h, sizeof h, 1, file) != 1 ||
!validate_header(&h)) {
if (file != NULL) fclose(file);
return -1;
}
double *xyz = malloc(3 * (size_t)h.node_count * sizeof *xyz);
const size_t count = 3 * (size_t)h.node_count;
unsigned char extra;
if (xyz == NULL || fread(xyz, sizeof *xyz, count, file) != count ||
fread(&extra, 1, 1, file) != 0 || ferror(file) ||
fnv1a64(xyz, count * sizeof *xyz) != h.payload_checksum) {
free(xyz); fclose(file); return -1;
}
fclose(file);
table = (BlackbodyLut){.xyz = xyz, .nodes = (size_t)h.node_count,
.log_min = h.log_temperature_min,
.log_max = h.log_temperature_max, .ready = 1};
table.index_scale = (table.nodes - 1) / (table.log_max - table.log_min);
return 0;
}
int blackbody_backend_init(const char *table_path, size_t lut_nodes,
double temperature_min_K,
double temperature_max_K,
const char *write_table_path, FILE *report) {
struct timespec start, finish;
timespec_get(&start, TIME_UTC);
if (table.ready) return -1;
if (lut_nodes != 0 || isfinite(temperature_min_K) ||
isfinite(temperature_max_K) || write_table_path != NULL)
return -1;
const char *path = table_path != NULL ? table_path : default_table_path;
if (read_table(path)) return -1;
timespec_get(&finish, TIME_UTC);
if (report != NULL)
fprintf(report,
"Blackbody LUT: %zu CIE 1931 2-deg 1 nm-linear XYZ nodes, "
"T=[%.9g, %.9g] K, loaded %s in %.6f s; "
"payload fnv1a64=%016llx\n",
table.nodes,
exp(table.log_min), exp(table.log_max),
path,
finish.tv_sec - start.tv_sec +
1e-9 * (finish.tv_nsec - start.tv_nsec),
(unsigned long long)fnv1a64(table.xyz,
3 * table.nodes * sizeof *table.xyz));
return 0;
}
void blackbody_backend_destroy(void) {
free(table.xyz);
table = (BlackbodyLut){0};
}
const char *blackbody_backend_name(void) { return "lut"; }
LinearRgb blackbody_to_linear_rgb(double temperature_K) {
if (!table.ready || !isfinite(temperature_K) || temperature_K <= 0.0) {
return (LinearRgb){0};
}
const double log_t = log(temperature_K);
if (log_t < table.log_min) {
double xyz[3];
if (blackbody_low_hybrid_xyz(temperature_K, xyz))
return (LinearRgb){0};
return blackbody_xyz_to_linear_rgb(xyz);
}
if (log_t > table.log_max) {
double xyz[3];
blackbody_rayleigh_jeans_xyz(temperature_K, 3, xyz);
return blackbody_xyz_to_linear_rgb(xyz);
}
const double position = (log_t - table.log_min) * table.index_scale;
size_t low = (size_t)position;
if (low >= table.nodes - 1) low = table.nodes - 2;
const double fraction = position - low;
double xyz[3];
{
size_t base;
double x;
if (low == 0) {
base = 0;
x = fraction;
} else if (low >= table.nodes - 2) {
base = table.nodes - 4;
x = 2.0 + fraction;
} else {
base = low - 1;
x = 1.0 + fraction;
}
const double weights[4] = {
-(x - 1.0) * (x - 2.0) * (x - 3.0) / 6.0,
x * (x - 2.0) * (x - 3.0) / 2.0,
-x * (x - 1.0) * (x - 3.0) / 2.0,
x * (x - 1.0) * (x - 2.0) / 6.0};
for (int channel = 0; channel < 3; ++channel) {
xyz[channel] = 0.0;
for (int point = 0; point < 4; ++point)
xyz[channel] += weights[point] *
table.xyz[3 * (base + (size_t)point) + channel];
xyz[channel] = fmax(0.0, xyz[channel]);
}
}
return blackbody_xyz_to_linear_rgb(xyz);
}
+309
View File
@@ -0,0 +1,309 @@
#include "dummy_psf.h"
#include <math.h>
#include <omp.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { DUMMY_SELECTOR_TILE = 32 };
typedef struct {
size_t worker, events, triangles, occupied_tiles;
double event_bbox_diagonal, triangle_bbox_diagonal;
double maximum_triangle_jump;
int adaptive_tile16;
} DummyChunkSample;
struct DummyPsfSink {
DummyChunkSample *samples;
size_t count, capacity, event_capacity;
size_t total_events;
int width, height, tiles_x, tiles_y;
int failed;
omp_lock_t lock;
};
struct DummyPsfChunk {
DummyPsfSink *sink;
uint32_t *tile_generation;
uint32_t generation;
size_t worker, events, triangles, occupied_tiles;
size_t last_triangle;
int have_event, have_triangle;
double event_min_x, event_max_x, event_min_y, event_max_y;
double triangle_min_x, triangle_max_x, triangle_min_y, triangle_max_y;
double last_triangle_x, last_triangle_y, maximum_triangle_jump;
};
static int append_sample(DummyPsfSink *sink, DummyChunkSample sample) {
int result = 0;
omp_set_lock(&sink->lock);
if (sink->failed) {
result = -1;
} else if (sink->count == sink->capacity) {
const size_t capacity = sink->capacity ? 2 * sink->capacity : 1024;
DummyChunkSample *samples =
capacity < sink->capacity || capacity > SIZE_MAX / sizeof *samples
? NULL
: realloc(sink->samples,
capacity * sizeof *samples);
if (samples == NULL) {
sink->failed = 1;
result = -1;
} else {
sink->samples = samples;
sink->capacity = capacity;
}
}
if (!result) {
sink->samples[sink->count++] = sample;
sink->total_events += sample.events;
}
omp_unset_lock(&sink->lock);
return result;
}
int dummy_psf_sink_create(DummyPsfSink **out, int width, int height,
size_t event_capacity) {
if (out == NULL || width <= 0 || height <= 0 || event_capacity == 0)
return -1;
DummyPsfSink *sink = calloc(1, sizeof *sink);
if (sink == NULL)
return -1;
sink->width = width;
sink->height = height;
sink->tiles_x = (width + DUMMY_SELECTOR_TILE - 1) / DUMMY_SELECTOR_TILE;
sink->tiles_y = (height + DUMMY_SELECTOR_TILE - 1) / DUMMY_SELECTOR_TILE;
sink->event_capacity = event_capacity;
omp_init_lock(&sink->lock);
*out = sink;
return 0;
}
int dummy_psf_chunk_create(DummyPsfChunk **out, DummyPsfSink *sink,
size_t worker_id) {
if (out == NULL || sink == NULL)
return -1;
DummyPsfChunk *chunk = calloc(1, sizeof *chunk);
if (chunk == NULL)
return -1;
const size_t tile_count = (size_t)sink->tiles_x * sink->tiles_y;
chunk->tile_generation = calloc(tile_count, sizeof *chunk->tile_generation);
if (chunk->tile_generation == NULL) {
free(chunk);
return -1;
}
chunk->sink = sink;
chunk->worker = worker_id;
chunk->generation = 1;
*out = chunk;
return 0;
}
static void reset_chunk(DummyPsfChunk *chunk) {
chunk->events = 0;
chunk->triangles = 0;
chunk->occupied_tiles = 0;
chunk->have_event = 0;
chunk->have_triangle = 0;
chunk->maximum_triangle_jump = 0.0;
if (++chunk->generation == 0) {
const size_t count = (size_t)chunk->sink->tiles_x * chunk->sink->tiles_y;
memset(chunk->tile_generation, 0, count * sizeof *chunk->tile_generation);
chunk->generation = 1;
}
}
int dummy_psf_chunk_flush(DummyPsfChunk *chunk) {
if (chunk == NULL)
return -1;
if (chunk->events == 0)
return 0;
const double event_diagonal =
hypot(chunk->event_max_x - chunk->event_min_x,
chunk->event_max_y - chunk->event_min_y);
const double triangle_diagonal =
hypot(chunk->triangle_max_x - chunk->triangle_min_x,
chunk->triangle_max_y - chunk->triangle_min_y);
const DummyChunkSample sample = {
.worker = chunk->worker,
.events = chunk->events,
.triangles = chunk->triangles,
.occupied_tiles = chunk->occupied_tiles,
.event_bbox_diagonal = event_diagonal,
.triangle_bbox_diagonal = triangle_diagonal,
.maximum_triangle_jump = chunk->maximum_triangle_jump,
.adaptive_tile16 = chunk->events >= 8192 && chunk->occupied_tiles != 0 &&
chunk->events / chunk->occupied_tiles >= 32};
const int result = append_sample(chunk->sink, sample);
reset_chunk(chunk);
return result;
}
int dummy_psf_chunk_emit(DummyPsfChunk *chunk, const PsfCachedEvent *event,
size_t triangle, double triangle_center_x,
double triangle_center_y) {
if (chunk == NULL || event == NULL)
return -1;
if (chunk->events == chunk->sink->event_capacity &&
dummy_psf_chunk_flush(chunk))
return -1;
if (!chunk->have_event) {
chunk->event_min_x = chunk->event_max_x = event->x;
chunk->event_min_y = chunk->event_max_y = event->y;
chunk->have_event = 1;
} else {
chunk->event_min_x = fmin(chunk->event_min_x, event->x);
chunk->event_max_x = fmax(chunk->event_max_x, event->x);
chunk->event_min_y = fmin(chunk->event_min_y, event->y);
chunk->event_max_y = fmax(chunk->event_max_y, event->y);
}
const int pixel_x = (int)floor(event->x);
const int pixel_y = (int)floor(event->y);
if (pixel_x >= 0 && pixel_x < chunk->sink->width && pixel_y >= 0 &&
pixel_y < chunk->sink->height) {
const size_t tile = (size_t)(pixel_y / DUMMY_SELECTOR_TILE) *
chunk->sink->tiles_x +
pixel_x / DUMMY_SELECTOR_TILE;
if (chunk->tile_generation[tile] != chunk->generation) {
chunk->tile_generation[tile] = chunk->generation;
++chunk->occupied_tiles;
}
}
if (!chunk->have_triangle || triangle != chunk->last_triangle) {
if (!chunk->have_triangle) {
chunk->triangle_min_x = chunk->triangle_max_x = triangle_center_x;
chunk->triangle_min_y = chunk->triangle_max_y = triangle_center_y;
chunk->have_triangle = 1;
} else {
chunk->triangle_min_x = fmin(chunk->triangle_min_x, triangle_center_x);
chunk->triangle_max_x = fmax(chunk->triangle_max_x, triangle_center_x);
chunk->triangle_min_y = fmin(chunk->triangle_min_y, triangle_center_y);
chunk->triangle_max_y = fmax(chunk->triangle_max_y, triangle_center_y);
chunk->maximum_triangle_jump =
fmax(chunk->maximum_triangle_jump,
hypot(triangle_center_x - chunk->last_triangle_x,
triangle_center_y - chunk->last_triangle_y));
}
chunk->last_triangle = triangle;
chunk->last_triangle_x = triangle_center_x;
chunk->last_triangle_y = triangle_center_y;
++chunk->triangles;
}
++chunk->events;
return 0;
}
void dummy_psf_chunk_destroy(DummyPsfChunk *chunk) {
if (chunk == NULL)
return;
(void)dummy_psf_chunk_flush(chunk);
free(chunk->tile_generation);
free(chunk);
}
static int compare_double(const void *left, const void *right) {
const double a = *(const double *)left;
const double b = *(const double *)right;
return (a > b) - (a < b);
}
static double percentile(const double *values, size_t count, double fraction) {
if (count == 0)
return 0.0;
const double position = fraction * (count - 1);
const size_t low = (size_t)floor(position);
const size_t high = low + 1 < count ? low + 1 : low;
return values[low] + (values[high] - values[low]) * (position - low);
}
static void report_group(const DummyPsfSink *sink, int full_only,
const char *label) {
size_t count = 0, adaptive = 0;
for (size_t i = 0; i < sink->count; ++i)
if (!full_only || sink->samples[i].events == sink->event_capacity)
++count;
if (count == 0) {
fprintf(stderr, "Dummy PSF %s chunks: none\n", label);
return;
}
double *events = count > SIZE_MAX / (6 * sizeof *events)
? NULL
: malloc(6 * count * sizeof *events);
if (events == NULL) {
fputs("Dummy PSF report allocation failed\n", stderr);
return;
}
double *triangles = events + count;
double *tiles = triangles + count;
double *event_distance = tiles + count;
double *triangle_distance = event_distance + count;
double *maximum_jump = triangle_distance + count;
size_t next = 0;
for (size_t i = 0; i < sink->count; ++i) {
const DummyChunkSample *sample = &sink->samples[i];
if (full_only && sample->events != sink->event_capacity)
continue;
events[next] = sample->events;
triangles[next] = sample->triangles;
tiles[next] = sample->occupied_tiles;
event_distance[next] = sample->event_bbox_diagonal;
triangle_distance[next] = sample->triangle_bbox_diagonal;
maximum_jump[next] = sample->maximum_triangle_jump;
adaptive += sample->adaptive_tile16;
++next;
}
double *series[] = {events, triangles, tiles, event_distance,
triangle_distance, maximum_jump};
const char *names[] = {"events", "distinct_triangles", "occupied_32px_tiles",
"event_bbox_diagonal_px",
"triangle_centroid_bbox_diagonal_px",
"maximum_successive_triangle_jump_px"};
for (size_t field = 0; field < 6; ++field) {
qsort(series[field], count, sizeof **series, compare_double);
fprintf(stderr,
"Dummy PSF %s %s: min=%.3f p10=%.3f p25=%.3f p50=%.3f "
"p75=%.3f p90=%.3f p99=%.3f max=%.3f\n",
label, names[field], series[field][0],
percentile(series[field], count, 0.10),
percentile(series[field], count, 0.25),
percentile(series[field], count, 0.50),
percentile(series[field], count, 0.75),
percentile(series[field], count, 0.90),
percentile(series[field], count, 0.99), series[field][count - 1]);
}
fprintf(stderr,
"Dummy PSF %s adaptive criterion: %zu/%zu chunks tile16-eligible "
"(events>=8192 and events/occupied_32px_tiles>=32)\n",
label, adaptive, count);
free(events);
}
void dummy_psf_sink_report(const DummyPsfSink *sink) {
if (sink == NULL)
return;
size_t full = 0;
for (size_t i = 0; i < sink->count; ++i)
full += sink->samples[i].events == sink->event_capacity;
fprintf(stderr,
"Dummy PSF diagnostic only: no HDR or image was accumulated/written.\n"
"Dummy PSF chunks: total=%zu full=%zu partial=%zu events=%zu "
"capacity=%zu selector_tile=%dpx\n",
sink->count, full, sink->count - full, sink->total_events,
sink->event_capacity, DUMMY_SELECTOR_TILE);
report_group(sink, 0, "all");
report_group(sink, 1, "full");
}
void dummy_psf_sink_destroy(DummyPsfSink *sink) {
if (sink == NULL)
return;
omp_destroy_lock(&sink->lock);
free(sink->samples);
free(sink);
}
+25
View File
@@ -0,0 +1,25 @@
#ifndef DUMMY_PSF_H
#define DUMMY_PSF_H
#include "optics.h"
#include <stddef.h>
typedef struct DummyPsfSink DummyPsfSink;
typedef struct DummyPsfChunk DummyPsfChunk;
/* Diagnostic-only consumer for the production PSF event stream. It preserves
* per-worker chunk boundaries but never accumulates or writes an HDR image. */
int dummy_psf_sink_create(DummyPsfSink **out, int width, int height,
size_t event_capacity);
int dummy_psf_chunk_create(DummyPsfChunk **out, DummyPsfSink *sink,
size_t worker_id);
int dummy_psf_chunk_emit(DummyPsfChunk *chunk, const PsfCachedEvent *event,
size_t triangle, double triangle_center_x,
double triangle_center_y);
int dummy_psf_chunk_flush(DummyPsfChunk *chunk);
void dummy_psf_chunk_destroy(DummyPsfChunk *chunk);
void dummy_psf_sink_report(const DummyPsfSink *sink);
void dummy_psf_sink_destroy(DummyPsfSink *sink);
#endif
+142 -4
View File
@@ -3,6 +3,9 @@
#ifdef PSF_BACKEND_HIP
#include "hip_psf.h"
#endif
#ifdef PSF_BACKEND_DUMMY
#include "dummy_psf.h"
#endif
#include "optics.h"
@@ -138,6 +141,11 @@ typedef struct {
double submit_seconds;
char hip_message[256];
HipPsfTiming hip_timing;
#endif
#ifdef PSF_BACKEND_DUMMY
DummyPsfSink *dummy;
DummyPsfChunk *dummy_chunk;
int borrowed_dummy;
#endif
int failed;
} PsfEventSink;
@@ -155,6 +163,16 @@ static int psf_event_sink_init(PsfEventSink *sink, double *hdr, int width,
*sink = (PsfEventSink){.hdr = hdr, .width = width, .height = height,
.cache = cache};
if (cache != NULL) {
#ifdef PSF_BACKEND_DUMMY
if (dummy_psf_sink_create(&sink->dummy, width, height,
PSF_EVENT_SINK_CAPACITY)) {
fputs("Dummy PSF backend initialization failed\n", stderr);
dummy_psf_sink_destroy(sink->dummy);
sink->dummy = NULL;
sink->failed = 1;
return -1;
}
#else
sink->events = malloc(PSF_EVENT_SINK_CAPACITY * sizeof *sink->events);
if (sink->events == NULL) {
#ifdef PSF_BACKEND_HIP
@@ -174,6 +192,7 @@ static int psf_event_sink_init(PsfEventSink *sink, double *hdr, int width,
sink->events = NULL;
return -1;
}
#endif
#endif
}
return 0;
@@ -182,6 +201,10 @@ static int psf_event_sink_init(PsfEventSink *sink, double *hdr, int width,
static int psf_event_sink_flush_unlocked(PsfEventSink *sink) {
if (sink->failed)
return -1;
#ifdef PSF_BACKEND_DUMMY
if (sink->dummy_chunk != NULL)
return dummy_psf_chunk_flush(sink->dummy_chunk);
#endif
#ifdef PSF_BACKEND_HIP
if (sink->hip != NULL) {
if (hip_psf_sink_submit(sink->hip, sink->events, sink->count,
@@ -233,6 +256,7 @@ static int psf_event_sink_finish_for_cpu(PsfEventSink *sink) {
return 0;
}
#ifndef PSF_BACKEND_DUMMY
static int psf_event_sink_resume_gpu(PsfEventSink *sink) {
#ifdef PSF_BACKEND_HIP
if (sink->hip != NULL && hip_psf_sink_load_hdr(sink->hip, sink->hdr,
@@ -246,8 +270,22 @@ static int psf_event_sink_resume_gpu(PsfEventSink *sink) {
#endif
return 0;
}
#endif
static int psf_event_sink_destroy(PsfEventSink *sink) {
#ifdef PSF_BACKEND_DUMMY
int dummy_result = sink->dummy_chunk != NULL
? dummy_psf_chunk_flush(sink->dummy_chunk)
: 0;
dummy_psf_chunk_destroy(sink->dummy_chunk);
sink->dummy_chunk = NULL;
if (!sink->borrowed_dummy) {
dummy_psf_sink_report(sink->dummy);
dummy_psf_sink_destroy(sink->dummy);
sink->dummy = NULL;
}
return dummy_result;
#endif
#ifdef PSF_BACKEND_HIP
if (sink->borrowed_hip) {
const int result = psf_event_sink_flush(sink);
@@ -267,10 +305,22 @@ static int psf_event_sink_destroy(PsfEventSink *sink) {
return result;
}
#if FRAME_PSF_EVENT_SINK || defined(PSF_BACKEND_HIP)
static void psf_event_sink_emit(PsfEventSink *sink, const PsfCachedEvent *event) {
#if FRAME_PSF_EVENT_SINK || defined(PSF_BACKEND_HIP) || defined(PSF_BACKEND_DUMMY)
static void psf_event_sink_emit(PsfEventSink *sink, const PsfCachedEvent *event,
size_t triangle, double triangle_center_x,
double triangle_center_y) {
if (sink->failed)
return;
#ifdef PSF_BACKEND_DUMMY
if (dummy_psf_chunk_emit(sink->dummy_chunk, event, triangle,
triangle_center_x, triangle_center_y))
sink->failed = 1;
return;
#else
(void)triangle;
(void)triangle_center_x;
(void)triangle_center_y;
#endif
if (sink->events == NULL) {
splat_prepared_cached_event(sink->hdr, sink->width, sink->height, event, sink->cache);
return;
@@ -1129,6 +1179,9 @@ static int splat_catalog_tile(const Star *stars, size_t count,
#endif
if (direct_fallback == 1) {
/* Exclude every other submit and fallback until HDR is back on device. */
#ifdef PSF_BACKEND_DUMMY
if (psf_event_sink_flush(context->event_sink)) return -1;
#else
#ifdef PSF_BACKEND_HIP
const double submit_start = omp_get_wtime();
if (context->event_sink->hip_lock)
@@ -1147,9 +1200,17 @@ static int splat_catalog_tile(const Star *stars, size_t count,
context->event_sink->submit_seconds += omp_get_wtime() - submit_start;
#endif
if (failed) return -1;
#endif
} else if (direct_fallback != 3) {
#if FRAME_PSF_EVENT_SINK || defined(PSF_BACKEND_HIP)
psf_event_sink_emit(context->event_sink, &event);
#if FRAME_PSF_EVENT_SINK || defined(PSF_BACKEND_HIP) || defined(PSF_BACKEND_DUMMY)
const double triangle_center_x =
(context->vertex[0]->image_x + context->vertex[1]->image_x +
context->vertex[2]->image_x) / 3.0;
const double triangle_center_y =
(context->vertex[0]->image_y + context->vertex[1]->image_y +
context->vertex[2]->image_y) / 3.0;
psf_event_sink_emit(context->event_sink, &event, context->triangle_index,
triangle_center_x, triangle_center_y);
#else
splat_prepared_cached_event(context->hdr, context->width, context->height,
&event, context->psf_cache);
@@ -1319,6 +1380,83 @@ size_t frame_splat_catalog(const FrameLensMesh *mesh,
progress->callback(progress->context, FRAME_SPLAT_PROGRESS_BEGIN, 0,
mesh->triangle_count);
#ifdef PSF_BACKEND_DUMMY
PsfEventSink owner;
if (psf_event_sink_init(&owner, hdr, width, height, psf_cache)) return SIZE_MAX;
size_t dummy_images = 0, dummy_direct = 0, dummy_clipped = 0,
dummy_discarded = 0;
int dummy_failed = 0, dummy_workers = 0;
const double dummy_start = omp_get_wtime();
#ifdef GR_DEBUG
double dummy_max_magnification = 0.0;
size_t dummy_clamped = 0;
#pragma omp parallel reduction(+ : dummy_images, dummy_direct, dummy_clipped, dummy_discarded, dummy_clamped) reduction(max : dummy_failed, dummy_max_magnification)
#else
#pragma omp parallel reduction(+ : dummy_images, dummy_direct, dummy_clipped, dummy_discarded) reduction(max : dummy_failed)
#endif
{
#pragma omp single
dummy_workers = omp_get_num_threads();
const size_t worker = (size_t)omp_get_thread_num();
PsfEventSink local = {.hdr = hdr, .width = width, .height = height,
.cache = psf_cache, .dummy = owner.dummy, .borrowed_dummy = 1};
if (dummy_psf_chunk_create(&local.dummy_chunk, owner.dummy, worker)) {
fputs("Dummy PSF worker chunk initialization failed\n", stderr);
local.failed = 1;
}
size_t completed = 0, next_report = 8;
if (progress && progress->worker_callback)
progress->worker_callback(progress->context, worker,
(size_t)dummy_workers, 0, 0);
#pragma omp for schedule(dynamic, 1) nowait
for (size_t t = 0; t < mesh->triangle_count; ++t) {
if (local.failed) continue;
const CatalogSplatStats stats = splat_catalog_triangles(
mesh, catalog, hdr, width, height, exposure, psf, psf_cache,
max_magnification, max_cache_psf_flux, psf_relative_tail, psf_min_y,
t, t + 1, &local);
dummy_images += stats.images;
dummy_direct += stats.direct_fallbacks;
dummy_clipped += stats.cached_wing_clipped;
dummy_discarded += stats.discarded_below_min_y;
dummy_failed |= stats.failed;
#ifdef GR_DEBUG
dummy_max_magnification = fmax(dummy_max_magnification,
stats.max_raw_magnification);
dummy_clamped += stats.magnification_clamped_triangles;
#endif
++completed;
if (progress && progress->worker_callback && completed == next_report) {
progress->worker_callback(progress->context, worker,
(size_t)dummy_workers, completed, 0);
if (next_report <= SIZE_MAX / 2) next_report *= 2;
}
}
if (psf_event_sink_destroy(&local)) dummy_failed = 1;
if (progress && progress->worker_callback)
progress->worker_callback(progress->context, worker,
(size_t)dummy_workers, completed, 1);
}
if (psf_event_sink_destroy(&owner)) dummy_failed = 1;
fprintf(stderr,
"Dummy PSF producers: %d workers; classification/chunk wall %.3f s\n",
dummy_workers, omp_get_wtime() - dummy_start);
copy_psf_splat_stats(psf_stats, (CatalogSplatStats){
.images = dummy_images, .direct_fallbacks = dummy_direct,
.cached_wing_clipped = dummy_clipped,
.discarded_below_min_y = dummy_discarded,
#ifdef GR_DEBUG
.max_raw_magnification = dummy_max_magnification,
.magnification_clamped_triangles = dummy_clamped,
#endif
});
if (dummy_failed) return SIZE_MAX;
if (progress != NULL && progress->callback != NULL)
progress->callback(progress->context, FRAME_SPLAT_PROGRESS_END,
mesh->triangle_count, mesh->triangle_count);
return dummy_images;
#endif
#ifdef PSF_BACKEND_HIP
/* CPU workers own only bounded event chunks. A single device cache/HDR is
* borrowed under a coarse submission lock, never duplicated per worker. */
+72 -1
View File
@@ -12,6 +12,7 @@
#include <math.h>
#include <omp.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
@@ -52,6 +53,7 @@ typedef struct {
double slab_duration;
double minkowski_proper_acceleration;
int catalog_load_workers;
const char *blackbody_table_path;
RefinementConfig refinement;
} Settings;
@@ -319,6 +321,8 @@ static int parse_args(int argc, char **argv, Settings *s,
&s->minkowski_proper_acceleration)) {
} else if (!strcmp(argv[i], "--catalog-load-workers") && i + 1 < argc &&
!parse_int(argv[++i], &s->catalog_load_workers)) {
} else if (!strcmp(argv[i], "--blackbody-table") && i + 1 < argc) {
s->blackbody_table_path = argv[++i];
} else if (!strcmp(argv[i], "--write-minkowski-accel-track") &&
i + 1 < argc)
s->write_minkowski_accel_track_path = argv[++i];
@@ -377,6 +381,10 @@ static void print_help(const char *program) {
" --psf-min-y Y Skip events below this linear HDR luminance (default: 0, disabled)\n"
" --psf-direct Disable the PSF lookup cache (default: disabled)\n"
" --catalog-load-workers N All-sky catalog loader workers (default: 4)\n"
" --blackbody-table FILE Explicit GRBBLUT3 table\n"
" (default: assets/blackbody/cie1931_2deg_xyz_1024.grbblut)\n",
stdout);
fputs(
"\nAdaptive lens mesh:\n"
" --coarse-cell-pixels N Initial mesh cell size in pixels (default: 16)\n"
" --refine-max-level N Maximum refinement level (default: 0)\n"
@@ -445,8 +453,13 @@ static void report_splat_progress(void *context, FrameSplatProgressStage stage,
progress->frame_id, total);
break;
case FRAME_SPLAT_PROGRESS_END:
#ifdef PSF_BACKEND_DUMMY
fprintf(stderr, "Frame %zu: catalog classification finished in %.1f s; reporting chunk statistics...\n",
progress->frame_id, omp_get_wtime() - progress->splat_start);
#else
fprintf(stderr, "Frame %zu: catalog splatting finished in %.1f s; writing image...\n",
progress->frame_id, omp_get_wtime() - progress->splat_start);
#endif
break;
}
}
@@ -922,7 +935,15 @@ static int render_lens_map(const Settings *s, StarCatalog *catalog) {
}
output_path = movie_path;
}
#ifdef PSF_BACKEND_DUMMY
(void)output_path;
#endif
#ifdef PSF_BACKEND_DUMMY
/* The dummy backend classifies real events but never touches pixels. */
double *hdr = calloc(1, sizeof *hdr);
#else
double *hdr = calloc((size_t)map.width * map.height * 3, sizeof *hdr);
#endif
if (hdr == NULL) { result = -1; break; }
CatalogPrefetchStats prefetch = {0};
PsfSplatStats psf_stats = {0};
@@ -945,7 +966,12 @@ static int render_lens_map(const Settings *s, StarCatalog *catalog) {
break;
}
if (s->draw_mesh)
#ifdef PSF_BACKEND_DUMMY
fputs("Dummy PSF backend ignores --draw-mesh.\n", stderr);
#else
frame_draw_mesh(&map.frames[i].mesh, hdr, map.width, map.height, 0.5, 0.5);
#endif
#ifndef PSF_BACKEND_DUMMY
#ifdef ENABLE_HDR_OUTPUT
if (s->write_hdr_output &&
write_hdr_fits(s->hdr_output_path, hdr, map.width, map.height,
@@ -960,6 +986,13 @@ static int render_lens_map(const Settings *s, StarCatalog *catalog) {
images, catalog->count, output_path, write_result == 0 ? "ok" : "write failed");
psf_kernel_cache_report(&s->psf_cache, &psf_stats, stderr);
if (write_result) { result = -1; break; }
#else
free(hdr);
fprintf(stderr,
"Dummy PSF classified %zu images from %zu catalog stars; no HDR, PNG, or PPM was written.\n",
images, catalog->count);
psf_kernel_cache_report(&s->psf_cache, &psf_stats, stderr);
#endif
}
lens_map_destroy(&map);
return result;
@@ -1026,6 +1059,20 @@ int main(int argc, char **argv) {
fputs("--lens-map-input and --lens-map-output are mutually exclusive.\n", stderr);
return 2;
}
#ifdef PSF_BACKEND_DUMMY
if (settings.lens_map_input_path == NULL) {
fputs("The dummy PSF backend requires --lens-map-input and never traces or writes images.\n",
stderr);
return 2;
}
if (settings.psf_direct) {
fputs("The dummy PSF backend measures cache-event chunks and does not support --psf-direct.\n",
stderr);
return 2;
}
fputs("Dummy PSF backend: --output and --hdr-output are accepted for command parity but no image files will be written.\n",
stderr);
#endif
#ifdef ENABLE_HDR_OUTPUT
if (settings.frames_dir != NULL && settings.write_hdr_output) {
fputs("--hdr-output is available only for a single-frame render.\n", stderr);
@@ -1072,14 +1119,37 @@ int main(int argc, char **argv) {
}
fprintf(stderr, "Created test catalog: %s\n", settings.catalog_path);
}
if (blackbody_backend_init(settings.blackbody_table_path,
0, NAN, NAN, NULL, stderr)) {
fprintf(stderr,
"Blackbody backend '%s' initialization failed; the LUT loads the "
"repository CIE GRBBLUT3 table by default or a valid explicit "
"table.\n",
blackbody_backend_name());
catalog_destroy(&catalog);
spacetime_destroy(&spacetime);
return 1;
}
fprintf(stderr, "Blackbody backend: %s\n", blackbody_backend_name());
if (!settings.psf_direct && psf_kernel_cache_init(&settings.psf_cache, &settings.psf,
settings.psf_relative_tail))
settings.psf_relative_tail)) {
#ifdef PSF_BACKEND_DUMMY
fputs("PSF cache construction failed; dummy chunk statistics are unavailable.\n",
stderr);
catalog_destroy(&catalog);
spacetime_destroy(&spacetime);
blackbody_backend_destroy();
return 1;
#else
fputs("PSF cache construction failed; using direct evaluator.\n", stderr);
#endif
}
psf_kernel_cache_report_ready(&settings.psf_cache, stderr);
if (settings.lens_map_input_path != NULL) {
const int result = render_lens_map(&settings, &catalog);
catalog_destroy(&catalog);
psf_kernel_cache_destroy(&settings.psf_cache);
blackbody_backend_destroy();
return result == 0 ? 0 : 1;
}
int result = settings.frames_dir != NULL
@@ -1089,5 +1159,6 @@ int main(int argc, char **argv) {
spacetime_destroy(&spacetime);
catalog_destroy(&catalog);
psf_kernel_cache_destroy(&settings.psf_cache);
blackbody_backend_destroy();
return result == 0 ? 0 : 1;
}
-62
View File
@@ -21,68 +21,6 @@ static double clamp(double value, double low, double high)
return value < low ? low : value > high ? high : value;
}
/* Wyman, Sloan, and Shirley (2013), Eq. 4: analytic fits to the CIE 1931
* 2-degree color-matching functions. Wavelength is in nanometres. */
static void cie_1931_2deg(double wavelength_nm, double xyz[3])
{
const double x1 = (wavelength_nm - 442.0) *
(wavelength_nm < 442.0 ? 0.0624 : 0.0374);
const double x2 = (wavelength_nm - 599.8) *
(wavelength_nm < 599.8 ? 0.0264 : 0.0323);
const double x3 = (wavelength_nm - 501.1) *
(wavelength_nm < 501.1 ? 0.0490 : 0.0382);
const double y1 = (wavelength_nm - 568.8) *
(wavelength_nm < 568.8 ? 0.0213 : 0.0247);
const double y2 = (wavelength_nm - 530.9) *
(wavelength_nm < 530.9 ? 0.0613 : 0.0322);
const double z1 = (wavelength_nm - 437.0) *
(wavelength_nm < 437.0 ? 0.0845 : 0.0278);
const double z2 = (wavelength_nm - 459.0) *
(wavelength_nm < 459.0 ? 0.0385 : 0.0725);
xyz[0] = 0.362 * exp(-0.5 * x1 * x1) +
1.056 * exp(-0.5 * x2 * x2) - 0.065 * exp(-0.5 * x3 * x3);
xyz[1] = 0.821 * exp(-0.5 * y1 * y1) +
0.286 * exp(-0.5 * y2 * y2);
xyz[2] = 1.217 * exp(-0.5 * z1 * z1) +
0.681 * exp(-0.5 * z2 * z2);
}
static double planck_radiance_lambda(double wavelength_m, double temperature_K)
{
const double h = 6.62607015e-34;
const double c = 299792458.0;
const double k = 1.380649e-23;
const double exponent = h * c / (wavelength_m * k * temperature_K);
return 2.0 * h * c * c /
(pow(wavelength_m, 5.0) * expm1(exponent));
}
LinearRgb blackbody_to_linear_rgb(double temperature_K)
{
/* Integrate Planck spectral radiance from 380 to 780 nm into CIE XYZ,
* then transform XYZ to linear sRGB. Results are W m^-2 sr^-1 in each
* linear-primary channel, before the catalog amplitude and exposure. */
double xyz[3] = {0.0, 0.0, 0.0};
const double wavelength_step_m = 5e-9;
if (!isfinite(temperature_K) || temperature_K <= 0.0)
return (LinearRgb){0.0, 0.0, 0.0};
for (int wavelength_nm = 380; wavelength_nm <= 780; wavelength_nm += 5) {
double matching[3];
const double radiance =
planck_radiance_lambda(wavelength_nm * 1e-9, temperature_K);
cie_1931_2deg(wavelength_nm, matching);
for (int channel = 0; channel < 3; ++channel)
xyz[channel] += radiance * matching[channel] * wavelength_step_m;
}
return (LinearRgb){
clamp(3.24096994 * xyz[0] - 1.53738318 * xyz[1] - 0.49861076 * xyz[2],
0.0, INFINITY),
clamp(-0.96924364 * xyz[0] + 1.87596750 * xyz[1] + 0.04155506 * xyz[2],
0.0, INFINITY),
clamp(0.05563008 * xyz[0] - 0.20397696 * xyz[1] + 1.05697151 * xyz[2],
0.0, INFINITY)};
}
enum {
PSF_PHASE_RESOLUTION = 64,
PSF_QUADRATURE_ORDER = 4,
+10
View File
@@ -50,6 +50,16 @@ extern "C" {
/* Integrate a Planck spectrum into absolute linear-sRGB spectral radiance
* (W m^-2 sr^-1), before catalog amplitude and display exposure. */
LinearRgb blackbody_to_linear_rgb(double temperature_K);
/* Backend initialization happens before renderer workers start. Integral and
* fixed backends reject LUT-only options. The LUT backend loads the sole
* repository CIE table by default, or validates an explicit equivalent file;
* legacy runtime-generation arguments are rejected. */
int blackbody_backend_init(const char *table_path, size_t lut_nodes,
double temperature_min_K,
double temperature_max_K,
const char *write_table_path, FILE *report);
void blackbody_backend_destroy(void);
const char *blackbody_backend_name(void);
int psf_kernel_cache_init(PsfKernelCache *cache,
const PointSpreadFunction *psf,
double relative_tail_fraction);
+4 -2
View File
@@ -1,6 +1,7 @@
/* Standalone bounded diagnostic. Include the production producer so its
* private query/mapping path stays identical; renderer builds omit the hook. */
#include "optics.h"
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -100,6 +101,7 @@ int main(int argc, char **argv) {
if (lens_map_read(argv[1],&map) || map.frame_count!=1 ||
last>map.frames[0].mesh.triangle_count || catalog_load_csv(&catalog,argv[2]) ||
catalog.count>32768) return 2;
if (blackbody_backend_init(NULL, 0, NAN, NAN, NULL, stderr)) return 1;
const int indexed=!strcmp(argv[6],"--diagnose-indexed") || !strcmp(argv[6],"--diagnose-indexed-serial");
if(indexed && index_subset(&catalog))return 1;
const char *kind=indexed ? "indexed-subset" : "memory";
@@ -126,7 +128,7 @@ int main(int argc, char **argv) {
}
printf("DIAGNOSTIC ONLY, no HDR: workers=%d catalog=%s stars=%zu triangles=[%zu,%zu) events=%zu cached=%zu wing=%zu direct=%zu discarded=%zu checksum=%016llx producer_wall=%.9f capped_or_failed=%d\n",
workers,kind,catalog.count,first,last,total_events,totals[0]+totals[2],totals[2],totals[1],totals[3],(unsigned long long)total_checksum,omp_get_wtime()-start,failed);
psf_kernel_cache_destroy(&cache);catalog_destroy(&catalog);lens_map_destroy(&map);
psf_kernel_cache_destroy(&cache);catalog_destroy(&catalog);lens_map_destroy(&map);blackbody_backend_destroy();
return failed ? 1 : 0;
}
PsfEventSink sink={.cache=&cache};
@@ -146,6 +148,6 @@ int main(int argc, char **argv) {
}
if (ferror(f) || fclose(f)) return 1;
}
psf_kernel_cache_destroy(&cache);catalog_destroy(&catalog);lens_map_destroy(&map);
psf_kernel_cache_destroy(&cache);catalog_destroy(&catalog);lens_map_destroy(&map);blackbody_backend_destroy();
return 0;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 KiB

After

Width:  |  Height:  |  Size: 225 KiB

+41 -11
View File
@@ -102,11 +102,13 @@ static size_t contributions(const std::vector<PsfCachedEvent>& events,int width,
return n;
}
int main(int argc,char **argv) {
if(argc<4 || argc>5) {puts("Usage: replay_psf INPUT.events EVENTS(1..65536) atomic|16|32 [disperse|mixed]\nExternal timeout <=45s; sequential processes only.");return 2;}
if(argc<4 || argc>5) {puts("Usage: replay_psf INPUT.events EVENTS(1..65536) atomic|16|32|adaptive [disperse|mixed]\nExternal timeout <=45s; sequential processes only.");return 2;}
char *end=nullptr;const long requested=strtol(argv[2],&end,10);
if(!*argv[2] || *end || requested<1 || requested>65536) return 2;
const int tile=!strcmp(argv[3],"atomic") ? 0 : !strcmp(argv[3],"16") ? 16 : !strcmp(argv[3],"32") ? 32 : -1;
if(tile<0 || (argc==5 && strcmp(argv[4],"disperse") && strcmp(argv[4],"mixed")))return 2;
const bool adaptive=!strcmp(argv[3],"adaptive");
const int requested_tile=!strcmp(argv[3],"atomic") ? 0 : !strcmp(argv[3],"16") ? 16 :
!strcmp(argv[3],"32") ? 32 : adaptive ? 16 : -1;
if(requested_tile<0 || (argc==5 && strcmp(argv[4],"disperse") && strcmp(argv[4],"mixed")))return 2;
FILE *f=fopen(argv[1],"r");if(!f){perror(argv[1]);return 2;}
int width,height;size_t count;PointSpreadFunction psf;double tail;
if(fscanf(f,"PSFEVENTS1 %d %d %zu %lf %lf %lf",&width,&height,&count,&psf.fwhm_pixels,&psf.moffat_beta,&tail)!=6 ||
@@ -153,8 +155,10 @@ int main(int argc,char **argv) {
const double create=omp_get_wtime()-start;
hipDeviceProp_t prop;check(hipGetDeviceProperties(&prop,0));
printf("device=%s arch=%s events=%zu frame=%dx%d mode=%s distribution=%s contributions=%zu CPU_reference=%.9f create=%.9f\n",prop.name,prop.gcnArchName,events.size(),width,height,argv[3],mixed?"fixture-mixed-direct":argc==5?"synthetic-phase-preserving-dispersal":"captured",work,cpu_time,create);fflush(stdout);
double bin=0,upload=0,prepare=0,kernel=0,merge=0,clear=0;size_t peak_scratch=0,ref_total=0,task_total=0;
double select=0,bin=0,upload=0,prepare=0,kernel=0,merge=0,clear=0;
size_t peak_scratch=0,ref_total=0,task_total=0,center_tiles=0,tile_chunks=0,atomic_chunks=0;
Prepared *prepared=nullptr;int *bounds=nullptr;
PsfCachedEvent *tile_events=nullptr;
unsigned *drefs=nullptr,*dstarts=nullptr;TileTask *dtasks=nullptr;double *partial=nullptr;
auto direct_boundary=[&]() {
if(hip_psf_sink_finish(s,gpu.data(),message,sizeof message)) {fprintf(stderr,"%s\n",message);exit(1);}
@@ -162,8 +166,9 @@ int main(int argc,char **argv) {
if(hip_psf_sink_load_hdr(s,gpu.data(),message,sizeof message)) {fprintf(stderr,"%s\n",message);exit(1);}
};
const double replay_start=omp_get_wtime();
if(tile) {
if(requested_tile) {
// Fixed hard bounds; no full-frame event list or per-chunk allocation on GPU.
check(hipMalloc(&tile_events,16384*sizeof(PsfCachedEvent)));
check(hipMalloc(&prepared,16384*sizeof(Prepared)));
check(hipMalloc(&bounds,16384*(size_t)(2*cache.radius_pixels+1)*2*sizeof(int)));
check(hipMalloc(&drefs,32*1024*1024));check(hipMalloc(&dtasks,2*1024*1024));
@@ -171,7 +176,32 @@ int main(int argc,char **argv) {
}
for(size_t offset=0;offset<events.size();offset+=16384) {
const size_t n=std::min((size_t)16384,events.size()-offset);
if(!tile) {if(hip_psf_sink_submit(s,events.data()+offset,n,message,sizeof message)) {fprintf(stderr,"%s\n",message);return 1;}if(mixed && offset==0)direct_boundary();continue;}
int tile=requested_tile;
if(adaptive) {
start=omp_get_wtime();
const int selector_tile=32,nx=(width+selector_tile-1)/selector_tile;
const int ny=(height+selector_tile-1)/selector_tile;
std::vector<unsigned char> occupied((size_t)nx*ny,0);
size_t count_occupied=0;
for(size_t i=0;i<n;++i) {
const int x=(int)floor(events[offset+i].x),y=(int)floor(events[offset+i].y);
if(x<0 || x>=width || y<0 || y>=height)continue;
unsigned char &mark=occupied[(size_t)(y/selector_tile)*nx+x/selector_tile];
if(!mark) {mark=1;++count_occupied;}
}
/* This threshold is deliberately experimental. The captured dense and
* lensed chunks have >=45 events per occupied center tile, while the
* equal-work dispersed control has about 2.4. Small chunks retain the
* lower-overhead production atomic path. */
tile=n>=8192 && count_occupied && n/count_occupied>=32 ? 16 : 0;
center_tiles+=count_occupied;select+=omp_get_wtime()-start;
}
if(!tile) {
++atomic_chunks;
if(hip_psf_sink_submit(s,events.data()+offset,n,message,sizeof message)) {fprintf(stderr,"%s\n",message);return 1;}
if(mixed && offset==0)direct_boundary();continue;
}
++tile_chunks;
start=omp_get_wtime();
const int nx=(width+tile-1)/tile,ny=(height+tile-1)/tile;
std::vector<std::vector<unsigned>> lists(nx*ny);
@@ -208,13 +238,13 @@ int main(int argc,char **argv) {
peak_scratch=std::max(peak_scratch,bytes+refs.size()*sizeof(unsigned)+tasks.size()*sizeof(TileTask)+starts.size()*sizeof(unsigned)+n*(sizeof(Prepared)+(size_t)(2*cache.radius_pixels+1)*2*sizeof(int)));
ref_total+=refs.size();task_total+=tasks.size();bin+=omp_get_wtime()-start;
start=omp_get_wtime();
check(hipMemcpyAsync(s->slots[0].device,events.data()+offset,n*sizeof(PsfCachedEvent),hipMemcpyHostToDevice,s->stream));
check(hipMemcpyAsync(tile_events,events.data()+offset,n*sizeof(PsfCachedEvent),hipMemcpyHostToDevice,s->stream));
if(!refs.empty())check(hipMemcpyAsync(drefs,refs.data(),refs.size()*sizeof(unsigned),hipMemcpyHostToDevice,s->stream));
if(!tasks.empty())check(hipMemcpyAsync(dtasks,tasks.data(),tasks.size()*sizeof(TileTask),hipMemcpyHostToDevice,s->stream));
check(hipMemcpyAsync(dstarts,starts.data(),starts.size()*sizeof(unsigned),hipMemcpyHostToDevice,s->stream));
upload+=sync_time(s,start);
start=omp_get_wtime();
hipLaunchKernelGGL(prepare_tiles,dim3((n*32+127)/128),dim3(128),0,s->stream,s->slots[0].device,n,s->phase_resolution,s->radius_pixels,s->max_radius_pixels,prepared,bounds);
hipLaunchKernelGGL(prepare_tiles,dim3((n*32+127)/128),dim3(128),0,s->stream,tile_events,n,s->phase_resolution,s->radius_pixels,s->max_radius_pixels,prepared,bounds);
check(hipGetLastError());prepare+=sync_time(s,start);
start=omp_get_wtime();
if(!tasks.empty())hipLaunchKernelGGL(tile_partial,dim3(tasks.size()),dim3(tile*tile),0,s->stream,prepared,bounds,drefs,dtasks,tile,nx,width,height,s->weights,s->phase_resolution,s->radius_pixels,partial,s->hdr);
@@ -225,10 +255,10 @@ int main(int argc,char **argv) {
// Every partial pixel is written by exactly one thread: no memset required.
}
if(hip_psf_sink_finish(s,gpu.data(),message,sizeof message)){fprintf(stderr,"%s\n",message);return 1;}
if(tile) {start=omp_get_wtime();check(hipFree(prepared));check(hipFree(bounds));check(hipFree(drefs));check(hipFree(dtasks));check(hipFree(dstarts));check(hipFree(partial));clear=omp_get_wtime()-start;}
if(requested_tile) {start=omp_get_wtime();check(hipFree(tile_events));check(hipFree(prepared));check(hipFree(bounds));check(hipFree(drefs));check(hipFree(dtasks));check(hipFree(dstarts));check(hipFree(partial));clear=omp_get_wtime()-start;}
const double wall=omp_get_wtime()-replay_start;
HipPsfTiming timing={};hip_psf_sink_get_timing(s,&timing);
if(!tile){upload=timing.upload_seconds;kernel=timing.kernel_seconds;}
upload+=timing.upload_seconds;kernel+=timing.kernel_seconds;
double max_abs=0,max_rel=0;long double sums[3]={},diffs[3]={};bool pass=true;
for(size_t i=0;i<values;++i) {
if(!std::isfinite(cpu[i]) || !std::isfinite(gpu[i]))pass=false;
@@ -238,7 +268,7 @@ int main(int argc,char **argv) {
}
long double ysum=.2126L*sums[0]+.7152L*sums[1]+.0722L*sums[2],ydiff=.2126L*diffs[0]+.7152L*diffs[1]+.0722L*diffs[2];
struct rusage usage;getrusage(RUSAGE_SELF,&usage);
printf("complete_replay=%.9f replay_wall=%.9f bin=%.9f upload=%.9f prepare=%.9f accumulation=%.9f merge=%.9f download=%.9f cleanup=%.9f events_s=%.3f contributions_s=%.3f refs=%zu tasks=%zu scratch_used_peak=%zu scratch_device_reserved=%zu RSS_KiB=%ld max_abs=%.17g max_rel=%.17g flux_R=%.17Lg flux_G=%.17Lg flux_B=%.17Lg flux_Y=%.17Lg\n",create+wall,wall,bin,upload,prepare,kernel,merge,timing.download_seconds,clear,events.size()/wall,work/wall,ref_total,task_total,peak_scratch,tile?162*1024*1024+131072+16384*(sizeof(Prepared)+(size_t)(2*cache.radius_pixels+1)*2*sizeof(int)):0,usage.ru_maxrss,max_abs,max_rel,sums[0]?diffs[0]/sums[0]:0,sums[1]?diffs[1]/sums[1]:0,sums[2]?diffs[2]/sums[2]:0,ysum?ydiff/ysum:0);
printf("complete_replay=%.9f replay_wall=%.9f select=%.9f bin=%.9f upload=%.9f prepare=%.9f accumulation=%.9f merge=%.9f download=%.9f cleanup=%.9f events_s=%.3f contributions_s=%.3f center_tiles=%zu tile_chunks=%zu atomic_chunks=%zu refs=%zu tasks=%zu scratch_used_peak=%zu scratch_device_reserved=%zu RSS_KiB=%ld max_abs=%.17g max_rel=%.17g flux_R=%.17Lg flux_G=%.17Lg flux_B=%.17Lg flux_Y=%.17Lg\n",create+wall,wall,select,bin,upload,prepare,kernel,merge,timing.download_seconds,clear,events.size()/wall,work/wall,center_tiles,tile_chunks,atomic_chunks,ref_total,task_total,peak_scratch,requested_tile?163*1024*1024+131072+16384*(sizeof(Prepared)+(size_t)(2*cache.radius_pixels+1)*2*sizeof(int)):0,usage.ru_maxrss,max_abs,max_rel,sums[0]?diffs[0]/sums[0]:0,sums[1]?diffs[1]/sums[1]:0,sums[2]?diffs[2]/sums[2]:0,ysum?ydiff/ysum:0);
for(int c=0;c<3;++c)if(fabsl(diffs[c])>1e-10L*fmaxl(fabsl(sums[c]),1e-30L))pass=false;
if(fabsl(ydiff)>1e-10L*fmaxl(fabsl(ysum),1e-30L))pass=false;
hip_psf_sink_destroy(s);psf_kernel_cache_destroy(&cache);
+3 -1
View File
@@ -74,7 +74,8 @@ int main(void) {
FrameLensMesh mesh = {0};
double *hdr = calloc((size_t)width * height * 3, sizeof *hdr);
int result = 1;
if (hdr == NULL || spacetime_create_minkowski(&spacetime, 10.0) ||
if (blackbody_backend_init(NULL, 0, NAN, NAN, NULL, stderr) ||
hdr == NULL || spacetime_create_minkowski(&spacetime, 10.0) ||
frame_lens_mesh_build_coarse(&mesh, width, height, 20, 30.0) ||
frame_lens_mesh_trace(&mesh, &spacetime, &observer, &trace))
goto done;
@@ -507,6 +508,7 @@ int main(void) {
done:
frame_lens_mesh_destroy(&mesh);
spacetime_destroy(&spacetime);
blackbody_backend_destroy();
free(hdr);
return result;
}