Skip to content

Commit f3f5fc2

Browse files
authored
Merge pull request #2006 from CEED/test/cuda-graph
cuda-gen: Add CUDA Graph capture and replay for composite operators
2 parents db4e14d + b63fc7a commit f3f5fc2

9 files changed

Lines changed: 269 additions & 18 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Specifically, directories set with `CeedAddJitSourceRoot(ceed, "foo/bar")` will
3535
- Add `CeedGetBuildConfiguration()` to access compilers, flags, and related information about the build environment.
3636
- Add support for full `CeedOperator` assembly for operators with multiple active fields with different bases for CPU backends and `/gpu/cuda/ref` and `/gpu/hip/gen` backends.
3737
- Add `CeedVectorFilter` to zero out components of a `CeedVector` that have absolute value below a specified threshold value.
38+
- Add `CeedOperatorSetEnableCudaGraph` for CUDA Graph capture/replay on `/gpu/cuda/gen` composite operators. Enabled by default; use `CEED_ENABLE_CUDA_GRAPH=0` to turn off.
3839

3940
### Examples
4041

backends/cuda-gen/ceed-cuda-gen-operator.c

Lines changed: 224 additions & 14 deletions
Large diffs are not rendered by default.

backends/cuda-gen/ceed-cuda-gen.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <ceed/backend.h>
1111
#include <ceed/jit-source/cuda/cuda-types.h>
1212
#include <cuda.h>
13+
#include <cuda_runtime.h>
1314

1415
typedef struct {
1516
bool use_fallback, use_assembly_fallback;
@@ -25,6 +26,15 @@ typedef struct {
2526
Fields_Cuda G;
2627
CeedScalar *W;
2728
Points_Cuda points;
29+
30+
// Graph capture data
31+
bool use_graph;
32+
bool graph_created;
33+
bool warmup_done;
34+
cudaGraph_t graph;
35+
cudaGraphExec_t graph_instance;
36+
const CeedScalar *captured_input_ptr;
37+
CeedScalar *captured_output_ptr;
2838
} CeedOperator_Cuda_gen;
2939

3040
typedef struct {

backends/cuda-ref/ceed-cuda-ref-qfunctioncontext.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ static inline int CeedQFunctionContextSyncH2D_Cuda(const CeedQFunctionContext ct
3636
CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_data_owned, ctx_size));
3737
impl->d_data = impl->d_data_owned;
3838
}
39-
CeedCallCuda(ceed, cudaMemcpy(impl->d_data, impl->h_data, ctx_size, cudaMemcpyHostToDevice));
39+
40+
CeedCallCuda(ceed, cudaMemcpyAsync(impl->d_data, impl->h_data, ctx_size, cudaMemcpyHostToDevice, cudaStreamPerThread));
41+
4042
CeedCallBackend(CeedDestroy(&ceed));
4143
return CEED_ERROR_SUCCESS;
4244
}

backends/cuda-ref/ceed-cuda-ref-vector.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ static inline int CeedVectorSyncH2D_Cuda(const CeedVector vec) {
5757
CeedCallCuda(CeedVectorReturnCeed(vec), cudaMalloc((void **)&impl->d_array_owned, bytes));
5858
impl->d_array = impl->d_array_owned;
5959
}
60-
CeedCallCuda(CeedVectorReturnCeed(vec), cudaMemcpy(impl->d_array, impl->h_array, bytes, cudaMemcpyHostToDevice));
60+
CeedCallCuda(CeedVectorReturnCeed(vec), cudaMemcpyAsync(impl->d_array, impl->h_array, bytes, cudaMemcpyHostToDevice, cudaStreamPerThread));
6161
return CEED_ERROR_SUCCESS;
6262
}
6363

