Collective Variables Module - Developer Documentation
Loading...
Searching...
No Matches
colvar_gpu_support.h
1#ifndef COLVAR_GPU_SUPPORT_H
2#define COLVAR_GPU_SUPPORT_H
3
4#include <vector>
5#include <iostream>
6#include <unordered_map>
7
8class colvarmodule;
9
10#define COLVARS_STRINGIFY(s) STRINGIFY_HELPER(s)
11#define STRINGIFY_HELPER(s) #s
12
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>
18#endif
19#define COLVARS_SYNC_WARP __syncwarp()
20#endif // defined(COLVARS_CUDA)
21
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"); \
35 } while (0)
36#elif defined(__HIP_PLATFORM_NVIDIA__)
37 #define COLVARS_SYNC_WARP __syncwarp()
38#else
39 #error "Unknown HIP platform"
40#endif
41#endif // defined(COLVARS_HIP)
42
43#if defined(COLVARS_HIP)
44#ifndef cudaError_t
45#define cudaError_t hipError_t
46#endif // cudaError_t
47
48#ifndef cudaFree
49#define cudaFree hipFree
50#endif // cudaFree
51
52#ifndef cudaFreeHost
53#define cudaFreeHost hipFreeHost
54#endif // cudaFreeHost
55
56#ifndef cudaFreeAsync
57#define cudaFreeAsync hipFreeAsync
58#endif // cudaFreeAsync
59
60#ifndef cudaGetErrorString
61#define cudaGetErrorString hipGetErrorString
62#endif // cudaGetErrorString
63
64#ifndef cudaGraphAddChildGraphNode
65#define cudaGraphAddChildGraphNode hipGraphAddChildGraphNode
66#endif // cudaGraphAddChildGraphNode
67
68#ifndef cudaGraphAddKernelNode
69#define cudaGraphAddKernelNode hipGraphAddKernelNode
70#endif // cudaGraphAddKernelNode
71
72#ifndef cudaGraphAddMemcpyNode
73#define cudaGraphAddMemcpyNode hipGraphAddMemcpyNode
74#endif // cudaGraphAddMemcpyNode
75
76#ifndef cudaGraphAddMemsetNode
77#define cudaGraphAddMemsetNode hipGraphAddMemsetNode
78#endif // cudaGraphAddMemsetNode
79
80#ifndef cudaGraphCreate
81#define cudaGraphCreate hipGraphCreate
82#endif // cudaGraphCreate
83
84#ifndef cudaGraphDestroy
85#define cudaGraphDestroy hipGraphDestroy
86#endif // cudaGraphDestroy
87
88#ifndef cudaGraphExecDestroy
89#define cudaGraphExecDestroy hipGraphExecDestroy
90#endif // cudaGraphExecDestroy
91
92#ifndef cudaGraphExecMemcpyNodeSetParams
93#define cudaGraphExecMemcpyNodeSetParams hipGraphExecMemcpyNodeSetParams
94#endif // cudaGraphExecMemcpyNodeSetParams
95
96#ifndef cudaGraphExec_t
97#define cudaGraphExec_t hipGraphExec_t
98#endif // cudaGraphExec_t
99
100#ifndef cudaGraphInstantiate
101#define cudaGraphInstantiate hipGraphInstantiate
102#endif // cudaGraphInstantiate
103
104#ifndef cudaGraphInstantiateWithParams
105#define cudaGraphInstantiateWithParams hipGraphInstantiateWithParams
106#endif // cudaGraphInstantiateWithParams
107
108#ifndef cudaGraphInstantiateParams
109#define cudaGraphInstantiateParams hipGraphInstantiateParams
110#endif // cudaGraphInstantiateParams
111
112#ifndef cudaGraphInstantiateFlagUpload
113#define cudaGraphInstantiateFlagUpload hipGraphInstantiateFlagUpload
114#endif // cudaGraphInstantiateFlagUpload
115
116#ifndef cudaGraphInstantiateSuccess
117#define cudaGraphInstantiateSuccess hipGraphInstantiateSuccess
118#endif // cudaGraphInstantiateSuccess
119
120#ifndef cudaGraphLaunch
121#define cudaGraphLaunch hipGraphLaunch
122#endif // cudaGraphLaunch
123
124#ifndef cudaGraphNode_t
125#define cudaGraphNode_t hipGraphNode_t
126#endif // cudaGraphNode_t
127
128#ifndef cudaGraph_t
129#define cudaGraph_t hipGraph_t
130#endif // cudaGraph_t
131
132#ifndef cudaGraphDebugDotPrint
133#define cudaGraphDebugDotPrint hipGraphDebugDotPrint
134#endif // cudaGraphDebugDotPrint
135
136#ifndef cudaGraphDebugDotFlags
137#define cudaGraphDebugDotFlags hipGraphDebugDotFlags
138#endif // cudaGraphDebugDotFlags
139
140#ifndef cudaGraphDebugDotFlagsVerbose
141#define cudaGraphDebugDotFlagsVerbose hipGraphDebugDotFlagsVerbose
142#endif // cudaGraphDebugDotFlagsVerbose
143
144#ifndef cudaHostAllocMapped
145#define cudaHostAllocMapped hipHostAllocMapped
146#endif // cudaHostAllocMapped
147
148#ifndef cudaHostAllocDefault
149#define cudaHostAllocDefault hipHostAllocDefault
150#endif // cudaHostAllocDefault
151
152#ifndef cudaHostAlloc
153#define cudaHostAlloc hipHostAlloc
154#endif // cudaHostAlloc
155
156#ifndef cudaLaunchKernel
157#define cudaLaunchKernel hipLaunchKernel
158#endif // cudaLaunchKernel
159
160#ifndef cudaKernelNodeParams
161#define cudaKernelNodeParams hipKernelNodeParams
162#endif // cudaKernelNodeParams
163
164#ifndef cudaMalloc
165#define cudaMalloc hipMalloc
166#endif // cudaMalloc
167
168#ifndef cudaMallocAsync
169#define cudaMallocAsync hipMallocAsync
170#endif // cudaMallocAsync
171
172#ifndef cudaMallocHost
173#define cudaMallocHost hipMallocHost
174#endif // cudaMallocHost
175
176#ifndef cudaGraphAddMemcpyNode1D
177#define cudaGraphAddMemcpyNode1D hipGraphAddMemcpyNode1D
178#endif
179
180#ifndef cudaMemcpy
181#define cudaMemcpy hipMemcpy
182#endif // cudaMemcpy
183
184#ifndef cudaMemcpy3DParms
185#define cudaMemcpy3DParms hipMemcpy3DParms
186#endif // cudaMemcpy3DParms
187
188#ifndef cudaMemcpyAsync
189#define cudaMemcpyAsync hipMemcpyAsync
190#endif // cudaMemcpyAsync
191
192#ifndef cudaMemcpyDeviceToDevice
193#define cudaMemcpyDeviceToDevice hipMemcpyDeviceToDevice
194#endif // cudaMemcpyDeviceToDevice
195
196#ifndef cudaMemcpyDeviceToHost
197#define cudaMemcpyDeviceToHost hipMemcpyDeviceToHost
198#endif // cudaMemcpyDeviceToHost
199
200#ifndef cudaMemcpyHostToDevice
201#define cudaMemcpyHostToDevice hipMemcpyHostToDevice
202#endif // cudaMemcpyHostToDevice
203
204#ifndef cudaMemcpyKind
205#define cudaMemcpyKind hipMemcpyKind
206#endif // cudaMemcpyKind
207
208#ifndef cudaMemset
209#define cudaMemset hipMemset
210#endif // cudaMemset
211
212#ifndef cudaMemsetParams
213#define cudaMemsetParams hipMemsetParams
214#endif // cudaMemsetParams
215
216#ifndef cudaMemsetAsync
217#define cudaMemsetAsync hipMemsetAsync
218#endif // cudaMemsetAsync
219
220#ifndef cudaStreamCreate
221#define cudaStreamCreate hipStreamCreate
222#endif // cudaStreamCreate
223
224#ifndef cudaStreamDestroy
225#define cudaStreamDestroy hipStreamDestroy
226#endif // cudaStreamDestroy
227
228#ifndef cudaStreamSynchronize
229#define cudaStreamSynchronize hipStreamSynchronize
230#endif // cudaStreamSynchronize
231
232#ifndef cudaStream_t
233#define cudaStream_t hipStream_t
234#endif // cudaStream_t
235
236#ifndef cudaSuccess
237#define cudaSuccess hipSuccess
238#endif // cudaSuccess
239
240#ifndef make_cudaExtent
241#define make_cudaExtent make_hipExtent
242#endif // make_cudaExtent
243
244#ifndef make_cudaPitchedPtr
245#define make_cudaPitchedPtr make_hipPitchedPtr
246#endif // make_cudaPitchedPtr
247
248#ifndef make_cudaPos
249#define make_cudaPos make_hipPos
250#endif // make_cudaPos
251
252#ifndef cudaEvent_t
253#define cudaEvent_t hipEvent_t
254#endif // cudaEvent_t
255
256#ifndef cudaEventCreateWithFlags
257#define cudaEventCreateWithFlags hipEventCreateWithFlags
258#endif // cudaEventCreate
259
260#ifndef cudaEventDisableTiming
261#define cudaEventDisableTiming hipEventDisableTiming
262#endif // cudaEventDisableTiming
263
264#ifndef cudaEventDestroy
265#define cudaEventDestroy hipEventDestroy
266#endif // cudaEventDestroy
267
268#ifndef cudaEventRecord
269#define cudaEventRecord hipEventRecord
270#endif // cudaEventRecord
271
272#ifndef cudaEventSynchronize
273#define cudaEventSynchronize hipEventSynchronize
274#endif // cudaEventSynchronize
275
276#ifndef cudaStreamWaitEvent
277#define cudaStreamWaitEvent hipStreamWaitEvent
278#endif // cudaStreamWaitEvent
279
280#ifndef cudaGraphAddEventRecordNode
281#define cudaGraphAddEventRecordNode hipGraphAddEventRecordNode
282#endif // cudaGraphAddEventRecordNode
283
284#ifndef cudaGetDevice
285#define cudaGetDevice hipGetDevice
286#endif // cudaGetDevice
287
288#ifndef cudaDeviceProp
289#define cudaDeviceProp hipDeviceProp_t
290#endif // cudaDeviceProp
291
292#ifndef cudaDeviceGetPCIBusId
293#define cudaDeviceGetPCIBusId hipDeviceGetPCIBusId
294#endif // cudaDeviceGetPCIBusId
295
296#ifndef cudaGetDeviceProperties
297#define cudaGetDeviceProperties hipGetDeviceProperties
298#endif // cudaGetDeviceProperties
299
300#ifndef cudaDeviceGetAttribute
301#define cudaDeviceGetAttribute hipDeviceGetAttribute
302#endif // cudaDeviceGetAttribute
303
304#ifndef cudaDevAttrWarpSize
305#define cudaDevAttrWarpSize hipDeviceAttributeWarpSize
306#endif // cudaDevAttrWarpSize
307
308#endif // defined(COLVARS_HIP)
309
310namespace colvars_gpu {
311
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;
317// static unsigned int default_atom_wise_num_blocks = 64;
318#endif
319
320#if defined(COLVARS_CUDA) || defined(COLVARS_HIP)
321#define COLVARS_HOST_DEVICE __device__ __host__
322#define COLVARS_DEVICE __device__
323#else
324#define COLVARS_HOST_DEVICE
325#define COLVARS_DEVICE
326#endif
327
328// HIP does not have cuda::std::array since libhipcxx is not a part of the ROCm distribution,
329// so reinvent the wheel...
330#if defined(COLVARS_CUDA) || defined(COLVARS_HIP)
331template <typename T, unsigned long N>
332class array1d {
333public:
334 T m_data[N];
335 using value_type = T;
336 using size_type = decltype(N);
337 using reference = value_type&;
338 using const_reference = const value_type&;
339 using pointer = T*;
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];}
344};
345#endif
346
347// TODO: What about SYCL?
348#if ( defined(COLVARS_CUDA) || defined(COLVARS_HIP) )
357template <typename T>
359public:
360 using value_type = T;
361
362 CudaHostAllocator() = default;
363
364 template<typename U>
365 constexpr CudaHostAllocator(const CudaHostAllocator<U>&) noexcept {}
366
367 friend bool operator==(const CudaHostAllocator&, const CudaHostAllocator&) { return true; }
368 friend bool operator!=(const CudaHostAllocator&, const CudaHostAllocator&) { return false; }
369
370 T* allocate(size_t n) {
371 T* ptr;
372 if (cudaHostAlloc(&ptr, n * sizeof(T), cudaHostAllocMapped) != cudaSuccess) {
373 throw std::bad_alloc();
374 }
375 return ptr;
376 }
377 void deallocate(T* ptr, size_t n) noexcept {
378 (void)cudaFreeHost(ptr);
379 }
380 template<typename U, typename... Args>
381 void construct(U* p, Args&&... args) {
382 new(p) U(std::forward<Args>(args)...);
383 }
384
385 template<typename U>
386 void destroy(U* p) noexcept {
387 p->~U();
388 }
389};
390#endif
391
392
393#if defined(COLVARS_CUDA) || defined (COLVARS_HIP)
402int gpuAssert(cudaError_t code, const char *file, int line);
403#endif
404
405} // namespace colvars_gpu
406
407#if defined(COLVARS_CUDA) || defined (COLVARS_HIP)
410#define checkGPUError(ans) colvars_gpu::gpuAssert((ans), __FILE__, __LINE__);
411#endif
412
413namespace colvars_gpu {
414#if defined(COLVARS_CUDA) || defined (COLVARS_HIP)
415
420public:
424 int reset();
426 ~gpu_graph_t();
428 int dump_graph(const std::string& filename);
430 int init_graph_exec(colvarmodule* cvmodule, cudaStream_t stream);
434 cudaGraph_t graph = nullptr;
436 cudaGraphExec_t graph_exec = nullptr;
438 std::unordered_map<std::string, cudaGraphNode_t> nodes = {};
439};
440
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);
448
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);
456
468template <typename T>
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);
475}
476
490template <typename T>
491int add_copy_node(
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);
497}
498
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 = "");
517
518#endif // defined(COLVARS_CUDA) || defined (COLVARS_HIP)
519}
520
521#endif // COLVAR_GPU_SUPPORT_H
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