NVRS-CUDA · mixed-precision CPR

A mixed-precision, GPU-native CPR solver for fully implicit reservoir simulation

A GPU-resident, fully implicit three-phase black-oil simulator whose linear solver combines FP64 flexible GMRES with a reduced-precision constrained-pressure-residual preconditioner, benchmarked against OPM Flow on the Norne field, SPE10 model 2 and models of up to five million cells.

GPU computingMixed precisionCPRFGMRESAlgebraic multigridBlack-oilOPM Flow
3.5xNorne, one GB200 GPU against OPM Flow's fastest tested configuration (CPU CPR, 16 ranks); see the methodology table
18.6xSPE10, one VR72 GPU against OPM Flow's CPU solver on two threads; see the methodology table
1.12 Mcells in SPE10 model 2, on one GPU
FP64accuracy with an FP32 preconditioner
01 · Overview

A fully implicit simulator that lives on the GPU


NVRS-CUDA is a three-phase black-oil simulator with dissolved gas and vaporised oil in which property evaluation, analytic Jacobian assembly, algebraic multigrid and the well equations all run on the device. Each Newton step is solved with flexible GMRES and a two-stage constrained-pressure-residual (CPR) preconditioner: stage 1 is one AmgX algebraic-multigrid V-cycle on the pressure block, stage 2 is 2 x 2 block Jacobi. The state, residuals and Krylov recurrences stay in double precision; the preconditioner runs in lower precision. BoomerAMG from HYPRE and Ginkgo can replace AmgX in stage 1.

GPU-resident Newton loop

The host reads the deck and writes results; inside a Newton iteration nothing returns to the host.

Mixed-precision CPR

Stage 1: one AmgX V-cycle on the pressure block in FP32. Stage 2: 2 x 2 block Jacobi. Outer FGMRES in FP64 keeps the answer exact.

Block-sparse operator, CUDA graphs

A block-sparse operator cuts the cost per Krylov iteration; graph replay is used only where it pays for itself.

Validated against OPM Flow

Norne, SPE10 model 2 and synthetic models of up to five million cells, well by well and field by field.

02 · Mathematics

Why reduced precision is safe here


In plain words
  • Newton handles the nonlinear conservation equations: each time step becomes a sequence of linear systems.
  • FGMRES solves each linear system, in FP64, and measures the true residual at every iteration.
  • CPR is the preconditioner that makes FGMRES fast: a multigrid V-cycle for the pressure part, then a cheap 2 x 2 block correction for everything else.
  • Reduced precision is used only inside the preconditioner, where it moves fewer bytes; FP64 FGMRES and the Newton tolerances decide when the solution is accurate enough.

Two-stage CPR: one AmgX V-cycle approximates the inverse of the pressure block A_p, then 2 x 2 block Jacobi (M_2) acts on the full system.

Flexible GMRES minimises the true residual over whatever directions the preconditioner produced, so rounding inside the preconditioner changes the iteration count, not the solution.

The condition that licenses an FP32 preconditioner: FP32 unit roundoff times the conditioning of the preconditioned operator.

03 · The simulator, live

Inside one Newton step: FGMRES with two-stage CPR


This is the simulator in miniature, running in your browser. A fully implicit two-phase model has pressure and water saturation in every cell, so the Jacobian has 2 x 2 blocks. Every time step is a Newton loop, and every Newton step solves J δu = −R with FGMRES in FP64, preconditioned by two-stage CPR. Stage 1 applies quasi-IMPES weights to form the pressure matrix and one aggregation-multigrid V-cycle (the role AmgX plays). Stage 2 is 2 x 2 block Jacobi. Choose the precision of the preconditioner and watch the iteration counts, the time per stage and the solution.

1Assemble R, Janalytic Jacobian, 2 x 2 blocksFP64
2FGMRESouter Krylov on the full systemFP64
3CPR stage 1quasi-IMPES pressure matrix, one multigrid V-cycleFP32
4CPR stage 22 x 2 block Jacobi on the full systemFP32
5Newton updatechop, converge, grow or cut the stepFP64

Interactive CPU implementation of the algorithm, in JavaScript in your browser. The GPU results on this page come from the separate research implementation.

