Skip to content
Oakfield Operator Calculus Function Reference Site

Benchmark Examples

Test performance and convergence of operators and integrators via oakcli.

Measures average step time with the runtime’s monotonic clock:

tstep=elapsed12000000.t_{\text{step}} = \frac{\text{elapsed}}{12000000}.
local steps = 12000000
local 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 ctx

Example output:

Terminal window
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)

Collects the last NN step metrics and reports

Δtˉ=1Ni=1Nmiaccepted.\bar{\Delta t} = \frac{1}{N}\sum_{i=1}^{N} m_i^{\text{accepted}}.
local steps = 12000000
local 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 = 0
for _, m in ipairs(history) do
avg_dt = avg_dt + m.accepted_dt
end
avg_dt = avg_dt / #history
ooc.log("Average dt over last %d steps: %.6f", #history, avg_dt)
ooc.shutdown(ctx)
return ctx

Example output:

Terminal window
oakcli run --script step-metrics.lua --steps 0
[INFO] Starting simulation with 12000000 steps
[INFO] Average dt over last 128 steps: 0.016667

Compares a 3-tap and 9-tap minimal convolution kernel to see how wider stencils scale.

local steps = 12000000
local N = 512
local 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-9
end
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 ctx

Example output:

Terminal window
oakcli run --script kernel-timings.lua --steps 0
[INFO] Starting simulation with 12000000 steps
[INFO] 3-tap: 17.209 s, 9-tap: 46.522 s

Contrasts wall-clock runtime for RK4 and RKF45 so you can inspect ratios like

trkf45/trk4t_{\text{rkf45}} / t_{\text{rk4}}

before committing to adaptive stepping.

local steps = 12000000
local dt = 0.01
local 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 elapsed
end
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 ctx

Example output:

Terminal window
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