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