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 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; 222b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 230d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 242b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 250d0321e0SJeremy L Thompson 26*6574a04fSJeremy L Thompson CeedCheck(impl->h_data, ceed, CEED_ERROR_BACKEND, "No valid host data to sync to device"); 270d0321e0SJeremy L Thompson 28539ec17dSJeremy L Thompson size_t ctxsize; 292b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctxsize)); 30539ec17dSJeremy L Thompson 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 { 362b730f8bSJeremy L Thompson CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_data_owned, ctxsize)); 370d0321e0SJeremy L Thompson impl->d_data = impl->d_data_owned; 380d0321e0SJeremy L Thompson } 390d0321e0SJeremy L Thompson 402b730f8bSJeremy L Thompson CeedCallCuda(ceed, cudaMemcpy(impl->d_data, impl->h_data, ctxsize, cudaMemcpyHostToDevice)); 410d0321e0SJeremy L Thompson 420d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 430d0321e0SJeremy L Thompson } 440d0321e0SJeremy L Thompson 450d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 460d0321e0SJeremy L Thompson // Sync device to host 470d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 482b730f8bSJeremy L Thompson static inline int CeedQFunctionContextSyncD2H_Cuda(const CeedQFunctionContext ctx) { 490d0321e0SJeremy L Thompson Ceed ceed; 502b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 510d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 522b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 530d0321e0SJeremy L Thompson 54*6574a04fSJeremy L Thompson CeedCheck(impl->d_data, ceed, CEED_ERROR_BACKEND, "No valid device data to sync to host"); 550d0321e0SJeremy L Thompson 56539ec17dSJeremy L Thompson size_t ctxsize; 572b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctxsize)); 58539ec17dSJeremy L Thompson 590d0321e0SJeremy L Thompson if (impl->h_data_borrowed) { 600d0321e0SJeremy L Thompson impl->h_data = impl->h_data_borrowed; 610d0321e0SJeremy L Thompson } else if (impl->h_data_owned) { 620d0321e0SJeremy L Thompson impl->h_data = impl->h_data_owned; 630d0321e0SJeremy L Thompson } else { 642b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctxsize, &impl->h_data_owned)); 650d0321e0SJeremy L Thompson impl->h_data = impl->h_data_owned; 660d0321e0SJeremy L Thompson } 670d0321e0SJeremy L Thompson 682b730f8bSJeremy L Thompson CeedCallCuda(ceed, cudaMemcpy(impl->h_data, impl->d_data, ctxsize, cudaMemcpyDeviceToHost)); 690d0321e0SJeremy L Thompson 700d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 710d0321e0SJeremy L Thompson } 720d0321e0SJeremy L Thompson 730d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 740d0321e0SJeremy L Thompson // Sync data of type 750d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 762b730f8bSJeremy L Thompson static inline int CeedQFunctionContextSync_Cuda(const CeedQFunctionContext ctx, CeedMemType mem_type) { 7743c928f4SJeremy L Thompson switch (mem_type) { 782b730f8bSJeremy L Thompson case CEED_MEM_HOST: 792b730f8bSJeremy L Thompson return CeedQFunctionContextSyncD2H_Cuda(ctx); 802b730f8bSJeremy L Thompson case CEED_MEM_DEVICE: 812b730f8bSJeremy L Thompson return CeedQFunctionContextSyncH2D_Cuda(ctx); 820d0321e0SJeremy L Thompson } 830d0321e0SJeremy L Thompson return CEED_ERROR_UNSUPPORTED; 840d0321e0SJeremy L Thompson } 850d0321e0SJeremy L Thompson 860d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 870d0321e0SJeremy L Thompson // Set all pointers as invalid 880d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 892b730f8bSJeremy L Thompson static inline int CeedQFunctionContextSetAllInvalid_Cuda(const CeedQFunctionContext ctx) { 900d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 912b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 920d0321e0SJeremy L Thompson 930d0321e0SJeremy L Thompson impl->h_data = NULL; 940d0321e0SJeremy L Thompson impl->d_data = NULL; 950d0321e0SJeremy L Thompson 960d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 970d0321e0SJeremy L Thompson } 980d0321e0SJeremy L Thompson 990d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1000d0321e0SJeremy L Thompson // Check if ctx has valid data 1010d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1022b730f8bSJeremy L Thompson static inline int CeedQFunctionContextHasValidData_Cuda(const CeedQFunctionContext ctx, bool *has_valid_data) { 1030d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 1042b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 1050d0321e0SJeremy L Thompson 10652b3e6a7SJed Brown *has_valid_data = impl && (!!impl->h_data || !!impl->d_data); 1070d0321e0SJeremy L Thompson 1080d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1090d0321e0SJeremy L Thompson } 1100d0321e0SJeremy L Thompson 1110d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1120d0321e0SJeremy L Thompson // Check if ctx has borrowed data 1130d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1142b730f8bSJeremy L Thompson static inline int CeedQFunctionContextHasBorrowedDataOfType_Cuda(const CeedQFunctionContext ctx, CeedMemType mem_type, 1150d0321e0SJeremy L Thompson bool *has_borrowed_data_of_type) { 1160d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 1172b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 1180d0321e0SJeremy L Thompson 11943c928f4SJeremy L Thompson switch (mem_type) { 1200d0321e0SJeremy L Thompson case CEED_MEM_HOST: 1210d0321e0SJeremy L Thompson *has_borrowed_data_of_type = !!impl->h_data_borrowed; 1220d0321e0SJeremy L Thompson break; 1230d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 1240d0321e0SJeremy L Thompson *has_borrowed_data_of_type = !!impl->d_data_borrowed; 1250d0321e0SJeremy L Thompson break; 1260d0321e0SJeremy L Thompson } 1270d0321e0SJeremy L Thompson 1280d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1290d0321e0SJeremy L Thompson } 1300d0321e0SJeremy L Thompson 1310d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1320d0321e0SJeremy L Thompson // Check if data of given type needs sync 1330d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1342b730f8bSJeremy L Thompson static inline int CeedQFunctionContextNeedSync_Cuda(const CeedQFunctionContext ctx, CeedMemType mem_type, bool *need_sync) { 1350d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 1362b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 1370d0321e0SJeremy L Thompson 1380d0321e0SJeremy L Thompson bool has_valid_data = true; 1392b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 14043c928f4SJeremy L Thompson switch (mem_type) { 1410d0321e0SJeremy L Thompson case CEED_MEM_HOST: 1420d0321e0SJeremy L Thompson *need_sync = has_valid_data && !impl->h_data; 1430d0321e0SJeremy L Thompson break; 1440d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 1450d0321e0SJeremy L Thompson *need_sync = has_valid_data && !impl->d_data; 1460d0321e0SJeremy L Thompson break; 1470d0321e0SJeremy L Thompson } 1480d0321e0SJeremy L Thompson 1490d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1500d0321e0SJeremy L Thompson } 1510d0321e0SJeremy L Thompson 1520d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1530d0321e0SJeremy L Thompson // Set data from host 1540d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1552b730f8bSJeremy L Thompson static int CeedQFunctionContextSetDataHost_Cuda(const CeedQFunctionContext ctx, const CeedCopyMode copy_mode, void *data) { 1560d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 1572b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 1580d0321e0SJeremy L Thompson 1592b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->h_data_owned)); 16043c928f4SJeremy L Thompson switch (copy_mode) { 1610d0321e0SJeremy L Thompson case CEED_COPY_VALUES: { 162539ec17dSJeremy L Thompson size_t ctxsize; 1632b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctxsize)); 1642b730f8bSJeremy L Thompson CeedCallBackend(CeedMallocArray(1, ctxsize, &impl->h_data_owned)); 1650d0321e0SJeremy L Thompson impl->h_data_borrowed = NULL; 1660d0321e0SJeremy L Thompson impl->h_data = impl->h_data_owned; 167539ec17dSJeremy L Thompson memcpy(impl->h_data, data, ctxsize); 1680d0321e0SJeremy L Thompson } break; 1690d0321e0SJeremy L Thompson case CEED_OWN_POINTER: 1700d0321e0SJeremy L Thompson impl->h_data_owned = data; 1710d0321e0SJeremy L Thompson impl->h_data_borrowed = NULL; 1720d0321e0SJeremy L Thompson impl->h_data = data; 1730d0321e0SJeremy L Thompson break; 1740d0321e0SJeremy L Thompson case CEED_USE_POINTER: 1750d0321e0SJeremy L Thompson impl->h_data_borrowed = data; 1760d0321e0SJeremy L Thompson impl->h_data = data; 1770d0321e0SJeremy L Thompson break; 1780d0321e0SJeremy L Thompson } 1790d0321e0SJeremy L Thompson 1800d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1810d0321e0SJeremy L Thompson } 1820d0321e0SJeremy L Thompson 1830d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1840d0321e0SJeremy L Thompson // Set data from device 1850d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1862b730f8bSJeremy L Thompson static int CeedQFunctionContextSetDataDevice_Cuda(const CeedQFunctionContext ctx, const CeedCopyMode copy_mode, void *data) { 1870d0321e0SJeremy L Thompson Ceed ceed; 1882b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 1890d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 1902b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 1910d0321e0SJeremy L Thompson 1922b730f8bSJeremy L Thompson CeedCallCuda(ceed, cudaFree(impl->d_data_owned)); 1930d0321e0SJeremy L Thompson impl->d_data_owned = NULL; 19443c928f4SJeremy L Thompson switch (copy_mode) { 195539ec17dSJeremy L Thompson case CEED_COPY_VALUES: { 196539ec17dSJeremy L Thompson size_t ctxsize; 1972b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetContextSize(ctx, &ctxsize)); 1982b730f8bSJeremy L Thompson CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_data_owned, ctxsize)); 1990d0321e0SJeremy L Thompson impl->d_data_borrowed = NULL; 2000d0321e0SJeremy L Thompson impl->d_data = impl->d_data_owned; 2012b730f8bSJeremy L Thompson CeedCallCuda(ceed, cudaMemcpy(impl->d_data, data, ctxsize, cudaMemcpyDeviceToDevice)); 202539ec17dSJeremy L Thompson } break; 2030d0321e0SJeremy L Thompson case CEED_OWN_POINTER: 2040d0321e0SJeremy L Thompson impl->d_data_owned = data; 2050d0321e0SJeremy L Thompson impl->d_data_borrowed = NULL; 2060d0321e0SJeremy L Thompson impl->d_data = data; 2070d0321e0SJeremy L Thompson break; 2080d0321e0SJeremy L Thompson case CEED_USE_POINTER: 2090d0321e0SJeremy L Thompson impl->d_data_owned = NULL; 2100d0321e0SJeremy L Thompson impl->d_data_borrowed = data; 2110d0321e0SJeremy L Thompson impl->d_data = data; 2120d0321e0SJeremy L Thompson break; 2130d0321e0SJeremy L Thompson } 2140d0321e0SJeremy L Thompson 2150d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2160d0321e0SJeremy L Thompson } 2170d0321e0SJeremy L Thompson 2180d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2190d0321e0SJeremy L Thompson // Set the data used by a user context, 2200d0321e0SJeremy L Thompson // freeing any previously allocated data if applicable 2210d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2222b730f8bSJeremy L Thompson static int CeedQFunctionContextSetData_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, const CeedCopyMode copy_mode, void *data) { 2230d0321e0SJeremy L Thompson Ceed ceed; 2242b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 2250d0321e0SJeremy L Thompson 2262b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextSetAllInvalid_Cuda(ctx)); 22743c928f4SJeremy L Thompson switch (mem_type) { 2280d0321e0SJeremy L Thompson case CEED_MEM_HOST: 22943c928f4SJeremy L Thompson return CeedQFunctionContextSetDataHost_Cuda(ctx, copy_mode, data); 2300d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 23143c928f4SJeremy L Thompson return CeedQFunctionContextSetDataDevice_Cuda(ctx, copy_mode, data); 2320d0321e0SJeremy L Thompson } 2330d0321e0SJeremy L Thompson 2340d0321e0SJeremy L Thompson return CEED_ERROR_UNSUPPORTED; 2350d0321e0SJeremy L Thompson } 2360d0321e0SJeremy L Thompson 2370d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2380d0321e0SJeremy L Thompson // Take data 2390d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2402b730f8bSJeremy L Thompson static int CeedQFunctionContextTakeData_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) { 2410d0321e0SJeremy L Thompson Ceed ceed; 2422b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 2430d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 2442b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 2450d0321e0SJeremy L Thompson 24643c928f4SJeremy L Thompson // Sync data to requested mem_type 2470d0321e0SJeremy L Thompson bool need_sync = false; 2482b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextNeedSync_Cuda(ctx, mem_type, &need_sync)); 2492b730f8bSJeremy L Thompson if (need_sync) CeedCallBackend(CeedQFunctionContextSync_Cuda(ctx, mem_type)); 2500d0321e0SJeremy L Thompson 2510d0321e0SJeremy L Thompson // Update pointer 25243c928f4SJeremy L Thompson switch (mem_type) { 2530d0321e0SJeremy L Thompson case CEED_MEM_HOST: 2540d0321e0SJeremy L Thompson *(void **)data = impl->h_data_borrowed; 2550d0321e0SJeremy L Thompson impl->h_data_borrowed = NULL; 2560d0321e0SJeremy L Thompson impl->h_data = NULL; 2570d0321e0SJeremy L Thompson break; 2580d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 2590d0321e0SJeremy L Thompson *(void **)data = impl->d_data_borrowed; 2600d0321e0SJeremy L Thompson impl->d_data_borrowed = NULL; 2610d0321e0SJeremy L Thompson impl->d_data = NULL; 2620d0321e0SJeremy L Thompson break; 2630d0321e0SJeremy L Thompson } 2640d0321e0SJeremy L Thompson 2650d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2660d0321e0SJeremy L Thompson } 2670d0321e0SJeremy L Thompson 2680d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 26928bfd0b7SJeremy L Thompson // Core logic for GetData. 27028bfd0b7SJeremy L Thompson // If a different memory type is most up to date, this will perform a copy 2710d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2722b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataCore_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) { 2730d0321e0SJeremy L Thompson Ceed ceed; 2742b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 2750d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 2762b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 2770d0321e0SJeremy L Thompson 27843c928f4SJeremy L Thompson // Sync data to requested mem_type 2790d0321e0SJeremy L Thompson bool need_sync = false; 2802b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextNeedSync_Cuda(ctx, mem_type, &need_sync)); 2812b730f8bSJeremy L Thompson if (need_sync) CeedCallBackend(CeedQFunctionContextSync_Cuda(ctx, mem_type)); 2820d0321e0SJeremy L Thompson 2830d0321e0SJeremy L Thompson // Update pointer 28443c928f4SJeremy L Thompson switch (mem_type) { 2850d0321e0SJeremy L Thompson case CEED_MEM_HOST: 2860d0321e0SJeremy L Thompson *(void **)data = impl->h_data; 2870d0321e0SJeremy L Thompson break; 2880d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 2890d0321e0SJeremy L Thompson *(void **)data = impl->d_data; 2900d0321e0SJeremy L Thompson break; 2910d0321e0SJeremy L Thompson } 2920d0321e0SJeremy L Thompson 29328bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 29428bfd0b7SJeremy L Thompson } 29528bfd0b7SJeremy L Thompson 29628bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------ 29728bfd0b7SJeremy L Thompson // Get read-only access to the data 29828bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------ 2992b730f8bSJeremy L Thompson static int CeedQFunctionContextGetDataRead_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) { 30028bfd0b7SJeremy L Thompson return CeedQFunctionContextGetDataCore_Cuda(ctx, mem_type, data); 30128bfd0b7SJeremy L Thompson } 30228bfd0b7SJeremy L Thompson 30328bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------ 30428bfd0b7SJeremy L Thompson // Get read/write access to the data 30528bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------ 3062b730f8bSJeremy L Thompson static int CeedQFunctionContextGetData_Cuda(const CeedQFunctionContext ctx, const CeedMemType mem_type, void *data) { 30728bfd0b7SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 3082b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 30928bfd0b7SJeremy L Thompson 3102b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetDataCore_Cuda(ctx, mem_type, data)); 31128bfd0b7SJeremy L Thompson 3120d0321e0SJeremy L Thompson // Mark only pointer for requested memory as valid 3132b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextSetAllInvalid_Cuda(ctx)); 31443c928f4SJeremy L Thompson switch (mem_type) { 3150d0321e0SJeremy L Thompson case CEED_MEM_HOST: 3160d0321e0SJeremy L Thompson impl->h_data = *(void **)data; 3170d0321e0SJeremy L Thompson break; 3180d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 3190d0321e0SJeremy L Thompson impl->d_data = *(void **)data; 3200d0321e0SJeremy L Thompson break; 3210d0321e0SJeremy L Thompson } 3220d0321e0SJeremy L Thompson 3230d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3240d0321e0SJeremy L Thompson } 3250d0321e0SJeremy L Thompson 3260d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3270d0321e0SJeremy L Thompson // Destroy the user context 3280d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3290d0321e0SJeremy L Thompson static int CeedQFunctionContextDestroy_Cuda(const CeedQFunctionContext ctx) { 3300d0321e0SJeremy L Thompson Ceed ceed; 3312b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 3320d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 3332b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetBackendData(ctx, &impl)); 3340d0321e0SJeremy L Thompson 3352b730f8bSJeremy L Thompson CeedCallCuda(ceed, cudaFree(impl->d_data_owned)); 3362b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->h_data_owned)); 3372b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl)); 3380d0321e0SJeremy L Thompson 3390d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3400d0321e0SJeremy L Thompson } 3410d0321e0SJeremy L Thompson 3420d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3430d0321e0SJeremy L Thompson // QFunctionContext Create 3440d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3450d0321e0SJeremy L Thompson int CeedQFunctionContextCreate_Cuda(CeedQFunctionContext ctx) { 3460d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 3470d0321e0SJeremy L Thompson Ceed ceed; 3482b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextGetCeed(ctx, &ceed)); 3490d0321e0SJeremy L Thompson 3502b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", CeedQFunctionContextHasValidData_Cuda)); 3512b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasBorrowedDataOfType", CeedQFunctionContextHasBorrowedDataOfType_Cuda)); 3522b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", CeedQFunctionContextSetData_Cuda)); 3532b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", CeedQFunctionContextTakeData_Cuda)); 3542b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", CeedQFunctionContextGetData_Cuda)); 3552b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", CeedQFunctionContextGetDataRead_Cuda)); 3562b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", CeedQFunctionContextDestroy_Cuda)); 3570d0321e0SJeremy L Thompson 3582b730f8bSJeremy L Thompson CeedCallBackend(CeedCalloc(1, &impl)); 3592b730f8bSJeremy L Thompson CeedCallBackend(CeedQFunctionContextSetBackendData(ctx, impl)); 3600d0321e0SJeremy L Thompson 3610d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3620d0321e0SJeremy L Thompson } 3630d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 364