xref: /libCEED/rust/libceed-sys/c-src/backends/cuda-ref/ceed-cuda-ref-qfunctioncontext.c (revision 2b730f8b5a9c809740a0b3b302db43a719c636b1)
13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, 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 
80d0321e0SJeremy L Thompson #include <ceed/backend.h>
9*2b730f8bSJeremy L Thompson #include <ceed/ceed.h>
100d0321e0SJeremy L Thompson #include <cuda_runtime.h>
110d0321e0SJeremy L Thompson #include <string.h>
12*2b730f8bSJeremy L Thompson 
130d0321e0SJeremy L Thompson #include "ceed-cuda-ref.h"
140d0321e0SJeremy L Thompson 
150d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
160d0321e0SJeremy L Thompson // Sync host to device
170d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
18*2b730f8bSJeremy L Thompson static inline int CeedQFunctionContextSyncH2D_Cuda(const CeedQFunctionContext ctx) {
190d0321e0SJeremy L Thompson   Ceed ceed;
20*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
210d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
22*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
230d0321e0SJeremy L Thompson 
24*2b730f8bSJeremy L Thompson   if (!impl->h_data) {
250d0321e0SJeremy L Thompson     // LCOV_EXCL_START
26*2b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "No valid host data to sync to device");
270d0321e0SJeremy L Thompson     // LCOV_EXCL_STOP
28*2b730f8bSJeremy L Thompson   }
290d0321e0SJeremy L Thompson 
30539ec17dSJeremy L Thompson   size_t ctxsize;
31*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctxsize));
32539ec17dSJeremy L Thompson 
330d0321e0SJeremy L Thompson   if (impl->d_data_borrowed) {
340d0321e0SJeremy L Thompson     impl->d_data = impl->d_data_borrowed;
350d0321e0SJeremy L Thompson   } else if (impl->d_data_owned) {
360d0321e0SJeremy L Thompson     impl->d_data = impl->d_data_owned;
370d0321e0SJeremy L Thompson   } else {
38*2b730f8bSJeremy L Thompson     CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_data_owned, ctxsize));
390d0321e0SJeremy L Thompson     impl->d_data = impl->d_data_owned;
400d0321e0SJeremy L Thompson   }
410d0321e0SJeremy L Thompson 
42*2b730f8bSJeremy L Thompson   CeedCallCuda(ceed, cudaMemcpy(impl->d_data, impl->h_data, ctxsize, cudaMemcpyHostToDevice));
430d0321e0SJeremy L Thompson 
440d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
450d0321e0SJeremy L Thompson }
460d0321e0SJeremy L Thompson 
470d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
480d0321e0SJeremy L Thompson // Sync device to host
490d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
50*2b730f8bSJeremy L Thompson static inline int CeedQFunctionContextSyncD2H_Cuda(const CeedQFunctionContext ctx) {
510d0321e0SJeremy L Thompson   Ceed ceed;
52*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
530d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
54*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
550d0321e0SJeremy L Thompson 
56*2b730f8bSJeremy L Thompson   if (!impl->d_data) {
570d0321e0SJeremy L Thompson     // LCOV_EXCL_START
58*2b730f8bSJeremy L Thompson     return CeedError(ceed, CEED_ERROR_BACKEND, "No valid device data to sync to host");
590d0321e0SJeremy L Thompson     // LCOV_EXCL_STOP
60*2b730f8bSJeremy L Thompson   }
610d0321e0SJeremy L Thompson 
62539ec17dSJeremy L Thompson   size_t ctxsize;
63*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctxsize));
64539ec17dSJeremy L Thompson 
650d0321e0SJeremy L Thompson   if (impl->h_data_borrowed) {
660d0321e0SJeremy L Thompson     impl->h_data = impl->h_data_borrowed;
670d0321e0SJeremy L Thompson   } else if (impl->h_data_owned) {
680d0321e0SJeremy L Thompson     impl->h_data = impl->h_data_owned;
690d0321e0SJeremy L Thompson   } else {
70*2b730f8bSJeremy L Thompson     CeedCallBackend(CeedMallocArray(1, ctxsize, &impl->h_data_owned));
710d0321e0SJeremy L Thompson     impl->h_data = impl->h_data_owned;
720d0321e0SJeremy L Thompson   }
730d0321e0SJeremy L Thompson 
74*2b730f8bSJeremy L Thompson   CeedCallCuda(ceed, cudaMemcpy(impl->h_data, impl->d_data, ctxsize, cudaMemcpyDeviceToHost));
750d0321e0SJeremy L Thompson 
760d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
770d0321e0SJeremy L Thompson }
780d0321e0SJeremy L Thompson 
790d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
800d0321e0SJeremy L Thompson // Sync data of type
810d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
82*2b730f8bSJeremy L Thompson static inline int CeedQFunctionContextSync_Cuda(const CeedQFunctionContext ctx, CeedMemType mem_type) {
8343c928f4SJeremy L Thompson   switch (mem_type) {
84*2b730f8bSJeremy L Thompson     case CEED_MEM_HOST:
85*2b730f8bSJeremy L Thompson       return CeedQFunctionContextSyncD2H_Cuda(ctx);
86*2b730f8bSJeremy L Thompson     case CEED_MEM_DEVICE:
87*2b730f8bSJeremy L Thompson       return CeedQFunctionContextSyncH2D_Cuda(ctx);
880d0321e0SJeremy L Thompson   }
890d0321e0SJeremy L Thompson   return CEED_ERROR_UNSUPPORTED;
900d0321e0SJeremy L Thompson }
910d0321e0SJeremy L Thompson 
920d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
930d0321e0SJeremy L Thompson // Set all pointers as invalid
940d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
95*2b730f8bSJeremy L Thompson static inline int CeedQFunctionContextSetAllInvalid_Cuda(const CeedQFunctionContext ctx) {
960d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
97*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
980d0321e0SJeremy L Thompson 
990d0321e0SJeremy L Thompson   impl->h_data = NULL;
1000d0321e0SJeremy L Thompson   impl->d_data = NULL;
1010d0321e0SJeremy L Thompson 
1020d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1030d0321e0SJeremy L Thompson }
1040d0321e0SJeremy L Thompson 
1050d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1060d0321e0SJeremy L Thompson // Check if ctx has valid data
1070d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
108*2b730f8bSJeremy L Thompson static inline int CeedQFunctionContextHasValidData_Cuda(const CeedQFunctionContext ctx, bool *has_valid_data) {
1090d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
110*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
1110d0321e0SJeremy L Thompson 
11252b3e6a7SJed Brown   *has_valid_data = impl && (!!impl->h_data || !!impl->d_data);
1130d0321e0SJeremy L Thompson 
1140d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1150d0321e0SJeremy L Thompson }
1160d0321e0SJeremy L Thompson 
1170d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1180d0321e0SJeremy L Thompson // Check if ctx has borrowed data
1190d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
120*2b730f8bSJeremy L Thompson static inline int CeedQFunctionContextHasBorrowedDataOfType_Cuda(const CeedQFunctionContext ctx, CeedMemType mem_type,
1210d0321e0SJeremy L Thompson                                                                  bool *has_borrowed_data_of_type) {
1220d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
123*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
1240d0321e0SJeremy L Thompson 
12543c928f4SJeremy L Thompson   switch (mem_type) {
1260d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
1270d0321e0SJeremy L Thompson       *has_borrowed_data_of_type = !!impl->h_data_borrowed;
1280d0321e0SJeremy L Thompson       break;
1290d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
1300d0321e0SJeremy L Thompson       *has_borrowed_data_of_type = !!impl->d_data_borrowed;
1310d0321e0SJeremy L Thompson       break;
1320d0321e0SJeremy L Thompson   }
1330d0321e0SJeremy L Thompson 
1340d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1350d0321e0SJeremy L Thompson }
1360d0321e0SJeremy L Thompson 
1370d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1380d0321e0SJeremy L Thompson // Check if data of given type needs sync
1390d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
140*2b730f8bSJeremy L Thompson static inline int CeedQFunctionContextNeedSync_Cuda(const CeedQFunctionContext ctx, CeedMemType mem_type, bool *need_sync) {
1410d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
142*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
1430d0321e0SJeremy L Thompson 
1440d0321e0SJeremy L Thompson   bool has_valid_data = true;
145*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextHasValidData(ctx, &has_valid_data));
14643c928f4SJeremy L Thompson   switch (mem_type) {
1470d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
1480d0321e0SJeremy L Thompson       *need_sync = has_valid_data && !impl->h_data;
1490d0321e0SJeremy L Thompson       break;
1500d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
1510d0321e0SJeremy L Thompson       *need_sync = has_valid_data && !impl->d_data;
1520d0321e0SJeremy L Thompson       break;
1530d0321e0SJeremy L Thompson   }
1540d0321e0SJeremy L Thompson 
1550d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1560d0321e0SJeremy L Thompson }
1570d0321e0SJeremy L Thompson 
1580d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1590d0321e0SJeremy L Thompson // Set data from host
1600d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
161*2b730f8bSJeremy L Thompson static int CeedQFunctionContextSetDataHost_Cuda(const CeedQFunctionContext ctx, const CeedCopyMode copy_mode, void *data) {
1620d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
163*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
1640d0321e0SJeremy L Thompson 
165*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->h_data_owned));
16643c928f4SJeremy L Thompson   switch (copy_mode) {
1670d0321e0SJeremy L Thompson     case CEED_COPY_VALUES: {
168539ec17dSJeremy L Thompson       size_t ctxsize;
169*2b730f8bSJeremy L Thompson       CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctxsize));
170*2b730f8bSJeremy L Thompson       CeedCallBackend(CeedMallocArray(1, ctxsize, &impl->h_data_owned));
1710d0321e0SJeremy L Thompson       impl->h_data_borrowed = NULL;
1720d0321e0SJeremy L Thompson       impl->h_data          = impl->h_data_owned;
173539ec17dSJeremy L Thompson       memcpy(impl->h_data, data, ctxsize);
1740d0321e0SJeremy L Thompson     } break;
1750d0321e0SJeremy L Thompson     case CEED_OWN_POINTER:
1760d0321e0SJeremy L Thompson       impl->h_data_owned    = data;
1770d0321e0SJeremy L Thompson       impl->h_data_borrowed = NULL;
1780d0321e0SJeremy L Thompson       impl->h_data          = data;
1790d0321e0SJeremy L Thompson       break;
1800d0321e0SJeremy L Thompson     case CEED_USE_POINTER:
1810d0321e0SJeremy L Thompson       impl->h_data_borrowed = data;
1820d0321e0SJeremy L Thompson       impl->h_data          = data;
1830d0321e0SJeremy L Thompson       break;
1840d0321e0SJeremy L Thompson   }
1850d0321e0SJeremy L Thompson 
1860d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
1870d0321e0SJeremy L Thompson }
1880d0321e0SJeremy L Thompson 
1890d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
1900d0321e0SJeremy L Thompson // Set data from device
1910d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
192*2b730f8bSJeremy L Thompson static int CeedQFunctionContextSetDataDevice_Cuda(const CeedQFunctionContext ctx, const CeedCopyMode copy_mode, void *data) {
1930d0321e0SJeremy L Thompson   Ceed ceed;
194*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
1950d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
196*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
1970d0321e0SJeremy L Thompson 
198*2b730f8bSJeremy L Thompson   CeedCallCuda(ceed, cudaFree(impl->d_data_owned));
1990d0321e0SJeremy L Thompson   impl->d_data_owned = NULL;
20043c928f4SJeremy L Thompson   switch (copy_mode) {
201539ec17dSJeremy L Thompson     case CEED_COPY_VALUES: {
202539ec17dSJeremy L Thompson       size_t ctxsize;
203*2b730f8bSJeremy L Thompson       CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctxsize));
204*2b730f8bSJeremy L Thompson       CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_data_owned, ctxsize));
2050d0321e0SJeremy L Thompson       impl->d_data_borrowed = NULL;
2060d0321e0SJeremy L Thompson       impl->d_data          = impl->d_data_owned;
207*2b730f8bSJeremy L Thompson       CeedCallCuda(ceed, cudaMemcpy(impl->d_data, data, ctxsize, cudaMemcpyDeviceToDevice));
208539ec17dSJeremy L Thompson     } break;
2090d0321e0SJeremy L Thompson     case CEED_OWN_POINTER:
2100d0321e0SJeremy L Thompson       impl->d_data_owned    = data;
2110d0321e0SJeremy L Thompson       impl->d_data_borrowed = NULL;
2120d0321e0SJeremy L Thompson       impl->d_data          = data;
2130d0321e0SJeremy L Thompson       break;
2140d0321e0SJeremy L Thompson     case CEED_USE_POINTER:
2150d0321e0SJeremy L Thompson       impl->d_data_owned    = NULL;
2160d0321e0SJeremy L Thompson       impl->d_data_borrowed = data;
2170d0321e0SJeremy L Thompson       impl->d_data          = data;
2180d0321e0SJeremy L Thompson       break;
2190d0321e0SJeremy L Thompson   }
2200d0321e0SJeremy L Thompson 
2210d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2220d0321e0SJeremy L Thompson }
2230d0321e0SJeremy L Thompson 
2240d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2250d0321e0SJeremy L Thompson // Set the data used by a user context,
2260d0321e0SJeremy L Thompson //   freeing any previously allocated data if applicable
2270d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
228*2b730f8bSJeremy L Thompson static int CeedQFunctionContextSetData_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, const CeedCopyMode copy_mode, void *data) {
2290d0321e0SJeremy L Thompson   Ceed ceed;
230*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
2310d0321e0SJeremy L Thompson 
232*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextSetAllInvalid_Cuda(ctx));
23343c928f4SJeremy L Thompson   switch (mem_type) {
2340d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
23543c928f4SJeremy L Thompson       return CeedQFunctionContextSetDataHost_Cuda(ctx, copy_mode, data);
2360d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
23743c928f4SJeremy L Thompson       return CeedQFunctionContextSetDataDevice_Cuda(ctx, copy_mode, data);
2380d0321e0SJeremy L Thompson   }
2390d0321e0SJeremy L Thompson 
2400d0321e0SJeremy L Thompson   return CEED_ERROR_UNSUPPORTED;
2410d0321e0SJeremy L Thompson }
2420d0321e0SJeremy L Thompson 
2430d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
2440d0321e0SJeremy L Thompson // Take data
2450d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
246*2b730f8bSJeremy L Thompson static int CeedQFunctionContextTakeData_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) {
2470d0321e0SJeremy L Thompson   Ceed ceed;
248*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
2490d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
250*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
2510d0321e0SJeremy L Thompson 
25243c928f4SJeremy L Thompson   // Sync data to requested mem_type
2530d0321e0SJeremy L Thompson   bool need_sync = false;
254*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextNeedSync_Cuda(ctx, mem_type, &need_sync));
255*2b730f8bSJeremy L Thompson   if (need_sync) CeedCallBackend(CeedQFunctionContextSync_Cuda(ctx, mem_type));
2560d0321e0SJeremy L Thompson 
2570d0321e0SJeremy L Thompson   // Update pointer
25843c928f4SJeremy L Thompson   switch (mem_type) {
2590d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
2600d0321e0SJeremy L Thompson       *(void **)data        = impl->h_data_borrowed;
2610d0321e0SJeremy L Thompson       impl->h_data_borrowed = NULL;
2620d0321e0SJeremy L Thompson       impl->h_data          = NULL;
2630d0321e0SJeremy L Thompson       break;
2640d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
2650d0321e0SJeremy L Thompson       *(void **)data        = impl->d_data_borrowed;
2660d0321e0SJeremy L Thompson       impl->d_data_borrowed = NULL;
2670d0321e0SJeremy L Thompson       impl->d_data          = NULL;
2680d0321e0SJeremy L Thompson       break;
2690d0321e0SJeremy L Thompson   }
2700d0321e0SJeremy L Thompson 
2710d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
2720d0321e0SJeremy L Thompson }
2730d0321e0SJeremy L Thompson 
2740d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
27528bfd0b7SJeremy L Thompson // Core logic for GetData.
27628bfd0b7SJeremy L Thompson //   If a different memory type is most up to date, this will perform a copy
2770d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
278*2b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataCore_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) {
2790d0321e0SJeremy L Thompson   Ceed ceed;
280*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
2810d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
282*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
2830d0321e0SJeremy L Thompson 
28443c928f4SJeremy L Thompson   // Sync data to requested mem_type
2850d0321e0SJeremy L Thompson   bool need_sync = false;
286*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextNeedSync_Cuda(ctx, mem_type, &need_sync));
287*2b730f8bSJeremy L Thompson   if (need_sync) CeedCallBackend(CeedQFunctionContextSync_Cuda(ctx, mem_type));
2880d0321e0SJeremy L Thompson 
2890d0321e0SJeremy L Thompson   // Update pointer
29043c928f4SJeremy L Thompson   switch (mem_type) {
2910d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
2920d0321e0SJeremy L Thompson       *(void **)data = impl->h_data;
2930d0321e0SJeremy L Thompson       break;
2940d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
2950d0321e0SJeremy L Thompson       *(void **)data = impl->d_data;
2960d0321e0SJeremy L Thompson       break;
2970d0321e0SJeremy L Thompson   }
2980d0321e0SJeremy L Thompson 
29928bfd0b7SJeremy L Thompson   return CEED_ERROR_SUCCESS;
30028bfd0b7SJeremy L Thompson }
30128bfd0b7SJeremy L Thompson 
30228bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------
30328bfd0b7SJeremy L Thompson // Get read-only access to the data
30428bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------
305*2b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataRead_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) {
30628bfd0b7SJeremy L Thompson   return CeedQFunctionContextGetDataCore_Cuda(ctx, mem_type, data);
30728bfd0b7SJeremy L Thompson }
30828bfd0b7SJeremy L Thompson 
30928bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------
31028bfd0b7SJeremy L Thompson // Get read/write access to the data
31128bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------
312*2b730f8bSJeremy L Thompson static int CeedQFunctionContextGetData_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) {
31328bfd0b7SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
314*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
31528bfd0b7SJeremy L Thompson 
316*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetDataCore_Cuda(ctx, mem_type, data));
31728bfd0b7SJeremy L Thompson 
3180d0321e0SJeremy L Thompson   // Mark only pointer for requested memory as valid
319*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextSetAllInvalid_Cuda(ctx));
32043c928f4SJeremy L Thompson   switch (mem_type) {
3210d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
3220d0321e0SJeremy L Thompson       impl->h_data = *(void **)data;
3230d0321e0SJeremy L Thompson       break;
3240d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
3250d0321e0SJeremy L Thompson       impl->d_data = *(void **)data;
3260d0321e0SJeremy L Thompson       break;
3270d0321e0SJeremy L Thompson   }
3280d0321e0SJeremy L Thompson 
3290d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3300d0321e0SJeremy L Thompson }
3310d0321e0SJeremy L Thompson 
3320d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3330d0321e0SJeremy L Thompson // Destroy the user context
3340d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3350d0321e0SJeremy L Thompson static int CeedQFunctionContextDestroy_Cuda(const CeedQFunctionContext ctx) {
3360d0321e0SJeremy L Thompson   Ceed ceed;
337*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
3380d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
339*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl));
3400d0321e0SJeremy L Thompson 
341*2b730f8bSJeremy L Thompson   CeedCallCuda(ceed, cudaFree(impl->d_data_owned));
342*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->h_data_owned));
343*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
3440d0321e0SJeremy L Thompson 
3450d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3460d0321e0SJeremy L Thompson }
3470d0321e0SJeremy L Thompson 
3480d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3490d0321e0SJeremy L Thompson // QFunctionContext Create
3500d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
3510d0321e0SJeremy L Thompson int CeedQFunctionContextCreate_Cuda(CeedQFunctionContext ctx) {
3520d0321e0SJeremy L Thompson   CeedQFunctionContext_Cuda *impl;
3530d0321e0SJeremy L Thompson   Ceed                       ceed;
354*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed));
3550d0321e0SJeremy L Thompson 
356*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", CeedQFunctionContextHasValidData_Cuda));
357*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasBorrowedDataOfType", CeedQFunctionContextHasBorrowedDataOfType_Cuda));
358*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", CeedQFunctionContextSetData_Cuda));
359*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", CeedQFunctionContextTakeData_Cuda));
360*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", CeedQFunctionContextGetData_Cuda));
361*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", CeedQFunctionContextGetDataRead_Cuda));
362*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", CeedQFunctionContextDestroy_Cuda));
3630d0321e0SJeremy L Thompson 
364*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
365*2b730f8bSJeremy L Thompson   CeedCallBackend(CeedQFunctionContextSetBackendData(ctx, impl));
3660d0321e0SJeremy L Thompson 
3670d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3680d0321e0SJeremy L Thompson }
3690d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
370