@@ -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 ));
0 commit comments