Menu ▾ ▴

#25 PractRand 0.96: folded FPF/64 results depend on reporting checkpoints

v1.0_(example)
open
nobody
None
5
2026-10-27
2026-10-27
IgneousRed
No

Changing only the reporting schedule changes folded FPF/64 statistics at the same tested byte count, using the same RNG and seed.

Reproduced on macOS arm64 (Apple M2), using single-threaded CPU testing:

RNG_test sfc16 -seed 0 -te 1 -tf 2 -tlmin 10 -tlmax 26 -a -tlmaxonly -singlethreaded > early.txt
RNG_test sfc16 -seed 0 -te 1 -tf 2 -tlmin 24 -tlmax 26 -a -tlmaxonly -singlethreaded > late.txt

The runs begin reporting at 1 KiB and 16 MiB respectively. Compare their shared 16, 32, and 64 MiB checkpoints. Statistics at each shared checkpoint should be identical.

For example, at 16 MiB:

early.txt:
[Low1/8]FPF/64:(0,14-5)  R= -0.3  p = 0.569  normal

late.txt:
[Low1/8]FPF/64:(0,14-5)  R= +0.4  p = 0.397  normal

Across the three shared checkpoints, 336 of 4,600 result records differ, all folded FPF/64 results. Diagnostic logging confirms differences in unrounded raw statistics, processed values, p-values, and suspicion.

The cause appears to be the interaction between transform flushing and FPF sampling. Transform_Baseclass::get_results() calls flush(true), so requesting a report changes the input-call boundaries seen by child tests. In FPF::test_blocks(), the large-footprint, long-stride path initializes its 32-bit-word loop with:

for (long i = blocks_tested ? -1 : 0; i < max; i += stride32)

For FPF/64, stride32 is 2. Starting at word 0 on the first call and word −1 on subsequent calls changes the sampling phase. Changing how much transformed data reaches the first call therefore changes which windows are counted.

As a diagnostic control, deriving the starting offset from the cumulative stream position made all 4,600 shared records identical between these reporting schedules.

Discussion


Log in to post a comment.