@@ -341,7 +341,7 @@ std::vector<Case> RegisterCases()
341341 };
342342 // Tag the just-registered case as a known, documented nondeterminism exception
343343 // (see Case::knownIssue): reported with its magnitude but not a gate failure.
344- auto markKnown = [&cases](const std::string& reason) {
344+ [[maybe_unused]] auto markKnown = [&cases](const std::string& reason) {
345345 cases.back ().knownIssue = true ;
346346 cases.back ().knownIssueReason = reason;
347347 };
@@ -523,22 +523,17 @@ std::vector<Case> RegisterCases()
523523 f->SetInputData (in.ugrid );
524524 return vtkSmartPointer<vtkAlgorithm>(f);
525525 });
526- add (
527- " vtkLengthDistribution" , " Filters/Statistics" , Risk::Reduce,
528- [](const Inputs& in) {
529- vtkNew<vtkLengthDistribution> f;
530- f->SetInputData (in.ugrid );
531- return vtkSmartPointer<vtkAlgorithm>(f);
532- },
533- /* orderRelaxed=*/ true );
534- // NOT a threading defect: vtkLengthDistribution draws its samples from a
535- // vtkReservoirSampler seeded from std::random_device on every call
536- // (Common/Math/vtkReservoirSampler.cxx), and for each sampled cell it randomly
537- // picks which 2 vertices to measure. Its output is therefore nondeterministic
538- // even SINGLE-THREADED -- the serial reference is itself random -- so a
539- // parallel-vs-serial gate cannot apply. Excluded from the pass/fail count.
540- markKnown (" unseeded RNG (vtkReservoirSampler <- std::random_device); "
541- " nondeterministic even single-threaded, not a threading defect" );
526+ add (" vtkLengthDistribution" , " Filters/Statistics" , Risk::Reduce, [](const Inputs& in) {
527+ vtkNew<vtkLengthDistribution> f;
528+ f->SetInputData (in.ugrid );
529+ return vtkSmartPointer<vtkAlgorithm>(f);
530+ });
531+ // Now GATED byte-exact: vtkLengthDistribution used to seed its
532+ // vtkReservoirSampler from std::random_device on every call, making the
533+ // output nondeterministic even single-threaded. The sampler is now seedable
534+ // and the filter seeds it (default Seed=0), so both the sampled cell subset
535+ // and the per-cell vertex picks are deterministic; each sample writes its own
536+ // table row, so serial and threaded output are byte-identical.
542537 add (" vtkSelectEnclosedPoints" , " Filters/Modeling" , Risk::Reduce, [](const Inputs& in) {
543538 vtkNew<vtkSelectEnclosedPoints> f;
544539 f->SetInputData (in.cloud );
@@ -650,15 +645,16 @@ std::vector<Case> RegisterCases()
650645 f->SetClipFunction (plane (1 , 1 , 0 ));
651646 return vtkSmartPointer<vtkAlgorithm>(f);
652647 });
653- // Expected byte-exact: the GEOMETRY of the default OUTPUT_STYLE_BOUNDARY path is
648+ // GATED byte-exact: the GEOMETRY of the default OUTPUT_STYLE_BOUNDARY path is
654649 // deterministic (integer voxel-center coords, serial prefix-sum offsets,
655- // per-thread label lookup, Jacobi double-buffered smoothing) -- and indeed the
656- // validator measures points + connectivity byte-identical. HOWEVER the
657- // "BoundaryLabels" cell-data comes out as garbage (~9e8, far outside the 0..3
658- // label range) that changes every run -- an uninitialized/wild read that is
659- // nondeterministic even SINGLE-THREADED. The serial-vs-serial pre-check catches
660- // this and reports it as SERIAL-UNSTABLE (a real defect, but orthogonal to
661- // threading), so it is not charged against the parallel-vs-serial gate.
650+ // per-thread label lookup, Jacobi double-buffered smoothing) -- points +
651+ // connectivity are byte-identical. The "BoundaryLabels" cell-data used to come
652+ // out as garbage (~9e8, far outside the 0..3 label range) that changed every
653+ // run: the quad count is a padded upper bound, so an isolated boundary case
654+ // could reserve a scalar tuple GenerateQuads never wrote, and SetNumberOfTuples
655+ // left that storage uninitialized. The scalar buffer is now zero-initialized at
656+ // allocation, so any padding tuple is deterministic and every emitted quad
657+ // overwrites its own -- BoundaryLabels is now byte-identical serial-vs-parallel.
662658 add (" vtkSurfaceNets3D" , " Filters/Core" , Risk::Iso, [](const Inputs& in) {
663659 vtkNew<vtkSurfaceNets3D> f;
664660 f->SetInputData (in.labelImage );
0 commit comments