Scratch resets and gated counters

- Terrain batch scratch marks reset in finally blocks so a failing kernel cannot grow the scratch
- Generator evaluation counters only count when generation counters are enabled
- Core tests run with generation counters enabled
This commit is contained in:
Brian Neumann-Fopiano committed 2026-10-22 04:08:14 -04:00
1 parent 6582d9d14d
commit ae1a84702c
5 files changed
+95 -30

No files matched your search

+1
View File
@@ -178,6 +178,7 @@ dependencies {
tasks.named('test').configure {
maxHeapSize = '1g'
jvmArgs('-XX:+ExitOnOutOfMemoryError')
systemProperty('iris.generation.counters', 'true')
}
java {
@@ -1,5 +1,7 @@
package art.arcane.iris.generation.bake;
import art.arcane.iris.generation.runtime.GenerationCounter;
import java.util.concurrent.atomic.LongAdder;
public final class GeneratorEvaluations {
@@ -12,15 +14,24 @@ public final class GeneratorEvaluations {
}
public static void bakedChunk(long evaluations) {
if (!GenerationCounter.ENABLED) {
return;
}
BAKED_CHUNKS.increment();
BAKED.add(evaluations);
}
public static void batched(long evaluations) {
if (!GenerationCounter.ENABLED) {
return;
}
BATCHED.add(evaluations);
}
public static void scalar(int evaluations) {
if (!GenerationCounter.ENABLED) {
return;
}
SCALAR.add(evaluations);
}
@@ -85,6 +85,16 @@ public final class TerrainProgram {
}
int mark = scratch.mark();
int indexMark = scratch.indexMark();
try {
return accumulate(members, group, scratch, xs, zs, count, lows, highs, heights);
} finally {
scratch.reset(mark);
scratch.resetIndices(indexMark);
}
}
private long accumulate(IrisGenerator[] members, int group, TerrainBatchScratch scratch, double[] xs, double[] zs,
int count, double[] lows, double[] highs, double[] heights) {
int[] modes = scratch.indices(count);
int activeCount = 0;
for (int index = 0; index < count; index++) {
@@ -111,7 +121,6 @@ public final class TerrainProgram {
activeCount++;
}
if (activeCount == 0) {
scratch.resetIndices(indexMark);
return 0L;
}
double[] activeX = scratch.buffer(activeCount);
@@ -154,8 +163,6 @@ public final class TerrainProgram {
for (int index = 0; index < activeCount; index++) {
heights[activeIndex[index]] += sums[index] / members.length;
}
scratch.reset(mark);
scratch.resetIndices(indexMark);
return (long) activeCount * members.length;
}
}
@@ -91,10 +91,15 @@ public final class GeneratorProgram {
return sample(scratch, x, z);
}
int mark = scratch.mark();
double[] cached = scratch.buffer(1);
boolean hit = IrisGenerator.cachedSurface(stripes, x, z, superSeed, cached, 0);
double value = cached[0];
scratch.reset(mark);
boolean hit;
double value;
try {
double[] cached = scratch.buffer(1);
hit = IrisGenerator.cachedSurface(stripes, x, z, superSeed, cached, 0);
value = cached[0];
} finally {
scratch.reset(mark);
}
if (hit) {
return value;
}
@@ -125,6 +130,15 @@ public final class GeneratorProgram {
private void surfaceHeights(TerrainBatchScratch scratch, double[] xs, double[] zs, int count, double[] out) {
int mark = scratch.mark();
int indexMark = scratch.indexMark();
try {
fillSurfaceHeights(scratch, xs, zs, count, out);
} finally {
scratch.resetIndices(indexMark);
scratch.reset(mark);
}
}
private void fillSurfaceHeights(TerrainBatchScratch scratch, double[] xs, double[] zs, int count, double[] out) {
int[] northWest = scratch.indices(count);
int[] northEast = scratch.indices(count);
int[] southWest = scratch.indices(count);
@@ -209,14 +223,21 @@ public final class GeneratorProgram {
}
out[index] = surfaceDetail == 0D ? smooth : smooth + (detail[detailIndex[index]] - smooth) * surfaceDetail;
}
scratch.resetIndices(indexMark);
scratch.reset(mark);
}
private void resolveLattice(TerrainBatchScratch scratch, int nodes, double[] lattice) {
IrisGenerator.SurfaceCacheStripe[] stripes = generator.surfaceStripes();
int indexMark = scratch.indexMark();
int mark = scratch.mark();
try {
fillLattice(scratch, nodes, lattice, stripes);
} finally {
scratch.reset(mark);
scratch.resetIndices(indexMark);
}
}
private void fillLattice(TerrainBatchScratch scratch, int nodes, double[] lattice, IrisGenerator.SurfaceCacheStripe[] stripes) {
int[] missing = scratch.indices(nodes);
double[] missingX = scratch.buffer(nodes);
double[] missingZ = scratch.buffer(nodes);
@@ -242,12 +263,18 @@ public final class GeneratorProgram {
}
}
}
scratch.reset(mark);
scratch.resetIndices(indexMark);
}
private void sample(TerrainBatchScratch scratch, double[] xs, double[] zs, int count, double[] out) {
int mark = scratch.mark();
try {
sampleBatch(scratch, xs, zs, count, out);
} finally {
scratch.reset(mark);
}
}
private void sampleBatch(TerrainBatchScratch scratch, double[] xs, double[] zs, int count, double[] out) {
double[] sampleX = scratch.buffer(count);
double[] sampleZ = scratch.buffer(count);
double[] noise = scratch.buffer(count);
@@ -284,6 +311,5 @@ public final class GeneratorProgram {
out[index] = generator.cell(xs[index], zs[index], out[index], 0D);
}
}
scratch.reset(mark);
}
}
@@ -52,6 +52,14 @@ public final class NoiseLayerProgram {
return;
}
int mark = scratch.mark();
try {
fill(scratch, xs, zs, count, out);
} finally {
scratch.reset(mark);
}
}
private void fill(TerrainBatchScratch scratch, double[] xs, double[] zs, int count, double[] out) {
double[] sampleX = scratch.buffer(count);
double[] sampleZ = scratch.buffer(count);
if (children.length == 0) {
@@ -81,7 +89,6 @@ public final class NoiseLayerProgram {
for (int index = 0; index < count; index++) {
out[index] = post(out[index]);
}
scratch.reset(mark);
}
void evaluatePair(TerrainBatchScratch scratch, double[] xs, double[] zs, int count, double[] forward, double[] reverse) {
@@ -91,6 +98,14 @@ public final class NoiseLayerProgram {
return;
}
int mark = scratch.mark();
try {
fillPair(scratch, xs, zs, count, forward, reverse);
} finally {
scratch.reset(mark);
}
}
private void fillPair(TerrainBatchScratch scratch, double[] xs, double[] zs, int count, double[] forward, double[] reverse) {
int pairs = count * 2;
double[] sampleX = scratch.buffer(pairs);
double[] sampleZ = scratch.buffer(pairs);
@@ -122,7 +137,6 @@ public final class NoiseLayerProgram {
forward[index] = post(values[index]);
reverse[index] = post(values[count + index]);
}
scratch.reset(mark);
}
public double sample(TerrainBatchScratch scratch, double x, double z) {
@@ -133,14 +147,17 @@ public final class NoiseLayerProgram {
double sampleZ = z;
if (children.length > 0) {
int mark = scratch.mark();
double[] pair = scratch.buffer(2);
for (int child = 0; child < children.length; child++) {
children[child].samplePair(scratch, x, z, pair);
double offset = childOffsets[child];
sampleX += pair[0] - offset;
sampleZ += pair[1] - offset;
try {
double[] pair = scratch.buffer(2);
for (int child = 0; child < children.length; child++) {
children[child].samplePair(scratch, x, z, pair);
double offset = childOffsets[child];
sampleX += pair[0] - offset;
sampleZ += pair[1] - offset;
}
} finally {
scratch.reset(mark);
}
scratch.reset(mark);
}
return post(program.sample2D((sampleX / zoom) + offsetX, (sampleZ / zoom) + offsetZ));
}
@@ -157,16 +174,19 @@ public final class NoiseLayerProgram {
double reverseZ = x;
if (children.length > 0) {
int mark = scratch.mark();
double[] pair = scratch.buffer(2);
for (int child = 0; child < children.length; child++) {
children[child].samplePair(scratch, x, z, pair);
double offset = childOffsets[child];
forwardX += pair[0] - offset;
forwardZ += pair[1] - offset;
reverseX += pair[1] - offset;
reverseZ += pair[0] - offset;
try {
double[] pair = scratch.buffer(2);
for (int child = 0; child < children.length; child++) {
children[child].samplePair(scratch, x, z, pair);
double offset = childOffsets[child];
forwardX += pair[0] - offset;
forwardZ += pair[1] - offset;
reverseX += pair[1] - offset;
reverseZ += pair[0] - offset;
}
} finally {
scratch.reset(mark);
}
scratch.reset(mark);
}
out[0] = post(program.sample2D((forwardX / zoom) + offsetX, (forwardZ / zoom) + offsetZ));
out[1] = post(program.sample2D((reverseX / zoom) + offsetX, (reverseZ / zoom) + offsetZ));