Way too much

This commit is contained in:
Brian Neumann-Fopiano
2026-08-25 12:52:12 -04:00
parent 2797a5bf22
commit 07cc76614f
131 changed files with 6826 additions and 1094 deletions
+5 -1
View File
@@ -55,6 +55,8 @@ Provider<String> probeWarmupChunks = providers.gradleProperty('probeWarmupChunks
Provider<String> probeMeasuredChunks = providers.gradleProperty('probeMeasuredChunks').orElse('1024')
Provider<String> probeCenterChunkX = providers.gradleProperty('probeCenterChunkX').orElse('2048')
Provider<String> probeCenterChunkZ = providers.gradleProperty('probeCenterChunkZ').orElse('2048')
Provider<String> probeMulticore = providers.gradleProperty('probeMulticore').orElse('false')
Provider<String> probeStudio = providers.gradleProperty('probeStudio').orElse('false')
tasks.register('genProbe', JavaExec) {
group = 'verification'
@@ -76,7 +78,9 @@ tasks.register('genProbe', JavaExec) {
probeWarmupChunks.get(),
probeMeasuredChunks.get(),
probeCenterChunkX.get(),
probeCenterChunkZ.get())
probeCenterChunkZ.get(),
probeMulticore.get(),
probeStudio.get())
}
}
@@ -59,7 +59,6 @@ import java.util.stream.Stream;
public final class GenerationProbe {
private static final long SEED = 1337L;
private static final int SIGNATURE_SAMPLE_STEP = 8;
private static final List<Throwable> REPORTED = Collections.synchronizedList(new ArrayList<>());
private static final class InertPreservation implements PreservationRegistry {
@@ -127,7 +126,7 @@ public final class GenerationProbe {
}
record ProbeConfiguration(File packSource, String dimensionKey, int warmupChunks, int measuredChunks,
int centerChunkX, int centerChunkZ) {
int centerChunkX, int centerChunkZ, boolean multicore, boolean studio) {
ProbeConfiguration {
if (packSource == null) {
throw new IllegalArgumentException("Pack folder is required.");
@@ -144,8 +143,8 @@ public final class GenerationProbe {
}
static ProbeConfiguration parse(String[] args) {
if (args.length != 6) {
throw new IllegalArgumentException("Expected: <pack> <dimension> <warmupChunks> <measuredChunks> <centerChunkX> <centerChunkZ>");
if (args.length != 8) {
throw new IllegalArgumentException("Expected: <pack> <dimension> <warmupChunks> <measuredChunks> <centerChunkX> <centerChunkZ> <multicore> <studio>");
}
return new ProbeConfiguration(
new File(args[0]),
@@ -153,7 +152,9 @@ public final class GenerationProbe {
Integer.parseInt(args[2]),
Integer.parseInt(args[3]),
Integer.parseInt(args[4]),
Integer.parseInt(args[5]));
Integer.parseInt(args[5]),
Boolean.parseBoolean(args[6]),
Boolean.parseBoolean(args[7]));
}
}
@@ -189,18 +190,21 @@ public final class GenerationProbe {
TimingSummary measuredTimings, String signature) {
}
record ProbeResult(String status, String dimensionKey, int warmupChunks, int measuredChunks,
record ProbeResult(String status, String dimensionKey, int warmupChunks, int measuredChunks, boolean multicore,
boolean studio,
int successfulChunks, int failedChunks, long engineReadyNanos, long firstChunkNanos,
TimingSummary measuredTimings, String signature) {
String machineLine() {
double measuredSeconds = measuredTimings.totalNanos() / 1_000_000_000D;
double chunksPerSecond = measuredSeconds == 0D ? 0D : measuredChunks / measuredSeconds;
return String.format(Locale.ROOT,
"IRIS_GENPROBE_RESULT version=1 status=%s dimension=%s warmup_chunks=%d measured_chunks=%d successful_chunks=%d failed_chunks=%d engine_ready_ms=%.3f first_chunk_ms=%.3f measured_median_ms=%.3f measured_p95_ms=%.3f measured_max_ms=%.3f measured_total_ms=%.3f measured_cps=%.3f signature=%s",
"IRIS_GENPROBE_RESULT version=1 status=%s dimension=%s warmup_chunks=%d measured_chunks=%d multicore=%s studio=%s successful_chunks=%d failed_chunks=%d engine_ready_ms=%.3f first_chunk_ms=%.3f measured_median_ms=%.3f measured_p95_ms=%.3f measured_max_ms=%.3f measured_total_ms=%.3f measured_cps=%.3f signature=%s",
status,
dimensionKey,
warmupChunks,
measuredChunks,
multicore,
studio,
successfulChunks,
failedChunks,
nanosToMillis(engineReadyNanos),
@@ -239,6 +243,8 @@ public final class GenerationProbe {
configuration.dimensionKey(),
configuration.warmupChunks(),
configuration.measuredChunks(),
configuration.multicore(),
configuration.studio(),
0,
configuration.warmupChunks() + configuration.measuredChunks(),
0L,
@@ -285,6 +291,8 @@ public final class GenerationProbe {
System.out.println("[genprobe] warmup chunks: " + configuration.warmupChunks());
System.out.println("[genprobe] measured chunks: " + configuration.measuredChunks());
System.out.println("[genprobe] center chunk: " + configuration.centerChunkX() + "," + configuration.centerChunkZ());
System.out.println("[genprobe] multicore: " + configuration.multicore());
System.out.println("[genprobe] studio: " + configuration.studio());
long engineStart = System.nanoTime();
data = IrisData.get(pack);
@@ -302,7 +310,11 @@ public final class GenerationProbe {
.maxHeight(dimension.getMaxHeight())
.build();
EngineTarget target = new EngineTarget(world, dimension, data);
engine = new IrisEngine(target, IrisEngine.InitializationMode.RUNTIME);
engine = new IrisEngine(
target,
configuration.studio()
? IrisEngine.InitializationMode.STUDIO
: IrisEngine.InitializationMode.RUNTIME);
long engineReadyNanos = System.nanoTime() - engineStart;
List<Throwable> initNoise = settleAndDrain();
@@ -311,7 +323,6 @@ public final class GenerationProbe {
+ " seed=" + engine.getSeedManager().getSeed()
+ " minY=" + engine.getMinHeight() + " maxY=" + engine.getMaxHeight()
+ " timeMs=" + String.format(Locale.ROOT, "%.3f", nanosToMillis(engineReadyNanos)));
GenerationResult generation = generate(engine, configuration);
String status = generation.failedChunks() == 0 ? "PASS" : "FAIL";
printGenerationFailures(generation);
@@ -320,6 +331,8 @@ public final class GenerationProbe {
configuration.dimensionKey(),
configuration.warmupChunks(),
configuration.measuredChunks(),
configuration.multicore(),
configuration.studio(),
generation.successfulChunks(),
generation.failedChunks(),
engineReadyNanos,
@@ -390,7 +403,12 @@ public final class GenerationProbe {
Hunk<PlatformBiome> biomes = Hunk.newArrayHunk(16, height, 16);
long started = System.nanoTime();
try {
engine.generate(coordinate.x() << 4, coordinate.z() << 4, blocks, biomes, false);
engine.generate(
coordinate.x() << 4,
coordinate.z() << 4,
blocks,
biomes,
configuration.multicore());
} catch (Throwable e) {
failures.add(e);
}
@@ -465,10 +483,9 @@ public final class GenerationProbe {
private static void updateSignature(MessageDigest digest, ChunkCoordinate coordinate,
Hunk<PlatformBlockState> blocks, Hunk<PlatformBiome> biomes, int height) {
updateDigest(digest, coordinate.x() + "," + coordinate.z());
int verticalStep = Math.max(1, height / 16);
for (int x = 0; x < 16; x += SIGNATURE_SAMPLE_STEP) {
for (int z = 0; z < 16; z += SIGNATURE_SAMPLE_STEP) {
for (int y = 0; y < height; y += verticalStep) {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = 0; y < height; y++) {
PlatformBlockState state = blocks.get(x, y, z);
PlatformBiome biome = biomes.get(x, y, z);
updateDigest(digest, state == null ? "minecraft:air" : state.key());
@@ -0,0 +1,157 @@
package art.arcane.iris.probe;
import art.arcane.iris.engine.river.RiverBodyProfile;
import art.arcane.iris.engine.river.RiverEdgeId;
import art.arcane.iris.engine.river.RiverNode;
import art.arcane.iris.engine.river.RiverNodeId;
import art.arcane.iris.engine.river.RiverPolyline;
import art.arcane.iris.engine.river.RiverReach;
import art.arcane.iris.engine.river.RiverRouteState;
import art.arcane.iris.engine.river.RiverSample;
import art.arcane.iris.engine.river.RiverTile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
public final class RiverTileProbe {
private static final int WARMUP_ROUNDS = 5;
private static final int MEASURED_ROUNDS = 25;
private static final int SAMPLES_PER_ROUND = 8_192;
private RiverTileProbe() {
}
public static void main(String[] args) {
RiverTile tile = createTile();
long expectedSignature = sampleRound(tile);
for (int round = 0; round < WARMUP_ROUNDS; round++) {
requireSignature(expectedSignature, sampleRound(tile));
}
long[] timings = new long[MEASURED_ROUNDS];
for (int round = 0; round < MEASURED_ROUNDS; round++) {
long start = System.nanoTime();
long signature = sampleRound(tile);
timings[round] = System.nanoTime() - start;
requireSignature(expectedSignature, signature);
System.out.printf(Locale.ROOT,
"IRIS_RIVER_TILE_SAMPLE round=%d nanos=%d signature=%016x%n",
round,
timings[round],
signature);
}
long[] sorted = timings.clone();
Arrays.sort(sorted);
System.out.printf(Locale.ROOT,
"IRIS_RIVER_TILE_RESULT version=1 rounds=%d samples_per_round=%d median_nanos=%d p95_nanos=%d signature=%016x%n",
MEASURED_ROUNDS,
SAMPLES_PER_ROUND,
sorted[MEASURED_ROUNDS / 2],
sorted[(int) StrictMath.ceil(MEASURED_ROUNDS * 0.95D) - 1],
expectedSignature);
}
private static RiverTile createTile() {
List<RiverReach> reaches = new ArrayList<>(64);
for (int reachIndex = 0; reachIndex < 64; reachIndex++) {
RiverNode from = node(0L, reachIndex, 0D, reachIndex * 32D);
RiverNode to = node(1L, reachIndex, 2_048D, reachIndex * 32D);
RiverBodyProfile profile = profile(reachIndex);
double[] x = new double[33];
double[] z = new double[33];
for (int point = 0; point < x.length; point++) {
x[point] = point * 64D;
z[point] = reachIndex * 32D
+ StrictMath.sin(point * 0.625D + reachIndex * 0.25D) * 12D;
}
reaches.add(new RiverReach(
RiverEdgeId.of(from.id(), to.id()),
from,
to,
RiverRouteState.WET,
1 + reachIndex % 4,
1 + reachIndex % 3,
profile.maximumWidth(),
profile.maximumBankWidth(),
profile.maximumDepth(),
profile,
false,
false,
new RiverPolyline(x, z)
));
}
return new RiverTile(0, 0, 0, 0, 2_048, 2_048, reaches);
}
private static RiverBodyProfile profile(int reachIndex) {
double[] positions = new double[17];
double[] widths = new double[17];
double[] bankWidths = new double[17];
double[] depths = new double[17];
double[] roofScales = new double[17];
for (int index = 0; index < positions.length; index++) {
double position = index / 16D;
double body = StrictMath.sin(StrictMath.PI * position);
positions[index] = position;
widths[index] = 8D + reachIndex % 5 + body * 6D;
bankWidths[index] = 4D + reachIndex % 3 + body * 4D;
depths[index] = 3D + reachIndex % 2 + body * 2D;
roofScales[index] = 1D - body * 0.4D;
}
return new RiverBodyProfile(positions, widths, bankWidths, depths, roofScales);
}
private static RiverNode node(long cellX, long cellZ, double x, double z) {
return new RiverNode(
new RiverNodeId(cellX, cellZ),
x,
z,
64D,
64D,
64D,
64D,
false,
true
);
}
private static long sampleRound(RiverTile tile) {
long signature = 0xCBF29CE484222325L;
for (int sampleIndex = 0; sampleIndex < SAMPLES_PER_ROUND; sampleIndex++) {
double x = Math.floorMod(sampleIndex * 1_229, 2_048) + 0.375D;
double z = Math.floorMod(sampleIndex * 811, 2_048) + 0.625D;
double additionalRadius = 16D + sampleIndex % 17;
RiverSample sample = tile.sampleExpanded(x, z, additionalRadius);
signature = mix(signature, sample.present() ? 1L : 0L);
if (!sample.present()) {
continue;
}
signature = mix(signature, sample.reachId().stableId());
signature = mix(signature, Double.doubleToLongBits(sample.distance()));
signature = mix(signature, Double.doubleToLongBits(sample.alongReach()));
signature = mix(signature, Double.doubleToLongBits(sample.carveWeight()));
signature = mix(signature, Double.doubleToLongBits(sample.width()));
signature = mix(signature, Double.doubleToLongBits(sample.bankWidth()));
signature = mix(signature, Double.doubleToLongBits(sample.depth()));
signature = mix(signature, sample.section().ordinal());
}
return signature;
}
private static long mix(long hash, long value) {
return (hash ^ value) * 0x100000001B3L;
}
private static void requireSignature(long expected, long actual) {
if (actual != expected) {
throw new IllegalStateException(String.format(
Locale.ROOT,
"River tile output changed: expected %016x but got %016x",
expected,
actual
));
}
}
}
@@ -22,7 +22,9 @@ public final class GenerationProbeTest {
"256",
"1024",
"2048",
"-2048"
"-2048",
"true",
"true"
});
assertEquals(new File("/tmp/pack"), configuration.packSource());
@@ -31,6 +33,8 @@ public final class GenerationProbeTest {
assertEquals(1024, configuration.measuredChunks());
assertEquals(2048, configuration.centerChunkX());
assertEquals(-2048, configuration.centerChunkZ());
assertTrue(configuration.multicore());
assertTrue(configuration.studio());
}
@Test
@@ -38,11 +42,11 @@ public final class GenerationProbeTest {
assertThrows(IllegalArgumentException.class,
() -> GenerationProbe.ProbeConfiguration.parse(new String[]{"/tmp/pack"}));
assertThrows(IllegalArgumentException.class,
() -> new GenerationProbe.ProbeConfiguration(new File("/tmp/pack"), " ", 1, 1, 0, 0));
() -> new GenerationProbe.ProbeConfiguration(new File("/tmp/pack"), " ", 1, 1, 0, 0, false, false));
assertThrows(IllegalArgumentException.class,
() -> new GenerationProbe.ProbeConfiguration(new File("/tmp/pack"), "overworld", 0, 1, 0, 0));
() -> new GenerationProbe.ProbeConfiguration(new File("/tmp/pack"), "overworld", 0, 1, 0, 0, false, false));
assertThrows(IllegalArgumentException.class,
() -> new GenerationProbe.ProbeConfiguration(new File("/tmp/pack"), "overworld", 1, 0, 0, 0));
() -> new GenerationProbe.ProbeConfiguration(new File("/tmp/pack"), "overworld", 1, 0, 0, 0, false, false));
}
@Test
@@ -73,11 +77,11 @@ public final class GenerationProbeTest {
GenerationProbe.TimingSummary timings = new GenerationProbe.TimingSummary(
10_000_000L, 20_000_000L, 30_000_000L, 40_000_000L);
GenerationProbe.ProbeResult result = new GenerationProbe.ProbeResult(
"PASS", "underworld", 2, 4, 6, 0,
"PASS", "underworld", 2, 4, true, true, 6, 0,
5_000_000L, 6_000_000L, timings, "0123456789abcdef");
assertEquals(
"IRIS_GENPROBE_RESULT version=1 status=PASS dimension=underworld warmup_chunks=2 measured_chunks=4 successful_chunks=6 failed_chunks=0 engine_ready_ms=5.000 first_chunk_ms=6.000 measured_median_ms=10.000 measured_p95_ms=20.000 measured_max_ms=30.000 measured_total_ms=40.000 measured_cps=100.000 signature=0123456789abcdef",
"IRIS_GENPROBE_RESULT version=1 status=PASS dimension=underworld warmup_chunks=2 measured_chunks=4 multicore=true studio=true successful_chunks=6 failed_chunks=0 engine_ready_ms=5.000 first_chunk_ms=6.000 measured_median_ms=10.000 measured_p95_ms=20.000 measured_max_ms=30.000 measured_total_ms=40.000 measured_cps=100.000 signature=0123456789abcdef",
result.machineLine());
}