Throughput against openmm‑plumed, on three machines.
Five MD systems, three backends, one timing protocol, run on three machines whose CPU clocks
span a 3× range and whose GPUs come from three generations. Every number is ns/day
from a single integrator.step(N) call, with no per-step Python and no CPU to GPU
traffic inside the timed window. The spread in CPU clock is what pins down where
openmm‑plumed's overhead lives.
Three machines
We ran GLUED and openmm‑plumed on hardware people actually own rather than on one sweet‑spot box: a many‑core server CPU, a high‑clock workstation CPU and a 7 GHz‑boost HEDT CPU. From A to C the GPUs get weaker, 5090 to 4090 to 3090, and the CPUs get faster.
The CPUs go 2.25, 4.40 and 7.02 GHz max clock while the GPUs go 5090, 4090, 3090. If openmm‑plumed's overhead were bound by PCIe or sync, the weaker GPU would dominate and the small‑system numbers would stay flat or fall. If it is bound by CPU compute, the small‑system PLUMED numbers should rise with CPU clock even as the GPU gets weaker. They rise, and close to linearly.
What the CPU swap tells us
openmm‑plumed's ceiling is the CPU, not the transfer between CPU and GPU.
On Machine A, an EPYC 7742 at 2.25 GHz, openmm‑plumed sits at about 50 ns/day on every case from 23 atoms to 168k atoms. That is a flat line across four orders of magnitude in system size, and on its own it fits two different bottlenecks: per‑step transfer latency between CPU and GPU, or single‑thread PLUMED compute on the host.
Machines B and C have the same wiring, the same openmm‑plumed bridge and the same PCIe sync, but faster CPUs and weaker GPUs. If transfer or sync were the limit, the small‑system numbers should not move, or should drop with the weaker GPU. Instead they rise with CPU clock, close to linearly:
Machine C has the slowest GPU of the three and still beats Machine A by 24× on the small case, because PLUMED's bottleneck never touches the GPU. On small systems the limit is PLUMED's single‑thread CPU compute. The GPU sits idle while the host finishes each bias step.
On the larger systems, KOR and Kv1.2, the MD step itself dominates wall time and the gap narrows. GLUED leads PLUMED by 1.35 to 3.6× on Machines B and C and by 3 to 6× on Machine A. Absolute wall time on these systems is set by the GPU, so the 5090 host wins overall.
Headline numbers
Each figure reads Machine A, then Machine B, then Machine C. The large Machine A speedups come from the slow CPU throttling PLUMED hardest. The right‑most number is the floor: what GLUED still gains on the fastest‑CPU host.
Per‑case throughput in ns/day
Same OpenMM LangevinMiddleIntegrator, dt = 2 fs, same warmup and timed
window on all three hosts. Across backends only the bias wiring changes. Within a case only the
host changes.
| Case and host | Atoms | raw OpenMM | GLUED | PLUMED | GLUED / raw | GLUED / PLUMED |
|---|---|---|---|---|---|---|
| Alanine dipeptide in vacuumad_vacuum, CV_DIHEDRAL, OPES_METAD | 23 | |||||
| A5090 + EPYC | 6 403.4 | 4 589.4 | 49.7 | 0.72× | 92.3× | |
| B4090 + i9 | 9 574.2 | 5 915.9 | 558.8 | 0.62× | 10.6× | |
| C3090 + TR PRO | 7 332.2 | 5 190.7 | 1 197.6 | 0.71× | 4.33× | |
| Alanine dipeptide in waterad_water, CV_DIHEDRAL, OPES_METAD, PME | 722 | |||||
| A5090 + EPYC | 2 015.0 | 1 847.4 | 56.6 | 0.92× | 32.6× | |
| B4090 + i9 | 3 228.8 | 2 960.0 | 496.8 | 0.92× | 5.96× | |
| C3090 + TR PRO | 2 687.4 | 2 553.6 | 750.6 | 0.95× | 3.40× | |
| κ‑opioid receptor, A100 activation scorekor_a100, 5× CV_DISTANCE + expression, OPES_METAD | 71 873 | |||||
| A5090 + EPYC | 332.4 | 301.7 | 49.8 | 0.91× | 6.1× | |
| B4090 + i9 | 303.7 | 296.8 | 143.4 | 0.98× | 2.07× | |
| C3090 + TR PRO | 158.2 | 157.9 | 116.7 | 1.00× | 1.35× | |
| κ‑opioid receptor, learned CVkor_deepcv_small, CV_PYTORCH (10 atoms, 2k params), OPES_EXPLORE | 71 873 | |||||
| A5090 + EPYC | 314.5 | 155.2 | 51.1 | 0.49× | 3.0× | |
| B4090 + i9 | 303.3 | 137.2 | 90.5 | 0.45× | 1.52× | |
| C3090 + TR PRO | 158.2 | 118.4 | 116.4 | 0.75× | 1.02× | |
| Kv1.2 ion channel, S4 voltage sensorkv12_s4, 7× CV_POSITION + expression, OPES_EXPLORE | 167 817 | |||||
| A5090 + EPYC | 167.4 | 177.1 | 48.6 | 1.06× | 3.6× | |
| B4090 + i9 | 151.7 | 150.3 | 79.0 | 0.99× | 1.90× | |
| C3090 + TR PRO | 73.5 | 73.8 | 54.4 | 1.00× | 1.36× | |
Per‑case charts
One panel per system, split into the three machines, so you can see which gaps depend on the host and which do not. Bars use a log scale from 10 to 10 000 ns/day, so equal lengths mean equal ratios, not equal differences in ns/day.
Methodology
The protocol is identical across backends and machines. Only the bias mechanism changes. Raw OpenMM omits the bias entirely and is the floor.
Zero round‑trips on the timed path
The timed phase is one integrator.step(N) call. No getState(getPositions=…),
no DCD, no COLVAR, no Python in the inner loop. PyTorch CVs run their forward and backward pass on
the same CUDA stream as the integrator (torch::from_blob on the GPU position pointer,
c10::cuda::CUDAStreamGuard).
Same OpenMM context across backends
GLUED and openmm‑plumed differ only in the Force attached to the System. PLUMED
reads its input from one .dat file per case. GLUED's CVs are declared through
force.add_* calls in Python. Same integrator, same dt, same warmup, same starting
positions.
Warmup and sync
A 1000‑step untimed warmup lets NVRTC compile every CV and bias kernel and lets caches fill.
Before timing starts and after it ends, a flag‑free context.getState() flushes the
CUDA queue so wall time includes every queued kernel.
integrator.step(warmup_steps) # untimed; NVRTC compiles kernels here context.getState() # stream sync — no buffer download t0 = time.perf_counter() integrator.step(timed_steps) # the one timed call — no Python inside context.getState() # stream sync — waits for queued GPU work elapsed = time.perf_counter() - t0 ns_per_day = timed_steps * dt_ps * 86_400 / (elapsed * 1000)
What the numbers say
The PLUMED bottleneck is the host CPU, not PCIe.
On Machine A every PLUMED case lands between 48.6 and 56.6 ns/day, a flat line across four orders of magnitude in system size. On the small cases that plateau lifts to about 560 ns/day on Machine B and about 1200 ns/day on Machine C, tracking max CPU clock (2.25, 4.40, 7.02 GHz) almost linearly even though Machine C has the weakest GPU. Transfer and sync latency do not scale with CPU clock. Single‑thread PLUMED compute does.
GLUED's lead shrinks as PLUMED catches up.
GLUED's lead over openmm‑plumed is largest where PLUMED is most CPU‑bound, meaning small systems on slow CPUs: 92× on Machine A's ad_vacuum, 4.3× on Machine C's. As the MD step gets expensive (KOR, Kv1.2) or the CPU gets fast enough (Machine C), the gap narrows to 1.0 to 1.4×. GLUED still wins everywhere, just by less.
The bias machinery costs almost nothing.
GLUED's ratio against raw OpenMM is 0.91 to 1.06× on Machine A, 0.92 to 0.99× on Machine B and 0.95 to 1.00× on Machine C for every analytical‑CV case (ad_water, kor_a100, kv12_s4). On Machine C's kor_a100 GLUED runs 157.9 against 158.2 ns/day. The chain‑rule plumbing is at the noise floor.
Learned CVs: GLUED wins until the model itself dominates.
On the 10‑atom TorchScript MLP, GLUED leads openmm‑plumed by 3.0× on
slow‑CPU Machine A, 1.52× on Machine B and 1.02× on
fast‑CPU Machine C. The convergence on Machine C matters: the MLP forward and backward pass is
now the dominant cost on both paths, and PLUMED's host‑side staging is small next to the model.
GLUED keeps the tensor on the GPU with a zero‑copy torch::from_blob. You pay for
the model and nothing else.
A 23‑atom system is a microbenchmark, not a use case.
On gas‑phase alanine dipeptide, GLUED runs at 0.62 to 0.72× of raw OpenMM on all three machines. The bias kernels have a fixed launch cost, and that is a real fraction of a step that does almost no MD work. Raw OpenMM on Machine B hits 9 574 ns/day here. This is the floor where GPU launch overhead, not chemistry, decides the number. Treat ad_vacuum as a stress test of the bias plumbing, not as a workload.
GPU strength still decides large‑system wall time.
PLUMED's plateau is CPU‑bound, but the absolute throughput on big systems is set by the GPU. Raw OpenMM on kv12_s4 goes 167 ns/day on the 5090, 152 on the 4090 and 73 on the 3090, a clean GPU‑generation curve. Machine C has the fastest CPU and lifts PLUMED furthest off the plateau, but its 3090 gets roughly half the kv12_s4 throughput of Machine A's 5090. Pick the GPU for the system you run. The CPU clock matters when PLUMED is in the loop.
References
- Ibrahim, P., Wifling, D. & Clark, T. A Universal Activation Index for Class A GPCRs. J. Chem. Inf. Model. 59, 3938–3945 (2019). doi:10.1021/acs.jcim.9b00604 Defines the A100 activation index used as the kor_a100 CV
- Doering, N. P. et al. Mechanistic Insights into G Protein-Biased κ-Opioid Receptor Signaling Using Dual-Charged Naltrexamine Amides. J. Med. Chem. 69, 3833–3851 (2026). doi:10.1021/acs.jmedchem.5c02135 Applies the A100 index to the KOR system benchmarked here
- Bjelkmar, P., Niemelä, P. S., Vattulainen, I. & Lindahl, E. Conformational Changes and Slow Dynamics through Microsecond Polarized Atomistic Molecular Simulation of an Integral Kv1.2 Ion Channel. PLoS Comput. Biol. 5, e1000289 (2009). doi:10.1371/journal.pcbi.1000289 Source of the S4 voltage-sensor motion that the kv12_s4 CV tracks