1#ifndef COLVAR_GPU_SUPPORT_H
2#define COLVAR_GPU_SUPPORT_H
6#include <unordered_map>
10#define COLVARS_STRINGIFY(s) STRINGIFY_HELPER(s)
11#define STRINGIFY_HELPER(s) #s
13#if defined(COLVARS_CUDA)
14#include <cuda_runtime.h>
15#ifdef COLVARS_NVTX_PROFILING
16#include <nvtx3/nvToolsExt.h>
17#include <nvtx3/nvToolsExtCudaRt.h>
19#define COLVARS_SYNC_WARP __syncwarp()
22#if defined(COLVARS_HIP)
23#include <hip/hip_runtime.h>
24#if defined(__HIP_PLATFORM_AMD__)
31 #define COLVARS_SYNC_WARP do {\
32 __builtin_amdgcn_fence(__ATOMIC_RELEASE, "wavefront"); \
33 __builtin_amdgcn_wave_barrier(); \
34 __builtin_amdgcn_fence(__ATOMIC_ACQUIRE, "wavefront"); \
36#elif defined(__HIP_PLATFORM_NVIDIA__)
37 #define COLVARS_SYNC_WARP __syncwarp()
39 #error "Unknown HIP platform"
43#if defined(COLVARS_HIP)
45#define cudaError_t hipError_t
49#define cudaFree hipFree
53#define cudaFreeHost hipFreeHost
57#define cudaFreeAsync hipFreeAsync
60#ifndef cudaGetErrorString
61#define cudaGetErrorString hipGetErrorString
64#ifndef cudaGraphAddChildGraphNode
65#define cudaGraphAddChildGraphNode hipGraphAddChildGraphNode
68#ifndef cudaGraphAddKernelNode
69#define cudaGraphAddKernelNode hipGraphAddKernelNode
72#ifndef cudaGraphAddMemcpyNode
73#define cudaGraphAddMemcpyNode hipGraphAddMemcpyNode
76#ifndef cudaGraphAddMemsetNode
77#define cudaGraphAddMemsetNode hipGraphAddMemsetNode
80#ifndef cudaGraphCreate
81#define cudaGraphCreate hipGraphCreate
84#ifndef cudaGraphDestroy
85#define cudaGraphDestroy hipGraphDestroy
88#ifndef cudaGraphExecDestroy
89#define cudaGraphExecDestroy hipGraphExecDestroy
92#ifndef cudaGraphExecMemcpyNodeSetParams
93#define cudaGraphExecMemcpyNodeSetParams hipGraphExecMemcpyNodeSetParams
96#ifndef cudaGraphExec_t
97#define cudaGraphExec_t hipGraphExec_t
100#ifndef cudaGraphInstantiate
101#define cudaGraphInstantiate hipGraphInstantiate
104#ifndef cudaGraphInstantiateWithParams
105#define cudaGraphInstantiateWithParams hipGraphInstantiateWithParams
108#ifndef cudaGraphInstantiateParams
109#define cudaGraphInstantiateParams hipGraphInstantiateParams
112#ifndef cudaGraphInstantiateFlagUpload
113#define cudaGraphInstantiateFlagUpload hipGraphInstantiateFlagUpload
116#ifndef cudaGraphInstantiateSuccess
117#define cudaGraphInstantiateSuccess hipGraphInstantiateSuccess
120#ifndef cudaGraphLaunch
121#define cudaGraphLaunch hipGraphLaunch
124#ifndef cudaGraphNode_t
125#define cudaGraphNode_t hipGraphNode_t
129#define cudaGraph_t hipGraph_t
132#ifndef cudaGraphDebugDotPrint
133#define cudaGraphDebugDotPrint hipGraphDebugDotPrint
136#ifndef cudaGraphDebugDotFlags
137#define cudaGraphDebugDotFlags hipGraphDebugDotFlags
140#ifndef cudaGraphDebugDotFlagsVerbose
141#define cudaGraphDebugDotFlagsVerbose hipGraphDebugDotFlagsVerbose
144#ifndef cudaHostAllocMapped
145#define cudaHostAllocMapped hipHostAllocMapped
148#ifndef cudaHostAllocDefault
149#define cudaHostAllocDefault hipHostAllocDefault
153#define cudaHostAlloc hipHostAlloc
156#ifndef cudaLaunchKernel
157#define cudaLaunchKernel hipLaunchKernel
160#ifndef cudaKernelNodeParams
161#define cudaKernelNodeParams hipKernelNodeParams
165#define cudaMalloc hipMalloc
168#ifndef cudaMallocAsync
169#define cudaMallocAsync hipMallocAsync
172#ifndef cudaMallocHost
173#define cudaMallocHost hipMallocHost
176#ifndef cudaGraphAddMemcpyNode1D
177#define cudaGraphAddMemcpyNode1D hipGraphAddMemcpyNode1D
181#define cudaMemcpy hipMemcpy
184#ifndef cudaMemcpy3DParms
185#define cudaMemcpy3DParms hipMemcpy3DParms
188#ifndef cudaMemcpyAsync
189#define cudaMemcpyAsync hipMemcpyAsync
192#ifndef cudaMemcpyDeviceToDevice
193#define cudaMemcpyDeviceToDevice hipMemcpyDeviceToDevice
196#ifndef cudaMemcpyDeviceToHost
197#define cudaMemcpyDeviceToHost hipMemcpyDeviceToHost
200#ifndef cudaMemcpyHostToDevice
201#define cudaMemcpyHostToDevice hipMemcpyHostToDevice
204#ifndef cudaMemcpyKind
205#define cudaMemcpyKind hipMemcpyKind
209#define cudaMemset hipMemset
212#ifndef cudaMemsetParams
213#define cudaMemsetParams hipMemsetParams
216#ifndef cudaMemsetAsync
217#define cudaMemsetAsync hipMemsetAsync
220#ifndef cudaStreamCreate
221#define cudaStreamCreate hipStreamCreate
224#ifndef cudaStreamDestroy
225#define cudaStreamDestroy hipStreamDestroy
228#ifndef cudaStreamSynchronize
229#define cudaStreamSynchronize hipStreamSynchronize
233#define cudaStream_t hipStream_t
237#define cudaSuccess hipSuccess
240#ifndef make_cudaExtent
241#define make_cudaExtent make_hipExtent
244#ifndef make_cudaPitchedPtr
245#define make_cudaPitchedPtr make_hipPitchedPtr
249#define make_cudaPos make_hipPos
253#define cudaEvent_t hipEvent_t
256#ifndef cudaEventCreateWithFlags
257#define cudaEventCreateWithFlags hipEventCreateWithFlags
260#ifndef cudaEventDisableTiming
261#define cudaEventDisableTiming hipEventDisableTiming
264#ifndef cudaEventDestroy
265#define cudaEventDestroy hipEventDestroy
268#ifndef cudaEventRecord
269#define cudaEventRecord hipEventRecord
272#ifndef cudaEventSynchronize
273#define cudaEventSynchronize hipEventSynchronize
276#ifndef cudaStreamWaitEvent
277#define cudaStreamWaitEvent hipStreamWaitEvent
280#ifndef cudaGraphAddEventRecordNode
281#define cudaGraphAddEventRecordNode hipGraphAddEventRecordNode
285#define cudaGetDevice hipGetDevice
288#ifndef cudaDeviceProp
289#define cudaDeviceProp hipDeviceProp_t
292#ifndef cudaDeviceGetPCIBusId
293#define cudaDeviceGetPCIBusId hipDeviceGetPCIBusId
296#ifndef cudaGetDeviceProperties
297#define cudaGetDeviceProperties hipGetDeviceProperties
300#ifndef cudaDeviceGetAttribute
301#define cudaDeviceGetAttribute hipDeviceGetAttribute
304#ifndef cudaDevAttrWarpSize
305#define cudaDevAttrWarpSize hipDeviceAttributeWarpSize
310namespace colvars_gpu {
312#if defined(COLVARS_CUDA) || defined(COLVARS_HIP)
314constexpr static unsigned int default_block_size = 128;
316constexpr static unsigned int default_reduce_max_num_blocks = 64;
320#if defined(COLVARS_CUDA) || defined(COLVARS_HIP)
321#define COLVARS_HOST_DEVICE __device__ __host__
322#define COLVARS_DEVICE __device__
324#define COLVARS_HOST_DEVICE
325#define COLVARS_DEVICE
330#if defined(COLVARS_CUDA) || defined(COLVARS_HIP)
331template <
typename T,
unsigned long N>
335 using value_type = T;
336 using size_type =
decltype(N);
337 using reference = value_type&;
338 using const_reference =
const value_type&;
340 using const_pointer =
const T*;
341 COLVARS_HOST_DEVICE
constexpr size_type size()
const {
return N;}
342 COLVARS_HOST_DEVICE reference operator[](size_type pos) {
return m_data[pos];}
343 COLVARS_HOST_DEVICE const_reference operator[](size_type pos)
const {
return m_data[pos];}
348#if ( defined(COLVARS_CUDA) || defined(COLVARS_HIP) )
360 using value_type = T;
370 T* allocate(
size_t n) {
372 if (cudaHostAlloc(&ptr, n *
sizeof(T), cudaHostAllocMapped) != cudaSuccess) {
373 throw std::bad_alloc();
377 void deallocate(T* ptr,
size_t n)
noexcept {
378 (void)cudaFreeHost(ptr);
380 template<
typename U,
typename... Args>
381 void construct(U* p, Args&&... args) {
382 new(p) U(std::forward<Args>(args)...);
386 void destroy(U* p)
noexcept {
393#if defined(COLVARS_CUDA) || defined (COLVARS_HIP)
402int gpuAssert(cudaError_t code,
const char *file,
int line);
407#if defined(COLVARS_CUDA) || defined (COLVARS_HIP)
410#define checkGPUError(ans) colvars_gpu::gpuAssert((ans), __FILE__, __LINE__);
413namespace colvars_gpu {
414#if defined(COLVARS_CUDA) || defined (COLVARS_HIP)
438 std::unordered_map<std::string, cudaGraphNode_t>
nodes = {};
444int add_clear_array_node_impl(
445 void* dst,
const size_t num_elements,
const size_t sizeofT,
446 cudaGraphNode_t& node_out, cudaGraph_t& graph,
447 const std::vector<cudaGraphNode_t>& dependencies);
452int add_copy_node_impl(
453 const void* src,
void* dst,
const size_t num_elements,
const size_t sizeofT,
454 cudaMemcpyKind kind, cudaGraphNode_t& node_out, cudaGraph_t& graph,
455 const std::vector<cudaGraphNode_t>& dependencies);
469int add_clear_array_node(
470 T* dst,
const size_t num_elements,
471 cudaGraphNode_t& node_out, cudaGraph_t& graph,
472 const std::vector<cudaGraphNode_t>& dependencies) {
473 return add_clear_array_node_impl(
474 dst, num_elements,
sizeof(T), node_out, graph, dependencies);
492 const T* src, T* dst,
size_t num_elements,
493 cudaMemcpyKind kind, cudaGraphNode_t& node_out, cudaGraph_t& graph,
494 const std::vector<cudaGraphNode_t>& dependencies) {
495 return add_copy_node_impl(src, dst, num_elements,
sizeof(T),
496 kind, node_out, graph, dependencies);
512int prepare_dependencies(
513 const std::vector<std::pair<std::string, bool>>& node_names,
514 std::vector<cudaGraphNode_t>& dependencies,
515 const std::unordered_map<std::string, cudaGraphNode_t>& map,
516 const std::string& caller_operation_name =
"");
Collective variables module (main class)
Definition: colvarmodule.h:71
Allocator for pinned host memory using cudaHostAlloc.
Definition: colvar_gpu_support.h:358
Definition: colvar_gpu_support.h:332
A struct for holding a CUDA graph and its execution object.
Definition: colvar_gpu_support.h:419
cudaGraph_t graph
CUDA graph object.
Definition: colvar_gpu_support.h:434
~gpu_graph_t()
Destructor.
Definition: colvar_gpu_support.cpp:103
int reset()
Reset the CUDA graph.
Definition: colvar_gpu_support.cpp:107
cudaGraphExec_t graph_exec
CUDA graph execution instance object.
Definition: colvar_gpu_support.h:436
int dump_graph(const std::string &filename)
Dump the CUDA graph to a dot file for debugging.
Definition: colvar_gpu_support.cpp:145
bool graph_exec_initialized
Flag to describe whether the graph execution instance has been initialized.
Definition: colvar_gpu_support.h:432
int init_graph_exec(colvarmodule *cvmodule, cudaStream_t stream)
Initialize CUDA graph execution instance.
Definition: colvar_gpu_support.cpp:122
std::unordered_map< std::string, cudaGraphNode_t > nodes
List of compute nodes.
Definition: colvar_gpu_support.h:438
gpu_graph_t()
Constructor.
Definition: colvar_gpu_support.h:422