xref: /libCEED/rust/libceed-sys/c-src/backends/cuda-ref/ceed-cuda-ref-qfunctioncontext.c (revision 5aed82e4fa97acf4ba24a7f10a35f5303a6798e0)
1*5aed82e4SJeremy L Thompson // Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
30d0321e0SJeremy L Thompson //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
50d0321e0SJeremy L Thompson //
63d8e8822SJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
70d0321e0SJeremy L Thompson 
849aac155SJeremy L Thompson #include <ceed.h>
90d0321e0SJeremy L Thompson #include <ceed/backend.h>
100d0321e0SJeremy L Thompson #include <cuda_runtime.h>
1149aac155SJeremy L Thompson #include <stdbool.h>
120d0321e0SJeremy L Thompson #include <string.h>
132b730f8bSJeremy L Thompson 
1449aac155SJeremy L Thompson #include "../cuda/ceed-cuda-common.h"
150d0321e0SJeremy L Thompson #include "ceed-cuda-ref.h"
160d0321e0SJeremy L Thompson 
170d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
180d0321e0SJeremy L Thompson // Sync host to device
190d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
202b730f8bSJeremy L Thompson static inline int CeedQFunctionContextSyncH2D_Cuda(const CeedQFunctionContext ctx) {
210d0321e0SJeremy L Thompson   Ceed                       ceed;
22ca735530SJeremy L Thompson   size_t                     ctx_size;
230d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
24ca735530SJeremy L Thompson 
25ca735530SJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
262b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
270d0321e0SJeremy L Thompson 
286574a04fSJeremy L Thompson   CeedCheck(impl->h_data, ceed, CEED_ERROR_BACKEND, "No valid host data to sync to device");
290d0321e0SJeremy L Thompson 
30ca735530SJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
310d0321e0SJeremy L Thompson   if (impl->d_data_borrowed) {
320d0321e0SJeremy L Thompson     impl->d_data = impl->d_data_borrowed;
330d0321e0SJeremy L Thompson   } else if (impl->d_data_owned) {
340d0321e0SJeremy L Thompson     impl->d_data = impl->d_data_owned;
350d0321e0SJeremy L Thompson   } else {
36ca735530SJeremy L Thompson     CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_data_owned, ctx_size));
370d0321e0SJeremy L Thompson     impl->d_data = impl->d_data_owned;
380d0321e0SJeremy L Thompson   }
39ca735530SJeremy L Thompson   CeedCallCuda(ceed, cudaMemcpy(impl->d_data, impl->h_data, ctx_size, cudaMemcpyHostToDevice));
400d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
410d0321e0SJeremy L Thompson }
420d0321e0SJeremy L Thompson 
430d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
440d0321e0SJeremy L Thompson // Sync device to host
450d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
462b730f8bSJeremy L Thompson static inline int CeedQFunctionContextSyncD2H_Cuda(const CeedQFunctionContext ctx) {
470d0321e0SJeremy L Thompson   Ceed                       ceed;
48ca735530SJeremy L Thompson   size_t                     ctx_size;
490d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
50ca735530SJeremy L Thompson 
51ca735530SJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
522b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
530d0321e0SJeremy L Thompson 
546574a04fSJeremy L Thompson   CeedCheck(impl->d_data, ceed, CEED_ERROR_BACKEND, "No valid device data to sync to host");
550d0321e0SJeremy L Thompson 
56ca735530SJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
57539ec17dSJeremy L Thompson 
580d0321e0SJeremy L Thompson   if (impl->h_data_borrowed) {
590d0321e0SJeremy L Thompson     impl->h_data = impl->h_data_borrowed;
600d0321e0SJeremy L Thompson   } else if (impl->h_data_owned) {
610d0321e0SJeremy L Thompson     impl->h_data = impl->h_data_owned;
620d0321e0SJeremy L Thompson   } else {
63ca735530SJeremy L Thompson     CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->h_data_owned));
640d0321e0SJeremy L Thompson     impl->h_data = impl->h_data_owned;
650d0321e0SJeremy L Thompson   }
66ca735530SJeremy L Thompson   CeedCallCuda(ceed, cudaMemcpy(impl->h_data, impl->d_data, ctx_size, cudaMemcpyDeviceToHost));
670d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
680d0321e0SJeremy L Thompson }
690d0321e0SJeremy L Thompson 
700d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
710d0321e0SJeremy L Thompson // Sync data of type
720d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
732b730f8bSJeremy L Thompson static inline int CeedQFunctionContextSync_Cuda(const CeedQFunctionContext ctx, CeedMemType mem_type) {
7443c928f4SJeremy L Thompson   switch (mem_type) {
752b730f8bSJeremy L Thompson     case CEED_MEM_HOST:
762b730f8bSJeremy L Thompson       return CeedQFunctionContextSyncD2H_Cuda(ctx);
772b730f8bSJeremy L Thompson     case CEED_MEM_DEVICE:
782b730f8bSJeremy L Thompson       return CeedQFunctionContextSyncH2D_Cuda(ctx);
790d0321e0SJeremy L Thompson   }
800d0321e0SJeremy L Thompson   return CEED_ERROR_UNSUPPORTED;
810d0321e0SJeremy L Thompson }
820d0321e0SJeremy L Thompson 
830d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
840d0321e0SJeremy L Thompson // Set all pointers as invalid
850d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
862b730f8bSJeremy L Thompson static inline int CeedQFunctionContextSetAllInvalid_Cuda(const CeedQFunctionContext ctx) {
870d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
880d0321e0SJeremy L Thompson 
89ca735530SJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
900d0321e0SJeremy L Thompson   impl->h_data = NULL;
910d0321e0SJeremy L Thompson   impl->d_data = NULL;
920d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
930d0321e0SJeremy L Thompson }
940d0321e0SJeremy L Thompson 
950d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
960d0321e0SJeremy L Thompson // Check if ctx has valid data
970d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
982b730f8bSJeremy L Thompson static inline int CeedQFunctionContextHasValidData_Cuda(const CeedQFunctionContext ctx, bool *has_valid_data) {
990d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
100ca735530SJeremy L Thompson 
1012b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
1021c66c397SJeremy L Thompson   *has_valid_data = impl && (impl->h_data || impl->d_data);
1030d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1040d0321e0SJeremy L Thompson }
1050d0321e0SJeremy L Thompson 
1060d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1070d0321e0SJeremy L Thompson // Check if ctx has borrowed data
1080d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1092b730f8bSJeremy L Thompson static inline int CeedQFunctionContextHasBorrowedDataOfType_Cuda(const CeedQFunctionContext ctx, CeedMemType mem_type,
1100d0321e0SJeremy L Thompson                                                                  bool *has_borrowed_data_of_type) {
1110d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
1120d0321e0SJeremy L Thompson 
113ca735530SJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
11443c928f4SJeremy L Thompson   switch (mem_type) {
1150d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
1161c66c397SJeremy L Thompson       *has_borrowed_data_of_type = impl->h_data_borrowed;
1170d0321e0SJeremy L Thompson       break;
1180d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
1191c66c397SJeremy L Thompson       *has_borrowed_data_of_type = impl->d_data_borrowed;
1200d0321e0SJeremy L Thompson       break;
1210d0321e0SJeremy L Thompson   }
1220d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1230d0321e0SJeremy L Thompson }
1240d0321e0SJeremy L Thompson 
1250d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1260d0321e0SJeremy L Thompson // Check if data of given type needs sync
1270d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1282b730f8bSJeremy L Thompson static inline int CeedQFunctionContextNeedSync_Cuda(const CeedQFunctionContext ctx, CeedMemType mem_type, bool *need_sync) {
1290d0321e0SJeremy L Thompson   bool                       has_valid_data = true;
130ca735530SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
131ca735530SJeremy L Thompson 
132ca735530SJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
1332b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
13443c928f4SJeremy L Thompson   switch (mem_type) {
1350d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
1360d0321e0SJeremy L Thompson       *need_sync = has_valid_data && !impl->h_data;
1370d0321e0SJeremy L Thompson       break;
1380d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
1390d0321e0SJeremy L Thompson       *need_sync = has_valid_data && !impl->d_data;
1400d0321e0SJeremy L Thompson       break;
1410d0321e0SJeremy L Thompson   }
1420d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1430d0321e0SJeremy L Thompson }
1440d0321e0SJeremy L Thompson 
1450d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1460d0321e0SJeremy L Thompson // Set data from host
1470d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1482b730f8bSJeremy L Thompson static int CeedQFunctionContextSetDataHost_Cuda(const CeedQFunctionContext ctx, const CeedCopyMode copy_mode, void *data) {
1490d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
150ca735530SJeremy L Thompson 
1512b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
1520d0321e0SJeremy L Thompson 
1532b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->h_data_owned));
15443c928f4SJeremy L Thompson   switch (copy_mode) {
1550d0321e0SJeremy L Thompson     case CEED_COPY_VALUES: {
156ca735530SJeremy L Thompson       size_t ctx_size;
157ca735530SJeremy L Thompson       CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
158ca735530SJeremy L Thompson       CeedCallBackend(CeedMallocArray(1, ctx_size, &impl->h_data_owned));
1590d0321e0SJeremy L Thompson       impl->h_data_borrowed = NULL;
1600d0321e0SJeremy L Thompson       impl->h_data          = impl->h_data_owned;
161ca735530SJeremy L Thompson       memcpy(impl->h_data, data, ctx_size);
1620d0321e0SJeremy L Thompson     } break;
1630d0321e0SJeremy L Thompson     case CEED_OWN_POINTER:
1640d0321e0SJeremy L Thompson       impl->h_data_owned    = data;
1650d0321e0SJeremy L Thompson       impl->h_data_borrowed = NULL;
1660d0321e0SJeremy L Thompson       impl->h_data          = data;
1670d0321e0SJeremy L Thompson       break;
1680d0321e0SJeremy L Thompson     case CEED_USE_POINTER:
1690d0321e0SJeremy L Thompson       impl->h_data_borrowed = data;
1700d0321e0SJeremy L Thompson       impl->h_data          = data;
1710d0321e0SJeremy L Thompson       break;
1720d0321e0SJeremy L Thompson   }
1730d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1740d0321e0SJeremy L Thompson }
1750d0321e0SJeremy L Thompson 
1760d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1770d0321e0SJeremy L Thompson // Set data from device
1780d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1792b730f8bSJeremy L Thompson static int CeedQFunctionContextSetDataDevice_Cuda(const CeedQFunctionContext ctx, const CeedCopyMode copy_mode, void *data) {
1800d0321e0SJeremy L Thompson   Ceed                       ceed;
1810d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
182ca735530SJeremy L Thompson 
183ca735530SJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1842b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
1850d0321e0SJeremy L Thompson 
1862b730f8bSJeremy L Thompson   CeedCallCuda(ceed, cudaFree(impl->d_data_owned));
1870d0321e0SJeremy L Thompson   impl->d_data_owned = NULL;
18843c928f4SJeremy L Thompson   switch (copy_mode) {
189539ec17dSJeremy L Thompson     case CEED_COPY_VALUES: {
190ca735530SJeremy L Thompson       size_t ctx_size;
191ca735530SJeremy L Thompson       CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctx_size));
192ca735530SJeremy L Thompson       CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_data_owned, ctx_size));
1930d0321e0SJeremy L Thompson       impl->d_data_borrowed = NULL;
1940d0321e0SJeremy L Thompson       impl->d_data          = impl->d_data_owned;
195ca735530SJeremy L Thompson       CeedCallCuda(ceed, cudaMemcpy(impl->d_data, data, ctx_size, cudaMemcpyDeviceToDevice));
196539ec17dSJeremy L Thompson     } break;
1970d0321e0SJeremy L Thompson     case CEED_OWN_POINTER:
1980d0321e0SJeremy L Thompson       impl->d_data_owned    = data;
1990d0321e0SJeremy L Thompson       impl->d_data_borrowed = NULL;
2000d0321e0SJeremy L Thompson       impl->d_data          = data;
2010d0321e0SJeremy L Thompson       break;
2020d0321e0SJeremy L Thompson     case CEED_USE_POINTER:
2030d0321e0SJeremy L Thompson       impl->d_data_owned    = NULL;
2040d0321e0SJeremy L Thompson       impl->d_data_borrowed = data;
2050d0321e0SJeremy L Thompson       impl->d_data          = data;
2060d0321e0SJeremy L Thompson       break;
2070d0321e0SJeremy L Thompson   }
2080d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2090d0321e0SJeremy L Thompson }
2100d0321e0SJeremy L Thompson 
2110d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2120d0321e0SJeremy L Thompson // Set the data used by a user context,
2130d0321e0SJeremy L Thompson //   freeing any previously allocated data if applicable
2140d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2152b730f8bSJeremy L Thompson static int CeedQFunctionContextSetData_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, const CeedCopyMode copy_mode, void *data) {
2162b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextSetAllInvalid_Cuda(ctx));
21743c928f4SJeremy L Thompson   switch (mem_type) {
2180d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
21943c928f4SJeremy L Thompson       return CeedQFunctionContextSetDataHost_Cuda(ctx, copy_mode, data);
2200d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
22143c928f4SJeremy L Thompson       return CeedQFunctionContextSetDataDevice_Cuda(ctx, copy_mode, data);
2220d0321e0SJeremy L Thompson   }
2230d0321e0SJeremy L Thompson   return CEED_ERROR_UNSUPPORTED;
2240d0321e0SJeremy L Thompson }
2250d0321e0SJeremy L Thompson 
2260d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2270d0321e0SJeremy L Thompson // Take data
2280d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2292b730f8bSJeremy L Thompson static int CeedQFunctionContextTakeData_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) {
2300d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
231ca735530SJeremy L Thompson 
2322b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
2330d0321e0SJeremy L Thompson 
23443c928f4SJeremy L Thompson   // Sync data to requested mem_type
2350d0321e0SJeremy L Thompson   bool need_sync = false;
2362b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextNeedSync_Cuda(ctx, mem_type, &need_sync));
2372b730f8bSJeremy L Thompson   if (need_sync) CeedCallBackend(CeedQFunctionContextSync_Cuda(ctx, mem_type));
2380d0321e0SJeremy L Thompson 
2390d0321e0SJeremy L Thompson   // Update pointer
24043c928f4SJeremy L Thompson   switch (mem_type) {
2410d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
2420d0321e0SJeremy L Thompson       *(void **)data        = impl->h_data_borrowed;
2430d0321e0SJeremy L Thompson       impl->h_data_borrowed = NULL;
2440d0321e0SJeremy L Thompson       impl->h_data          = NULL;
2450d0321e0SJeremy L Thompson       break;
2460d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
2470d0321e0SJeremy L Thompson       *(void **)data        = impl->d_data_borrowed;
2480d0321e0SJeremy L Thompson       impl->d_data_borrowed = NULL;
2490d0321e0SJeremy L Thompson       impl->d_data          = NULL;
2500d0321e0SJeremy L Thompson       break;
2510d0321e0SJeremy L Thompson   }
2520d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2530d0321e0SJeremy L Thompson }
2540d0321e0SJeremy L Thompson 
2550d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
25628bfd0b7SJeremy L Thompson // Core logic for GetData.
25728bfd0b7SJeremy L Thompson //   If a different memory type is most up to date, this will perform a copy
2580d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2592b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataCore_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) {
260ca735530SJeremy L Thompson   bool                       need_sync = false;
2610d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
262ca735530SJeremy L Thompson 
2632b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
2640d0321e0SJeremy L Thompson 
26543c928f4SJeremy L Thompson   // Sync data to requested mem_type
2662b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextNeedSync_Cuda(ctx, mem_type, &need_sync));
2672b730f8bSJeremy L Thompson   if (need_sync) CeedCallBackend(CeedQFunctionContextSync_Cuda(ctx, mem_type));
2680d0321e0SJeremy L Thompson 
2690d0321e0SJeremy L Thompson   // Update pointer
27043c928f4SJeremy L Thompson   switch (mem_type) {
2710d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
2720d0321e0SJeremy L Thompson       *(void **)data = impl->h_data;
2730d0321e0SJeremy L Thompson       break;
2740d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
2750d0321e0SJeremy L Thompson       *(void **)data = impl->d_data;
2760d0321e0SJeremy L Thompson       break;
2770d0321e0SJeremy L Thompson   }
27828bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
27928bfd0b7SJeremy L Thompson }
28028bfd0b7SJeremy L Thompson 
28128bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------
28228bfd0b7SJeremy L Thompson // Get read-only access to the data
28328bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------
2842b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataRead_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) {
28528bfd0b7SJeremy L Thompson   return CeedQFunctionContextGetDataCore_Cuda(ctx, mem_type, data);
28628bfd0b7SJeremy L Thompson }
28728bfd0b7SJeremy L Thompson 
28828bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------
28928bfd0b7SJeremy L Thompson // Get read/write access to the data
29028bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------
2912b730f8bSJeremy L Thompson static int CeedQFunctionContextGetData_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) {
29228bfd0b7SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
29328bfd0b7SJeremy L Thompson 
294ca735530SJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
2952b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetDataCore_Cuda(ctx, mem_type, data));
29628bfd0b7SJeremy L Thompson 
2970d0321e0SJeremy L Thompson   // Mark only pointer for requested memory as valid
2982b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextSetAllInvalid_Cuda(ctx));
29943c928f4SJeremy L Thompson   switch (mem_type) {
3000d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
3010d0321e0SJeremy L Thompson       impl->h_data = *(void **)data;
3020d0321e0SJeremy L Thompson       break;
3030d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
3040d0321e0SJeremy L Thompson       impl->d_data = *(void **)data;
3050d0321e0SJeremy L Thompson       break;
3060d0321e0SJeremy L Thompson   }
3070d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3080d0321e0SJeremy L Thompson }
3090d0321e0SJeremy L Thompson 
3100d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3110d0321e0SJeremy L Thompson // Destroy the user context
3120d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3130d0321e0SJeremy L Thompson static int CeedQFunctionContextDestroy_Cuda(const CeedQFunctionContext ctx) {
3140d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
3150d0321e0SJeremy L Thompson 
316ca735530SJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
3176e536b99SJeremy L Thompson   CeedCallCuda(CeedQFunctionContextReturnCeed(ctx), cudaFree(impl->d_data_owned));
3182b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->h_data_owned));
3192b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
3200d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3210d0321e0SJeremy L Thompson }
3220d0321e0SJeremy L Thompson 
3230d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3240d0321e0SJeremy L Thompson // QFunctionContext Create
3250d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3260d0321e0SJeremy L Thompson int CeedQFunctionContextCreate_Cuda(CeedQFunctionContext ctx) {
3270d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
3280d0321e0SJeremy L Thompson   Ceed                       ceed;
3290d0321e0SJeremy L Thompson 
330ca735530SJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
3312b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", CeedQFunctionContextHasValidData_Cuda));
3322b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasBorrowedDataOfType", CeedQFunctionContextHasBorrowedDataOfType_Cuda));
3332b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", CeedQFunctionContextSetData_Cuda));
3342b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", CeedQFunctionContextTakeData_Cuda));
3352b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", CeedQFunctionContextGetData_Cuda));
3362b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", CeedQFunctionContextGetDataRead_Cuda));
3372b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", CeedQFunctionContextDestroy_Cuda));
3382b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
3392b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextSetBackendData(ctx, impl));
3400d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3410d0321e0SJeremy L Thompson }
3422a86cc9dSSebastian Grimberg 
3430d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
344