Skip to content

Commit e5b9be4

Browse files
authored
Merge pull request #2019 from CEED/zach/fix-cuda
Fix CUDA Graph implementation
2 parents 03c6d39 + 3d14a97 commit e5b9be4

3 files changed

Lines changed: 25 additions & 28 deletions

File tree

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

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,8 @@ static int CeedOperatorApplyAddComposite_Cuda_gen(CeedOperator op, CeedVector in
424424
CeedCallBackend(CeedOperatorCompositeGetSubList(op, &sub_operators));
425425
CeedCallBackend(CeedOperatorGetData(op, &impl));
426426
if (!impl->use_graph || (input_vec == CEED_VECTOR_NONE && output_vec == CEED_VECTOR_NONE)) {
427-
return CeedOperatorApplyAddComposite_NoGraph_Cuda_gen(op, input_vec, output_vec, request);
427+
CeedCallBackend(CeedOperatorApplyAddComposite_NoGraph_Cuda_gen(op, input_vec, output_vec, request));
428+
return CEED_ERROR_SUCCESS;
428429
}
429430
if (!impl->warmup_done) {
430431
CeedCallBackend(CeedOperatorApplyAddComposite_NoGraph_Cuda_gen(op, input_vec, output_vec, request));
@@ -434,20 +435,24 @@ static int CeedOperatorApplyAddComposite_Cuda_gen(CeedOperator op, CeedVector in
434435

435436
bool need_build = !impl->graph_created;
436437

437-
if (!need_build && input_vec != CEED_VECTOR_NONE) {
438-
const CeedScalar *in_ptr;
438+
// Refresh device data prior to building graph to prevent needed to copy vectors or qf context during capture
439+
if (input_vec != CEED_VECTOR_NONE) {
440+
const CeedScalar *in_arr;
439441

440-
CeedCallBackend(CeedVectorGetArrayRead(input_vec, CEED_MEM_DEVICE, &in_ptr));
441-
need_build = in_ptr != impl->captured_input_ptr;
442-
CeedCallBackend(CeedVectorRestoreArrayRead(input_vec, &in_ptr));
442+
CeedCallBackend(CeedVectorGetArrayRead(input_vec, CEED_MEM_DEVICE, &in_arr));
443+
need_build = need_build || in_arr != impl->captured_input_ptr;
444+
CeedCallBackend(CeedVectorRestoreArrayRead(input_vec, &in_arr));
443445
}
444-
if (!need_build && output_vec != CEED_VECTOR_NONE) {
445-
CeedScalar *out_ptr;
446+
if (output_vec != CEED_VECTOR_NONE) {
447+
CeedScalar *out_arr;
446448

447-
CeedCallBackend(CeedVectorGetArray(output_vec, CEED_MEM_DEVICE, &out_ptr));
448-
need_build = out_ptr != impl->captured_output_ptr;
449-
CeedCallBackend(CeedVectorRestoreArray(output_vec, &out_ptr));
449+
CeedCallBackend(CeedVectorGetArray(output_vec, CEED_MEM_DEVICE, &out_arr));
450+
need_build = need_build || out_arr != impl->captured_output_ptr;
451+
CeedCallBackend(CeedVectorRestoreArray(output_vec, &out_arr));
450452
}
453+
CeedCallBackend(CeedCompositeRefreshForReplay_Cuda_gen(sub_operators, num_suboperators));
454+
455+
// TODO: Use the Graph API rebuild functions to check for and update memory address changes
451456
if (need_build) {
452457
const CeedScalar *input_arr = NULL;
453458
CeedScalar *output_arr = NULL;
@@ -473,7 +478,10 @@ static int CeedOperatorApplyAddComposite_Cuda_gen(CeedOperator op, CeedVector in
473478
for (CeedInt i = 0; i < num_suboperators; i++) {
474479
bool is_run_good = true;
475480

476-
if (CeedOperatorApplyAddCore_Cuda_gen(sub_operators[i], capture_stream, input_arr, output_arr, &is_run_good, request) || !is_run_good) {
481+
// Critical: still need to error if this function returns non-zero; we do not know what state the vectors are in and
482+
// ignoring the error leads to issues at destruction-time (vectors that think there are readers when there are none)
483+
CeedCallBackend(CeedOperatorApplyAddCore_Cuda_gen(sub_operators[i], capture_stream, input_arr, output_arr, &is_run_good, request));
484+
if (!is_run_good) {
477485
capture_ok = false;
478486
break;
479487
}
@@ -495,6 +503,7 @@ static int CeedOperatorApplyAddComposite_Cuda_gen(CeedOperator op, CeedVector in
495503
if (input_vec != CEED_VECTOR_NONE) CeedCallBackend(CeedVectorRestoreArrayRead(input_vec, &input_arr));
496504
if (output_vec != CEED_VECTOR_NONE) CeedCallBackend(CeedVectorRestoreArray(output_vec, &output_arr));
497505
if (!capture_ok) {
506+
CeedDebug(CeedOperatorReturnCeed(op), "/gpu/cuda/gen: Graph capture failure");
498507
cudaGetLastError();
499508
CeedCallCuda(CeedOperatorReturnCeed(op), cudaDeviceSynchronize());
500509
cudaGetLastError();
@@ -506,20 +515,8 @@ static int CeedOperatorApplyAddComposite_Cuda_gen(CeedOperator op, CeedVector in
506515
}
507516
impl->graph_created = true;
508517
}
509-
if (input_vec != CEED_VECTOR_NONE) {
510-
const CeedScalar *in_arr;
511-
512-
CeedCallBackend(CeedVectorGetArrayRead(input_vec, CEED_MEM_DEVICE, &in_arr));
513-
CeedCallBackend(CeedVectorRestoreArrayRead(input_vec, &in_arr));
514-
}
515-
if (output_vec != CEED_VECTOR_NONE) {
516-
CeedScalar *out_arr;
517-
518-
CeedCallBackend(CeedVectorGetArray(output_vec, CEED_MEM_DEVICE, &out_arr));
519-
CeedCallBackend(CeedVectorRestoreArray(output_vec, &out_arr));
520-
}
521-
CeedCallBackend(CeedCompositeRefreshForReplay_Cuda_gen(sub_operators, num_suboperators));
522518
if (cudaGraphLaunch(impl->graph_instance, NULL) != cudaSuccess) {
519+
CeedDebug(CeedOperatorReturnCeed(op), "/gpu/cuda/gen: Graph launch failure");
523520
cudaGetLastError();
524521
if (impl->graph_instance) CeedCallCuda(CeedOperatorReturnCeed(op), cudaGraphExecDestroy(impl->graph_instance));
525522
if (impl->graph) CeedCallCuda(CeedOperatorReturnCeed(op), cudaGraphDestroy(impl->graph));

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static inline int CeedQFunctionContextSyncH2D_Cuda(const CeedQFunctionContext ct
3737
impl->d_data = impl->d_data_owned;
3838
}
3939

40-
CeedCallCuda(ceed, cudaMemcpyAsync(impl->d_data, impl->h_data, ctx_size, cudaMemcpyHostToDevice, cudaStreamPerThread));
40+
CeedCallCuda(ceed, cudaMemcpy(impl->d_data, impl->h_data, ctx_size, cudaMemcpyHostToDevice));
4141

4242
CeedCallBackend(CeedDestroy(&ceed));
4343
return CEED_ERROR_SUCCESS;

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), cudaMemcpyAsync(impl->d_array, impl->h_array, bytes, cudaMemcpyHostToDevice, cudaStreamPerThread));
60+
CeedCallCuda(CeedVectorReturnCeed(vec), cudaMemcpy(impl->d_array, impl->h_array, bytes, cudaMemcpyHostToDevice));
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), cudaMemsetAsync(impl->d_array, 0, length * sizeof(CeedScalar), cudaStreamPerThread));
329+
CeedCallCuda(CeedVectorReturnCeed(vec), cudaMemset(impl->d_array, 0, length * sizeof(CeedScalar)));
330330
} else {
331331
CeedCallBackend(CeedDeviceSetValue_Cuda(impl->d_array, length, val));
332332
}

0 commit comments

Comments
 (0)