Skip to content

Commit 684cb3c

Browse files
committed
Print CSV file for offline p-value analysis
Signed-off-by: Simon Dudley <[email protected]>
1 parent bb6cf66 commit 684cb3c

File tree

1 file changed

+79
-6
lines changed

1 file changed

+79
-6
lines changed

ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/benchmarks/BenchmarkExecutor.java

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,13 @@
3737
import org.hyperledger.besu.evm.gascalculator.ShanghaiGasCalculator;
3838
import org.hyperledger.besu.evm.precompile.PrecompiledContract;
3939

40+
import java.io.IOException;
4041
import java.io.PrintStream;
41-
import java.util.HashMap;
42+
import java.io.PrintWriter;
43+
import java.nio.charset.StandardCharsets;
44+
import java.nio.file.Files;
45+
import java.nio.file.Path;
46+
import java.nio.file.Paths;
4247
import java.util.LinkedHashMap;
4348
import java.util.Locale;
4449
import java.util.Map;
@@ -175,6 +180,11 @@ public void precompile(
175180
}
176181
});
177182

183+
if (filteredTestCases.isEmpty()) {
184+
output.println("No test cases matched the pattern: " + config.testCasePattern().orElse(null));
185+
return;
186+
}
187+
178188
if (config.warmInvert()) {
179189
runPrecompileInvertedWarmup(filteredTestCases, contract);
180190
} else {
@@ -186,25 +196,57 @@ private void runPrecompile(
186196
final Map<String, Bytes> testCases, final PrecompiledContract contract) {
187197

188198
// Fully warmup and execute, test case by test case
199+
Map<String, DescriptiveStatistics> timeStatsMap = new LinkedHashMap<>();
189200
for (final Map.Entry<String, Bytes> testCase : testCases.entrySet()) {
190201
try {
191202
/*final double execTime =*/ runPrecompileBenchmark(
192203
testCase.getKey(), testCase.getValue(), contract);
193204
long gasCost = contract.gasRequirement(testCase.getValue());
194205
// logPrecompilePerformance(testCase.getKey(), gasCost, execTime);
195206
logResultsWithError(testCase.getKey(), gasCost, timeStats);
207+
timeStatsMap.put(testCase.getKey(), timeStats);
196208
} catch (final IllegalArgumentException e) {
197209
output.printf("%s Input is Invalid%n", testCase.getKey());
198210
}
199211
}
212+
213+
// Also log csv output
214+
// output.println("Test,Iteration,Time (ns)");
215+
Path out = Paths.get("benchmark_results.csv");
216+
try (PrintWriter csv =
217+
new PrintWriter(Files.newBufferedWriter(out, StandardCharsets.UTF_8), true)) {
218+
csv.println("case,iteration,time (ns)");
219+
for (final Map.Entry<String, DescriptiveStatistics> testCaseStats : timeStatsMap.entrySet()) {
220+
String testCase = testCaseStats.getKey();
221+
double[] values = testCaseStats.getValue().getValues();
222+
if (values.length != execIterations) {
223+
System.err.printf(
224+
"⚠️ %s: expected %d samples but got %d%n", testCase, execIterations, values.length);
225+
}
226+
for (int i = 0; i < values.length; i++) {
227+
long ns = (long) values[i]; // back to raw nanoseconds
228+
// build the CSV line “case,iteration,ns”
229+
csv.println(testCase + "," + i + "," + ns);
230+
}
231+
}
232+
output.println(
233+
"✔️ Wrote "
234+
+ timeStatsMap.size()
235+
+ " cases × "
236+
+ execIterations
237+
+ " samples → "
238+
+ out.toAbsolutePath());
239+
} catch (IOException e) {
240+
throw new RuntimeException(e);
241+
}
200242
}
201243

202244
// compute mean ± error on derived‐gas and MGps (99.9% CI).
203245
private void logResultsWithError(
204246
final String testCase, final long gasCost, final DescriptiveStatistics timeStats) {
205247
precompileTableHeader.run();
206248
int n = (int) timeStats.getN();
207-
double meanTime = timeStats.getMean();
249+
double meanTime = timeStats.getMean() / 1e9;
208250
// double sdTime = timeStats.getStandardDeviation();
209251
// double seTime = sdTime / Math.sqrt(n);
210252

@@ -218,7 +260,8 @@ private void logResultsWithError(
218260

219261
// 3) compute throughput per iteration (MGps) and its stats
220262
DescriptiveStatistics tpStats = new DescriptiveStatistics(execIterations);
221-
for (double tSec : timeStats.getValues()) {
263+
for (double tNs : timeStats.getValues()) {
264+
double tSec = tNs / 1e9;
222265
double mgps = gasCost / tSec / 1_000_000.0;
223266
tpStats.addValue(mgps);
224267
}
@@ -250,7 +293,7 @@ private void runPrecompileInvertedWarmup(
250293
}
251294
}
252295

253-
Map<String, DescriptiveStatistics> timeStatsMap = new HashMap<>();
296+
Map<String, DescriptiveStatistics> timeStatsMap = new LinkedHashMap<>();
254297
// Also run all test cases in serial inside one iteration
255298
// Map<String, Long> totalElapsedByTestName = new HashMap<>();
256299
int executions = 0;
@@ -267,7 +310,7 @@ private void runPrecompileInvertedWarmup(
267310
// add the time to the stats for this test case
268311
timeStatsMap
269312
.computeIfAbsent(testCase.getKey(), k -> new DescriptiveStatistics())
270-
.addValue(iterationElapsed / 1e9);
313+
.addValue((double) iterationElapsed);
271314
}
272315
}
273316
executions++;
@@ -285,6 +328,36 @@ private void runPrecompileInvertedWarmup(
285328
output.printf("%s Input is Invalid%n", testCase.getKey());
286329
}
287330
}
331+
332+
// Also log csv output
333+
// output.println("Test,Iteration,Time (ns)");
334+
Path out = Paths.get("benchmark_results_inverted.csv");
335+
try (PrintWriter csv =
336+
new PrintWriter(Files.newBufferedWriter(out, StandardCharsets.UTF_8), true)) {
337+
csv.println("case,iteration,time (ns)");
338+
for (final Map.Entry<String, DescriptiveStatistics> testCaseStats : timeStatsMap.entrySet()) {
339+
String testCase = testCaseStats.getKey();
340+
double[] values = testCaseStats.getValue().getValues();
341+
if (values.length != execIterations) {
342+
System.err.printf(
343+
"⚠️ %s: expected %d samples but got %d%n", testCase, execIterations, values.length);
344+
}
345+
for (int i = 0; i < values.length; i++) {
346+
long ns = (long) values[i]; // back to raw nanoseconds
347+
// build the CSV line “case,iteration,ns”
348+
csv.println(testCase + "," + i + "," + ns);
349+
}
350+
}
351+
output.println(
352+
"✔️ Wrote "
353+
+ timeStatsMap.size()
354+
+ " cases × "
355+
+ execIterations
356+
+ " samples → "
357+
+ out.toAbsolutePath());
358+
} catch (IOException e) {
359+
throw new RuntimeException(e);
360+
}
288361
}
289362

290363
/**
@@ -333,7 +406,7 @@ protected double runPrecompileBenchmark(
333406
long iterationStart = System.nanoTime();
334407
final var result = contract.computePrecompile(arg, fakeFrame);
335408
long iterationElapsed = System.nanoTime() - iterationStart;
336-
timeStats.addValue(iterationElapsed / 1e9);
409+
timeStats.addValue((double) iterationElapsed);
337410

338411
totalElapsed += iterationElapsed;
339412
executions++;

0 commit comments

Comments
 (0)