Commit 4eb71440 authored by Numanoglu's avatar Numanoglu
Browse files

Streamline BVH heuristic measurements

parent 2c9eea60
......@@ -43,25 +43,25 @@ public final class BvhSyntheticScenarioCatalog {
new SsiScenario("flat-box-grid-large",
SyntheticSolidGeometryFactory.flatBoxGrid(Lod.LOD2, 240)),
new SsiScenario("thin-ratio-025",
SyntheticSolidGeometryFactory.thinRatioSweepBoxes(Lod.LOD2, 120, 0.25)),
SyntheticSolidGeometryFactory.thinRatioVariationBoxes(Lod.LOD2, 120, 0.25)),
new SsiScenario("thin-ratio-050",
SyntheticSolidGeometryFactory.thinRatioSweepBoxes(Lod.LOD2, 120, 0.50)),
SyntheticSolidGeometryFactory.thinRatioVariationBoxes(Lod.LOD2, 120, 0.50)),
new SsiScenario("thin-ratio-075",
SyntheticSolidGeometryFactory.thinRatioSweepBoxes(Lod.LOD2, 120, 0.75)),
SyntheticSolidGeometryFactory.thinRatioVariationBoxes(Lod.LOD2, 120, 0.75)),
new SsiScenario("aspect-005",
SyntheticSolidGeometryFactory.aspectSweepBoxes(Lod.LOD2, 120, 5.0)),
SyntheticSolidGeometryFactory.aspectRatioVariationBoxes(Lod.LOD2, 120, 5.0)),
new SsiScenario("aspect-020",
SyntheticSolidGeometryFactory.aspectSweepBoxes(Lod.LOD2, 120, 20.0)),
SyntheticSolidGeometryFactory.aspectRatioVariationBoxes(Lod.LOD2, 120, 20.0)),
new SsiScenario("aspect-080",
SyntheticSolidGeometryFactory.aspectSweepBoxes(Lod.LOD2, 120, 80.0)),
SyntheticSolidGeometryFactory.aspectRatioVariationBoxes(Lod.LOD2, 120, 80.0)),
new SsiScenario("spread-tight",
SyntheticSolidGeometryFactory.spreadSweepBoxes(Lod.LOD2, 120, 3.5)),
SyntheticSolidGeometryFactory.centerSpreadVariationBoxes(Lod.LOD2, 120, 3.5)),
new SsiScenario("spread-wide",
SyntheticSolidGeometryFactory.spreadSweepBoxes(Lod.LOD2, 120, 20.0)),
SyntheticSolidGeometryFactory.centerSpreadVariationBoxes(Lod.LOD2, 120, 20.0)),
new SsiScenario("relvol-compact",
SyntheticSolidGeometryFactory.relativeVolumeSweepBoxes(Lod.LOD2, 80, 5.0, 1.1)),
SyntheticSolidGeometryFactory.relativeVolumeVariationBoxes(Lod.LOD2, 80, 5.0, 1.1)),
new SsiScenario("relvol-sparse",
SyntheticSolidGeometryFactory.relativeVolumeSweepBoxes(Lod.LOD2, 80, 5.0, 5.0)),
SyntheticSolidGeometryFactory.relativeVolumeVariationBoxes(Lod.LOD2, 80, 5.0, 5.0)),
new SsiScenario("citylike-mixed-small",
SyntheticCityGmlLikeGeometryFactory.mixedUrbanDistrict(Lod.LOD2, 3, 3)),
new SsiScenario("citylike-mixed-large",
......@@ -97,15 +97,15 @@ public final class BvhSyntheticScenarioCatalog {
new NestedScenario("clustered-pair",
SyntheticNestedRingGeometryFactory.clusteredInnerRingsWithNestedPair(16, 80)),
new NestedScenario("aspect-005",
SyntheticNestedRingGeometryFactory.aspectSweepInnerRings(180, 5.0)),
SyntheticNestedRingGeometryFactory.aspectRatioVariationInnerRings(180, 5.0)),
new NestedScenario("aspect-020",
SyntheticNestedRingGeometryFactory.aspectSweepInnerRings(180, 20.0)),
SyntheticNestedRingGeometryFactory.aspectRatioVariationInnerRings(180, 20.0)),
new NestedScenario("aspect-080",
SyntheticNestedRingGeometryFactory.aspectSweepInnerRings(180, 80.0)),
SyntheticNestedRingGeometryFactory.aspectRatioVariationInnerRings(180, 80.0)),
new NestedScenario("spread-tight",
SyntheticNestedRingGeometryFactory.spreadSweepInnerRings(240, 2.0)),
SyntheticNestedRingGeometryFactory.centerSpreadVariationInnerRings(240, 2.0)),
new NestedScenario("spread-wide",
SyntheticNestedRingGeometryFactory.spreadSweepInnerRings(240, 20.0)));
SyntheticNestedRingGeometryFactory.centerSpreadVariationInnerRings(240, 20.0)));
}
public static List<RsiScenario> rsiScenarios() {
......@@ -121,15 +121,15 @@ public final class BvhSyntheticScenarioCatalog {
new RsiScenario("rsi-zigzag-heavy",
SyntheticRingGeometryFactory.performanceRingGeometry(400, 4_000, EPSILON)),
new RsiScenario("rsi-aspect-005",
SyntheticRingGeometryFactory.aspectSweepGeometry(240, 5.0)),
SyntheticRingGeometryFactory.aspectRatioVariationGeometry(240, 5.0)),
new RsiScenario("rsi-aspect-020",
SyntheticRingGeometryFactory.aspectSweepGeometry(240, 20.0)),
SyntheticRingGeometryFactory.aspectRatioVariationGeometry(240, 20.0)),
new RsiScenario("rsi-aspect-080",
SyntheticRingGeometryFactory.aspectSweepGeometry(240, 80.0)),
SyntheticRingGeometryFactory.aspectRatioVariationGeometry(240, 80.0)),
new RsiScenario("rsi-spread-tight",
SyntheticRingGeometryFactory.spreadSweepGeometry(240, 4.0)),
SyntheticRingGeometryFactory.centerSpreadVariationGeometry(240, 4.0)),
new RsiScenario("rsi-spread-wide",
SyntheticRingGeometryFactory.spreadSweepGeometry(240, 30.0)));
SyntheticRingGeometryFactory.centerSpreadVariationGeometry(240, 30.0)));
}
public static final class SsiScenario {
......
......@@ -139,7 +139,7 @@ public final class SyntheticNestedRingGeometryFactory {
return polygon;
}
public static ConcretePolygon aspectSweepInnerRings(int count, double aspectRatio) {
public static ConcretePolygon aspectRatioVariationInnerRings(int count, double aspectRatio) {
int columns = (int) Math.ceil(Math.sqrt(count));
double width = Math.max(1.0, aspectRatio);
double extent = columns * (width + 4.0) + 20.0;
......@@ -152,7 +152,7 @@ public final class SyntheticNestedRingGeometryFactory {
return polygon;
}
public static ConcretePolygon spreadSweepInnerRings(int count, double spacing) {
public static ConcretePolygon centerSpreadVariationInnerRings(int count, double spacing) {
int columns = (int) Math.ceil(Math.sqrt(count));
double extent = columns * spacing + 20.0;
ConcretePolygon polygon = basePolygonWithExtent(extent);
......
......@@ -68,7 +68,7 @@ public final class SyntheticRingGeometryFactory {
return geometry;
}
public static Geometry aspectSweepGeometry(int ringCount, double aspectRatio) {
public static Geometry aspectRatioVariationGeometry(int ringCount, double aspectRatio) {
Geometry geometry = new Geometry(GeometryType.SOLID, Lod.LOD2, Orientation.OUTWARD);
double width = Math.max(1.0, aspectRatio);
for (int i = 0; i < ringCount; i++) {
......@@ -80,7 +80,7 @@ public final class SyntheticRingGeometryFactory {
return geometry;
}
public static Geometry spreadSweepGeometry(int ringCount, double spacing) {
public static Geometry centerSpreadVariationGeometry(int ringCount, double spacing) {
Geometry geometry = new Geometry(GeometryType.SOLID, Lod.LOD2, Orientation.OUTWARD);
for (int i = 0; i < ringCount; i++) {
double x = (i % 20) * spacing;
......
......@@ -91,7 +91,7 @@ public final class SyntheticSolidGeometryFactory {
return geometry;
}
public static Geometry thinRatioSweepBoxes(Lod lod, int count, double thinRatio) {
public static Geometry thinRatioVariationBoxes(Lod lod, int count, double thinRatio) {
Geometry geometry = newSolid(lod);
int columns = (int) Math.ceil(Math.sqrt(count));
int thinCount = (int) Math.round(count * thinRatio);
......@@ -108,7 +108,7 @@ public final class SyntheticSolidGeometryFactory {
return geometry;
}
public static Geometry aspectSweepBoxes(Lod lod, int count, double aspectRatio) {
public static Geometry aspectRatioVariationBoxes(Lod lod, int count, double aspectRatio) {
Geometry geometry = newSolid(lod);
int columns = (int) Math.ceil(Math.sqrt(count));
double width = Math.max(1.0, aspectRatio);
......@@ -122,7 +122,7 @@ public final class SyntheticSolidGeometryFactory {
return geometry;
}
public static Geometry spreadSweepBoxes(Lod lod, int count, double spacing) {
public static Geometry centerSpreadVariationBoxes(Lod lod, int count, double spacing) {
Geometry geometry = newSolid(lod);
int columns = (int) Math.ceil(Math.sqrt(count));
for (int i = 0; i < count; i++) {
......@@ -134,7 +134,7 @@ public final class SyntheticSolidGeometryFactory {
return geometry;
}
public static Geometry relativeVolumeSweepBoxes(Lod lod, int count, double boxSize, double spacingFactor) {
public static Geometry relativeVolumeVariationBoxes(Lod lod, int count, double boxSize, double spacingFactor) {
Geometry geometry = newSolid(lod);
int columns = (int) Math.ceil(Math.sqrt(count));
double spacing = boxSize * spacingFactor;
......
......@@ -82,7 +82,7 @@ public class BvhStrategyHeuristicExplorationTest {
}
private static void addSsiObservations(List<BvhHeuristicTimingSupport.Observation> observations) {
// SSI uses polygons as BVH elements and compares against the brute-force solid check.
// SSI uses polygons as BVH elements.
for (BvhSyntheticScenarioCatalog.SsiScenario scenario : BvhSyntheticScenarioCatalog.ssiScenarios()) {
List<Polygon> polygons = scenario.geometry.getPolygons();
BvhInputMetricsCollector.Metrics metrics =
......@@ -92,8 +92,6 @@ public class BvhStrategyHeuristicExplorationTest {
scenario.name,
metrics,
polygons.size(),
"BRUTE_FORCE",
() -> SelfIntersectionUtil.calculateSolidSelfIntersection0(scenario.geometry, DELTA).size(),
strategy -> calculateSsiWithTree(scenario.geometry, strategy)));
}
}
......@@ -109,8 +107,6 @@ public class BvhStrategyHeuristicExplorationTest {
scenario.name,
metrics,
rings.size(),
NestedRingsCheck.Variant.OLD.name(),
() -> runNestedCheck(scenario.polygon, NestedRingsCheck.Variant.OLD),
strategy -> runNestedCheck(scenario.polygon, BvhHeuristicTimingSupport.nestedVariantFor(strategy))));
}
}
......@@ -125,8 +121,6 @@ public class BvhStrategyHeuristicExplorationTest {
scenario.name,
metrics,
countEdges(scenario.geometry),
RingSelfIntCheck.Variant.OLD.name(),
() -> runRsiCheck(scenario.geometry, RingSelfIntCheck.Variant.OLD),
strategy -> runRsiCheck(scenario.geometry, BvhHeuristicTimingSupport.rsiVariantFor(strategy))));
}
}
......
......@@ -41,8 +41,6 @@ public final class BvhExplorationCsvWriter {
"candidatePolicy",
"winnerBvh",
"match",
"baselineVariant",
"baselineMs",
"bestBvhMs",
"candidatePolicyMs",
"regretMs",
......@@ -96,8 +94,6 @@ public final class BvhExplorationCsvWriter {
observation.candidateRulePrediction,
observation.fastestBvh.variant,
observation.candidateRuleMatchLabel(),
observation.baseline == null ? "" : observation.baseline.variant,
measurementMillis(observation.baseline),
measurementMillis(observation.fastestBvh),
measurementMillis(observation.candidateRuleMeasurement),
decimalOrEmpty(observation.candidateRegretMillis()),
......@@ -158,7 +154,7 @@ public final class BvhExplorationCsvWriter {
if (value.indexOf(',') < 0 && value.indexOf('"') < 0 && value.indexOf('\n') < 0) {
return value;
}
return '"' + value.replace("\"", "\"\"") + '"';
return '"' + value.replace("\"", "\"\"") + '"';
}
private static String measurementMillis(BvhPerformanceTestSupport.Measurement measurement) {
......
......@@ -30,18 +30,10 @@ public final class BvhHeuristicTimingSupport {
String scenarioName,
BvhInputMetricsCollector.Metrics metrics,
int inputSize,
String baselineName,
MeasuredOperation baselineOperation,
StrategyOperation strategyOperation) {
// Full checks compare each BVH variant against the old or brute-force implementation.
// Correctness against OLD or brute force is covered by the dedicated variant tests.
List<BvhPerformanceTestSupport.Measurement> measurements = new ArrayList<>();
BvhPerformanceTestSupport.Measurement baseline = BvhPerformanceTestSupport.measure(
scenarioName,
baselineName,
inputSize,
baselineOperation::run);
measurements.add(baseline);
Integer expectedResultCount = null;
for (SplitStrategy strategy : BvhPerformanceTestSupport.concreteStrategies()) {
BvhPerformanceTestSupport.Measurement bvhMeasurement = BvhPerformanceTestSupport.measure(
scenarioName,
......@@ -49,8 +41,12 @@ public final class BvhHeuristicTimingSupport {
inputSize,
() -> strategyOperation.run(strategy));
measurements.add(bvhMeasurement);
assertEquals(checkName + " result differs for " + scenarioName + " / " + strategy,
baseline.resultCount, bvhMeasurement.resultCount);
if (expectedResultCount == null) {
expectedResultCount = bvhMeasurement.resultCount;
} else {
assertEquals(checkName + " result differs for " + scenarioName + " / " + strategy,
expectedResultCount.intValue(), bvhMeasurement.resultCount);
}
}
String currentPolicyPrediction = predictFromCurrentPolicy(checkName, metrics);
......@@ -58,9 +54,7 @@ public final class BvhHeuristicTimingSupport {
return new Observation(
checkName,
metrics,
fastest(measurements),
fastestBvh(measurements),
baseline,
currentPolicyPrediction,
candidateRulePrediction,
measurementForPrediction(measurements, currentPolicyPrediction),
......@@ -73,20 +67,20 @@ public final class BvhHeuristicTimingSupport {
BvhInputMetricsCollector.Metrics metrics,
int inputSize,
StrategyOperation strategyOperation) {
// Real CityGML runs measure only broad-phase candidate search, so the first BVH variant is the count baseline.
// The first BVH result count is reused only to verify the remaining variants.
List<BvhPerformanceTestSupport.Measurement> measurements = new ArrayList<>();
BvhPerformanceTestSupport.Measurement baseline = null;
Integer expectedResultCount = null;
for (SplitStrategy strategy : BvhPerformanceTestSupport.concreteStrategies()) {
BvhPerformanceTestSupport.Measurement bvhMeasurement = BvhPerformanceTestSupport.measure(
scenarioName,
strategy.name(),
inputSize,
() -> strategyOperation.run(strategy));
if (baseline == null) {
baseline = bvhMeasurement;
if (expectedResultCount == null) {
expectedResultCount = bvhMeasurement.resultCount;
} else {
assertEquals(checkName + " broad-phase count differs for " + scenarioName + " / " + strategy,
baseline.resultCount, bvhMeasurement.resultCount);
expectedResultCount.intValue(), bvhMeasurement.resultCount);
}
measurements.add(bvhMeasurement);
}
......@@ -96,9 +90,7 @@ public final class BvhHeuristicTimingSupport {
return new Observation(
checkName,
metrics,
fastest(measurements),
fastestBvh(measurements),
baseline,
currentPolicyPrediction,
candidateRulePrediction,
measurementForPrediction(measurements, currentPolicyPrediction),
......@@ -199,26 +191,10 @@ public final class BvhHeuristicTimingSupport {
throw new IllegalArgumentException("Unsupported check name: " + checkName);
}
private static BvhPerformanceTestSupport.Measurement fastest(
List<BvhPerformanceTestSupport.Measurement> measurements) {
BvhPerformanceTestSupport.Measurement fastest = measurements.get(0);
for (BvhPerformanceTestSupport.Measurement measurement : measurements) {
if (measurement.averageNanos < fastest.averageNanos) {
fastest = measurement;
}
}
return fastest;
}
private static BvhPerformanceTestSupport.Measurement fastestBvh(
List<BvhPerformanceTestSupport.Measurement> measurements) {
BvhPerformanceTestSupport.Measurement fastest = null;
for (BvhPerformanceTestSupport.Measurement measurement : measurements) {
if ("BRUTE_FORCE".equals(measurement.variant)
|| NestedRingsCheck.Variant.OLD.name().equals(measurement.variant)
|| RingSelfIntCheck.Variant.OLD.name().equals(measurement.variant)) {
continue;
}
if (fastest == null || measurement.averageNanos < fastest.averageNanos) {
fastest = measurement;
}
......@@ -230,18 +206,13 @@ public final class BvhHeuristicTimingSupport {
List<BvhPerformanceTestSupport.Measurement> measurements,
String prediction) {
for (BvhPerformanceTestSupport.Measurement measurement : measurements) {
if (measurement.variant.equals(prediction)
|| ("OLD".equals(prediction) && "BRUTE_FORCE".equals(measurement.variant))) {
if (measurement.variant.equals(prediction)) {
return measurement;
}
}
return null;
}
public interface MeasuredOperation {
int run();
}
/**
* Operation that can be executed with each concrete BVH split strategy.
*/
......@@ -259,9 +230,7 @@ public final class BvhHeuristicTimingSupport {
public static final class Observation {
public final String checkName;
public final BvhInputMetricsCollector.Metrics metrics;
public final BvhPerformanceTestSupport.Measurement fastest;
public final BvhPerformanceTestSupport.Measurement fastestBvh;
public final BvhPerformanceTestSupport.Measurement baseline;
public final BvhPerformanceTestSupport.Measurement currentPolicyMeasurement;
public final BvhPerformanceTestSupport.Measurement candidateRuleMeasurement;
public final String currentPolicyPrediction;
......@@ -270,18 +239,14 @@ public final class BvhHeuristicTimingSupport {
Observation(
String checkName,
BvhInputMetricsCollector.Metrics metrics,
BvhPerformanceTestSupport.Measurement fastest,
BvhPerformanceTestSupport.Measurement fastestBvh,
BvhPerformanceTestSupport.Measurement baseline,
String currentPolicyPrediction,
String candidateRulePrediction,
BvhPerformanceTestSupport.Measurement currentPolicyMeasurement,
BvhPerformanceTestSupport.Measurement candidateRuleMeasurement) {
this.checkName = checkName;
this.metrics = metrics;
this.fastest = fastest;
this.fastestBvh = fastestBvh;
this.baseline = baseline;
this.currentPolicyPrediction = currentPolicyPrediction;
this.candidateRulePrediction = candidateRulePrediction;
this.currentPolicyMeasurement = currentPolicyMeasurement;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment