Runtime and model execution¶
These measurements cover work outside the CFD equations: field transforms, model-input preparation, inference, artefact handling and resident memory.
Measurement index¶
| Measurement | Isolates | Excludes |
|---|---|---|
| Field transform | Native in-place field arithmetic | Solver equations and model transport |
| Model-input packing | Cast and interleave into a packed tensor | Inference and transport |
| Equinox execution | Cold JAX activation and warm model calls | Python and JAX import |
| Joblib and ONNX | Backend load and prediction | Fjord and process startup |
| Compiled estimator | Compilation, cache load and prediction | Solver integration |
| ModelHost memory | Production SHM exchange and workspace retention | OpenFOAM equations |
| Generation turnover | Immutable runtime publication and collection | Native compilation |
Throughput is reported as processed rows or source bytes per measured second. Unless a section states otherwise, central values and deviations follow the benchmark reporting contract.
Field transform¶
Two hundred in-place fused transforms were applied to one million three-component float64 cells. Seven warm runs were reduced by their median.
| Platform | Elapsed | Field throughput |
|---|---|---|
| MacBook | 0.42972 ± 0.02107 s | 10,652 ± 497 MiB/s |
| Roihu CPU | 1.22934 ± 0.01652 s | 3,724 ± 50 MiB/s |
The final field range was [1, 7.31602] in every run.
Model-input packing¶
Two hundred packs converted three one-million-cell float64 scalar fields into one interleaved float32 tensor. The comparison is an idealised two-pass cast and interleave.
| Platform | Two-pass | FoamNordic pack | Speed ratio | Source throughput |
|---|---|---|---|---|
| MacBook | 0.12257 s | 0.16095 s | 0.762× | 28,442 MiB/s |
| Roihu CPU | 0.24974 s | 0.25064 s | 0.9996× | 18,264 MiB/s |
The MacBook used seven runs. Roihu job 1090004 used one core from a small allocation and measured 21 runs after one warm-up. Checksums were identical.
Equinox model execution¶
An Equinox MLP with ten inputs, three 128-wide hidden layers and one output ran on 262,144 rows per call. Each platform completed one unmeasured compilation and warm-up call followed by 20 measured inference calls.
| Platform | Cold activation | Median inference | Maximum deviation | Throughput | FNOM size |
|---|---|---|---|---|---|
| MacBook CPU | 1.736e-1 ± 4.42e-2 s | 2.466e-2 s | ± 1.04e-3 s | 10,630,665 rows/s | 148.1 kB |
| Roihu GH200 | 1.208 ± 7.580e-2 s | 2.785e-3 s | ± 6.726e-4 s | 94,114,030 rows/s | 148.5 kB |
Cold activation includes FNOM loading, evaluator construction, JIT compilation and first inference, but excludes Python and JAX import. Warm inference includes NumPy-to-JAX input and contiguous NumPy output. The MacBook used JAX 0.11.0; Roihu job 1093649 used JAX 0.11.1 on one GH200. The script is tools/benchmarks/equinox_runtime.py.
Joblib and ONNX model execution¶
Roihu job 1091323 used one thread on a test node. Both backends used the same scikit-learn MLP with ten inputs, three 128-wide hidden layers and one output.
| Backend | FNOM size | Median cold load | Maximum deviation |
|---|---|---|---|
| Joblib | 561.8 kB | 1.288e-3 s | ± 1.142e-2 s |
| ONNX | 139.5 kB | 6.546e-4 s | ± 6.146e-2 s |
Cold load used 11 repetitions.
| Batch rows | Joblib median | ONNX median | ONNX speedup | Joblib throughput | ONNX throughput |
|---|---|---|---|---|---|
| 1 | 5.614e-5 s | 5.720e-6 s | 9.81× | 17,813 rows/s | 174,825 rows/s |
| 256 | 1.941e-4 s | 9.725e-5 s | 2.00× | 1,319,098 rows/s | 2,632,391 rows/s |
| 4,096 | 2.217e-3 s | 1.500e-3 s | 1.48× | 1,847,573 rows/s | 2,730,996 rows/s |
| 262,144 | 1.845e-1 s | 1.538e-1 s | 1.20× | 1,420,869 rows/s | 1,704,270 rows/s |
Warm inference used 21 repetitions per batch. ONNX used single-threaded ONNX Runtime 1.29.0 in Python; the result excludes Fjord transport and process startup.
Compiled estimator crossover¶
Roihu job 1091731 compared compiled and Joblib FNOM on one thread using an ExtraTrees regressor with 32 trees, maximum depth 10 and ten inputs.
| Backend | FNOM size | Median initial load | Maximum deviation | Median cached load |
|---|---|---|---|---|
| Compiled | 1.244 MB | 7.433e-1 s | ± 7.077e-1 s | 2.437e-3 s |
| Joblib | 1.651 MB | 3.531e-3 s | ± 9.489e-3 s | — |
The compiled initial load includes native compilation: its median compiler time was 7.399e-1 s over seven fresh caches. Eleven subsequent cache hits loaded in 2.437e-3 ± 1.233e-3 s. Joblib load also used 11 repetitions.
| Batch rows | Compiled median | Joblib median | Compiled speedup | Compiled throughput | Joblib throughput |
|---|---|---|---|---|---|
| 1 | 5.751e-6 s | 9.277e-4 s | 161.31× | 173,882 rows/s | 1,078 rows/s |
| 256 | 4.497e-4 s | 1.611e-3 s | 3.58× | 569,263 rows/s | 158,934 rows/s |
| 4,096 | 7.763e-3 s | 7.416e-3 s | 0.96× | 527,628 rows/s | 552,337 rows/s |
| 262,144 | 3.641e-1 s | 3.552e-1 s | 0.98× | 720,033 rows/s | 737,962 rows/s |
Warm inference used 21 repetitions per batch. Compiled execution is faster for the two smaller batches; the paths are similar at 4,096 and 262,144 rows.
Resident ModelHost memory¶
The production ModelHost ran a deterministic affine kernel over SHM. Each run used 20 exchanges of 1,024 rows, three of 1,048,576 rows, then 20 small exchanges. Large float64 inputs and outputs occupied 80 MiB and 8 MiB.
Each platform used seven independently started processes. The table reports medians and maximum observed deviations.
| Platform | Connected RSS | Initial small RSS | Large RSS | Returned-small RSS | Peak RSS |
|---|---|---|---|---|---|
| MacBook | 1.125 MiB | 3.281 ± 0.015 MiB | 209.641 ± 0.016 MiB | 209.641 ± 0.015 MiB | 209.641 ± 0.015 MiB |
| Roihu CPU | 1.828 ± 0.035 MiB | 3.734 ± 0.031 MiB | 130.164 ± 0.031 MiB | 50.160 ± 0.031 MiB | 206.211 ± 0.031 MiB |
| Platform | Publication peak | Receive peak | Working peak | Retained workspace |
|---|---|---|---|---|
| MacBook | 16 MiB | 80 MiB | 96 MiB | 80 KiB |
| Roihu CPU | 16 MiB | 80 MiB | 96 MiB | 80 KiB |
Internal accounting was identical on both platforms. MacBook RSS remained at its high-water mark; Roihu returned to 50.160 MiB after the final small exchanges. Both retained only the 1,024-row active workspace. Roihu job 1093451 used one test node.
Runtime generation turnover¶
Each of seven MacBook stress series published 256 immutable runtime generations with 64 KiB payloads. Every publication atomically replaced the selector and ran garbage collection. One generation stayed pinned; another pin moved every 16 publications. After both pins were released, only the current and most recent generations survived, matching retention policy.
| Platform | Series time | Publish latency | GC latency | Collected generations |
|---|---|---|---|---|
| MacBook | 3.471 ± 0.703 s | 3.089 ms | 5.498 ms | 254 of 256 |
The 1,792 publications preserved the current generation and both pinned generations. Released pins were collected. The script is tools/benchmarks/generation_turnover.py.