core: stamp passage route slabs into the tile cache (L125, evaluator v225)

Conservative route slabs with an outside sentinel, tight expanded segment bounds; DensityGrid exact fallbacks
479k -> 0 per run. Near-ready 2-14% faster than L119, still +4.7..+10.2% vs L109; whole view within -0.5..+8%.
Same look (floor offset 7.884 mm, captures checked), seam audit bit-identical, fast tier + walk audits,
Clang/GCC W1/W8/W12 determinism green. BVH and 25 cm tolerance trials rejected. Not for merge yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
This commit is contained in:
Fr0zkaandClaude Opus 5.5 committed 2026-10-30 14:43:31 +01:00
1 parent 103fa75e1c
commit 4111b967bd
40 files changed
+2748 -28

No files matched your search

@@ -155,11 +155,27 @@ namespace VoxelForgeCore
std::uint64_t passageSweepDetailShellSamples = 0; std::uint64_t passageSweepDetailShellSamples = 0;
std::uint64_t passageSweepGridSamples = 0; std::uint64_t passageSweepGridSamples = 0;
std::uint64_t passageSweepNoInfluenceGridSamples = 0; std::uint64_t passageSweepNoInfluenceGridSamples = 0;
std::uint64_t passageSweepTouchedSamples = 0;
std::uint64_t passageSweepStampedOutsideSamples = 0;
std::uint64_t passageSweepCacheValidSamples = 0;
std::uint64_t passageSweepCacheValidUniqueSamples = 0;
std::uint64_t passageSweepUniqueTouchedSamples = 0;
std::uint64_t passageSweepBodyBandSamples = 0;
std::uint64_t passageSweepShellBandSamples = 0;
std::uint64_t passageSweepUniqueBandSamples = 0;
std::uint64_t passageSweepOverlapPairs = 0;
std::uint64_t passageSweepContributingPairs = 0;
std::uint64_t passageSweepCrossPassageOverlaps = 0;
std::uint64_t passageSweepFloorProfileCalls = 0;
std::uint64_t passageSweepAllocatedBytes = 0;
std::uint64_t passageSweepPrepareScratchBytes = 0;
std::uint64_t passageSweepLookups = 0; std::uint64_t passageSweepLookups = 0;
std::uint64_t passageSweepCacheHits = 0; std::uint64_t passageSweepCacheHits = 0;
std::uint64_t passageSweepBaseInfluenceHits = 0; std::uint64_t passageSweepBaseInfluenceHits = 0;
std::uint64_t passageSweepOutOfInfluenceHits = 0; std::uint64_t passageSweepOutOfInfluenceHits = 0;
std::uint64_t passageSweepMissingSamples = 0; std::uint64_t passageSweepMissingSamples = 0;
std::uint64_t passageSweepOffGridMisses = 0;
std::uint64_t passageSweepUnpreparedMisses = 0;
std::array<std::uint64_t,12> passageSweepMissingLookupsByCaller{}; std::array<std::uint64_t,12> passageSweepMissingLookupsByCaller{};
std::array<std::uint64_t,12> passageSweepExactRouteFallbacksByCaller{}; std::array<std::uint64_t,12> passageSweepExactRouteFallbacksByCaller{};
std::array<std::uint64_t,12> passageSweepFeatureBoundSkipsByCaller{}; std::array<std::uint64_t,12> passageSweepFeatureBoundSkipsByCaller{};
@@ -478,7 +494,7 @@ namespace VoxelForgeCore
// Version 223 projects the floor onto one continuous arc-length profile and groups // Version 223 projects the floor onto one continuous arc-length profile and groups
// dense passage samples into coarse tile candidates. Version 224 keeps the same // dense passage samples into coarse tile candidates. Version 224 keeps the same
// continuous floor while relaxing the spline chord tolerance and bounding shell work. // continuous floor while relaxing the spline chord tolerance and bounding shell work.
inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 224; inline constexpr std::uint32_t WorldAssemblyEvaluatorVersion = 225;
enum class FieldChannel : std::uint32_t enum class FieldChannel : std::uint32_t
{ {
+143 -21
View File
@@ -272,7 +272,7 @@ public:
std::uint32_t segmentIndex=std::numeric_limits<std::uint32_t>::max(); std::uint32_t segmentIndex=std::numeric_limits<std::uint32_t>::max();
std::uint32_t floorSegmentIndex=std::numeric_limits<std::uint32_t>::max(); std::uint32_t floorSegmentIndex=std::numeric_limits<std::uint32_t>::max();
float wallRelief=0.0f; float wallRelief=0.0f;
bool valid=false,hasWallRelief=false; bool valid=false,hasWallRelief=false,hasExactContribution=false;
}; };
struct FPassageTileSweepData struct FPassageTileSweepData
{ {
@@ -288,7 +288,8 @@ public:
std::vector<std::int32_t> passageToSweep; std::vector<std::int32_t> passageToSweep;
std::vector<FPassageSamples> passages; std::vector<FPassageSamples> passages;
std::atomic<std::uint64_t> lookups{0},cacheHits{0},baseInfluenceHits{0}, std::atomic<std::uint64_t> lookups{0},cacheHits{0},baseInfluenceHits{0},
outOfInfluenceHits{0},missingSamples{0}; outOfInfluenceHits{0},missingSamples{0},offGridMisses{0},
unpreparedMisses{0};
std::array<std::atomic<std::uint64_t>,PassageDensityQueryCallerCount> std::array<std::atomic<std::uint64_t>,PassageDensityQueryCallerCount>
missingLookupsByCaller{},exactRouteFallbacksByCaller{}, missingLookupsByCaller{},exactRouteFallbacksByCaller{},
featureBoundSkipsByCaller{},tileFreeSkipsByCaller{}, featureBoundSkipsByCaller{},tileFreeSkipsByCaller{},
@@ -389,6 +390,10 @@ public:
passageSweepData_->outOfInfluenceHits.load(std::memory_order_relaxed); passageSweepData_->outOfInfluenceHits.load(std::memory_order_relaxed);
profileStats_->passageSweepMissingSamples=passageSweepData_->missingSamples.load( profileStats_->passageSweepMissingSamples=passageSweepData_->missingSamples.load(
std::memory_order_relaxed); std::memory_order_relaxed);
profileStats_->passageSweepOffGridMisses=passageSweepData_->offGridMisses.load(
std::memory_order_relaxed);
profileStats_->passageSweepUnpreparedMisses=
passageSweepData_->unpreparedMisses.load(std::memory_order_relaxed);
for(std::size_t caller=0;caller<PassageDensityQueryCallerCount;++caller) for(std::size_t caller=0;caller<PassageDensityQueryCallerCount;++caller)
{ {
profileStats_->passageSweepMissingLookupsByCaller[caller]= profileStats_->passageSweepMissingLookupsByCaller[caller]=
@@ -11459,10 +11464,17 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
?shape_->ResolvedLayout->coreVoxelSizeMicrometres:250000); ?shape_->ResolvedLayout->coreVoxelSizeMicrometres:250000);
sweep->passageToSweep.assign(passageRouteSegments_.size(),-1); sweep->passageToSweep.assign(passageRouteSegments_.size(),-1);
std::vector<std::uint8_t> anyPassageInfluence(gridSampleCount,0); std::vector<std::uint8_t> anyPassageInfluence(gridSampleCount,0);
std::vector<std::uint8_t> anyPreparedSample(profile?gridSampleCount:0,0);
std::vector<std::uint8_t> anyCacheValidSample(profile?gridSampleCount:0,0);
std::vector<std::uint8_t> anyExactBandSample(profile?gridSampleCount:0,0);
std::uint64_t preparedSampleCount=0,stampedOutsideSampleCount=0,
cacheValidSampleCount=0,contributingPairCount=0,
bodyBandSampleCount=0,shellBandSampleCount=0;
const double qPerMetre=static_cast<double>(Q)*1000000.0/ const double qPerMetre=static_cast<double>(Q)*1000000.0/
std::max<std::uint32_t>(1,shape_->ResolvedLayout std::max<std::uint32_t>(1,shape_->ResolvedLayout
?shape_->ResolvedLayout->coreVoxelSizeMicrometres:250000); ?shape_->ResolvedLayout->coreVoxelSizeMicrometres:250000);
const double shellThickness=0.75*qPerMetre; const double shellThickness=0.75*qPerMetre;
const double stampedOutsideDistance=sweep->influenceSubvoxels+1.0;
constexpr double MouthShellBlendMetres=5.0; constexpr double MouthShellBlendMetres=5.0;
const double wallReliefShell=0.41*qPerMetre; const double wallReliefShell=0.41*qPerMetre;
const double floorDetailShell=1.0*qPerMetre; const double floorDetailShell=1.0*qPerMetre;
@@ -11507,28 +11519,73 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
candidate.sweepMaximumSubvoxels[axis],first[axis],last[axis]); candidate.sweepMaximumSubvoxels[axis],first[axis],last[axis]);
if(first[0]>last[0]||first[1]>last[1]||first[2]>last[2])continue; if(first[0]>last[0]||first[1]>last[1]||first[2]>last[2])continue;
// Stamp the conservative route feature slab once. Segment geometry below
// visits its own tight expanded bounds, avoiding the old feature-box x
// segment-count scan.
for(std::int32_t gz=first[2];gz<=last[2];++gz) for(std::int32_t gz=first[2];gz<=last[2];++gz)
{ {
for(std::int32_t gy=first[1];gy<=last[1];++gy) for(std::int32_t gy=first[1];gy<=last[1];++gy)
for(std::int32_t gx=first[0];gx<=last[0];++gx) for(std::int32_t gx=first[0];gx<=last[0];++gx)
{ {
const double qz=static_cast<double>(sweep->gridMinimumSubvoxels[2]
+static_cast<std::int64_t>(gz)*sweep->stepSubvoxels);
const std::size_t sampleIndex=(static_cast<std::size_t>(gz)
*static_cast<std::size_t>(sweep->dimension)+static_cast<std::size_t>(gy))
*static_cast<std::size_t>(sweep->dimension)+static_cast<std::size_t>(gx);
auto& sample=passageSamples.samples[sampleIndex];
// Every grid sample inside a conservative feature slab has a known
// outside value unless a segment contributes within the prepared
// influence. This makes slab gaps cheap rock instead of cache misses.
if(!sample.valid)
{
sample.signedDistance=stampedOutsideDistance;
sample.shellSignedDistance=stampedOutsideDistance;
sample.roundSignedDistance=stampedOutsideDistance;
sample.centerZSubvoxels=qz;
sample.floorCenterZSubvoxels=qz;
sample.radiusSubvoxels=0.0;
sample.floorDepthSubvoxels=0.0;
sample.floorCenterDistanceSq=std::numeric_limits<double>::infinity();
sample.t=0.0;
sample.floorT=0.0;
sample.segmentIndex=static_cast<std::uint32_t>(candidate.segmentIndex);
sample.floorSegmentIndex=static_cast<std::uint32_t>(candidate.segmentIndex);
sample.wallRelief=0.0f;
sample.valid=true;
sample.hasWallRelief=false;
sample.hasExactContribution=false;
}
}
}
for(std::size_t segmentIndex=candidate.segmentIndex;
segmentIndex<segmentEndIndex;++segmentIndex)
{
const auto& segment=segments[segmentIndex];
if(segment.lengthSq<=0.0)continue;
std::array<std::int32_t,3> segmentFirst{},segmentLast{};
for(std::size_t axis=0;axis<3;++axis)
gridRange(axis,segment.sweepMinimumSubvoxels[axis],
segment.sweepMaximumSubvoxels[axis],
segmentFirst[axis],segmentLast[axis]);
if(segmentFirst[0]>segmentLast[0]
||segmentFirst[1]>segmentLast[1]
||segmentFirst[2]>segmentLast[2])continue;
for(std::int32_t gz=segmentFirst[2];gz<=segmentLast[2];++gz)
{
for(std::int32_t gy=segmentFirst[1];gy<=segmentLast[1];++gy)
for(std::int32_t gx=segmentFirst[0];gx<=segmentLast[0];++gx)
{
const double qx=static_cast<double>(sweep->gridMinimumSubvoxels[0] const double qx=static_cast<double>(sweep->gridMinimumSubvoxels[0]
+static_cast<std::int64_t>(gx)*sweep->stepSubvoxels); +static_cast<std::int64_t>(gx)*sweep->stepSubvoxels);
const double qy=static_cast<double>(sweep->gridMinimumSubvoxels[1] const double qy=static_cast<double>(sweep->gridMinimumSubvoxels[1]
+static_cast<std::int64_t>(gy)*sweep->stepSubvoxels); +static_cast<std::int64_t>(gy)*sweep->stepSubvoxels);
const double qz=static_cast<double>(sweep->gridMinimumSubvoxels[2] const double qz=static_cast<double>(sweep->gridMinimumSubvoxels[2]
+static_cast<std::int64_t>(gz)*sweep->stepSubvoxels); +static_cast<std::int64_t>(gz)*sweep->stepSubvoxels);
for(std::size_t segmentIndex=candidate.segmentIndex; const std::size_t sampleIndex=(static_cast<std::size_t>(gz)
segmentIndex<segmentEndIndex;++segmentIndex) *static_cast<std::size_t>(sweep->dimension)+static_cast<std::size_t>(gy))
{ *static_cast<std::size_t>(sweep->dimension)+static_cast<std::size_t>(gx);
const auto& segment=segments[segmentIndex]; auto& sample=passageSamples.samples[sampleIndex];
if(segment.lengthSq<=0.0
||qx<segment.sweepMinimumSubvoxels[0]
||qx>segment.sweepMaximumSubvoxels[0]
||qy<segment.sweepMinimumSubvoxels[1]
||qy>segment.sweepMaximumSubvoxels[1]
||qz<segment.sweepMinimumSubvoxels[2]
||qz>segment.sweepMaximumSubvoxels[2])continue;
const double projectionXY=(qx-segment.a[0])*segment.delta[0] const double projectionXY=(qx-segment.a[0])*segment.delta[0]
+(qy-segment.a[1])*segment.delta[1]; +(qy-segment.a[1])*segment.delta[1];
const double t=std::clamp((projectionXY const double t=std::clamp((projectionXY
@@ -11540,6 +11597,8 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
const double ex=qx-cx,ey=qy-cy,ez=qz-cz; const double ex=qx-cx,ey=qy-cy,ez=qz-cz;
const double signedDistance=FStandaloneShapeWorld::DeterministicSqrt( const double signedDistance=FStandaloneShapeWorld::DeterministicSqrt(
ex*ex+ey*ey+ez*ez)-radius; ex*ex+ey*ey+ez*ez)-radius;
if(profile&&signedDistance<sweep->influenceSubvoxels+1.0)
++contributingPairCount;
const double floorT=segment.horizontalLengthSq>1.0e-12 const double floorT=segment.horizontalLengthSq>1.0e-12
?projectionXY/segment.horizontalLengthSq:t; ?projectionXY/segment.horizontalLengthSq:t;
const double floorTClamped=std::clamp(floorT,0.0,1.0); const double floorTClamped=std::clamp(floorT,0.0,1.0);
@@ -11557,10 +11616,6 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
{ {
if(profile)++profileStats_->passageSweepOutsideInfluencePairs; if(profile)++profileStats_->passageSweepOutsideInfluencePairs;
} }
const std::size_t sampleIndex=(static_cast<std::size_t>(gz)
*static_cast<std::size_t>(sweep->dimension)+static_cast<std::size_t>(gy))
*static_cast<std::size_t>(sweep->dimension)+static_cast<std::size_t>(gx);
auto& sample=passageSamples.samples[sampleIndex];
if(floorCenterDistanceSq<sample.floorCenterDistanceSq if(floorCenterDistanceSq<sample.floorCenterDistanceSq
||(floorCenterDistanceSq==sample.floorCenterDistanceSq ||(floorCenterDistanceSq==sample.floorCenterDistanceSq
&&segmentIndex<sample.floorSegmentIndex)) &&segmentIndex<sample.floorSegmentIndex))
@@ -11637,9 +11692,11 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
++profileStats_->passageSweepShellSupportSkips; ++profileStats_->passageSweepShellSupportSkips;
// Rank the tube body by round SDF. Its floor plane is selected // Rank the tube body by round SDF. Its floor plane is selected
// independently above from the nearest centerline position. // independently above from the nearest centerline position.
if(!sample.valid||signedDistance<sample.roundSignedDistance if(signedDistance<stampedOutsideDistance
||(signedDistance==sample.roundSignedDistance &&(!sample.hasExactContribution
&&segmentIndex<sample.segmentIndex)) ||signedDistance<sample.roundSignedDistance
||(signedDistance==sample.roundSignedDistance
&&segmentIndex<sample.segmentIndex)))
{ {
sample.roundSignedDistance=signedDistance; sample.roundSignedDistance=signedDistance;
sample.centerZSubvoxels=cz; sample.centerZSubvoxels=cz;
@@ -11648,9 +11705,10 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
sample.segmentIndex=static_cast<std::uint32_t>(segmentIndex); sample.segmentIndex=static_cast<std::uint32_t>(segmentIndex);
sample.valid=true; sample.valid=true;
sample.hasWallRelief=false; sample.hasWallRelief=false;
sample.hasExactContribution=true;
if(profile)++profileStats_->passageSweepMinimumUpdates; if(profile)++profileStats_->passageSweepMinimumUpdates;
} }
} }
} }
} }
} }
@@ -11665,6 +11723,23 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
{ {
auto& sample=passageSamples.samples[sampleIndex]; auto& sample=passageSamples.samples[sampleIndex];
if(!sample.valid)continue; if(!sample.valid)continue;
if(profile)
{
++cacheValidSampleCount;
anyCacheValidSample[sampleIndex]=1;
}
if(!sample.hasExactContribution)
{
if(profile)++stampedOutsideSampleCount;
sample.signedDistance=stampedOutsideDistance;
sample.shellSignedDistance=stampedOutsideDistance;
continue;
}
if(profile)
{
++preparedSampleCount;
anyPreparedSample[sampleIndex]=1;
}
const std::int32_t gx=static_cast<std::int32_t>(sampleIndex const std::int32_t gx=static_cast<std::int32_t>(sampleIndex
%static_cast<std::size_t>(sweep->dimension)); %static_cast<std::size_t>(sweep->dimension));
const std::int32_t gy=static_cast<std::int32_t>((sampleIndex const std::int32_t gy=static_cast<std::int32_t>((sampleIndex
@@ -11682,6 +11757,17 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
sample.signedDistance=FStandaloneShapeWorld::PassageFlatBottomDistance( sample.signedDistance=FStandaloneShapeWorld::PassageFlatBottomDistance(
static_cast<float>(sample.roundSignedDistance), static_cast<float>(sample.roundSignedDistance),
sample.floorCenterZSubvoxels,qz,sample.floorDepthSubvoxels,qPerMetre); sample.floorCenterZSubvoxels,qz,sample.floorDepthSubvoxels,qPerMetre);
if(profile&&std::abs(sample.signedDistance)<=sweep->stepSubvoxels)
{
++bodyBandSampleCount;
anyExactBandSample[sampleIndex]=1;
}
if(profile&&std::isfinite(sample.shellSignedDistance)
&&std::abs(sample.shellSignedDistance)<=sweep->stepSubvoxels)
{
++shellBandSampleCount;
anyExactBandSample[sampleIndex]=1;
}
const double radius=sample.radiusSubvoxels; const double radius=sample.radiusSubvoxels;
const double centerZ=sample.centerZSubvoxels; const double centerZ=sample.centerZSubvoxels;
if(sample.signedDistance<=sweep->influenceSubvoxels) if(sample.signedDistance<=sweep->influenceSubvoxels)
@@ -11710,6 +11796,38 @@ inline void FStandaloneShapeWorld::FScopedPassageTileQueries::prepareSweptTubeBa
profileStats_->passageSweepNoInfluenceGridSamples= profileStats_->passageSweepNoInfluenceGridSamples=
static_cast<std::uint64_t>(std::count(anyPassageInfluence.begin(), static_cast<std::uint64_t>(std::count(anyPassageInfluence.begin(),
anyPassageInfluence.end(),static_cast<std::uint8_t>(0))); anyPassageInfluence.end(),static_cast<std::uint8_t>(0)));
profileStats_->passageSweepTouchedSamples=preparedSampleCount;
profileStats_->passageSweepStampedOutsideSamples=stampedOutsideSampleCount;
profileStats_->passageSweepCacheValidSamples=cacheValidSampleCount;
profileStats_->passageSweepCacheValidUniqueSamples=
static_cast<std::uint64_t>(std::count(anyCacheValidSample.begin(),
anyCacheValidSample.end(),static_cast<std::uint8_t>(1)));
profileStats_->passageSweepUniqueTouchedSamples=
static_cast<std::uint64_t>(std::count(anyPreparedSample.begin(),
anyPreparedSample.end(),static_cast<std::uint8_t>(1)));
profileStats_->passageSweepBodyBandSamples=bodyBandSampleCount;
profileStats_->passageSweepShellBandSamples=shellBandSampleCount;
profileStats_->passageSweepUniqueBandSamples=
static_cast<std::uint64_t>(std::count(anyExactBandSample.begin(),
anyExactBandSample.end(),static_cast<std::uint8_t>(1)));
profileStats_->passageSweepContributingPairs=contributingPairCount;
profileStats_->passageSweepOverlapPairs=contributingPairCount
>=preparedSampleCount
?contributingPairCount-preparedSampleCount:0;
profileStats_->passageSweepCrossPassageOverlaps=preparedSampleCount
>=profileStats_->passageSweepUniqueTouchedSamples
?preparedSampleCount-profileStats_->passageSweepUniqueTouchedSamples:0;
profileStats_->passageSweepFloorProfileCalls=
profileStats_->passageSweepSegmentSamplePairs;
std::uint64_t allocatedBytes=sizeof(*sweep)
+sweep->passageToSweep.capacity()*sizeof(std::int32_t)
+sweep->passages.capacity()*sizeof(FPassageTileSweepData::FPassageSamples);
for(const auto& passageSamples:sweep->passages)
allocatedBytes+=passageSamples.samples.capacity()
*sizeof(FPassageSweepSample);
profileStats_->passageSweepAllocatedBytes=allocatedBytes;
profileStats_->passageSweepPrepareScratchBytes=gridSampleCount
*(sizeof(std::uint8_t)*4);
profileStats_->passageSweepPrepareNanoseconds+=static_cast<std::uint64_t>( profileStats_->passageSweepPrepareNanoseconds+=static_cast<std::uint64_t>(
std::max<std::int64_t>(0,std::chrono::duration_cast<std::chrono::nanoseconds>( std::max<std::int64_t>(0,std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::steady_clock::now()-prepareStart).count())); std::chrono::steady_clock::now()-prepareStart).count()));
@@ -11735,12 +11853,14 @@ FStandaloneShapeWorld::FScopedPassageTileQueries::sweptSample(
}; };
if(passageIndex>=sweep->passageToSweep.size()) if(passageIndex>=sweep->passageToSweep.size())
{ {
sweep->unpreparedMisses.fetch_add(1,std::memory_order_relaxed);
recordMissing(); recordMissing();
return nullptr; return nullptr;
} }
const std::int32_t passageSweepIndex=sweep->passageToSweep[passageIndex]; const std::int32_t passageSweepIndex=sweep->passageToSweep[passageIndex];
if(passageSweepIndex<0||static_cast<std::size_t>(passageSweepIndex)>=sweep->passages.size()) if(passageSweepIndex<0||static_cast<std::size_t>(passageSweepIndex)>=sweep->passages.size())
{ {
sweep->unpreparedMisses.fetch_add(1,std::memory_order_relaxed);
recordMissing(); recordMissing();
return nullptr; return nullptr;
} }
@@ -11754,6 +11874,7 @@ FStandaloneShapeWorld::FScopedPassageTileQueries::sweptSample(
if(rounded<0||rounded>=sweep->dimension if(rounded<0||rounded>=sweep->dimension
||std::abs(coordinate-static_cast<double>(rounded))>1.0e-5) ||std::abs(coordinate-static_cast<double>(rounded))>1.0e-5)
{ {
sweep->offGridMisses.fetch_add(1,std::memory_order_relaxed);
recordMissing(); recordMissing();
return nullptr; return nullptr;
} }
@@ -11765,6 +11886,7 @@ FStandaloneShapeWorld::FScopedPassageTileQueries::sweptSample(
const auto& samples=sweep->passages[static_cast<std::size_t>(passageSweepIndex)].samples; const auto& samples=sweep->passages[static_cast<std::size_t>(passageSweepIndex)].samples;
if(index>=samples.size()||!samples[index].valid) if(index>=samples.size()||!samples[index].valid)
{ {
sweep->unpreparedMisses.fetch_add(1,std::memory_order_relaxed);
recordMissing(); recordMissing();
return nullptr; return nullptr;
} }
@@ -0,0 +1,46 @@
# Linux125 — passage slab stamping
## Result
**No-go for the L109 speed bar.** The v225 stamp candidate keeps the L119 10 cm curve tolerance and smooth half-pipe look. It is 4.72–10.19% slower than L109 for near-ready LOD0–2, though 1.96–14.23% faster than L119. Whole-view readiness ranges from 0.47% faster to 8.04% slower than L109.
The BVH trial was rejected: preparation was 5–6× slower. The final design stamps conservative route slabs with an outside sentinel and evaluates segment geometry over tight expanded bounds. The separate 25 cm tolerance trial was also rejected: it remained 11–23% slower than L109 and its maximum floor-root offset was 8.601 mm.
## Count first
The tile cache already stores prepared segment contributions. At LOD0, each stratum still evaluates 3.11–8.49M segment/sample pairs, while the exact one-sample band is 5.16–7.41% of grid samples and pair overlap is 67–73%. Stamping cuts exact fallback work, but preparation remains dominated by segment/sample work.
| Stratum | LOD0 pairs (M) | Exact band | Pair overlap L119 → stamp | Prepare ms L119 → stamp | Exact fallbacks (k) L119 → stamp | Max tile cache (MiB) | Process RSS MiB L119 → stamp |
| --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| S0 | 3.11 | 5.16% | 67.3 → 67.2% | 246 → 272 | 426 → 73 | 3.93 | 724 → 723 |
| S1 | 8.49 | 6.53% | 72.6 → 72.0% | 620 → 700 | 912 → 172 | 7.85 | 580 → 583 |
| S2 | 8.30 | 7.41% | 72.6 → 72.0% | 606 → 621 | 892 → 180 | 7.85 | 643 → 641 |
| S3 | 5.27 | 5.35% | 67.7 → 67.6% | 443 → 463 | 198 → 73 | 3.93 | 657 → 667 |
Across strata, mean preparation time by LOD was **LOD0 479→514 ms, LOD1 121→130 ms, LOD2 3.8→4.1 ms**. Exact-band fractions were 6.18%, 4.14%, and 6.16%; pair overlap was about 71%, 67%, and 68% respectively. Per-caller LOD0 exact fallbacks show the main gain: DensityGrid fell from 479k calls per run on average to zero. Remaining callers account for about 124k calls per run, led by skirt refinement (75k), midpoint correction (19k), and skirt extrusion (18k). Off-grid misses remain on the canonical exact path: 96–235k per stratum at LOD0.
## Timing
Five interleaved L80 measurements per cell, one warmup per version, all four strata. The final quiet-machine gate was 1-minute load 0.63 and 98.8% CPU idle. Values are medians in seconds; near-ready is LOD0–2.
| Stratum | Workers | Near L109 / L119 / v225 | Whole view L109 / L119 / v225 |
| --- | ---: | ---: | ---: |
| S0 | 8 | 0.745 / 0.850 / 0.780 | 1.694 / 1.762 / 1.686 |
| S0 | 12 | 0.767 / 0.878 / 0.807 | 1.680 / 1.783 / 1.714 |
| S1 | 8 | 0.921 / 1.144 / 0.981 | 1.771 / 2.017 / 1.855 |
| S1 | 12 | 0.887 / 1.082 / 0.962 | 1.711 / 1.912 / 1.794 |
| S2 | 8 | 0.973 / 1.165 / 1.025 | 1.811 / 2.020 / 1.861 |
| S2 | 12 | 0.905 / 1.070 / 0.965 | 1.689 / 1.862 / 1.758 |
| S3 | 8 | 0.809 / 0.943 / 0.879 | 1.667 / 1.871 / 1.801 |
| S3 | 12 | 0.760 / 0.855 / 0.838 | 1.587 / 1.687 / 1.674 |
## Quality and verification
- Floor probe: 9 stations × 51 samples; maximum root offset 7.884 mm, matching the L119 probe. Route centerline openness passed for 21,425/21,425 samples; maximum grade was 10.695°.
- Fast tier and walk audits: PASS, 264 checks across 80 runs.
- Seams: the audit exits nonzero on any shared-sample mismatch. Four adjacent LOD0 tile pairs passed, with 1,225 shared samples per pair (4,900 total), bit-identical and max delta 0.
- Determinism: all 18 Clang/GCC W1/W8/W12 runs matched across owner4 surface-world, owner2 surface-world, and owner2 floating-islands. Output changed; evaluator version 225 and v225 canonical baselines were added. Source stamp: `c1ac9c910e8bb26eba5e25f0396a3b68845627b27bf52cf3f951a37c873783f3`.
- Captures: 23/23 L119 views rendered at the same poses; 19 pass and 4 low-contrast-visible. [Compare captures side by side](captures/COMPARE.html).
- Linux VFHostEditor: PASS, 31/31 actions, 75.24 s total with `-NoUBA -MaxParallelActions=4`. Unreal ran without `prlimit`.
Logs, counts, probes, hashes, and timings are under `Saved/Linux/l125/`.
@@ -0,0 +1,100 @@
#!/usr/bin/env python3
"""Render the exact 23 L119 camera views with the L125 candidate."""
from __future__ import annotations
import importlib.util
import json
import math
import os
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
RESEARCH = Path(__file__).resolve().parent
CAPTURES = RESEARCH / "captures"
SAVED = ROOT / "Saved/Linux/l125/captures"
BASELINE_INDEX = (ROOT / "Standalone/Research/WorldAssemblerM3/Linux119"
/ "captures/L119/capture-index.json")
LAYOUT = ROOT / "Saved/Linux/l125/hashes/owner4-surface-world-w12-clang.layout.json"
CLANG = ROOT / os.environ.get("L125_CAPTURE_CLANG",
"Saved/Linux/l125/bin/VoxelForgeCoreHeadless-l125-clang")
RENDERER = ROOT / os.environ.get("L125_CAPTURE_RENDERER",
"Saved/Linux/l125/bin/VoxelForgeOffscreenCapture-l125-clang")
HELPER_PATH = ROOT / "Standalone/Research/WorldAssemblerM3/Linux113/RunL113Captures.py"
SPEC = importlib.util.spec_from_file_location("l113_capture_helpers", HELPER_PATH)
if SPEC is None or SPEC.loader is None:
raise SystemExit("cannot load the verified L113 capture helpers")
HELPERS = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(HELPERS)
HELPERS.RESEARCH = RESEARCH
HELPERS.CAPTURES = CAPTURES
HELPERS.SAVED = SAVED
HELPERS.BINARIES = {"L125": CLANG}
HELPERS.RENDERERS = {"L125": RENDERER}
def main() -> int:
if any(not path.is_file() for path in (BASELINE_INDEX, LAYOUT, CLANG, RENDERER)):
raise SystemExit("missing L119 camera set, L125 layout, or capture binary")
baseline = json.loads(BASELINE_INDEX.read_text(encoding="utf-8"))
layout = json.loads(LAYOUT.read_text(encoding="utf-8"))
rows = []
CAPTURES.mkdir(parents=True, exist_ok=True)
SAVED.mkdir(parents=True, exist_ok=True)
for view in baseline["captures"]:
row = HELPERS.capture("L125", view, layout)
row["variant"] = "L125-v225"
if view["kind"] == "rock-floor-close":
scene = ROOT / row["scene"]
anchor = HELPERS.nearest_surface_anchor(scene, view["target"], margin_m=5.0,
preferred_normal=(0.0, 0.0, 1.0), minimum_alignment=0.85)
alignment = HELPERS.dot(anchor["normal"], (0.0, 0.0, 1.0))
camera_distance = math.dist(row["camera_actual_m"], anchor["position_m"])
row.update({"floor_anchor_position_m": anchor["position_m"],
"floor_anchor_normal": anchor["normal"],
"closeup_camera_to_floor_distance_m": camera_distance,
"closeup_floor_normal_alignment": alignment,
"verified_upward_floor_normal": alignment >= 0.85})
if (not row["verified"] or not 2.0 <= camera_distance <= 3.2
or anchor["distance_m"] > 0.25 or alignment < 0.85
or row["drawn_triangles"] <= 0
or row["pixel_quality_status"] not in
("pass", "low_contrast_geometry_visible")):
raise RuntimeError(f"L125 floor close-up failed at {view['name']}")
rows.append(row)
if len(rows) != len(baseline["captures"]) or len(rows) != 23:
raise RuntimeError(f"expected all 23 L119 views, captured {len(rows)}")
index = CAPTURES / "L125" / "capture-index.json"
index.parent.mkdir(parents=True, exist_ok=True)
index.write_text(json.dumps({"captures": rows}, indent=2) + "\n",
encoding="utf-8")
html = ["<!doctype html><meta charset='utf-8'>",
"<title>L119 / L125 tunnel capture comparison</title>",
"<style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}"
"section{margin:28px 0}h2{font-size:18px}div{display:grid;"
"grid-template-columns:1fr 1fr;gap:12px}img{width:100%;height:auto}"
"p{color:#bbb}</style>",
"<h1>L119 / L125 v225: identical views</h1>"]
old_by_name = {Path(row["capture"]).name: row for row in baseline["captures"]}
for row in rows:
name = Path(row["capture"]).name
old = old_by_name[name]
old_path = os.path.relpath(ROOT / "Standalone/Research/WorldAssemblerM3/Linux119"
/ old["capture"], CAPTURES)
new_path = os.path.relpath(RESEARCH / row["capture"], CAPTURES)
html.extend(["<section>", f"<h2>{row['passage']} — {row['station']}</h2>",
f"<p>{row['kind']} · L119 {old['pixel_quality_status']} · "
f"L125 {row['pixel_quality_status']}</p>", "<div>",
f"<figure><figcaption>L119</figcaption><img src='{old_path}'></figure>",
f"<figure><figcaption>L125 v225</figcaption><img src='{new_path}'></figure>",
"</div>", "</section>"])
(CAPTURES / "COMPARE.html").write_text("\n".join(html) + "\n",
encoding="utf-8")
print(f"[L125Captures] rendered={len(rows)} views index={index.relative_to(ROOT)}",
flush=True)
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,78 @@
#!/usr/bin/env python3
"""Probe reconstructed tunnel floor roots at the nine L119 stations."""
from __future__ import annotations
import csv
import json
import math
import os
import re
import statistics
import subprocess
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / os.environ.get("L125_PROBE_DIR", "Saved/Linux/l125/density-probe")
BINARY = ROOT / os.environ.get("L125_PROBE_BINARY",
"Saved/Linux/l125/bin/VoxelForgeCoreHeadless-l125-clang")
DATA = ROOT / "Standalone/data/owner_world.json"
SLOPE = re.compile(
r"^\[L115DensitySlopeSample\] passage=(\S+) station=(\S+) s_m=([\d.]+) "
r".*?planned_floor_m=(-?[\d.]+) root_floor_m=(-?[\d.]+|nan) "
r"residual_m=(-?[\d.]+|nan)", re.M)
def main() -> int:
OUT.mkdir(parents=True, exist_ok=True)
log, layout = OUT / "owner4-clang.log", OUT / "layout.json"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BINARY), str(DATA), "--world-assembler-prototype",
"--stream-benchmark", "--stream-pipeline", "--workers=12", "--clip-radius=3",
"--max-clip-level=8", "--max-level=8",
"--camera=8,16,-372.2626953125,0,0", "--audit-resolved-layout-passages",
f"--resolved-layout-output={layout}",
]
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run(command, cwd=ROOT,
env={**os.environ, "VOXELFORGE_L115_DENSITY_PROFILE": "1"},
stdout=stream, stderr=subprocess.STDOUT, check=False, timeout=1740)
if result.returncode:
raise SystemExit(f"density probe failed: {log}; exit={result.returncode}")
text = log.read_text(encoding="utf-8", errors="replace")
groups: dict[tuple[str, str], list[dict]] = {}
for passage, station, distance, planned, root, residual in SLOPE.findall(text):
root_value = float(root) if root != "nan" else math.nan
residual_value = float(residual) if residual != "nan" else math.nan
groups.setdefault((passage, station), []).append({
"route_s_m": float(distance), "planned_floor_m": float(planned),
"root_floor_m": root_value, "offset_m": residual_value})
summary = []
with (OUT / "zero-crossing-offsets.csv").open("w", newline="", encoding="utf-8") as stream:
writer = csv.DictWriter(stream, fieldnames=("passage", "station", "route_s_m",
"planned_floor_m", "root_floor_m", "offset_m"))
writer.writeheader()
for (passage, station), samples in sorted(groups.items()):
for sample in samples:
writer.writerow({"passage": passage, "station": station, **sample})
finite = [sample["offset_m"] for sample in samples
if math.isfinite(sample["offset_m"])]
summary.append({"passage": passage, "station": station,
"samples": len(samples), "finite_roots": len(finite),
"max_abs_offset_m": max(map(abs, finite)) if finite else None,
"median_abs_offset_m": statistics.median(map(abs, finite))
if finite else None,
"p95_abs_offset_m": sorted(map(abs, finite))[
min(len(finite)-1, math.ceil(0.95*len(finite))-1)]
if finite else None})
if not summary or any(item["samples"] != 51 for item in summary):
raise RuntimeError("density profile is missing 51-sample route stations")
(OUT / "zero-crossing-summary.json").write_text(
json.dumps(summary, indent=2) + "\n", encoding="utf-8")
print(f"[L125DensityProbe] exit={result.returncode} stations={len(summary)} "
f"log={log.relative_to(ROOT)}", flush=True)
return result.returncode
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,119 @@
#!/usr/bin/env python3
"""Check Clang/GCC W1/W8/W12 hashes and compare the candidate with L119."""
from __future__ import annotations
import json
import os
import re
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / os.environ.get("L125_HASH_DIR", "Saved/Linux/l125/hashes")
DATASETS = {
"owner4": ROOT / "Standalone/data/owner_world.json",
"owner2": ROOT / "Standalone/data/regression/owner_world_2strate_l61.json",
}
BINARIES = {
"clang": ROOT / os.environ.get("L125_HASH_CLANG",
"Saved/Linux/l125/bin-stamp10/VoxelForgeCoreHeadless-l125-stamp10-clang"),
"gcc": ROOT / os.environ.get("L125_HASH_GCC",
"Saved/Linux/l125/bin-stamp10/VoxelForgeCoreHeadless-l125-stamp10-gcc"),
}
HASH = re.compile(r"^\[Pipeline(?:FullDetailHash|WholeViewHash|LODHash|ExactQueryHash)\].*$", re.M)
STAMP = re.compile(r"^\[VoxelForgeSourceStamp\] sha256=(\S+)$", re.M)
def run(dataset: str, recipe: str, workers: int, compiler: str) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
label = f"{dataset}-{recipe}-w{workers}-{compiler}"
log = OUT / f"{label}.log"
layout = OUT / f"{label}.layout.json"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BINARIES[compiler]), str(DATASETS[dataset]),
f"--workers={workers}", "--world-assembler-prototype", "--stream-benchmark",
"--stream-pipeline", "--force-generate", "--clip-radius=3",
"--max-clip-level=8", "--max-level=8", f"--recipe={recipe}",
"--stream-hash", f"--resolved-layout-output={layout}",
]
started = time.monotonic()
with log.open("w", encoding="utf-8") as stream:
result = subprocess.run(command, cwd=ROOT, stdout=stream,
stderr=subprocess.STDOUT, check=False, timeout=1740)
output = log.read_text(encoding="utf-8", errors="replace")
hashes = HASH.findall(output)
if result.returncode or len(hashes) != 12:
raise SystemExit(f"hash run failed or incomplete: {label}; exit={result.returncode} "
f"hashes={len(hashes)} log={log}")
row = {"dataset": dataset, "recipe": recipe, "workers": workers,
"compiler": compiler, "exit_code": result.returncode, "hashes": hashes,
"source_stamp": (STAMP.search(output).group(1)
if STAMP.search(output) else None),
"elapsed_s": round(time.monotonic() - started, 3),
"log": str(log.relative_to(ROOT))}
print("[L125HashRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def main() -> int:
if any(not path.is_file() for path in (*DATASETS.values(), *BINARIES.values())):
raise SystemExit("missing L125 hash input")
previous_path = ROOT / "Saved/Linux/l119/hashes/summary.json"
previous_doc = json.loads(previous_path.read_text(encoding="utf-8"))
previous = {(row["dataset"], row["recipe"], row["workers"], row["compiler"]): row
for row in previous_doc["runs"]}
rows = []
recipes = {"owner4": ("surface-world",),
"owner2": ("surface-world", "floating-islands")}
for dataset, dataset_recipes in recipes.items():
for recipe in dataset_recipes:
for workers in (1, 8, 12):
for compiler in ("clang", "gcc"):
rows.append(run(dataset, recipe, workers, compiler))
(OUT / "runs-partial.json").write_text(
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
groups = {}
for dataset, dataset_recipes in recipes.items():
for recipe in dataset_recipes:
key = f"{dataset}/{recipe}"
group = [row for row in rows if row["dataset"] == dataset
and row["recipe"] == recipe]
reference = group[0]["hashes"]
stable = all(row["hashes"] == reference for row in group)
old = previous[(dataset, recipe, 12, "clang")]["hashes"]
groups[key] = {
"all_worker_compiler_hashes_match": stable,
"matches_l119_v224": next(row for row in group
if row["workers"] == 12 and row["compiler"] == "clang")["hashes"] == old,
"source_stamps": sorted({row["source_stamp"] for row in group}),
"runs": [{"workers": row["workers"], "compiler": row["compiler"],
"log": row["log"]} for row in group],
}
if not stable:
raise SystemExit(f"determinism mismatch: {key}")
summary = {"runs": rows, "groups": groups}
(OUT / "summary.json").write_text(json.dumps(summary, indent=2) + "\n",
encoding="utf-8")
baseline_dir = ROOT / "Standalone/Tools/verify/baselines/owner-hash/canonical"
for dataset, recipe, style, baseline_name in (
("owner4", "surface-world", 1,
"owner-hash-owner4-surface-world-style1-v225.baseline"),
("owner2", "surface-world", 1,
"owner-hash-surface-world-style1-v225.baseline"),
("owner2", "floating-islands", 2,
"owner-hash-floating-islands-style2-v225.baseline"),
):
canonical = next(row for row in rows if row["dataset"] == dataset
and row["recipe"] == recipe and row["workers"] == 12
and row["compiler"] == "clang")
baseline = baseline_dir / baseline_name
baseline.write_text("\n".join(canonical["hashes"]) + "\n",
encoding="utf-8")
print("[L125HashSummary] " + json.dumps(groups, sort_keys=True), flush=True)
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,172 @@
#!/usr/bin/env python3
"""Measure passage sweep work by stratum and LOD."""
from __future__ import annotations
import json
import os
import re
import subprocess
import time
from collections import defaultdict
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / os.environ.get("L125_COUNTS_DIR", "Saved/Linux/l125/counts")
DATA = ROOT / "Standalone/data/owner_world.json"
BINARY = ROOT / os.environ.get("L125_COUNTS_BINARY",
"Saved/Linux/l125/bin/VoxelForgeCoreHeadless-l125-clang")
CAMERAS = {
0: (8.0, 16.0, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (19.166015625, -14.2001953125, -753.3740234375),
3: (-20.0625, -5.068359375, -900.353515625),
}
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
CALLERS = (
"Unknown", "DensityGrid", "GradientNormalFallback", "MidpointCorrection",
"SkirtSurfaceVertex", "SkirtExtrudedVertex", "SkirtClippedVertex",
"SkirtRefinementFace", "SkirtCoarseCentroid", "FarShellSurfaceQuery",
"FarShellProjectionNormal", "FarShellStratumRefinement",
)
def records(path: Path, tag: str) -> dict[str, dict[str, str]]:
result = {}
for line in path.read_text(encoding="utf-8", errors="replace").splitlines():
if line.startswith(tag + " "):
row = dict(FIELDS.findall(line))
result[row["key"]] = row
return result
def lod_of(key: str) -> int:
return int(key.rsplit("lod", 1)[1].rstrip(")"))
def run(strate: int, replicate: int) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
label = f"s{strate}-w8-profile{replicate}"
log = OUT / f"{label}.log"
camera = ",".join(f"{value:.12f}" for value in CAMERAS[strate]) + ",0,0"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BINARY), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
"--workers=8", "--clip-radius=3", "--max-clip-level=8", "--max-level=8",
f"--camera={camera}", "--profile-lod-work", "--profile-passage-composer",
]
started = time.monotonic()
peak_tree_rss_kib = 0
with log.open("w", encoding="utf-8") as output:
process = subprocess.Popen(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT)
deadline = started + 1740
page_kib = os.sysconf("SC_PAGE_SIZE") // 1024
while process.poll() is None:
pending = [process.pid]
seen = set()
rss_kib = 0
while pending:
pid = pending.pop()
if pid in seen:
continue
seen.add(pid)
try:
with open(f"/proc/{pid}/statm", encoding="ascii") as statm:
rss_kib += int(statm.read().split()[1]) * page_kib
with open(f"/proc/{pid}/task/{pid}/children", encoding="ascii") as children:
pending.extend(int(value) for value in children.read().split())
except (FileNotFoundError, ProcessLookupError, PermissionError,
IndexError, ValueError):
pass
peak_tree_rss_kib = max(peak_tree_rss_kib, rss_kib)
if time.monotonic() >= deadline:
process.kill()
process.wait()
raise SystemExit(f"profile exceeded 30 minutes: {log}")
time.sleep(0.01)
return_code = process.wait()
if return_code:
raise SystemExit(f"profile failed: {log}; exit={return_code}")
composer = records(log, "[PassageComposerTile]")
stages = records(log, "[CpuTileStages]")
counts = records(log, "[PassageSweepCount]")
per_lod: dict[int, dict] = defaultdict(lambda: {
"tiles": 0, "grid_samples": 0, "sweep_pairs": 0,
"route_candidates": 0, "carve_segment_visits": 0,
"sweep_prepare_ms": 0.0, "passage_worker_ms": 0.0,
"classify_ms": 0.0, "column_ms": 0.0, "mc_ms": 0.0,
"touched": 0, "touched_unique": 0, "body_band": 0,
"stamped_outside": 0, "cache_valid": 0, "cache_valid_unique": 0,
"shell_band": 0, "exact_band_unique": 0,
"contributing_pairs": 0, "overlap_pairs": 0, "cross_passage_overlap": 0,
"floor_profile_calls": 0,
"cache_bytes": 0, "scratch_bytes": 0,
"cache_bytes_max_tile": 0, "scratch_bytes_max_tile": 0,
"lookups": 0, "cache_hits": 0, "missing": 0,
"offgrid_miss": 0, "unprepared_miss": 0,
"missing_by_caller": [0] * len(CALLERS),
"fallback_by_caller": [0] * len(CALLERS),
})
for key, comp in composer.items():
lod = lod_of(key)
if lod > 2 or int(comp.get("features", "0")) == 0:
continue
stage = stages.get(key)
count = counts.get(key)
if stage is None or count is None:
raise SystemExit(f"missing stage/count row for {label} {key}")
row = per_lod[lod]
row["tiles"] += 1
row["grid_samples"] += int(comp["sweep_grid_samples"])
for name in ("sweep_pairs", "route_candidates", "carve_segment_visits",
"lookups", "cache_hits", "missing"):
source = {"route_candidates": "route_candidates",
"carve_segment_visits": "carve_segment_visits",
"lookups": "sweep_lookups", "cache_hits": "sweep_cache_hits",
"missing": "sweep_missing"}.get(name, name)
row[name] += int(comp[source])
row["sweep_prepare_ms"] += float(comp["sweep_prepare_ms"])
row["passage_worker_ms"] += float(comp["worker_ms"])
for name in ("classify_ms", "column_ms", "mc_ms"):
row[name] += float(stage[name])
for name in ("touched", "stamped_outside", "cache_valid", "cache_valid_unique",
"touched_unique", "body_band", "shell_band",
"exact_band_unique", "overlap_pairs", "cross_passage_overlap",
"contributing_pairs", "floor_profile_calls",
"cache_bytes", "scratch_bytes", "offgrid_miss",
"unprepared_miss"):
row[name] += int(count[name])
row["cache_bytes_max_tile"] = max(row["cache_bytes_max_tile"],
int(count["cache_bytes"]))
row["scratch_bytes_max_tile"] = max(row["scratch_bytes_max_tile"],
int(count["scratch_bytes"]))
for name, field in (("missing_by_caller", "sweep_missing_by_caller"),
("fallback_by_caller", "sweep_exact_fallback_by_caller")):
values = [int(value) for value in stage[field].split(",")]
row[name] = [a + b for a, b in zip(row[name], values)]
result_row = {
"strate": strate, "workers": 8, "replicate": replicate,
"elapsed_s": round(time.monotonic() - started, 3),
"peak_tree_rss_kib": peak_tree_rss_kib,
"by_lod": {str(lod): values for lod, values in sorted(per_lod.items())},
"log": str(log.relative_to(ROOT)),
}
print("[L125PassageCounts] " + json.dumps(result_row, sort_keys=True), flush=True)
return result_row
def main() -> int:
if not DATA.is_file() or not BINARY.is_file():
raise SystemExit("missing L125 passage-counter input")
runs = [run(strate, replicate) for strate in range(4) for replicate in (1, 2)]
(OUT / "summary.json").write_text(
json.dumps({"runs": runs, "caller_names": CALLERS}, indent=2) + "\n",
encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,138 @@
#!/usr/bin/env python3
"""Five interleaved L80 readiness runs for a candidate against L109/L119."""
from __future__ import annotations
import json
import os
import re
import statistics
import subprocess
import time
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / os.environ.get("L125_TIMING_DIR", "Saved/Linux/l125/timing")
DATA = ROOT / "Standalone/data/owner_world.json"
CANDIDATE = os.environ.get("L125_CANDIDATE_LABEL", "L125-stamp10")
BINARIES = {
"L109": ROOT / "Saved/Linux/l109/bin-final/VoxelForgeCoreHeadless-l109-clang",
"L119": ROOT / "Saved/Linux/l119/bin/VoxelForgeCoreHeadless-l119-clang",
CANDIDATE: ROOT / os.environ.get("L125_CANDIDATE_BINARY",
"Saved/Linux/l125/bin-stamp10/VoxelForgeCoreHeadless-l125-stamp10-clang"),
}
CAMERAS = {
0: (8.0, 16.0, -372.2626953125),
1: (25.8369140625, 3.19921875, -737.0),
2: (19.166015625, -14.2001953125, -753.3740234375),
3: (-20.0625, -5.068359375, -900.353515625),
}
PIPELINE = re.compile(r"^\[StreamPipeline\] (.*)$", re.M)
FIELDS = re.compile(r"([a-zA-Z0-9_]+)=([^ ]+)")
NEAR = re.compile(
r"^\[WorldAssemblerNearLODReady\] lods=0-2 tiles=(\d+)/(\d+) cold_ready_s=([0-9.]+)$",
re.M)
def run(strate: int, workers: int, version: str, phase: str, replicate: int) -> dict:
OUT.mkdir(parents=True, exist_ok=True)
label = f"s{strate}-w{workers}-{version}-{phase}{replicate}"
log = OUT / f"{label}.log"
camera = ",".join(f"{value:.12f}" for value in CAMERAS[strate]) + ",0,0"
command = [
"taskset", "-c", "0-11", "prlimit", "--as=6442450944", "--",
"timeout", "1740s", str(BINARIES[version]), str(DATA),
"--world-assembler-prototype", "--stream-benchmark", "--stream-pipeline",
f"--workers={workers}", "--clip-radius=3", "--max-clip-level=8",
"--max-level=8", f"--camera={camera}", "--profile-lod-work",
"--stream-scheduler-policy=3",
]
started = time.monotonic()
with log.open("w", encoding="utf-8") as output:
result = subprocess.run(command, cwd=ROOT, stdout=output,
stderr=subprocess.STDOUT, check=False, timeout=1740)
content = log.read_text(encoding="utf-8", errors="replace")
pipeline_match, near_match = PIPELINE.search(content), NEAR.search(content)
if result.returncode or pipeline_match is None or near_match is None:
raise SystemExit(f"readiness run failed: {log}; exit={result.returncode}")
pipeline = dict(FIELDS.findall(pipeline_match.group(1)))
row = {"strate": strate, "workers": workers, "version": version,
"phase": phase, "replicate": replicate, "exit_code": result.returncode,
"wall_s": round(time.monotonic() - started, 3),
"lod02_ready_s": float(near_match.group(3)),
"whole_view_ready_s": float(pipeline["whole_view_ready"].removesuffix("s")),
"whole_tiles": int(pipeline["whole_tiles"].split("/")[0]),
"log": str(log.relative_to(ROOT))}
print("[L125ToleranceTimingRun] " + json.dumps(row, sort_keys=True), flush=True)
return row
def cpu_idle_percent(interval_s: float = 2.0) -> float:
def totals() -> tuple[int, int]:
fields = Path("/proc/stat").read_text(encoding="utf-8").splitlines()[0].split()
values = [int(value) for value in fields[1:]]
return sum(values), values[3] + (values[4] if len(values) > 4 else 0)
total_before, idle_before = totals()
time.sleep(interval_s)
total_after, idle_after = totals()
return 100.0 * (idle_after-idle_before) / max(1, total_after-total_before)
def main() -> int:
if not DATA.is_file() or any(not binary.is_file() for binary in BINARIES.values()):
raise SystemExit("missing timing input")
OUT.mkdir(parents=True, exist_ok=True)
load_1m, idle_pct = os.getloadavg()[0], cpu_idle_percent()
uptime = subprocess.run(["uptime"], cwd=ROOT, text=True,
capture_output=True, check=True).stdout.strip()
top = subprocess.run(["ps", "-eo", "pid,pcpu,comm", "--sort=-pcpu"],
cwd=ROOT, text=True, capture_output=True, check=True).stdout
(OUT / "machine-load-before.txt").write_text(
f"uptime: {uptime}\n1-minute load: {load_1m:.2f}\n"
f"2-second CPU idle: {idle_pct:.1f}%\ntop CPU users:\n{top}",
encoding="utf-8")
print(f"[L125ToleranceTimingGate] load_1m={load_1m:.2f} "
f"cpu_idle_2s={idle_pct:.1f}% uptime={uptime}", flush=True)
if load_1m >= 0.9 or idle_pct < 97.0:
raise SystemExit("timing refused: machine is above the quiet-load gate")
rows = []
versions = ("L109", "L119", CANDIDATE)
for strate in range(4):
for workers in (8, 12):
for version in versions:
run(strate, workers, version, "warmup", 0)
for replicate in range(1, 6):
offset = (replicate - 1) % len(versions)
order = versions[offset:] + versions[:offset]
for version in order:
rows.append(run(strate, workers, version, "measured", replicate))
(OUT / "runs-partial.json").write_text(
json.dumps(rows, indent=2) + "\n", encoding="utf-8")
summary = []
for strate in range(4):
for workers in (8, 12):
item = {"strate": strate, "workers": workers, "replicates": 5}
medians = {}
for version in versions:
group = [row for row in rows if row["strate"] == strate
and row["workers"] == workers and row["version"] == version]
medians[version] = {}
for key in ("lod02_ready_s", "whole_view_ready_s"):
values = [row[key] for row in group]
medians[version][key] = statistics.median(values)
item[f"{version}_{key}_values"] = values
item[f"{version}_{key}_median"] = medians[version][key]
for comparison in ("L109", "L119"):
for key in ("lod02_ready_s", "whole_view_ready_s"):
item[f"L125_vs_{comparison}_{key}_delta_pct"] = round(
100.0 * (medians[CANDIDATE][key]
/medians[comparison][key]-1.0), 2)
summary.append(item)
(OUT / "summary.json").write_text(
json.dumps({"runs": rows, "summary": summary}, indent=2) + "\n",
encoding="utf-8")
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,188 @@
<!doctype html><meta charset='utf-8'>
<title>L119 / L125 tunnel capture comparison</title>
<style>body{font:14px system-ui;margin:24px;background:#17191d;color:#eee}section{margin:28px 0}h2{font-size:18px}div{display:grid;grid-template-columns:1fr 1fr;gap:12px}img{width:100%;height:auto}p{color:#bbb}</style>
<h1>L119 / L125 v225: identical views</h1>
<section>
<h2>passage/0-1/0 — rock-floor/401.7m</h2>
<p>rock-floor-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-0-1-0-rock-floor-station-1.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-0-1-0-rock-floor-station-1.png'></figure>
</div>
</section>
<section>
<h2>passage/0-1/0 — rock-floor/792.8m</h2>
<p>rock-floor-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-0-1-0-rock-floor-station-2.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-0-1-0-rock-floor-station-2.png'></figure>
</div>
</section>
<section>
<h2>passage/0-1/0 — rock-floor/1634.5m</h2>
<p>rock-floor-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-0-1-0-rock-floor-station-3.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-0-1-0-rock-floor-station-3.png'></figure>
</div>
</section>
<section>
<h2>passage/1-2/0 — rock-floor/27.0m</h2>
<p>rock-floor-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-1-2-0-rock-floor-station-1.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-1-2-0-rock-floor-station-1.png'></figure>
</div>
</section>
<section>
<h2>passage/1-2/0 — rock-floor/52.9m</h2>
<p>rock-floor-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-1-2-0-rock-floor-station-2.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-1-2-0-rock-floor-station-2.png'></figure>
</div>
</section>
<section>
<h2>passage/1-2/0 — rock-floor/78.9m</h2>
<p>rock-floor-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-1-2-0-rock-floor-station-3.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-1-2-0-rock-floor-station-3.png'></figure>
</div>
</section>
<section>
<h2>passage/2-3/0 — rock-floor/323.4m</h2>
<p>rock-floor-close · L119 low_contrast_geometry_visible · L125 low_contrast_geometry_visible</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-2-3-0-rock-floor-station-1.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-2-3-0-rock-floor-station-1.png'></figure>
</div>
</section>
<section>
<h2>passage/2-3/0 — rock-floor/333.4m</h2>
<p>rock-floor-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-2-3-0-rock-floor-station-2.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-2-3-0-rock-floor-station-2.png'></figure>
</div>
</section>
<section>
<h2>passage/2-3/0 — rock-floor/343.4m</h2>
<p>rock-floor-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-2-3-0-rock-floor-station-3.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-2-3-0-rock-floor-station-3.png'></figure>
</div>
</section>
<section>
<h2>passage/0-1/0 — section-1/4m-outside</h2>
<p>open-air-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-0-1-0-openair-1-4m-outside.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-0-1-0-openair-1-4m-outside.png'></figure>
</div>
</section>
<section>
<h2>passage/0-1/0 — section-1/4m-interior-wall</h2>
<p>open-air-close · L119 low_contrast_geometry_visible · L125 low_contrast_geometry_visible</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-0-1-0-openair-1-4m-interior-wall.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-0-1-0-openair-1-4m-interior-wall.png'></figure>
</div>
</section>
<section>
<h2>passage/0-1/0 — section-2/4m-outside</h2>
<p>open-air-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-0-1-0-openair-2-4m-outside.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-0-1-0-openair-2-4m-outside.png'></figure>
</div>
</section>
<section>
<h2>passage/0-1/0 — section-2/4m-interior-wall</h2>
<p>open-air-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-0-1-0-openair-2-4m-interior-wall.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-0-1-0-openair-2-4m-interior-wall.png'></figure>
</div>
</section>
<section>
<h2>passage/0-1/0 — section-3/4m-outside</h2>
<p>open-air-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-0-1-0-openair-3-4m-outside.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-0-1-0-openair-3-4m-outside.png'></figure>
</div>
</section>
<section>
<h2>passage/0-1/0 — section-3/4m-interior-wall</h2>
<p>open-air-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-0-1-0-openair-3-4m-interior-wall.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-0-1-0-openair-3-4m-interior-wall.png'></figure>
</div>
</section>
<section>
<h2>passage/1-2/0 — section-1/4m-outside</h2>
<p>open-air-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-1-2-0-openair-1-4m-outside.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-1-2-0-openair-1-4m-outside.png'></figure>
</div>
</section>
<section>
<h2>passage/1-2/0 — section-1/4m-interior-wall</h2>
<p>open-air-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-1-2-0-openair-1-4m-interior-wall.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-1-2-0-openair-1-4m-interior-wall.png'></figure>
</div>
</section>
<section>
<h2>passage/1-2/0 — section-2/4m-outside</h2>
<p>open-air-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-1-2-0-openair-2-4m-outside.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-1-2-0-openair-2-4m-outside.png'></figure>
</div>
</section>
<section>
<h2>passage/1-2/0 — section-2/4m-interior-wall</h2>
<p>open-air-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-1-2-0-openair-2-4m-interior-wall.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-1-2-0-openair-2-4m-interior-wall.png'></figure>
</div>
</section>
<section>
<h2>passage/2-3/0 — section-1/4m-outside</h2>
<p>open-air-close · L119 low_contrast_geometry_visible · L125 low_contrast_geometry_visible</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-2-3-0-openair-1-4m-outside.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-2-3-0-openair-1-4m-outside.png'></figure>
</div>
</section>
<section>
<h2>passage/2-3/0 — section-1/4m-interior-wall</h2>
<p>open-air-close · L119 low_contrast_geometry_visible · L125 low_contrast_geometry_visible</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-2-3-0-openair-1-4m-interior-wall.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-2-3-0-openair-1-4m-interior-wall.png'></figure>
</div>
</section>
<section>
<h2>passage/2-3/0 — section-2/4m-outside</h2>
<p>open-air-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-2-3-0-openair-2-4m-outside.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-2-3-0-openair-2-4m-outside.png'></figure>
</div>
</section>
<section>
<h2>passage/2-3/0 — section-2/4m-interior-wall</h2>
<p>open-air-close · L119 pass · L125 pass</p>
<div>
<figure><figcaption>L119</figcaption><img src='../../Linux119/captures/L119/L115/L115/passage-2-3-0-openair-2-4m-interior-wall.png'></figure>
<figure><figcaption>L125 v225</figcaption><img src='L125/passage-2-3-0-openair-2-4m-interior-wall.png'></figure>
</div>
</section>
File diff suppressed because it is too large. Load diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

@@ -59,6 +59,7 @@ namespace
int ShapeHelperLimit=8; int ShapeHelperLimit=8;
bool AuditBasePageEquivalence=false; bool AuditBasePageEquivalence=false;
bool AuditRouteParity=false; bool AuditRouteParity=false;
bool AuditPassageTileSeams=false;
bool AuditPassageSourceClamp=false; bool AuditPassageSourceClamp=false;
bool AuditPassageCarveReach=false; bool AuditPassageCarveReach=false;
bool RegionCrossing=false; bool RegionCrossing=false;
@@ -1465,6 +1466,7 @@ namespace
" --shape-helper-limit=8|12 (default 8; shape build A/B)\n" " --shape-helper-limit=8|12 (default 8; shape build A/B)\n"
" --audit-base-page-equivalence (hash one tile through both shape routes)\n" " --audit-base-page-equivalence (hash one tile through both shape routes)\n"
" --audit-route-parity (compare page, native-only, exact-query and mesh routes)\n" " --audit-route-parity (compare page, native-only, exact-query and mesh routes)\n"
" --audit-passage-tile-seams (compare shared LOD0 density samples in adjacent route tiles)\n"
" --audit-passage-source-clamp (compare passage source floors 2,3,4,6 over all near tiles)\n" " --audit-passage-source-clamp (compare passage source floors 2,3,4,6 over all near tiles)\n"
" --audit-passage-carve-reach (compare post-composer reaches 1.5,2,2.5,4 m over all near tiles)\n" " --audit-passage-carve-reach (compare post-composer reaches 1.5,2,2.5,4 m over all near tiles)\n"
" --audit-tile-shape-readiness (run a deliberately mis-marked tile against the native-only guard)\n" " --audit-tile-shape-readiness (run a deliberately mis-marked tile against the native-only guard)\n"
@@ -1547,6 +1549,7 @@ namespace
} }
else if(arg=="--audit-base-page-equivalence")options.AuditBasePageEquivalence=true; else if(arg=="--audit-base-page-equivalence")options.AuditBasePageEquivalence=true;
else if(arg=="--audit-route-parity")options.AuditRouteParity=true; else if(arg=="--audit-route-parity")options.AuditRouteParity=true;
else if(arg=="--audit-passage-tile-seams")options.AuditPassageTileSeams=true;
else if(arg=="--audit-passage-source-clamp")options.AuditPassageSourceClamp=true; else if(arg=="--audit-passage-source-clamp")options.AuditPassageSourceClamp=true;
else if(arg=="--audit-passage-carve-reach")options.AuditPassageCarveReach=true; else if(arg=="--audit-passage-carve-reach")options.AuditPassageCarveReach=true;
else if(arg=="--region-crossing")options.RegionCrossing=true; else if(arg=="--region-crossing")options.RegionCrossing=true;
@@ -2330,5 +2333,6 @@ int main(int argc,char** argv)
options.StreamingSchedulerPolicy,options.MovingCameraTrace, options.StreamingSchedulerPolicy,options.MovingCameraTrace,
options.MovingCameraSpeedMetersPerSecond,options.MovingCameraDurationSeconds, options.MovingCameraSpeedMetersPerSecond,options.MovingCameraDurationSeconds,
options.MovingCameraDwellSeconds,options.ColdWorkerTimeline, options.MovingCameraDwellSeconds,options.ColdWorkerTimeline,
options.AuditPassageSourceClamp,options.AuditPassageCarveReach); options.AuditPassageSourceClamp,options.AuditPassageCarveReach,
options.AuditPassageTileSeams);
} }
+121 -1
View File
@@ -24,6 +24,7 @@
#include <queue> #include <queue>
#include <string_view> #include <string_view>
#include <thread> #include <thread>
#include <tuple>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
@@ -2383,7 +2384,7 @@ namespace StandaloneStreamBenchmark
bool bMovingCameraTrace=false,double MovingCameraSpeedMetersPerSecond=0.0, bool bMovingCameraTrace=false,double MovingCameraSpeedMetersPerSecond=0.0,
double MovingCameraDurationSeconds=12.0,double MovingCameraDwellSeconds=5.0, double MovingCameraDurationSeconds=12.0,double MovingCameraDwellSeconds=5.0,
bool bColdWorkerTimeline=false,bool bAuditPassageSourceClamp=false, bool bColdWorkerTimeline=false,bool bAuditPassageSourceClamp=false,
bool bAuditPassageCarveReach=false) bool bAuditPassageCarveReach=false,bool bAuditPassageTileSeams=false)
{ {
using Clock=std::chrono::steady_clock; using Clock=std::chrono::steady_clock;
const std::clock_t ColdCpuOrigin=std::clock(); const std::clock_t ColdCpuOrigin=std::clock();
@@ -5676,6 +5677,125 @@ namespace StandaloneStreamBenchmark
return 9; return 9;
} }
} }
if(bAuditPassageTileSeams)
{
std::unordered_set<FVoxelTileKey,FStandaloneTileKeyHash> desiredKeys(
Desired.Tiles.begin(),Desired.Tiles.end());
std::vector<std::tuple<VoxelForgeCore::TileKey,
VoxelForgeCore::TileKey,std::size_t>> candidates;
candidates.reserve(128);
for(const FVoxelTileKey& nativeA:Desired.Tiles)
{
if(nativeA.Level!=0)continue;
const VoxelForgeCore::TileKey a{{nativeA.Coord.X,nativeA.Coord.Y,
nativeA.Coord.Z},0};
if(Shape.passageOverlapScore(a)==0)continue;
for(std::size_t axis=0;axis<3;++axis)
{
FVoxelTileKey nativeB=nativeA;
if(axis==0)++nativeB.Coord.X;
else if(axis==1)++nativeB.Coord.Y;
else ++nativeB.Coord.Z;
if(!desiredKeys.contains(nativeB))continue;
const VoxelForgeCore::TileKey b{{nativeB.Coord.X,nativeB.Coord.Y,
nativeB.Coord.Z},0};
if(Shape.passageOverlapScore(b)>0)
candidates.emplace_back(a,b,axis);
}
}
VoxelForgeCore::TileGenerationOptions seamOptions;
seamOptions.hashDensity=true;
seamOptions.captureDensitySamples=true;
seamOptions.forceFullDensityCapture=true;
seamOptions.profilePassageComposer=true;
const auto sampleIndex=[](std::int32_t x,std::int32_t y,std::int32_t z)
{
constexpr std::size_t Dim=VoxelForgeCore::CoreTileVoxelCount+3;
return (static_cast<std::size_t>(z)*Dim+static_cast<std::size_t>(y))*Dim
+static_cast<std::size_t>(x);
};
std::uint64_t comparedSamples=0,mismatches=0;
std::size_t testedPairs=0,examinedPairs=0;
double maximumDelta=0.0;
bool passed=false;
for(const auto& [a,b,axis]:candidates)
{
if(examinedPairs++>=128)break;
std::string errorA,errorB;
const auto tileA=Shape.generateTile(a,seamOptions,errorA);
const auto tileB=Shape.generateTile(b,seamOptions,errorB);
if(!tileA||!tileB)
{
if(examinedPairs==128)
std::printf("[PassageTileSeamCandidate] keyA=(%d,%d,%d,lod0) keyB=(%d,%d,%d,lod0) status=SKIP errorA=%s errorB=%s\n",
a.coordinate.x,a.coordinate.y,a.coordinate.z,b.coordinate.x,
b.coordinate.y,b.coordinate.z,errorA.c_str(),errorB.c_str());
continue;
}
if(tileA->diagnostics.passageSweepRouteSegmentCandidates==0
||tileB->diagnostics.passageSweepRouteSegmentCandidates==0)continue;
constexpr std::int32_t Dim=VoxelForgeCore::CoreTileVoxelCount+3;
const std::size_t expected=static_cast<std::size_t>(Dim)*Dim*Dim;
if(tileA->debugDensitySamples.size()!=expected
||tileB->debugDensitySamples.size()!=expected)
{
std::printf("[PassageTileSeam] axis=%c keyA=(%d,%d,%d,lod0) keyB=(%d,%d,%d,lod0) shared_samples=0 mismatches=1 max_abs_delta=inf status=FAIL reason=missing_full_density_capture\n",
"xyz"[axis],a.coordinate.x,a.coordinate.y,a.coordinate.z,
b.coordinate.x,b.coordinate.y,b.coordinate.z);
++mismatches;
break;
}
std::uint64_t pairMismatches=0;
double pairMaximumDelta=0.0;
for(std::int32_t v=0;v<Dim;++v)
for(std::int32_t w=0;w<Dim;++w)
{
std::array<std::int32_t,3> coordinateA{},coordinateB{};
coordinateA[axis]=Dim-2;
coordinateB[axis]=1;
coordinateA[(axis+1)%3]=v;
coordinateB[(axis+1)%3]=v;
coordinateA[(axis+2)%3]=w;
coordinateB[(axis+2)%3]=w;
const float densityA=tileA->debugDensitySamples[sampleIndex(
coordinateA[0],coordinateA[1],coordinateA[2])];
const float densityB=tileB->debugDensitySamples[sampleIndex(
coordinateB[0],coordinateB[1],coordinateB[2])];
if(std::bit_cast<std::uint32_t>(densityA)
!=std::bit_cast<std::uint32_t>(densityB))
{
++pairMismatches;
pairMaximumDelta=std::max(pairMaximumDelta,
std::abs(static_cast<double>(densityA)-densityB));
}
}
++testedPairs;
comparedSamples+=static_cast<std::uint64_t>(Dim)*Dim;
mismatches+=pairMismatches;
maximumDelta=std::max(maximumDelta,pairMaximumDelta);
std::printf("[PassageTileSeam] axis=%c keyA=(%d,%d,%d,lod0) keyB=(%d,%d,%d,lod0) shared_samples=%llu mismatches=%llu max_abs_delta=%.9g status=%s\n",
"xyz"[axis],a.coordinate.x,a.coordinate.y,a.coordinate.z,
b.coordinate.x,b.coordinate.y,b.coordinate.z,
static_cast<unsigned long long>(static_cast<std::uint64_t>(Dim)*Dim),
static_cast<unsigned long long>(pairMismatches),pairMaximumDelta,
pairMismatches==0?"PASS":"FAIL");
if(pairMismatches)break;
if(testedPairs>=4)break;
}
passed=testedPairs>0&&mismatches==0;
std::printf("[PassageTileSeamAudit] candidates=%zu examined=%zu pairs=%zu shared_samples=%llu mismatches=%llu max_abs_delta=%.9g status=%s\n",
candidates.size(),examinedPairs,testedPairs,
static_cast<unsigned long long>(comparedSamples),
static_cast<unsigned long long>(mismatches),maximumDelta,
passed?"PASS":"FAIL");
if(!passed)
{
Streamer.Stop();
return 10;
}
}
FStandaloneDesiredTileSet EarlyDesired=Desired; FStandaloneDesiredTileSet EarlyDesired=Desired;
if(bDeferFarWorld) if(bDeferFarWorld)
std::erase_if(EarlyDesired.Tiles,[](const FVoxelTileKey& Key){return Key.Level>1;}); std::erase_if(EarlyDesired.Tiles,[](const FVoxelTileKey& Key){return Key.Level>1;});
+19
View File
@@ -1606,6 +1606,25 @@ private:
static_cast<unsigned long long>(D.passageSweepBaseInfluenceHits), static_cast<unsigned long long>(D.passageSweepBaseInfluenceHits),
static_cast<unsigned long long>(D.passageSweepOutOfInfluenceHits), static_cast<unsigned long long>(D.passageSweepOutOfInfluenceHits),
static_cast<unsigned long long>(D.passageSweepMissingSamples)); static_cast<unsigned long long>(D.passageSweepMissingSamples));
if(D.passageComposerProfiled)
std::printf("[PassageSweepCount] key=(%d,%d,%d,lod%d) touched=%llu stamped_outside=%llu cache_valid=%llu cache_valid_unique=%llu touched_unique=%llu body_band=%llu shell_band=%llu exact_band_unique=%llu contributing_pairs=%llu overlap_pairs=%llu cross_passage_overlap=%llu floor_profile_calls=%llu cache_bytes=%llu scratch_bytes=%llu offgrid_miss=%llu unprepared_miss=%llu\n",
Event.Key.Coord.X,Event.Key.Coord.Y,Event.Key.Coord.Z,Event.Key.Level,
static_cast<unsigned long long>(D.passageSweepTouchedSamples),
static_cast<unsigned long long>(D.passageSweepStampedOutsideSamples),
static_cast<unsigned long long>(D.passageSweepCacheValidSamples),
static_cast<unsigned long long>(D.passageSweepCacheValidUniqueSamples),
static_cast<unsigned long long>(D.passageSweepUniqueTouchedSamples),
static_cast<unsigned long long>(D.passageSweepBodyBandSamples),
static_cast<unsigned long long>(D.passageSweepShellBandSamples),
static_cast<unsigned long long>(D.passageSweepUniqueBandSamples),
static_cast<unsigned long long>(D.passageSweepContributingPairs),
static_cast<unsigned long long>(D.passageSweepOverlapPairs),
static_cast<unsigned long long>(D.passageSweepCrossPassageOverlaps),
static_cast<unsigned long long>(D.passageSweepFloorProfileCalls),
static_cast<unsigned long long>(D.passageSweepAllocatedBytes),
static_cast<unsigned long long>(D.passageSweepPrepareScratchBytes),
static_cast<unsigned long long>(D.passageSweepOffGridMisses),
static_cast<unsigned long long>(D.passageSweepUnpreparedMisses));
} }
void RecordTimelineEvent(FStandaloneCpuTileTimelineEvent::EType Type, void RecordTimelineEvent(FStandaloneCpuTileTimelineEvent::EType Type,
const FVoxelTileKey& Key,int32 WorkerId,size_t QueueDepth,size_t ActiveWorkers, const FVoxelTileKey& Key,int32 WorkerId,size_t QueueDepth,size_t ActiveWorkers,
@@ -0,0 +1,12 @@
[PipelineFullDetailHash] tiles=960 density=0x91931a57a067fd92 mesh=0xa818654be89790ac payload=0x370ff80451105a39 topology=0x06e507557aa70173
[PipelineWholeViewHash] tiles=2370 density=0x3ce77475b5908860 mesh=0x80d3ca4b215ddb16 payload=0xf838e9c8ece70933 topology=0xdf790ec894e60a20
[PipelineLODHash] lod=0 tiles=512 density=0x2fd4c78685a43cfe mesh=0x50478cff1c1f8ca0 payload=0x54e48e57e0af26de topology=0x860c011cfdb9833a
[PipelineLODHash] lod=1 tiles=448 density=0x4b8d9a6dcd2942ad mesh=0x17e89b7087bfe711 payload=0x2389c109eb780db6 topology=0x7eccd4cf560d0630
[PipelineLODHash] lod=2 tiles=320 density=0xb3e6e0585b0fc92d mesh=0x16c9a82c59e0f3d3 payload=0x1b32fc2e695144de topology=0x89a1eddead8849c1
[PipelineLODHash] lod=3 tiles=208 density=0xe7c3ce8c79544110 mesh=0xff01589508cbbe69 payload=0xe4370a5d39da57c3 topology=0x2ea4ffeae7c72463
[PipelineLODHash] lod=4 tiles=240 density=0xfb11591772a3d18e mesh=0xebf2baee8764591b payload=0xe491d7ac9c0061ad topology=0xd618ac33b95ce494
[PipelineLODHash] lod=5 tiles=144 density=0x2f8b7b7fb1e67258 mesh=0x4cd508cbe97344fd payload=0x2b6e96a6050458c9 topology=0x4ff6d0eda8988573
[PipelineLODHash] lod=6 tiles=96 density=0x0114a34c8b8d6113 mesh=0xb1fec4d01ae1fa44 payload=0x3e50cfd429b8e950 topology=0x08090c96d15c1618
[PipelineLODHash] lod=7 tiles=96 density=0x3836ed8cfce73418 mesh=0x40bc6589c5fc1aac payload=0x677349bcae16790f topology=0x36e3aa53192e6a6b
[PipelineLODHash] lod=8 tiles=306 density=0x144f3c1fd722708b mesh=0xef77b28bf7fd9453 payload=0xe3f47b37fcd61489 topology=0x5a3c73e295494e04
[PipelineExactQueryHash] probes=9 density=0x7b7c50ac24ccadcc unclamped=0x7b7c50ac24ccadcc detail=0xefcba20c0c70c415 collision=0xe604823a249029bf path=direct-Core-queries
@@ -0,0 +1,12 @@
[PipelineFullDetailHash] tiles=960 density=0xafe828ccd81da549 mesh=0xa23718cb26e18c0e payload=0xc524fb57b6254d28 topology=0x46478bffbdcd90c4
[PipelineWholeViewHash] tiles=2578 density=0x7ed7c508dc890a62 mesh=0x4fd8654dfe4d53e2 payload=0xfc44de3f8111ce9f topology=0x481236023f075f96
[PipelineLODHash] lod=0 tiles=512 density=0xd7648f18f861312f mesh=0x9e31100f4bc349c9 payload=0xea4ccb601f71dbb6 topology=0x6f4145693c581d15
[PipelineLODHash] lod=1 tiles=448 density=0x7150ca8c361ffb83 mesh=0xa803bb427deeba9a payload=0xf4718f1ce85d4f4f topology=0x7b770585aafd8174
[PipelineLODHash] lod=2 tiles=320 density=0x2ff1b4f5511a4f96 mesh=0x27be33efad378dfe payload=0xe7de01a67e16d564 topology=0x82c0a268d6328dd5
[PipelineLODHash] lod=3 tiles=272 density=0xb50cb8ec0d827890 mesh=0x5cbaebc6fe2c0a37 payload=0x9827477f3a7f69e6 topology=0xb61d889f9393c4ec
[PipelineLODHash] lod=4 tiles=272 density=0xb743eb64967bddcd mesh=0xf6b5bd36b0ebfead payload=0xd1284c1540f50636 topology=0x4a6e197e2a1a9500
[PipelineLODHash] lod=5 tiles=208 density=0x38706b628a74dd17 mesh=0x445b1c7b51489cbb payload=0x713efc66290768f7 topology=0x56486b919146bb1e
[PipelineLODHash] lod=6 tiles=144 density=0xd53849b2002a1faa mesh=0xaa210abc8498c415 payload=0xd109aef8639706d1 topology=0x61a4d75fbbc35268
[PipelineLODHash] lod=7 tiles=96 density=0xb0ea9a140275c9cc mesh=0x3ffd8365c8b0ec29 payload=0x3577afb0a2e4a420 topology=0x97530aafde15b7e0
[PipelineLODHash] lod=8 tiles=306 density=0x8b3d1816799d67a0 mesh=0x80bf554f17700e1e payload=0xccbe22c3333a9c34 topology=0xcb11b28f6b6bcc50
[PipelineExactQueryHash] probes=9 density=0xf2df67b38b7802df unclamped=0x48b347986345b557 detail=0xefcba20c0c70c415 collision=0x137e8f6c0b03a624 path=direct-Core-queries
@@ -0,0 +1,12 @@
[PipelineFullDetailHash] tiles=960 density=0xace56c8f205238ad mesh=0xa9c603a1248de6b8 payload=0xea55f1f4fcc6a894 topology=0x5ea7bc78a1b678ae
[PipelineWholeViewHash] tiles=2370 density=0xb91a65f2b5d23dd1 mesh=0xcb21ea0acbcf7482 payload=0x812c3d1f7ff8d3b8 topology=0xb18b9bc29e243ba2
[PipelineLODHash] lod=0 tiles=512 density=0xcd6ab28cfa504aca mesh=0xf03dc80a669fca31 payload=0x397aded1c3d2d297 topology=0xb4a1dc84fabc1fe3
[PipelineLODHash] lod=1 tiles=448 density=0xce6e713828b2a20a mesh=0x1cf408c25d67d18c payload=0x8a2b5d20571c997e topology=0x51cd985fe8e7d100
[PipelineLODHash] lod=2 tiles=320 density=0xe06c3509977d89df mesh=0x4d81f55877e78bde payload=0x4dff71b395ce032c topology=0x8af5aa065efee965
[PipelineLODHash] lod=3 tiles=208 density=0x60940ca350c1110a mesh=0xd386632a7d9271c0 payload=0x02e312e98024ef89 topology=0x0a5335eabb257106
[PipelineLODHash] lod=4 tiles=240 density=0x0be8798407724eaf mesh=0x131c303cbbe51434 payload=0x2a90ecf0a2411ca0 topology=0xe3e054a371152e08
[PipelineLODHash] lod=5 tiles=144 density=0xf20897ad272103a9 mesh=0x13d00b6253ae1f72 payload=0x0db3880693a962fa topology=0x462bd87a80f15e89
[PipelineLODHash] lod=6 tiles=96 density=0xc040fcac457d6313 mesh=0x1ed132eeb718fb62 payload=0xcd0214e35577c6e3 topology=0x2c56c69e6fdcfd64
[PipelineLODHash] lod=7 tiles=96 density=0xc2d419446355fdb8 mesh=0x4ea44452574fc84b payload=0xfd9779bedfc9ae0f topology=0x8948546e770c9b72
[PipelineLODHash] lod=8 tiles=306 density=0x62db31696f2da831 mesh=0xd373f9e9481532fe payload=0x540a60526e0e3e46 topology=0xc725cb901e6dc335
[PipelineExactQueryHash] probes=9 density=0xc949c4df2ce6f9d9 unclamped=0xc949c4df2ce6f9d9 detail=0x114c501e2d830d94 collision=0xe6011d3a248d4849 path=direct-Core-queries
+4 -4
View File
@@ -122,11 +122,11 @@ RECIPE_RE = re.compile(
def owner_hash_baseline(recipe: str, style: int) -> tuple[Path, str]: def owner_hash_baseline(recipe: str, style: int) -> tuple[Path, str]:
if recipe == "surface-world" and style == 1: if recipe == "surface-world" and style == 1:
return (BASELINES / "owner-hash/canonical/owner-hash-surface-world-style1-v224.baseline", return (BASELINES / "owner-hash/canonical/owner-hash-surface-world-style1-v225.baseline",
"L119-v224-adaptive-half-pipe") "L125-v225-stamped-passage-sweep")
if recipe == "floating-islands" and style == 2: if recipe == "floating-islands" and style == 2:
return (BASELINES / "owner-hash/canonical/owner-hash-floating-islands-style2-v224.baseline", return (BASELINES / "owner-hash/canonical/owner-hash-floating-islands-style2-v225.baseline",
"L119-v224-adaptive-half-pipe") "L125-v225-stamped-passage-sweep")
raise VerificationFailure(f"no pinned owner hash baseline for {recipe} style {style}") raise VerificationFailure(f"no pinned owner hash baseline for {recipe} style {style}")