Benchmark Examples
CLI Examples
Section titled “CLI Examples”Test performance and convergence of operators and integrators via oakcli.
1) Wall-clock microbenchmark
Section titled “1) Wall-clock microbenchmark”Measures average step time with the runtime’s monotonic clock:
local steps = 12000000local ctx = ooc.create()
local function now() return ooc.monotonic_time()end
ooc.log("Starting simulation with %d steps", steps)
local t0 = now()
for i = 1, steps do ooc.step(ctx)end
local elapsed = now() - t0
ooc.log("%d steps in %.3f s (%.16f ms/step)", steps, elapsed, elapsed * 1000 / steps)
ooc.shutdown(ctx)
return ctxExample output:
oakcli run --script wall-clock.lua --steps 0[INFO] Starting simulation with 12000000 steps[INFO] 12000000 steps in 0.476 s (0.0000396332916668 ms/step)2) Step metrics sweep
Section titled “2) Step metrics sweep”Collects the last step metrics and reports
local steps = 12000000local ctx = ooc.create()
ooc.log("Starting simulation with %d steps", steps)
for i = 1, steps do ooc.step(ctx)end
local history = ooc.step_metrics_history(ctx, 128)
local avg_dt = 0for _, m in ipairs(history) do avg_dt = avg_dt + m.accepted_dtendavg_dt = avg_dt / #historyooc.log("Average dt over last %d steps: %.6f", #history, avg_dt)
ooc.shutdown(ctx)return ctxExample output:
oakcli run --script step-metrics.lua --steps 0[INFO] Starting simulation with 12000000 steps[INFO] Average dt over last 128 steps: 0.0166673) Parameterized kernel timings
Section titled “3) Parameterized kernel timings”Compares a 3-tap and 9-tap minimal convolution kernel to see how wider stencils scale.
local steps = 12000000local N = 512local ctx = ooc.create()
ooc.log("Starting simulation with %d steps", steps)
local u = ooc.add_field(ctx, {N}, { type = "complex_double", fill = {0.0, 0.0}})
local v = ooc.add_field(ctx, {N}, { type = "complex_double", fill = {0.0, 0.0}})
ooc.add_minimal_convolution_operator(ctx, u, v)
local function timed_run(kernel_opts) ooc.minimal_convolution_update(ctx, 0, kernel_opts) local profiler = ooc.profiler_new(1) profiler:begin_frame() for _ = 1, steps do ooc.step(ctx) end profiler:end_frame() local snap = profiler:snapshot() return (snap and snap.total_ns or 0) * 1e-9end
local base = timed_run({ kernel_length = 3})
local wide = timed_run({ kernel_length = 9, kernel = "1,2,3,4,3,2,1,0,0"})
ooc.log("3-tap: %.3f s, 9-tap: %.3f s", base, wide)
ooc.shutdown(ctx)return ctxExample output:
oakcli run --script kernel-timings.lua --steps 0[INFO] Starting simulation with 12000000 steps[INFO] 3-tap: 17.209 s, 9-tap: 46.522 s4) Integrator comparison
Section titled “4) Integrator comparison”Contrasts wall-clock runtime for RK4 and RKF45 so you can inspect ratios like
before committing to adaptive stepping.
local steps = 12000000local dt = 0.01local ctx = ooc.create()
ooc.set_timestep(ctx, dt)
local field = ooc.add_field(ctx, {512}, { type = "real_double", fill = 0.0})
ooc.add_stimulus_operator(ctx, field, { type = "stimulus_sine", amplitude = 0.1, wavenumber = 0.5, omega = 0.2, scale_by_dt = true})
ooc.log("Starting simulation with %d steps and dt = %.3f", steps, dt)
local function run_with(name, step_count) local integrator = ooc.create_context_integrator(ctx, name, { initial_dt = dt, adaptive = (name == "rkf45") })
ooc.set_integrator(ctx, integrator)
local profiler = ooc.profiler_new(1) profiler:begin_frame()
for _ = 1, step_count do ooc.integrator_step(ctx, integrator, dt) end
profiler:end_frame() local snap = profiler:snapshot() local elapsed = (snap and snap.total_ns or 0) * 1e-9
ooc.detach_integrator(ctx, integrator)
return elapsedend
local t_rk4 = run_with("rk4", steps)local t_rkf = run_with("rkf45", steps)
ooc.log("rk4 (fixed): %.3f s, rkf45 (adaptive): %.3f s", t_rk4, t_rkf)
ooc.shutdown(ctx)
return ctxExample output:
oakcli run --script integrator-comparison.lua --steps 0[INFO] Starting simulation with 12000000 steps and dt = 0.010[INFO] rk4 (fixed): 1.141 s, rkf45 (adaptive): 1.135 s