[GSoC] Feature: MultiDot and Linear Combination CUDA kernels (Originally: Jacobi preconditioner on GPU and CUDA Unified preconditiong matrix) - #2843
Conversation
… allocation of the preconditioning matrix.
|
That's great! |
pcarruscag
left a comment
There was a problem hiding this comment.
I think Areen looked into unified memory a bit.
Do you have some performance measurements? I imagine we save on the data transfer but suffer a little on the kernel performance?
Does unified memory introduce a significant restriction in terms of the required compute capability?
…ted on 1 test-case.
…ogic from device pointers. Validated on test-case turb_SA_RAE2822 comparing residuals over 100 iterations.
d12fd4b to
e070ec7
Compare
Thanks for the heads-up. Updated that commit and the following ones. |
For the moment, I've only one performance measurement on my local GPU Quadro P620:
Preliminary profiling shows indeed that the transfer of the preconditioning matrix is asynchronously launched but then the preconditioning kernel takes longer due to page fault. I intend to better profile what is going on with the CSysVector Unified memory implementation. Unified memory is available for the compute capability 6.0 or higher. Some of its advanced features seem to depend on the system. Is there some report by Areen? It could be interesting for me to read it. |
|
Thanks I was wondering about unified vs explicit transfers not CPU vs GPU. |
…roduct through custom CUDA kernel for norm of GPU, validated on rae2822 test-case comparing residuals between CPU and GPU
…ive assignment, validated on rae2822
…yntax tree. Binary vector expressions are coded into the tree and passed to the kernel for execution. Negative assignment is possible. validated on rae2822
…st in all the Host routines that access vectors to ensure correctness. Validated against rae2822
|
Yes, I understand. I have further developed my PR to cover the whole FGMRES solver so that operations with CSysVectors run on GPU, operators too. In the last commit, I also fell back from Unified to Managed CUDA memory for the CSysVector. In this way, I could profile as you suggested. For the moment I could do this only on my local Quadro P620, I'll be trying to get better GPUs on the cloud. Please find here SU2_ra2822_GPU_MA_vs_UM_nsys_prof.pdf |
…oped GPU multiDot and LinearCombination kernels
For the sake of completeness, I report a benchmark between Unified Memory (left column, commit 5fe25b8 ) and Managed Memory (right column, commit 4b43fa0 ) here: : SU2_rae2822_UM_vs_MA_NVIDIARTX2000AdaGene.pdf. I was able to run this on an RTX 2000 for the rae 2822 grid with 24576 elements. |
|
Good direction — fusing the Suggest dropping Blockers in
Determinism: Minor: 1024-thread blocks mean 8 KB shared memory per block for a reduction (128-256 is more typical), and the tree reduction assumes a power-of-two size — worth a Testing before this leaves draft: |
|
Sorry for the previous huge comment from Claude, I had it clean up, the findings look valid. |
Proposed Changes
This draft PR introduces CUDA Unified memory and Managed memory allocation, and memory management for the CSysVector class and the preconditioning matrix inside the Jacobi preconditioner. This allows for a benchmark between the two memory strategies within the FGMRES solver.
Also, this draft PR extends the section of GPU execution inside the FGMRES solver
Custom CUDA kernels are implemented for the preconditioning matrix, the multi dot product and the linear combination (inside the Modified Gram-Schmidt orthogonalization), and the vector norm calculation. Unary vector-scalar operations based on templates are also offloaded to GPU through a generic kernel. Moreover, abstract Syntax Tree are deployed to offload vector-vector binary operations to the GPU through a generic kernel based on a runtime evaluation of the tree.
The solver logic is not modified, and the GPU path is hidden inside the specific methods.
Unified memory approach 5fe25b8
A custom data() method recovers the CSysVector Unified pointer inside the CUDA logic, cleaning the logic from the double host/device pointers. All memory explicit memory copies are also removed from the CUDA logic, but explicit device synchronizations are introduced around MPI calls and at the end of the CUDA section.
Managed memory approach (current head) 4b43fa0
Operators accessing the CSysVector on Host after GPU operations demand synchronization, which is introduced explicitly in each.
Performance evaluation (on-going)
For the considered test-case (rae2822), the CPU execution expresses an Avg. s/iter: 0.198681.
The GPU execution with Unified memory expresses an Avg. s/iter: 0.238953.
The GPU execution with Managed memory expresses an Avg. s/iter: 0.372046.
The CPU is a Intel(R) Xeon(R) E-2276M CPU @ 2.80GHz with 12 cores. The GPU is a Quadro P620. Tests on more advanced hardware are ongoing.
Profiling results comparing the Unified Memory (left column) against the Managed Memory (right column) are available in the attached pdf:
SU2_ra2822_GPU_MA_vs_UM_nsys_prof.pdf
Asynchronous pre-fetching:
The Jacobi preconditioner calculations are performed on GPU through a new custom CUDA kernel under the preconditioner abstraction.
The preconditioning matrix is selected to test CUDA Unified Memory asynchronous prefetching to the GPU.
For simplicity, the double CPU/GPU pointer is still maintained in the current logic, although the device pointer reduces to an alias for the Unified Memory pointer when this kind of allocation is adopted.
This strategy introduces a simple context to test the CUDA Unified Memory usage and study the possibility of overlapping memory transfers and calculations without the need to introduce CUDA streams.
Concretely, this PR:
This work is part of my ongoing contribution during the Google Summer of Code 2026 program.
Validation
Validated locally with:
Nsys profiling was performed to confirm the asynchronous prefetching of the CUDA Unified Memory preconditioning matrix on my local GPU. Partial prefetching is observed, although page faults were reported during the preconditioner CUDA kernel, indicating that the calculations were slowed down by the prefetching matrix still being transferred to the GPU. This overlap is expected to largely improve on more modern hardware; tests are ongoing in the cloud.
Related Work
The Jacobi preconditioner kernels come from the PR #2825.
Observed Issues
Some issues were observed during this first period of GSoC:
Next steps
I propose to continue working on the following steps:
PR Checklist
pre-commit run --allto format old commits.