Two-phase oil and water, Corey relative permeability, slightly compressible rock. In the five-spot, water is injected at a fixed rate in the centre and four producers at fixed bottom-hole pressure sit in the corners, with a Peaceman-type well index proportional to the well-cell permeability. Every run is repeated with an FP64 preconditioner as the reference (red); the curves of the chosen precision (blue) lie on it. The model has no gas phase, so there is no WGPR. Newton, the update limits and the time-step control use the same settings as the simulator in the paper: OPM Flow's convergence test (CNV below 1e-2 and material balance below 1e-6 in every phase), at most 20 Newton iterations, saturation changes limited to 0.2 per iteration, FGMRES(30) to a relative 1e-6, and dyadic chopping of each report step (up to six halvings, one released after two clean report steps). FP16 is emulated by rounding every operation of the preconditioner, applied to the row-scaled pressure matrix. This app runs in your browser, in JavaScript on the CPU, with no GPU and no server: a two-phase model far smaller than the three-phase GPU simulator, but with the same stages in its nonlinear and linear solvers. The run and its FP64 reference each run in a Web Worker, so the page stays responsive, and play as a movie: every frame advances the chosen time and redraws the field and the well curves. A fully implicit step costs far more per cell than the IMPES waterflood further down this page, so the 56 x 56 grid plays at about one frame per half second.

04 · Movies

Fields against OPM Flow


05 · Results

Norne, SPE10 and the Million family


Wall clock in seconds on one GPU, from the paper. Flow is OPM Flow 2024.10 (its GPU linear solver on one rank for Norne and Bench3P, its CPU solver with two threads for SPE10 on the VR72 host). NVRS-CUDA runs every model on one GPU with BoomerAMG or AmgX in CPR stage 1.

ModelCellsGB200VR72
OPM FlowBoomerAMGAmgXOPM FlowBoomerAMGAmgX
Norne field44,431488.5171.5144.95243.8873.5435.73
Bench3P4,8009.253.000.895.323.440.95
SPE10 model 21,122,000n/r99.2253.06766.1691.7441.21
Million 1M1,000,000n/r26.2321.17n/r19.9414.87
Million 2M2,000,000n/r49.9439.38n/r38.2327.17
Million 4M4,000,000n/r81.8777.67n/r60.9752.33
Million 5M5,000,000n/r102.3295.61n/r76.6563.77

n/r: not run.

How the headline speed-ups were measured

ClaimModelNVRS-CUDABaselineWhat is timedCaveat
3.5xNorne, 44,431 cells, full history46.75 s, one GB200 GPU, AmgX in CPR stage 1 165.62 s, OPM Flow 2024.10, CPU CPR solver on 16 ranks, the fastest Flow configuration tested on the GB200 node wall clock of the whole run, median of threeGPU against CPU ranks on the same node
18.6xSPE10 model 2, 1,122,000 cells, 1,000 days41.21 s, one VR72 GPU, AmgX in CPR stage 1 766.16 s, OPM Flow 2024.10, CPU solver on two threads on the VR72 host wall clock of the whole runa GPU against two CPU threads, not a hardware-equivalent comparison

Both runs reproduce OPM Flow's fields and well rates (see Accuracy below, with the per-well R2 on Norne).

The Million family on one, two and four GPUs

Strong scaling of synthetic three-phase models from one to five million cells. Switch machines, or show the speed-up of each back end against its own one-GPU time; hover a bar for its value.

AmgX, 1 / 2 / 4 GPUs (light to dark)BoomerAMG, 1 / 2 / 4 GPUs
Hover a bar for its value.
CellsStage 1GB200VR72
1 GPU2 GPUs4 GPUs1 to 41 GPU2 GPUs4 GPUs1 to 4
1 MBoomerAMG26.2333.8543.270.61x19.9428.8849.610.40x
AmgX21.1718.9618.261.16x14.8714.0216.170.92x
2 MBoomerAMG49.9452.8465.320.76x38.2343.8372.110.53x
AmgX39.3831.0530.841.28x27.1721.2423.621.16x
4 MBoomerAMG81.8780.0086.670.94x60.9760.9685.210.72x
AmgX77.6758.0151.781.50x52.3336.5841.141.27x
5 MBoomerAMG102.3296.1696.641.06x76.6577.4993.300.81x
AmgX95.6171.1461.711.55x63.7743.9142.261.51x
Reading the scaling

