wip(assembler): round L2 -- the cross-platform hash check can fail; FP contraction changes the world
Clang -ffp-contract=on/fast and GCC's default (fast) all change the density hash on the L1 view; contraction off reproduces L1 (= Windows S13) at W1/W12. Seed sweep: 48 FloatingIslands seeds and 14 effective SurfaceWorld seeds (34 of 48 fell on a seed-independent cube) match across Clang/GCC and W1/W12. Standalone gains --seed/--recipe/--render-distance-chunks (viewer + headless) and a Windows replay script. Linux standalone workers get 32 MiB pthread stacks (TLS is 17.3 MiB/thread), so no external stack limit is needed. No Core or world-output change; MSVC compile unverified. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1276fd11e3
commit
303b7b9f24
17 files changed
+1401
-13
No files matched your search
@@ -2,6 +2,7 @@
|
||||
#include "StandaloneCoreScheduler.h"
|
||||
#include "StreamBenchmarkPipeline.h"
|
||||
#include "WorldAssemblyPrototype.h"
|
||||
#include "StandaloneTlsProbe.h"
|
||||
#include "../Core/src/StandaloneSnapshotAdapter.h"
|
||||
|
||||
#include <algorithm>
|
||||
@@ -32,6 +33,13 @@ namespace
|
||||
bool StreamHash=false;
|
||||
bool ProfileColumnOverlap=false;
|
||||
bool ForceGenerate=false;
|
||||
bool HasSeedOverride=false;
|
||||
int SeedOverride=0;
|
||||
bool HasRenderDistanceOverride=false;
|
||||
int RenderDistanceOverride=0;
|
||||
bool FloatingIslandsRecipe=false;
|
||||
bool TlsProbeRequested=false;
|
||||
int TlsProbeWorkers=0;
|
||||
bool HasCamera=false;
|
||||
FVector CameraMeters=FVector::ZeroVector;
|
||||
};
|
||||
@@ -72,6 +80,9 @@ namespace
|
||||
" --workers=N --clip-radius=N --max-clip-level=N --max-level=N\n"
|
||||
" --camera=X,Y,Z,YAW,PITCH (position in metres) --stream-hash\n"
|
||||
" --profile-column-overlap --far-horizon-lod8-step=N --force-generate\n"
|
||||
" --seed=N --recipe=surface-world|floating-islands\n"
|
||||
" --render-distance-chunks=N (0 disables the extra far ring)\n"
|
||||
" --tls-probe=N (Linux worker TLS/stack measurement; N=0..12)\n"
|
||||
" --process-affinity=MASK --process-priority=Normal --frame-limit=FPS (viewer compatibility only)\n",
|
||||
argv[0]);
|
||||
return false;
|
||||
@@ -82,6 +93,28 @@ namespace
|
||||
else if(arg=="--stream-hash")options.StreamHash=true;
|
||||
else if(arg=="--profile-column-overlap")options.ProfileColumnOverlap=true;
|
||||
else if(arg=="--force-generate")options.ForceGenerate=true;
|
||||
else if(arg.starts_with("--recipe="))
|
||||
{
|
||||
const std::string_view recipe=arg.substr(std::string_view("--recipe=").size());
|
||||
if(recipe=="surface-world")options.FloatingIslandsRecipe=false;
|
||||
else if(recipe=="floating-islands")options.FloatingIslandsRecipe=true;
|
||||
else {std::fprintf(stderr,"Invalid --recipe value: %.*s\n",static_cast<int>(recipe.size()),recipe.data());return false;}
|
||||
}
|
||||
else if(arg.starts_with("--seed="))
|
||||
{if(!readInt("--seed=",options.SeedOverride))return false;options.HasSeedOverride=true;}
|
||||
else if(arg.starts_with("--render-distance-chunks="))
|
||||
{
|
||||
if(!readInt("--render-distance-chunks=",options.RenderDistanceOverride))return false;
|
||||
options.RenderDistanceOverride=std::max(0,options.RenderDistanceOverride);
|
||||
options.HasRenderDistanceOverride=true;
|
||||
}
|
||||
else if(arg.starts_with("--tls-probe="))
|
||||
{
|
||||
if(!readInt("--tls-probe=",options.TlsProbeWorkers))return false;
|
||||
if(options.TlsProbeWorkers<0||options.TlsProbeWorkers>12)
|
||||
{std::fprintf(stderr,"--tls-probe must be in 0..12\n");return false;}
|
||||
options.TlsProbeRequested=true;
|
||||
}
|
||||
else if(arg.starts_with("--camera="))
|
||||
{
|
||||
if(!ParseCamera(arg.substr(9),options.CameraMeters))
|
||||
@@ -112,6 +145,7 @@ namespace
|
||||
options.ClipRadius=std::clamp(options.ClipRadius,1,64);
|
||||
options.MaxClipLevel=std::clamp(options.MaxClipLevel,0,8);
|
||||
options.FarHorizonLOD8InteriorStepVoxels=std::max(0,options.FarHorizonLOD8InteriorStepVoxels);
|
||||
if(options.TlsProbeRequested)return true;
|
||||
if(!options.WorldAssemblerPrototype||!options.StreamBenchmark||!options.StreamPipeline)
|
||||
{
|
||||
std::fprintf(stderr,"This headless target runs the world-assembler streaming pipeline; pass --world-assembler-prototype --stream-benchmark --stream-pipeline.\n");
|
||||
@@ -127,10 +161,12 @@ int main(int argc,char** argv)
|
||||
const auto coldStart=Clock::now();
|
||||
FOptions options;
|
||||
if(!ParseOptions(argc,argv,options))return 2;
|
||||
std::printf("[HeadlessConfig] data=%s workers=%d clip_radius=%d max_clip_level=%d max_level=%d hash=%s column_overlap=%s force_generate=%s\n",
|
||||
if(options.TlsProbeRequested)return StandaloneTlsProbe::Run(options.TlsProbeWorkers);
|
||||
std::printf("[HeadlessConfig] data=%s workers=%d clip_radius=%d max_clip_level=%d max_level=%d hash=%s column_overlap=%s force_generate=%s recipe=%s seed_override=%s render_distance_override=%s\n",
|
||||
options.DataPath.string().c_str(),options.WorkerCount,options.ClipRadius,options.MaxClipLevel,
|
||||
options.MaxLevel,options.StreamHash?"on":"off",options.ProfileColumnOverlap?"on":"off",
|
||||
options.ForceGenerate?"on":"off");
|
||||
options.ForceGenerate?"on":"off",options.FloatingIslandsRecipe?"floating-islands":"surface-world",
|
||||
options.HasSeedOverride?"yes":"no",options.HasRenderDistanceOverride?"yes":"no");
|
||||
std::printf("[ColdTimeline] stage=owner_data_load begin_ms=%.3f\n",
|
||||
std::chrono::duration<double,std::milli>(Clock::now()-coldStart).count());
|
||||
|
||||
@@ -147,6 +183,16 @@ int main(int argc,char** argv)
|
||||
if(!VFJson::Parser(std::move(ownerJsonText)).Parse(ownerJsonRoot,error))
|
||||
{std::fprintf(stderr,"Owner data load failed: %s\n",error.c_str());return 2;}
|
||||
}
|
||||
if(options.HasSeedOverride
|
||||
&&!StandaloneWorldAssemblyPrototype::OverrideStandaloneSeed(ownerJsonRoot,options.SeedOverride,error))
|
||||
{std::fprintf(stderr,"Seed override failed: %s\n",error.c_str());return 2;}
|
||||
if(options.HasRenderDistanceOverride
|
||||
&&!StandaloneWorldAssemblyPrototype::OverrideStandaloneRenderDistance(
|
||||
ownerJsonRoot,options.RenderDistanceOverride,error))
|
||||
{std::fprintf(stderr,"Render-distance override failed: %s\n",error.c_str());return 2;}
|
||||
if(options.FloatingIslandsRecipe
|
||||
&&!StandaloneWorldAssemblyPrototype::SelectTopStrateAsFloatingIslands(ownerJsonRoot,error))
|
||||
{std::fprintf(stderr,"Floating-island recipe selection failed: %s\n",error.c_str());return 2;}
|
||||
if(!StandaloneOwnerLoader::Resolve(ownerJsonRoot,*ownerWorld,error))
|
||||
{std::fprintf(stderr,"Owner data load failed: %s\n",error.c_str());return 2;}
|
||||
std::printf("[ColdTimeline] stage=owner_data_load end_ms=%.3f\n",
|
||||
@@ -167,9 +213,14 @@ int main(int argc,char** argv)
|
||||
cameraVoxels=FVector(options.CameraMeters.X*4.0f,options.CameraMeters.Y*4.0f,options.CameraMeters.Z*4.0f);
|
||||
|
||||
const auto planStart=Clock::now();
|
||||
VoxelForgeCore::WorldAssemblyManifest worldAssembly;
|
||||
if(!StandaloneWorldAssemblyPrototype::AttachRound1WorldAssemblyPrototype(
|
||||
*ownerWorld,ownerJsonRoot,error,{}))
|
||||
*ownerWorld,ownerJsonRoot,error,{},&worldAssembly))
|
||||
{std::fprintf(stderr,"World assembler prototype setup failed: %s\n",error.c_str());return 2;}
|
||||
if(options.FloatingIslandsRecipe
|
||||
&&!StandaloneWorldAssemblyPrototype::AttachFloatingIslandWorldAssembly(
|
||||
*ownerWorld,ownerJsonRoot,worldAssembly,error))
|
||||
{std::fprintf(stderr,"Floating-island assembly setup failed: %s\n",error.c_str());return 2;}
|
||||
std::printf("[WorldAssemblerPlanTiming] total_ms=%.3f status=PASS\n",
|
||||
std::chrono::duration<double,std::milli>(Clock::now()-planStart).count());
|
||||
|
||||
|
||||
Reference in new issue
Block a user