Kernel fusion¶
cuPDLPx fuses the affine updates, projections, reflection, and Halpern updates into two vector kernels. These operations have low arithmetic intensity; fusion reduces global memory traffic and kernel launches. See the Roofline model for the relationship between arithmetic intensity and memory bandwidth.
Fused operations¶
The fused updates combine PDHG, reflection, and Halpern anchoring, with vector operations highlighted below. Within each epoch, \((x^0,y^0)\) is the fixed anchor and \(k\) is the local iteration index.
The primal kernel computes \(\bar x^{k+1}\) once and reuses it for both the primal reflection and the PDHG extrapolation in the dual update.
Kernel execution¶
Each iteration uses two SpMV calls and two fused vector kernels:
- SpMV: compute \(A^\top y^k\) for the primal update.
- Fused primal kernel: perform the primal PDHG, reflection, and Halpern updates.
- SpMV: compute \(A\bar x^{k+1}\) for the dual update.
- Fused dual kernel: perform the dual PDHG, reflection, and Halpern updates.
Each GPU thread computes all three updates for one coordinate. The primal kernel writes \(x^{k+1}\) and \(\bar x^{k+1}\) to global memory, and the dual kernel writes \(y^{k+1}\). The second SpMV uses the stored vector \(\bar x^{k+1}\).
Major iterations
cuPDLPx evaluates termination and restart criteria at regular intervals; these iterations are called major iterations. For these checks, the fused kernels also save the PDHG iterates and reflected dual values to global memory. These values otherwise remain in registers. The primal kernel also performs dual-slack recovery.