More GPUs do not always help. With BoomerAMG in stage 1 the 1 M and 2 M models get slower from one to four GB200 GPUs (0.61x and 0.76x) and only break even at 5 M (1.06x), while AmgX gains from 1.16x to 1.55x. Splitting a fixed problem across more GPUs shrinks the work per GPU, but the halo exchanges and the setup of the multigrid hierarchy do not shrink with it; small problems hit that strong-scaling limit first. It is a property of the problem size and the communication, not a defect of either library, and it is reported here as measured.

06 · Performance

Speed on GB200 and VR72


07 · Precision

Mixed precision and emulated FP64


08 · Accuracy

Norne and SPE10 against OPM Flow


09 · Precision lab

FGMRES with a reduced-precision multigrid preconditioner


The argument of the paper, run live. A heterogeneous pressure equation, the system that CPR's first stage solves, is handed to flexible GMRES, preconditioned by one aggregation-multigrid V-cycle, the role AmgX plays in stage 1 of CPR. With the outer FGMRES in FP64, running the V-cycle in FP32 or even FP16 changes how many iterations are needed, not the accuracy reached. When the outer recurrences drop to FP32 as well, the residual stalls near FP32 roundoff. Every curve is the true residual, evaluated in FP64.

FP64 FGMRES + FP64 V-cycle FP64 FGMRES + FP32 V-cycle (the paper's design) FP64 FGMRES + FP16 V-cycle FP32 FGMRES + FP32 V-cycle

Interactive CPU implementation of the algorithm, in JavaScript in your browser. The GPU results on this page come from the separate research implementation.

5-point finite volumes, harmonic transmissibilities, an injector and a producer; 2 x 2 aggregates with Galerkin coarse operators, two damped-Jacobi sweeps before and after, exact coarsest solve. FP16 is emulated by rounding every operation; the FP16 hierarchy uses the diagonally scaled matrix, because field-unit entries exceed the largest half-precision number.

10 · Paper and references

Read more


C. Etienam, T. Onishi, O. Ovcharenko, N. Luiken, I. Said. A Mixed-Precision, GPU-Native Constrained-Pressure-Residual Solver for Fully Implicit Reservoir Simulation. Submitted to arXiv, 2026.

Linear-algebra libraries

M. Naumov, M. Arsaev, P. Castonguay, J. Cohen, J. Demouth, J. Eaton, S. Layton, N. Markovskiy, I. Reguly, N. Sakharnykh, V. Sellappan, R. Strzodka. AmgX: a library for GPU accelerated algebraic multigrid and preconditioned iterative methods. SIAM Journal on Scientific Computing 37(5), S602–S626, 2015. github.com/NVIDIA/AMGX

V. E. Henson, U. M. Yang. BoomerAMG: a parallel algebraic multigrid solver and preconditioner. Applied Numerical Mathematics 41(1), 155–177, 2002.
R. D. Falgout, U. M. Yang. hypre: a library of high performance preconditioners. Computational Science, ICCS 2002, Lecture Notes in Computer Science 2331, 632–641, Springer, 2002. github.com/hypre-space/hypre

H. Anzt, T. Cojean, G. Flegar, F. Göbel, T. Grützmacher, P. Nayak, T. Ribizel, Y. M. Tsai, E. S. Quintana-Ortí. Ginkgo: a modern linear operator algebra framework for high performance computing. ACM Transactions on Mathematical Software 48(1), 1–33, 2022. github.com/ginkgo-project/ginkgo

Y. Saad. A flexible inner-outer preconditioned GMRES algorithm. SIAM Journal on Scientific Computing 14(2), 461–469, 1993.
J. R. Wallis, R. P. Kendall, T. E. Little. Constrained residual acceleration of conjugate residual methods. SPE Reservoir Simulation Symposium, SPE 13536, 1985.
More

Other featured work