@@ -326,7 +326,7 @@ static int CeedVectorSetValue_Cuda(CeedVector vec, CeedScalar val) {
326326
}
327327
if (impl->d_array) {
328328
if (val == 0) {
329-
CeedCallCuda(CeedVectorReturnCeed(vec), cudaMemset(impl->d_array, 0, length * sizeof(CeedScalar)));
329+
CeedCallCuda(CeedVectorReturnCeed(vec), cudaMemsetAsync(impl->d_array, 0, length * sizeof(CeedScalar), cudaStreamPerThread));
330330
} else {
331331
CeedCallBackend(CeedDeviceSetValue_Cuda(impl->d_array, length, val));
332332
}

include/ceed-impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ struct CeedOperator_private {
368368
int (*ApplyAdd)(CeedOperator, CeedVector, CeedVector, CeedRequest *);
369369
int (*ApplyAddComposite)(CeedOperator, CeedVector, CeedVector, CeedRequest *);
370370
int (*ApplyJacobian)(CeedOperator, CeedVector, CeedVector, CeedVector, CeedVector, CeedRequest *);
371+
int (*SetEnableCudaGraph)(CeedOperator, bool);
371372
int (*Destroy)(CeedOperator);
372373
CeedOperatorField *input_fields;
373374
CeedOperatorField *output_fields;

include/ceed/cuda.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313
#include <cuda.h>
1414

1515
CEED_EXTERN int CeedQFunctionSetCUDAUserFunction(CeedQFunction qf, CUfunction f);
16+
CEED_EXTERN int CeedOperatorSetEnableCudaGraph(CeedOperator op, bool enable_graph);

interface/ceed-cuda.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
#include <cuda.h>
1313

1414
/**
15-
@brief Set CUDA function pointer to evaluate action at quadrature points
15+
@brief Set CUDA function pointer to evaluate action at quadrature points.
16+
17+
If the backend does not support `CUfunction` pointers for QFunctions, then the call succeeds without effect.
18+
When unsupported, a message is emitted via `CeedDebug`.
1619
1720
@param[in,out] qf `CeedQFunction` to set device pointer
1821
@param[in] f Device function pointer to evaluate action at quadrature points
@@ -29,3 +32,25 @@ int CeedQFunctionSetCUDAUserFunction(CeedQFunction qf, CUfunction f) {
2932
}
3033
return CEED_ERROR_SUCCESS;
3134
}
35+
36+
/**
37+
@brief Enable or disable CUDA Graph capture/replay for a `CeedOperator`.
38+
39+
If the backend does not support CUDA Graphs for operators, then the call succeeds without effect.
40+
When unsupported, a message is emitted via `CeedDebug`.
41+
42+
@param[in,out] op `CeedOperator`
43+
@param[in] enable_graph Boolean flag to enable CUDA Graph use
44+
45+
@return An error code: 0 - success, otherwise - failure
46+
47+
@ref User
48+
**/
49+
int CeedOperatorSetEnableCudaGraph(CeedOperator op, bool enable_graph) {
50+
if (!op->SetEnableCudaGraph) {
51+
CeedDebug(CeedOperatorReturnCeed(op), "Backend does not support CUDA Graphs for operators.");
52+
} else {
53+
CeedCall(op->SetEnableCudaGraph(op, enable_graph));
54+
}
55+
return CEED_ERROR_SUCCESS;
56+
}

interface/ceed.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,6 +1374,7 @@ int CeedInit(const char *resource, Ceed *ceed) {
13741374
CEED_FTABLE_ENTRY(CeedOperator, ApplyAdd),
13751375
CEED_FTABLE_ENTRY(CeedOperator, ApplyAddComposite),
13761376
CEED_FTABLE_ENTRY(CeedOperator, ApplyJacobian),
1377+
CEED_FTABLE_ENTRY(CeedOperator, SetEnableCudaGraph),
13771378
CEED_FTABLE_ENTRY(CeedOperator, Destroy),
13781379
{NULL, 0} // End of lookup table - used in SetBackendFunction loop
13791380
};

0 commit comments

Comments
 (0)