MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
cuda.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_CUDA_HPP
13#define MFEM_CUDA_HPP
14
15#include "../config/config.hpp"
16#include "error.hpp"
17
18// CUDA block size used by MFEM.
19#define MFEM_CUDA_BLOCKS 256
20
21#if defined(MFEM_USE_CUDA)
22#define MFEM_USE_CUDA_OR_HIP
23#define MFEM_DEVICE_SYNC MFEM_GPU_CHECK(cudaDeviceSynchronize())
24#define MFEM_STREAM_SYNC MFEM_GPU_CHECK(cudaStreamSynchronize(0))
25// Define a CUDA error check macro, MFEM_GPU_CHECK(x), where x returns/is of
26// type 'cudaError_t'. This macro evaluates 'x' and raises an error if the
27// result is not cudaSuccess.
28#define MFEM_GPU_CHECK(x) \
29 do { \
30 cudaError_t mfem_err_internal_var_name = (x); \
31 if (mfem_err_internal_var_name != cudaSuccess) { \
32 ::mfem::mfem_cuda_error(mfem_err_internal_var_name, #x, _MFEM_FUNC_NAME, \
33 __FILE__, __LINE__); \
34 } \
35 } while (0)
36
37// Macros defined only when compiling with CUDA language
38#if defined(__CUDACC__)
39#define MFEM_USE_CUDA_OR_HIP_LANG
40#define MFEM_DEVICE __device__
41#define MFEM_HOST __host__
42#define MFEM_LAMBDA __host__
43#define MFEM_LAUNCH_BOUNDS __launch_bounds__
44// #define MFEM_HOST_DEVICE __host__ __device__ // defined in config/config.hpp
45
46// Define the MFEM inner threading macros
47#if defined(__CUDA_ARCH__)
48#define MFEM_SHARED __shared__
49#define MFEM_SYNC_THREAD __syncthreads()
50#define MFEM_BLOCK_ID(k) blockIdx.k
51#define MFEM_THREAD_ID(k) threadIdx.k
52#define MFEM_THREAD_SIZE(k) blockDim.k
53#define MFEM_FOREACH_THREAD(i,k,N) for(int i=threadIdx.k; i<N; i+=blockDim.k)
54#define MFEM_FOREACH_THREAD_DIRECT(i,k,N) if(const int i=threadIdx.k; i<N)
55// Assigns a thread block shaped (SX,SY,SZ) contiguous in x.
56// Example (3,2,1) block:
57// 0 (0,0), 1 (1,0), 2 (2,0)
58// 3 (1,0), 4 (1,1), 5 (2,1)
59#define MFEM_FOREACH_THREAD_DIRECT_3D(ix, iy, iz, k, SX, SY, SZ) \
60 if (int ix = threadIdx.k % (SX), iy = threadIdx.k / (SX), iz = iy / (SY); \
61 (iy %= (SY)), (threadIdx.k < (SX) * (SY) * (SZ)))
62// Assigns a thread block shaped (OX,OY,OZ) to work on items (SX,SY,SZ),
63// contiguous in x. This intentionally offsets threads within the block to avoid
64// shared memory bank conflicts.
65// Example (3,2,1) block assigned to work on (2,2,1) items:
66// 0 (0,0), 1 (1,0), 2 (N/A)
67// 3 (1,0), 4 (1,1), 5 (N/A)
68#define MFEM_FOREACH_THREAD_DIRECT_3D_OFFSET(ix, iy, iz, k, SX, SY, SZ, OX, \
69 OY, OZ) \
70 if (int ix = threadIdx.k % (OX), iy = threadIdx.k / (OX), iz = iy / (OY); \
71 (ix < (SX)) && ((iy %= (OY)) < (SY)) && (iz < (SZ)))
72#endif // defined(__CUDA_ARCH__)
73#endif // defined(__CUDACC__)
74#endif // defined(MFEM_USE_CUDA)
75
76namespace mfem
77{
78
79#if defined(MFEM_USE_CUDA)
80// Function used by the macro MFEM_GPU_CHECK.
81void mfem_cuda_error(cudaError_t err, const char *expr, const char *func,
82 const char *file, int line);
83#endif
84
85/// Allocates device memory and returns destination ptr.
86void* CuMemAlloc(void **d_ptr, size_t bytes);
87
88/// Allocates managed device memory
89void* CuMallocManaged(void **d_ptr, size_t bytes);
90
91/// Allocates page-locked (pinned) host memory
92void* CuMemAllocHostPinned(void **ptr, size_t bytes);
93
94/// Frees device memory and returns destination ptr.
95void* CuMemFree(void *d_ptr);
96
97/// Frees page-locked (pinned) host memory and returns destination ptr.
98void* CuMemFreeHostPinned(void *ptr);
99
100/// Copies memory from Host to Device and returns destination ptr.
101void* CuMemcpyHtoD(void *d_dst, const void *h_src, size_t bytes);
102
103/// Copies memory from Host to Device and returns destination ptr.
104void* CuMemcpyHtoDAsync(void *d_dst, const void *h_src, size_t bytes);
105
106/// Copies memory from Device to Device
107void* CuMemcpyDtoD(void *d_dst, const void *d_src, size_t bytes);
108
109/// Copies memory from Device to Device
110void* CuMemcpyDtoDAsync(void *d_dst, const void *d_src, size_t bytes);
111
112/// Copies memory from Device to Host
113void* CuMemcpyDtoH(void *h_dst, const void *d_src, size_t bytes);
114
115/// Copies memory from Device to Host
116void* CuMemcpyDtoHAsync(void *h_dst, const void *d_src, size_t bytes);
117
118/// Check the error code returned by cudaGetLastError(), aborting on error.
119void CuCheckLastError();
120
121/// Get the number of CUDA devices
122int CuGetDeviceCount();
123
124} // namespace mfem
125
126#endif // MFEM_CUDA_HPP
void * CuMemAlloc(void **dptr, size_t bytes)
Allocates device memory and returns destination ptr.
Definition cuda.cpp:34
void * CuMemFree(void *dptr)
Frees device memory and returns destination ptr.
Definition cuda.cpp:79
void * CuMemcpyDtoHAsync(void *dst, const void *src, size_t bytes)
Copies memory from Device to Host.
Definition cuda.cpp:170
void * CuMallocManaged(void **dptr, size_t bytes)
Allocates managed device memory.
Definition cuda.cpp:49
void * CuMemcpyDtoH(void *dst, const void *src, size_t bytes)
Copies memory from Device to Host.
Definition cuda.cpp:155
void * CuMemAllocHostPinned(void **ptr, size_t bytes)
Allocates page-locked (pinned) host memory.
Definition cuda.cpp:64
void * CuMemFreeHostPinned(void *ptr)
Frees page-locked (pinned) host memory and returns destination ptr.
Definition cuda.cpp:94
void mfem_cuda_error(cudaError_t err, const char *expr, const char *func, const char *file, int line)
Definition cuda.cpp:23
void * CuMemcpyHtoD(void *dst, const void *src, size_t bytes)
Copies memory from Host to Device and returns destination ptr.
Definition cuda.cpp:109
int CuGetDeviceCount()
Get the number of CUDA devices.
Definition cuda.cpp:185
OutStream err(std::cerr)
Global stream used by the library for standard error output. Initially it uses the same std::streambu...
Definition globals.hpp:71
void * CuMemcpyHtoDAsync(void *dst, const void *src, size_t bytes)
Copies memory from Host to Device and returns destination ptr.
Definition cuda.cpp:124
void CuCheckLastError()
Check the error code returned by cudaGetLastError(), aborting on error.
Definition cuda.cpp:178
void * CuMemcpyDtoDAsync(void *dst, const void *src, size_t bytes)
Copies memory from Device to Device.
Definition cuda.cpp:147
void * CuMemcpyDtoD(void *dst, const void *src, size_t bytes)
Copies memory from Device to Device.
Definition cuda.cpp:132