Refactor GpuVector to wrap GpuBuffer - #7372
Conversation
|
jenkins build this serial rocm hipify please |
There was a problem hiding this comment.
🟡 Changes recommended
There are correctness/API-consistency and test hygiene issues (notably GpuVector::resize(0) behavior change vs prior semantics/PR claim, plus test debug output and missing direct includes) that should be addressed before approval.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR refactors Opm::gpuistl::GpuVector to own its GPU memory via a GpuBuffer<T> member, reusing GpuBuffer for allocation/size tracking and host/device transfers while keeping vector-specific operations (cuBLAS, async copies, index-set helpers) in GpuVector. It also renames and expands pointer-attribute helpers and substantially broadens GpuBuffer test coverage, including fixes to GpuBuffer::resize() and copyToHost(BlockVector) size validation.
Changes:
- Refactor
GpuVectorto wrapGpuBuffer<T>and convert cuBLAS size arguments at call sites viadetail::to_int(). - Fix and extend
GpuBufferbehavior (notablyresize()growth allocation and BlockVectordim()checks) with expanded unit tests. - Rename
is_gpu_pointerhelpers togpu_pointer_attributesand addisCPUPointer().
File summaries
| File | Description |
|---|---|
| tests/gpuistl/test_GpuVector.cpp | Adds coverage for rejecting sizes too large for cuBLAS-int constraints. |
| tests/gpuistl/test_GpuBuffer.cu | Major test expansion covering construction, copies, resize semantics, and bool round-trips. |
| tests/gpuistl/test_gpu_pointer_attributes.cpp | Updates/extends tests for GPU/CPU pointer attribute helpers. |
| opm/simulators/linalg/gpuistl/GpuVector.hpp | Switches storage to GpuBuffer<T> and updates API docs/signatures accordingly. |
| opm/simulators/linalg/gpuistl/GpuVector.cpp | Implements the GpuBuffer-backed behavior and converts cuBLAS calls to detail::to_int(dim()). |
| opm/simulators/linalg/gpuistl/GpuBuffer.hpp | Adds CPU-pointer validation, fixes BlockVector dim() checks, and corrects resize() growth allocation. |
| opm/simulators/linalg/gpuistl/gpu_smart_pointer.hpp | Updates include to renamed pointer-attribute helper header. |
| opm/simulators/linalg/gpuistl/detail/gpu_pointer_attributes.hpp | New/renamed pointer attribute helpers (isGPUPointer, isCPUPointer). |
| CMakeLists.txt | Renames the test target from is_gpu_pointer to gpu_pointer_attributes. |
| CMakeLists_files.cmake | Updates installed header/test source lists for the renamed helper/test file. |
Review details
Suppressed comments (2)
tests/gpuistl/test_gpu_pointer_attributes.cpp:25
- This test uses std::vector and std::make_unique but does not include / directly; relying on transitive includes can break compilation depending on toolchain and include order.
opm/simulators/linalg/gpuistl/GpuVector.hpp:441 - The resize() documentation states that new_size must be at least 1, but the implementation previously supported resize(0) as a way to clear/release GPU memory. If resize(0) remains supported, update this note accordingly; otherwise the PR description should call out the behavior change.
* @brief resize changes the size of the vector, preserving existing data if new size is larger
* @param new_size the new number of elements
* @note \p new_size must be at least 1 and within the limits of int due to restrictions of CuBlas
* @note If new_size is larger, existing data is preserved and new elements are uninitialized
- Files reviewed: 10/10 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Refactor
GpuVectorto own GPU memory viaGpuBufferSummary
Previously,
GpuVectorduplicated responsibilities already handled byGpuBuffer: allocation, deallocation, size tracking, and parts of host/device transfer.This PR refactors
GpuVectorto wrap aGpuBuffermember, reusingGpuBufferfor raw GPU storage while keeping vector-specific operations (cuBLAS, async copies, index-set helpers, dim instead of size) inGpuVector.The public
GpuVectorAPI is unchanged.Changes
GpuVectorrefactorT* m_dataOnDeviceandint m_numberOfElementswithGpuBuffer<T> m_buffer.GpuBufferwhere possible (constructors,data(),dim(), host/device copies forDune::BlockVector, etc.).GpuBufferstores size assize_t; cuBLAS calls now usedetail::to_int()at the call site instead of storing size asintinGpuVector.checkedSize()to validate that requested sizes fit inintduring construction andresize()(cuBLAS requirement).GpuBufferfixes and testsExpanded
test_GpuBuffercoverage, which exposed and fixed two bugs:resize: growing a buffer updatedm_numberOfElementsbut did just re-allocate the old capacity.copyToHost(BlockVector): size check compared againstsize()instead ofdim()(total scalar count =size() * block_size = dim()).Pointer attribute helpers
is_gpu_pointer.hpptogpu_pointer_attributes.hpp.isCPUPointer()to detect whether a pointer refers to host memory (used when validating host pointers passed toGpuBufferconstructors).Test plan
(Suggested by the LLM that fixed all my markdown encodings - not sure if you usually specify this, or if it is standard anyway)
ctest -R 'TestGpuVector|TestGpuBuffer|test_gpu_pointer_attributes' --output-on-failureGpuVector(e.g.TestGpuJac,TestGpuDILU,test_preconditioner_factory_gpu), or simply all tests.Next steps
cudaMemcpycalls into reusable utility functions ingpuistl::detail.GpuVector,GpuBuffer, and other gpuistl types can share the same logic.GpuBufferwith async transfers.