Skip to content

Port per-ray RNG seeding and SPLIT randstate fix from McCode #2808 (fixes #392) - #394

Merged
g5t merged 1 commit into
mccode-dev:mainfrom
willend:fix-392-per-ray-seeding
Oct 18, 2026
Merged

g5t merged 1 commit into
mccode-dev:mainfrom
willend:fix-392-per-ray-seeding

Conversation

@willend

@willend willend commented Oct 18, 2026

Copy link
Copy Markdown
Contributor

Fixes #392. This ports mccode-dev/McCode#2808 (fix for mccode-dev/McCode#2807) to mccode-antlr's code generator, so the generated C matches McCode's classic cogen.c.in.

Warning

Results change for every KISS-RNG run and for every instrument with SPLIT. They will not be bit-identical to earlier mccode-antlr output. The new output matches McCode's classic generator with #2808.

Changes

  • Per-ray seeding (c_raytrace.py, in both raytrace_all and the funnel loop): srandom(_hash((pidx+1)*(seed+1))) becomes srandom(_hash(_hash(seed) + cloop*gpu_innerloop + pidx)), and the per-batch seed = seed + gpu_innerloop is removed. The old key was a product, so different seeds and different MPI ranks shared rays, and the key wrapped at 2^32 on MSVC.
  • _uid is now cloop*gpu_innerloop + pidx, plus mpi_node_rank * loops*gpu_innerloop under MPI. This makes it unique across GPU batches. On CPU the values are unchanged.
  • randstate[RANDSTATE_LEN] replaces the hard-coded randstate[7] in the particle struct (c_header.py). Unlike what Port per-ray RNG seeding and _uid fix from McCode cogen (mccode-dev/McCode#2807) #392 assumed, mccode-antlr's RNG_ALG block did not define RANDSTATE_LEN; the runtime header that defines it comes after the struct. So this PR adds #define RANDSTATE_LEN 1 / 7 to that block, as cogen.c.in does. Older runtimes (v3.8.7) define the same value, which is a legal identical redefinition.
  • SPLIT bug: each SPLIT child used to restore only randstate[0], so KISS children restarted words 1-6 from the same state and got correlated streams. All RANDSTATE_LEN words are now backed up and restored, with the same loop and variable names as cogen.c.in.

sort_absorb_last() (FUNNEL + SPLIT) lives in the shared runtime mccode-r.c, so mccode-antlr picks it up with the McCode release.

Tested

  • pytest with MCCODEANTLR_MCCODE_POOCH__TAG=v3.8.7 and with latest (v3.9.2), C compile tests included: 1267 passed, 10 skipped (MPI, OpenACC, mcpl, build123d, matplotlib). No test needed changing.
  • Test_RNG_rand01: generated with this branch, compiled with the McCode #2808 runtime (786934b; its mccode-r.c / mccode-r.h.in changes spliced into the embedded runtime), and run with -s 1000 Ncount=1000. The md5 of the non-# lines of rngout.dat is 6c203d69205b0656c1391555e6068c93, the same as McCode's classic generator.
  • Unittest_SPLIT with SPLITS=10, -n 1e5: compiles and runs, PSD_I=1, PSD_N=1e6, as the instrument's example expects.

Not tested

  • MPI and OpenACC/GPU builds (no toolchain here), the funnel loop at runtime, McXtrace, and MSVC.
  • No statistical test of the SPLIT children's streams in mccode-antlr. McCode validated the seeding against a Mersenne Twister referee and with BigCrush.

🤖 Generated with Claude Code

…ixes mccode-dev#392)

Match McCode's classic code generator (mccode-dev/McCode#2808):
- seed each ray with _hash(_hash(seed) + cloop*gpu_innerloop + pidx)
  instead of _hash((pidx+1)*(seed+1)), and drop the per-batch seed bump,
  in raytrace_all and raytrace_all_funnel
- make _uid unique across GPU batches and MPI ranks
- size the particle randstate by RANDSTATE_LEN, defined in the RNG_ALG
  block as cogen.c.in does
- SPLIT backs up and restores all RANDSTATE_LEN words of the RNG state,
  not only word 0

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@willend

willend commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

@g5t parallel to McCode PR mccode-dev/McCode#2808

@g5t g5t left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A spot check looks like this is identical to your changes in McStas 🤞

@g5t
g5t merged commit 6064b61 into mccode-dev:main Oct 18, 2026
14 checks passed
@willend

willend commented Oct 18, 2026

Copy link
Copy Markdown
Contributor Author

@g5t cool, thanks. I will now proceed to merge on the McStas side also.

I have adapted my CI to take mccode-antlr from main, should give us a clearer picture of the state of everything going forward.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Port per-ray RNG seeding and _uid fix from McCode cogen (mccode-dev/McCode#2807)

2 participants