mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-11 19:14:11 +00:00
Enable native noise generation
- Enable exact Rust Billow sampling and report the selected backend. - Add generation parity probes and native comparison tooling.
This commit is contained in:
@@ -76,3 +76,8 @@ BUILDS/
|
|||||||
.compatwt/
|
.compatwt/
|
||||||
|
|
||||||
.worktrees/
|
.worktrees/
|
||||||
|
|
||||||
|
/VolmLib/
|
||||||
|
/docs/
|
||||||
|
/.perf/
|
||||||
|
/.codegraph/
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import art.arcane.volmlib.util.documentation.ChunkCoordinates;
|
|||||||
import art.arcane.volmlib.util.hunk.Hunk;
|
import art.arcane.volmlib.util.hunk.Hunk;
|
||||||
import art.arcane.volmlib.util.mantle.flag.MantleFlag;
|
import art.arcane.volmlib.util.mantle.flag.MantleFlag;
|
||||||
import art.arcane.volmlib.util.math.M;
|
import art.arcane.volmlib.util.math.M;
|
||||||
|
import art.arcane.volmlib.util.noise.FractalBillowSimplexNoise;
|
||||||
import art.arcane.volmlib.util.matter.MatterStructurePOI;
|
import art.arcane.volmlib.util.matter.MatterStructurePOI;
|
||||||
import art.arcane.volmlib.util.matter.Matter;
|
import art.arcane.volmlib.util.matter.Matter;
|
||||||
import art.arcane.volmlib.util.mantle.runtime.MantleChunk;
|
import art.arcane.volmlib.util.mantle.runtime.MantleChunk;
|
||||||
@@ -312,7 +313,8 @@ public class IrisEngine implements Engine {
|
|||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
IrisLogging.reportError(e);
|
IrisLogging.reportError(e);
|
||||||
}
|
}
|
||||||
IrisLogging.notice("Engine init: " + requiredTarget.getWorld().name() + "/" + requiredTarget.getDimension().getLoadKey() + " seed=" + getSeedManager().getSeed());
|
IrisLogging.notice("Engine init: " + requiredTarget.getWorld().name() + "/" + requiredTarget.getDimension().getLoadKey()
|
||||||
|
+ " seed=" + getSeedManager().getSeed() + " billow2D=" + FractalBillowSimplexNoise.nativeBackendStatus());
|
||||||
_t0 = M.ms();
|
_t0 = M.ms();
|
||||||
phaseStartedAt = System.nanoTime();
|
phaseStartedAt = System.nanoTime();
|
||||||
EngineRuntime initialRuntime = runtimeBuilder.buildRuntime(cacheIdentity);
|
EngineRuntime initialRuntime = runtimeBuilder.buildRuntime(cacheIdentity);
|
||||||
|
|||||||
+17
-2
@@ -154,10 +154,24 @@ tasks.register('terrain3DProbe', JavaExec) {
|
|||||||
|
|
||||||
tasks.register('genProbe', JavaExec) {
|
tasks.register('genProbe', JavaExec) {
|
||||||
group = 'verification'
|
group = 'verification'
|
||||||
description = 'Constructs a real Iris engine over a real pack and generates chunks into buffers on a Bukkit-free JVM.'
|
description = 'Constructs a real Iris engine over a real pack and verifies generation hashes and optional native backend usage.'
|
||||||
mainClass = 'art.arcane.iris.probe.GenerationProbe'
|
mainClass = 'art.arcane.iris.probe.GenerationProbe'
|
||||||
classpath = sourceSets.main.runtimeClasspath
|
classpath = sourceSets.main.runtimeClasspath
|
||||||
jvmArgs('--add-modules', 'jdk.incubator.vector')
|
jvmArgs('--add-modules', 'jdk.incubator.vector')
|
||||||
|
minHeapSize = '2g'
|
||||||
|
maxHeapSize = '6g'
|
||||||
|
if (providers.gradleProperty('probeNativeAccess').orElse('false').get().toBoolean()) {
|
||||||
|
jvmArgs('--enable-native-access=ALL-UNNAMED')
|
||||||
|
}
|
||||||
|
if (providers.gradleProperty('probeNativeBillow').isPresent()) {
|
||||||
|
systemProperty('volmlib.noise.nativeBillow', providers.gradleProperty('probeNativeBillow').get())
|
||||||
|
}
|
||||||
|
systemProperty('volmlib.noise.nativeBillowDiagnostics', providers.gradleProperty('probeNativeDiagnostics').orElse('false').get())
|
||||||
|
systemProperty('iris.probe.expectedBackend', providers.gradleProperty('probeExpectedBackend').orElse('').get())
|
||||||
|
systemProperty('iris.probe.requireNativeSamples', providers.gradleProperty('probeRequireNativeSamples').orElse('false').get())
|
||||||
|
if (providers.gradleProperty('probeNativeLibrary').isPresent()) {
|
||||||
|
systemProperty('volmlib.noise.nativeBillowLibrary', providers.gradleProperty('probeNativeLibrary').get())
|
||||||
|
}
|
||||||
dependsOn(':core:compileJava')
|
dependsOn(':core:compileJava')
|
||||||
doFirst {
|
doFirst {
|
||||||
if (!probePack.isPresent() || probePack.get().isBlank()) {
|
if (!probePack.isPresent() || probePack.get().isBlank()) {
|
||||||
@@ -174,7 +188,8 @@ tasks.register('genProbe', JavaExec) {
|
|||||||
probeCenterChunkX.get(),
|
probeCenterChunkX.get(),
|
||||||
probeCenterChunkZ.get(),
|
probeCenterChunkZ.get(),
|
||||||
probeMulticore.get(),
|
probeMulticore.get(),
|
||||||
probeStudio.get())
|
probeStudio.get(),
|
||||||
|
probeSeed.orElse('1337').get())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import art.arcane.iris.spi.IrisServices;
|
|||||||
import art.arcane.volmlib.nativelib.terrain.NativeBiome;
|
import art.arcane.volmlib.nativelib.terrain.NativeBiome;
|
||||||
import art.arcane.volmlib.nativelib.terrain.NativeBlockState;
|
import art.arcane.volmlib.nativelib.terrain.NativeBlockState;
|
||||||
import art.arcane.volmlib.util.hunk.Hunk;
|
import art.arcane.volmlib.util.hunk.Hunk;
|
||||||
|
import art.arcane.volmlib.util.noise.FractalBillowSimplexNoise;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
@@ -58,7 +59,6 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public final class GenerationProbe {
|
public final class GenerationProbe {
|
||||||
private static final long SEED = 1337L;
|
|
||||||
private static final List<Throwable> REPORTED = Collections.synchronizedList(new ArrayList<>());
|
private static final List<Throwable> REPORTED = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
|
||||||
private static final class InertPreservation implements PreservationRegistry {
|
private static final class InertPreservation implements PreservationRegistry {
|
||||||
@@ -126,7 +126,7 @@ public final class GenerationProbe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
record ProbeConfiguration(File packSource, String dimensionKey, int warmupChunks, int measuredChunks,
|
record ProbeConfiguration(File packSource, String dimensionKey, int warmupChunks, int measuredChunks,
|
||||||
int centerChunkX, int centerChunkZ, boolean multicore, boolean studio) {
|
int centerChunkX, int centerChunkZ, boolean multicore, boolean studio, long seed) {
|
||||||
ProbeConfiguration {
|
ProbeConfiguration {
|
||||||
if (packSource == null) {
|
if (packSource == null) {
|
||||||
throw new IllegalArgumentException("Pack folder is required.");
|
throw new IllegalArgumentException("Pack folder is required.");
|
||||||
@@ -143,8 +143,8 @@ public final class GenerationProbe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static ProbeConfiguration parse(String[] args) {
|
static ProbeConfiguration parse(String[] args) {
|
||||||
if (args.length != 8) {
|
if (args.length != 9) {
|
||||||
throw new IllegalArgumentException("Expected: <pack> <dimension> <warmupChunks> <measuredChunks> <centerChunkX> <centerChunkZ> <multicore> <studio>");
|
throw new IllegalArgumentException("Expected: <pack> <dimension> <warmupChunks> <measuredChunks> <centerChunkX> <centerChunkZ> <multicore> <studio> <seed>");
|
||||||
}
|
}
|
||||||
return new ProbeConfiguration(
|
return new ProbeConfiguration(
|
||||||
new File(args[0]),
|
new File(args[0]),
|
||||||
@@ -154,7 +154,8 @@ public final class GenerationProbe {
|
|||||||
Integer.parseInt(args[4]),
|
Integer.parseInt(args[4]),
|
||||||
Integer.parseInt(args[5]),
|
Integer.parseInt(args[5]),
|
||||||
Boolean.parseBoolean(args[6]),
|
Boolean.parseBoolean(args[6]),
|
||||||
Boolean.parseBoolean(args[7]));
|
Boolean.parseBoolean(args[7]),
|
||||||
|
Long.parseLong(args[8]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +278,9 @@ public final class GenerationProbe {
|
|||||||
throw new IllegalArgumentException("Pack folder not found: " + configuration.packSource().getAbsolutePath());
|
throw new IllegalArgumentException("Pack folder not found: " + configuration.packSource().getAbsolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
File workRoot = Files.createTempDirectory("iris-genprobe-").toFile();
|
Path temporaryRoot = Path.of("build", "generation-probe").toAbsolutePath();
|
||||||
|
Files.createDirectories(temporaryRoot);
|
||||||
|
File workRoot = Files.createTempDirectory(temporaryRoot, "iris-genprobe-").toFile();
|
||||||
IrisData data = null;
|
IrisData data = null;
|
||||||
Engine engine = null;
|
Engine engine = null;
|
||||||
Throwable executionFailure = null;
|
Throwable executionFailure = null;
|
||||||
@@ -288,6 +291,7 @@ public final class GenerationProbe {
|
|||||||
|
|
||||||
System.out.println("[genprobe] pack: " + configuration.packSource().getAbsolutePath());
|
System.out.println("[genprobe] pack: " + configuration.packSource().getAbsolutePath());
|
||||||
System.out.println("[genprobe] dimension: " + configuration.dimensionKey());
|
System.out.println("[genprobe] dimension: " + configuration.dimensionKey());
|
||||||
|
System.out.println("[genprobe] seed: " + configuration.seed());
|
||||||
System.out.println("[genprobe] warmup chunks: " + configuration.warmupChunks());
|
System.out.println("[genprobe] warmup chunks: " + configuration.warmupChunks());
|
||||||
System.out.println("[genprobe] measured chunks: " + configuration.measuredChunks());
|
System.out.println("[genprobe] measured chunks: " + configuration.measuredChunks());
|
||||||
System.out.println("[genprobe] center chunk: " + configuration.centerChunkX() + "," + configuration.centerChunkZ());
|
System.out.println("[genprobe] center chunk: " + configuration.centerChunkX() + "," + configuration.centerChunkZ());
|
||||||
@@ -304,7 +308,7 @@ public final class GenerationProbe {
|
|||||||
IrisWorld world = IrisWorld.builder()
|
IrisWorld world = IrisWorld.builder()
|
||||||
.platformIdentity("iris:probe")
|
.platformIdentity("iris:probe")
|
||||||
.name("probe")
|
.name("probe")
|
||||||
.seed(SEED)
|
.seed(configuration.seed())
|
||||||
.worldFolder(new File(workRoot, "world"))
|
.worldFolder(new File(workRoot, "world"))
|
||||||
.minHeight(dimension.getMinHeight())
|
.minHeight(dimension.getMinHeight())
|
||||||
.maxHeight(dimension.getMaxHeight())
|
.maxHeight(dimension.getMaxHeight())
|
||||||
@@ -323,7 +327,9 @@ public final class GenerationProbe {
|
|||||||
+ " seed=" + engine.getSeedManager().getSeed()
|
+ " seed=" + engine.getSeedManager().getSeed()
|
||||||
+ " minY=" + engine.getMinHeight() + " maxY=" + engine.getMaxHeight()
|
+ " minY=" + engine.getMinHeight() + " maxY=" + engine.getMaxHeight()
|
||||||
+ " timeMs=" + String.format(Locale.ROOT, "%.3f", nanosToMillis(engineReadyNanos)));
|
+ " timeMs=" + String.format(Locale.ROOT, "%.3f", nanosToMillis(engineReadyNanos)));
|
||||||
|
long nativeSamplesBefore = FractalBillowSimplexNoise.nativeSampleCount();
|
||||||
GenerationResult generation = generate(engine, configuration);
|
GenerationResult generation = generate(engine, configuration);
|
||||||
|
verifyBackend(nativeSamplesBefore);
|
||||||
String status = generation.failedChunks() == 0 ? "PASS" : "FAIL";
|
String status = generation.failedChunks() == 0 ? "PASS" : "FAIL";
|
||||||
printGenerationFailures(generation);
|
printGenerationFailures(generation);
|
||||||
return new ProbeResult(
|
return new ProbeResult(
|
||||||
@@ -354,6 +360,20 @@ public final class GenerationProbe {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void verifyBackend(long nativeSamplesBefore) {
|
||||||
|
String backend = FractalBillowSimplexNoise.nativeBackendStatus();
|
||||||
|
long nativeSamples = FractalBillowSimplexNoise.nativeSampleCount() - nativeSamplesBefore;
|
||||||
|
System.out.println("IRIS_GENPROBE_BACKEND status=" + backend + " native_samples=" + nativeSamples
|
||||||
|
+ " diagnostics=" + Boolean.getBoolean("volmlib.noise.nativeBillowDiagnostics"));
|
||||||
|
String expected = System.getProperty("iris.probe.expectedBackend", "");
|
||||||
|
if (!expected.isEmpty() && !expected.equals(backend)) {
|
||||||
|
throw new IllegalStateException("Expected backend " + expected + ", received " + backend);
|
||||||
|
}
|
||||||
|
if (Boolean.getBoolean("iris.probe.requireNativeSamples") && nativeSamples <= 0L) {
|
||||||
|
throw new IllegalStateException("Real chunk generation did not report native Billow samples.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void configureProbeRuntime(File workRoot) {
|
private static void configureProbeRuntime(File workRoot) {
|
||||||
REPORTED.clear();
|
REPORTED.clear();
|
||||||
StubPlatform.bindGenerationStateHandlers();
|
StubPlatform.bindGenerationStateHandlers();
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ public final class GenerationProbeTest {
|
|||||||
"2048",
|
"2048",
|
||||||
"-2048",
|
"-2048",
|
||||||
"true",
|
"true",
|
||||||
"true"
|
"true",
|
||||||
|
"-1"
|
||||||
});
|
});
|
||||||
|
|
||||||
assertEquals(new File("/tmp/pack"), configuration.packSource());
|
assertEquals(new File("/tmp/pack"), configuration.packSource());
|
||||||
@@ -35,6 +36,7 @@ public final class GenerationProbeTest {
|
|||||||
assertEquals(-2048, configuration.centerChunkZ());
|
assertEquals(-2048, configuration.centerChunkZ());
|
||||||
assertTrue(configuration.multicore());
|
assertTrue(configuration.multicore());
|
||||||
assertTrue(configuration.studio());
|
assertTrue(configuration.studio());
|
||||||
|
assertEquals(-1L, configuration.seed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -42,11 +44,25 @@ public final class GenerationProbeTest {
|
|||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> GenerationProbe.ProbeConfiguration.parse(new String[]{"/tmp/pack"}));
|
() -> GenerationProbe.ProbeConfiguration.parse(new String[]{"/tmp/pack"}));
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> new GenerationProbe.ProbeConfiguration(new File("/tmp/pack"), " ", 1, 1, 0, 0, false, false));
|
() -> new GenerationProbe.ProbeConfiguration(new File("/tmp/pack"), " ", 1, 1, 0, 0, false, false, 1337L));
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> new GenerationProbe.ProbeConfiguration(new File("/tmp/pack"), "overworld", 0, 1, 0, 0, false, false));
|
() -> new GenerationProbe.ProbeConfiguration(new File("/tmp/pack"), "overworld", 0, 1, 0, 0, false, false, 1337L));
|
||||||
assertThrows(IllegalArgumentException.class,
|
assertThrows(IllegalArgumentException.class,
|
||||||
() -> new GenerationProbe.ProbeConfiguration(new File("/tmp/pack"), "overworld", 1, 0, 0, 0, false, false));
|
() -> new GenerationProbe.ProbeConfiguration(new File("/tmp/pack"), "overworld", 1, 0, 0, 0, false, false, 1337L));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parsesSignedBorderCoordinatesAndFullWidthSeeds() {
|
||||||
|
GenerationProbe.ProbeConfiguration configuration = GenerationProbe.ProbeConfiguration.parse(new String[]{
|
||||||
|
"/tmp/pack", "overworld", "32", "96", "1874000", "-1874000", "false", "false",
|
||||||
|
Long.toString(Long.MIN_VALUE)
|
||||||
|
});
|
||||||
|
assertEquals(Long.MIN_VALUE, configuration.seed());
|
||||||
|
assertEquals(-1874000, configuration.centerChunkZ());
|
||||||
|
assertThrows(NumberFormatException.class,
|
||||||
|
() -> GenerationProbe.ProbeConfiguration.parse(new String[]{
|
||||||
|
"/tmp/pack", "overworld", "32", "96", "0", "0", "false", "false", "invalid"
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
import argparse
|
||||||
|
import fcntl
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from pathlib import Path
|
||||||
|
import statistics
|
||||||
|
import subprocess
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
def fields(line):
|
||||||
|
return dict(part.split('=', 1) for part in line.split()[1:])
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('--pack', required=True)
|
||||||
|
parser.add_argument('--dimension', required=True)
|
||||||
|
parser.add_argument('--volmlib', required=True)
|
||||||
|
parser.add_argument('--seed', type=int, default=1337)
|
||||||
|
parser.add_argument('--center-x', type=int, default=2048)
|
||||||
|
parser.add_argument('--center-z', type=int, default=2048)
|
||||||
|
parser.add_argument('--warmup', type=int, default=64)
|
||||||
|
parser.add_argument('--measured', type=int, default=192)
|
||||||
|
parser.add_argument('--pairs', type=int, default=2)
|
||||||
|
parser.add_argument('--diagnostics', action='store_true')
|
||||||
|
parser.add_argument('--output', required=True)
|
||||||
|
args = parser.parse_args()
|
||||||
|
if args.pairs < 1:
|
||||||
|
parser.error('--pairs must be positive')
|
||||||
|
root = Path(__file__).resolve().parents[1]
|
||||||
|
output = Path(args.output).resolve()
|
||||||
|
if not any(output.is_relative_to(root / allowed) for allowed in ('.perf', 'build')):
|
||||||
|
parser.error('--output must be inside this checkout\'s .perf or build directory')
|
||||||
|
output.mkdir(parents=True, exist_ok=False)
|
||||||
|
environment = os.environ.copy()
|
||||||
|
environment.pop('GIT_CONFIG_COUNT', None)
|
||||||
|
for variable in ('JAVA_TOOL_OPTIONS', '_JAVA_OPTIONS', 'JDK_JAVA_OPTIONS'):
|
||||||
|
environment.pop(variable, None)
|
||||||
|
results = []
|
||||||
|
expected_hashes = None
|
||||||
|
with open('/tmp/iris-acceleration-integration-benchmark.lock', 'a') as lock:
|
||||||
|
print('Waiting for generation benchmark lock', flush=True)
|
||||||
|
fcntl.flock(lock, fcntl.LOCK_EX)
|
||||||
|
for pair in range(args.pairs):
|
||||||
|
for native in ([False, True] if pair % 2 == 0 else [True, False]):
|
||||||
|
backend = 'native' if native else 'java'
|
||||||
|
command = [str(root / 'gradlew'), ':probe:genProbe', '--no-daemon',
|
||||||
|
'-PincludeNativeBillow=true', f'-PlocalVolmLibDirectory={args.volmlib}',
|
||||||
|
f'-PprobePack={Path(args.pack).resolve()}', f'-PprobeDimension={args.dimension}',
|
||||||
|
f'-PprobeSeed={args.seed}', f'-PprobeCenterChunkX={args.center_x}',
|
||||||
|
f'-PprobeCenterChunkZ={args.center_z}', f'-PprobeWarmupChunks={args.warmup}',
|
||||||
|
f'-PprobeMeasuredChunks={args.measured}', '-PprobeMulticore=false',
|
||||||
|
'-PprobeStudio=false', f'-PprobeNativeBillow={str(native).lower()}',
|
||||||
|
'-PprobeNativeAccess=true',
|
||||||
|
f'-PprobeNativeDiagnostics={str(args.diagnostics).lower()}',
|
||||||
|
f'-PprobeRequireNativeSamples={str(native and args.diagnostics).lower()}',
|
||||||
|
f'-PprobeExpectedBackend={"native" if native else "java-disabled"}']
|
||||||
|
label = f'{pair + 1}-{backend}'
|
||||||
|
(output / f'{label}.command.json').write_text(json.dumps(command, indent=2) + '\n')
|
||||||
|
print(f'Running {label}', flush=True)
|
||||||
|
started = time.monotonic()
|
||||||
|
with (output / f'{label}.log').open('w') as log:
|
||||||
|
completed = subprocess.run(command, cwd=root, env=environment, stdout=log,
|
||||||
|
stderr=subprocess.STDOUT, check=False)
|
||||||
|
text = (output / f'{label}.log').read_text()
|
||||||
|
lines = text.splitlines()
|
||||||
|
hashes = [line for line in lines if line.startswith('GENPROBE_CHUNK_HASH ')]
|
||||||
|
result_lines = [line for line in lines if line.startswith('IRIS_GENPROBE_RESULT ')]
|
||||||
|
backend_lines = [line for line in lines if line.startswith('IRIS_GENPROBE_BACKEND ')]
|
||||||
|
if completed.returncode != 0 or len(result_lines) != 1 or len(backend_lines) != 1:
|
||||||
|
raise RuntimeError(f'{label} failed; see {output / (label + ".log")}')
|
||||||
|
result = fields(result_lines[0])
|
||||||
|
status = fields(backend_lines[0])
|
||||||
|
if result['status'] != 'PASS' or len(hashes) != args.warmup + args.measured:
|
||||||
|
raise RuntimeError(f'{label} did not generate every chunk successfully')
|
||||||
|
expected_backend = 'native' if native else 'java-disabled'
|
||||||
|
if status['status'] != expected_backend:
|
||||||
|
raise RuntimeError(f'{label} backend mismatch: {status}')
|
||||||
|
if expected_hashes is None:
|
||||||
|
expected_hashes = hashes
|
||||||
|
elif hashes != expected_hashes:
|
||||||
|
raise RuntimeError(f'{label} chunk block/biome hashes differ')
|
||||||
|
results.append({'pair': pair + 1, 'backend': backend, 'result': result,
|
||||||
|
'backend_status': status, 'wall_seconds': time.monotonic() - started})
|
||||||
|
(output / 'results.json').write_text(json.dumps(results, indent=2) + '\n')
|
||||||
|
rates = {backend: statistics.median(float(run['result']['measured_cps']) for run in results
|
||||||
|
if run['backend'] == backend) for backend in ('java', 'native')}
|
||||||
|
summary = {'median_chunks_per_second': rates,
|
||||||
|
'native_throughput_change_percent': (rates['native'] / rates['java'] - 1) * 100,
|
||||||
|
'all_chunk_hashes_equal': True, 'diagnostics_enabled': args.diagnostics,
|
||||||
|
'run_count': len(results), 'seed': args.seed,
|
||||||
|
'unique_chunks': args.warmup + args.measured}
|
||||||
|
(output / 'summary.json').write_text(json.dumps(summary, indent=2) + '\n')
|
||||||
|
print(json.dumps(summary, indent=2))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user