Skip to content
Oakfield Operator Calculus Function Reference Site

Benchmark Examples

Test performance and convergence of operators and integrators via the command-line interface (sim_cli).

Measures average step time using high-resolution timing on macOS.

tstep=elapsed12000000t_{\text{step}} = \frac{\text{elapsed}}{12000000}
local sim = require("libsimcore")
local ffi = require("ffi")
local steps = 12000000
local ctx = sim.sim_create()
-- Setup for high-resolution timing on macOS
ffi.cdef [[
uint64_t mach_absolute_time(void);
typedef struct {
uint32_t numer;
uint32_t denom;
} mach_timebase_info_data_t;
int mach_timebase_info(mach_timebase_info_data_t *info);
]]
-- Allocate and populate timebase info
local info = ffi.new("mach_timebase_info_data_t")
ffi.C.mach_timebase_info(info)
-- High-resolution current time function
local function now()
return tonumber(ffi.C.mach_absolute_time() * info.numer / info.denom) * 1e-9
end
sim.log("Starting simulation with %d steps", steps)
-- Record start time
local t0 = now()
for i = 1, steps do
sim.sim_step(ctx)
end
-- Calculate elapsed time
local elapsed = now() - t0
sim.log("%d steps in %.3f s (%.16f ms/step)", steps, elapsed, elapsed * 1000 / steps)
sim.sim_shutdown(ctx)
return ctx

Example output:

Terminal window
oak@field % ./bin/sim_cli --script wall-clock.lua
[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 sim = require("libsimcore")
local steps = 12000000
local ctx = sim.sim_create()
sim.log("Starting simulation with %d steps", steps)
for i = 1, steps do
sim.sim_step(ctx)
end
local history = sim.sim_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
sim.log("Average dt over last %d steps: %.6f", #history, avg_dt)
sim.sim_shutdown(ctx)
return ctx

Example output:

Terminal window
oak@field % ./bin/sim_cli --script step-metrics.lua
[INFO] Starting simulation with 12000000 steps
[INFO] Average dt over last 128 steps: 0.016667

Simple CPU timing of two convolution kernels comparing t3-tapt_{3\text{-tap}} versus t9-tapt_{9\text{-tap}} to see how wider stencils scale.

local sim = require("libsimcore")
local steps = 12000000
local N = 512
local ctx = sim.sim_create()
sim.log("Starting simulation with %d steps", steps)
local u = sim.sim_add_field(ctx, {N}, {
type = "complex_double",
fill = {0.0, 0.0}
})
local v = sim.sim_add_field(ctx, {N}, {
type = "complex_double",
fill = {0.0, 0.0}
})
local op = sim.sim_add_minimal_convolution_operator(ctx, u, v)
local function timed_run(kernel_opts)
sim.sim_minimal_convolution_update(ctx, 0, kernel_opts)
local t0 = os.clock()
for _ = 1, steps do
sim.sim_step(ctx)
end
return os.clock() - t0
end
local base = timed_run({
kernel_taps = 3
})
local wide = timed_run({
kernel_taps = 9,
kernel = "1,2,3,4,3,2,1,0,0"
})
sim.log("3-tap: %.3f s, 9-tap: %.3f s", base, wide)
sim.sim_shutdown(ctx)
return ctx

Example output:

Terminal window
oak@field % ./bin/sim_cli --script kernel-timings.lua
[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 sim = require("libsimcore")
local steps = 12000000
local N = 512
local dt = 0.01
local ctx = sim.sim_create()
sim.sim_set_timestep(ctx, dt)
sim.log("Starting simulation with %d steps and dt = %.3f", steps, dt)
local function run_with(name, steps)
local integrator = sim.sim_create_context_integrator(ctx, name, {
initial_dt = dt,
adaptive = (name == "rkf45")
})
sim.sim_set_integrator(ctx, integrator)
local t0 = os.clock()
for _ = 1, steps do
sim.sim_integrator_step(ctx, integrator, dt)
end
local time = os.clock() - t0
sim.sim_detach_integrator(ctx, integrator)
return time
end
local t_rk4 = run_with("rk4", steps)
local t_rkf = run_with("rkf45", steps)
sim.log("rk4 (fixed): %.3f s, rkf45 (adaptive): %.3f s", t_rk4, t_rkf)
sim.sim_shutdown(ctx)
return ctx

Example output:

Terminal window
oak@field % ./bin/sim_cli --script integrator-comparison.lua
[INFO] Starting simulation with 12000000 steps and dt = 0.010
[INFO] rk4 (fixed): 1.141 s, rkf45 (adaptive): 1.135 s