build: put FPSemantics=Precise on the VoxelForge module — the experiment never ran
FPSemantics is a per-module ModuleRules property. It had been set on the VoxelM
GAME module, while every line of density code lives in VoxelForge, which kept
compiling /fp:fast. So the run that supposedly "reproduced the residue under
precise semantics" ran under fast semantics and proves nothing.
Retracting the previous commit's conclusion: /fp:fast is NOT eliminated as the
cause, and the notes claiming AUDIT C9 and OPSTACK-PLAN 2.6 are falsified are
withdrawn with it. Those documents were fine.
My error, and the third of its kind today: I reasoned a confident conclusion from
an unverified premise, one paragraph after writing that the lesson was to
instrument rather than assume. Checking took one grep and I only ran it after
Jahni suggested it.
The line is marked TEMPORARY with removal instructions and a guide to reading the
result. Combined with the WORST-POINT DUMP already committed, one build now
separates the two possibilities cleanly:
454 -> 0 : FP model was the cause; keeping precise then needs a profile,
because it costs the vectorisation T2.a's SIMD work was buying.
454 -> 454 : real logic difference; read the dump.
Either way the line comes back out afterwards.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -451,3 +451,43 @@ in the SDF (lattice edges or `VoxelSDF::Capsule`) or in `SmoothStep01`.
|
|||||||
small unexplained numeric difference, and those do not get smaller when you build on them.
|
small unexplained numeric difference, and those do not get smaller when you build on them.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2026-07-27 — CORRECTION: hypothesis 3 was never tested. My error, not Jahni's.
|
||||||
|
|
||||||
|
**`FPSemantics = FPSemanticsMode.Precise` was set in `Source/VoxelM/VoxelM.Build.cs` — the GAME
|
||||||
|
module.** `FPSemantics` is a `ModuleRules` property, i.e. **per module**. Every line of density code
|
||||||
|
lives in the `VoxelForge` module, which was still compiling `/fp:fast`. The float model never
|
||||||
|
changed for the code under test.
|
||||||
|
|
||||||
|
**So the previous entry is wrong and is retracted:** `/fp:fast` is NOT eliminated. The run that
|
||||||
|
"reproduced the residue under precise semantics" reproduced it under *fast* semantics, which is
|
||||||
|
exactly what it should have done and proves nothing.
|
||||||
|
|
||||||
|
**The failure mode, stated plainly because it is the third time in one day:** I accepted "it's with
|
||||||
|
fpsemantics precise" as fact and reasoned a confident conclusion from it — one paragraph after
|
||||||
|
writing that the lesson was to instrument rather than assume. The check took one `grep` and I did it
|
||||||
|
only after Jahni suggested it. **Verify the premise before reasoning from it, especially when the
|
||||||
|
premise is what makes the conclusion interesting.**
|
||||||
|
|
||||||
|
**Consequently:** the notes in the previous entry saying `AUDIT §C9` and `OPSTACK-PLAN §2.6` are
|
||||||
|
falsified are themselves withdrawn. Those documents' `/fp:fast` explanation is back to *plausible
|
||||||
|
and now genuinely about to be tested*. Nothing in them needs changing yet.
|
||||||
|
|
||||||
|
**What changed:** `FPSemantics = FPSemanticsMode.Precise` added to **`VoxelForge.Build.cs`**, clearly
|
||||||
|
marked as a temporary experiment with removal instructions and a read-the-result guide.
|
||||||
|
|
||||||
|
`VoxelM.Build.cs` can keep or drop its copy — it is harmless either way and irrelevant to this test.
|
||||||
|
|
||||||
|
**One build now answers everything**, because the WORST-POINT DUMP instrumentation is already in:
|
||||||
|
|
||||||
|
| Result | Meaning | Next |
|
||||||
|
|---|---|---|
|
||||||
|
| 454 → **0** | the FP model WAS the cause | remove the line; decide separately whether precise is worth its cost on the hot path (needs a profile) |
|
||||||
|
| 454 → **454** | real logic difference | remove the line; read the dump — identical recovered carve ⇒ fault after the conversion, differing carve ⇒ fault in the SDF or `SmoothStep01` |
|
||||||
|
|
||||||
|
**UNVERIFIED:** everything about this experiment.
|
||||||
|
|
||||||
|
**Next single action:** rebuild, re-run `MazeEquivalence`, read the two numbers. Phase 1 step 3 stays
|
||||||
|
paused.
|
||||||
|
|
||||||
|
---
|
||||||
|
|||||||
@@ -11,6 +11,33 @@ public class VoxelForge : ModuleRules
|
|||||||
// UseExplicitOrSharedPCHs is the modern recommended setting
|
// UseExplicitOrSharedPCHs is the modern recommended setting
|
||||||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// ⚠️ TEMPORARY EXPERIMENT — 2026-07-27. REMOVE THIS LINE WHEN THE ANSWER IS IN.
|
||||||
|
// ============================================================================
|
||||||
|
// Testing whether the ~1 ULP residue between GetMazeDensity and its operator-stack
|
||||||
|
// port (VoxelForge.OpStack.MazeEquivalence: 454 of 20000 samples, 0 crossing the
|
||||||
|
// isosurface) is caused by the compiler being allowed to reassociate identical
|
||||||
|
// source differently per translation unit.
|
||||||
|
//
|
||||||
|
// FPSemantics is a PER-MODULE property. Setting it on the VoxelM game module does
|
||||||
|
// NOT affect this one — every line of density code lives in VoxelForge, so the
|
||||||
|
// switch has to be here to mean anything. (That mistake already cost one build and
|
||||||
|
// one wrong conclusion.)
|
||||||
|
//
|
||||||
|
// UnrealBuildTool's Windows default is /fp:fast ("Default is imprecise FP
|
||||||
|
// semantics", VCToolChain.cs); every Clang target defaults to precise instead.
|
||||||
|
//
|
||||||
|
// READ THE RESULT LIKE THIS:
|
||||||
|
// 454 -> 0 : the FP model WAS the cause. Then decide separately whether to keep
|
||||||
|
// precise (it costs vectorisation on the density hot path — the thing
|
||||||
|
// T2.a's SIMD noise work was buying — for an unmeasured amount).
|
||||||
|
// 454 -> 454 : the FP model is NOT the cause and the difference is real logic.
|
||||||
|
// Read the WORST-POINT DUMP the test now prints.
|
||||||
|
//
|
||||||
|
// EITHER WAY THIS LINE COMES BACK OUT once measured. Keeping /fp:precise on the hot
|
||||||
|
// path is a decision that needs a profile, not a leftover from a diagnostic.
|
||||||
|
FPSemantics = FPSemanticsMode.Precise;
|
||||||
|
|
||||||
// Modules we depend on:
|
// Modules we depend on:
|
||||||
// - Core: Basic types (TArray, FString, etc.)
|
// - Core: Basic types (TArray, FString, etc.)
|
||||||
// - CoreUObject: UObject system (UCLASS, UPROPERTY, etc.)
|
// - CoreUObject: UObject system (UCLASS, UPROPERTY, etc.)
|
||||||
|
|||||||
Reference in New Issue
Block a user