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/ceed.h> 90d0321e0SJeremy L Thompson #include <ceed/backend.h> 100d0321e0SJeremy L Thompson #include <cuda_runtime.h> 110d0321e0SJeremy L Thompson #include <string.h> 120d0321e0SJeremy L Thompson #include "ceed-cuda-ref.h" 130d0321e0SJeremy L Thompson 140d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 150d0321e0SJeremy L Thompson // Sync host to device 160d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 170d0321e0SJeremy L Thompson static inline int CeedQFunctionContextSyncH2D_Cuda( 180d0321e0SJeremy L Thompson const CeedQFunctionContext ctx) { 190d0321e0SJeremy L Thompson int ierr; 200d0321e0SJeremy L Thompson Ceed ceed; 210d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 220d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 230d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 240d0321e0SJeremy L Thompson 250d0321e0SJeremy L Thompson if (!impl->h_data) 260d0321e0SJeremy L Thompson // LCOV_EXCL_START 270d0321e0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, 280d0321e0SJeremy L Thompson "No valid host data to sync to device"); 290d0321e0SJeremy L Thompson // LCOV_EXCL_STOP 300d0321e0SJeremy L Thompson 31539ec17dSJeremy L Thompson size_t ctxsize; 32539ec17dSJeremy L Thompson ierr = CeedQFunctionContextGetContextSize(ctx, &ctxsize); CeedChkBackend(ierr); 33539ec17dSJeremy L Thompson 340d0321e0SJeremy L Thompson if (impl->d_data_borrowed) { 350d0321e0SJeremy L Thompson impl->d_data = impl->d_data_borrowed; 360d0321e0SJeremy L Thompson } else if (impl->d_data_owned) { 370d0321e0SJeremy L Thompson impl->d_data = impl->d_data_owned; 380d0321e0SJeremy L Thompson } else { 39539ec17dSJeremy L Thompson ierr = cudaMalloc((void **)&impl->d_data_owned, ctxsize); 400d0321e0SJeremy L Thompson CeedChk_Cu(ceed, ierr); 410d0321e0SJeremy L Thompson impl->d_data = impl->d_data_owned; 420d0321e0SJeremy L Thompson } 430d0321e0SJeremy L Thompson 44539ec17dSJeremy L Thompson ierr = cudaMemcpy(impl->d_data, impl->h_data, ctxsize, 450d0321e0SJeremy L Thompson cudaMemcpyHostToDevice); CeedChk_Cu(ceed, ierr); 460d0321e0SJeremy L Thompson 470d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 480d0321e0SJeremy L Thompson } 490d0321e0SJeremy L Thompson 500d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 510d0321e0SJeremy L Thompson // Sync device to host 520d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 530d0321e0SJeremy L Thompson static inline int CeedQFunctionContextSyncD2H_Cuda( 540d0321e0SJeremy L Thompson const CeedQFunctionContext ctx) { 550d0321e0SJeremy L Thompson int ierr; 560d0321e0SJeremy L Thompson Ceed ceed; 570d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 580d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 590d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 600d0321e0SJeremy L Thompson 610d0321e0SJeremy L Thompson if (!impl->d_data) 620d0321e0SJeremy L Thompson // LCOV_EXCL_START 630d0321e0SJeremy L Thompson return CeedError(ceed, CEED_ERROR_BACKEND, 640d0321e0SJeremy L Thompson "No valid device data to sync to host"); 650d0321e0SJeremy L Thompson // LCOV_EXCL_STOP 660d0321e0SJeremy L Thompson 67539ec17dSJeremy L Thompson size_t ctxsize; 68539ec17dSJeremy L Thompson ierr = CeedQFunctionContextGetContextSize(ctx, &ctxsize); CeedChkBackend(ierr); 69539ec17dSJeremy L Thompson 700d0321e0SJeremy L Thompson if (impl->h_data_borrowed) { 710d0321e0SJeremy L Thompson impl->h_data = impl->h_data_borrowed; 720d0321e0SJeremy L Thompson } else if (impl->h_data_owned) { 730d0321e0SJeremy L Thompson impl->h_data = impl->h_data_owned; 740d0321e0SJeremy L Thompson } else { 75c470c2d9Snbeams ierr = CeedMallocArray(1, ctxsize, &impl->h_data_owned); 760d0321e0SJeremy L Thompson CeedChkBackend(ierr); 770d0321e0SJeremy L Thompson impl->h_data = impl->h_data_owned; 780d0321e0SJeremy L Thompson } 790d0321e0SJeremy L Thompson 80539ec17dSJeremy L Thompson ierr = cudaMemcpy(impl->h_data, impl->d_data, ctxsize, 810d0321e0SJeremy L Thompson cudaMemcpyDeviceToHost); CeedChk_Cu(ceed, ierr); 820d0321e0SJeremy L Thompson 830d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 840d0321e0SJeremy L Thompson } 850d0321e0SJeremy L Thompson 860d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 870d0321e0SJeremy L Thompson // Sync data of type 880d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 890d0321e0SJeremy L Thompson static inline int CeedQFunctionContextSync_Cuda( 9043c928f4SJeremy L Thompson const CeedQFunctionContext ctx, CeedMemType mem_type) { 9143c928f4SJeremy L Thompson switch (mem_type) { 920d0321e0SJeremy L Thompson case CEED_MEM_HOST: return CeedQFunctionContextSyncD2H_Cuda(ctx); 930d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: return CeedQFunctionContextSyncH2D_Cuda(ctx); 940d0321e0SJeremy L Thompson } 950d0321e0SJeremy L Thompson return CEED_ERROR_UNSUPPORTED; 960d0321e0SJeremy L Thompson } 970d0321e0SJeremy L Thompson 980d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 990d0321e0SJeremy L Thompson // Set all pointers as invalid 1000d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1010d0321e0SJeremy L Thompson static inline int CeedQFunctionContextSetAllInvalid_Cuda( 1020d0321e0SJeremy L Thompson const CeedQFunctionContext ctx) { 1030d0321e0SJeremy L Thompson int ierr; 1040d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 1050d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 1060d0321e0SJeremy L Thompson 1070d0321e0SJeremy L Thompson impl->h_data = NULL; 1080d0321e0SJeremy L Thompson impl->d_data = NULL; 1090d0321e0SJeremy L Thompson 1100d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1110d0321e0SJeremy L Thompson } 1120d0321e0SJeremy L Thompson 1130d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1140d0321e0SJeremy L Thompson // Check if ctx has valid data 1150d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1160d0321e0SJeremy L Thompson static inline int CeedQFunctionContextHasValidData_Cuda( 1170d0321e0SJeremy L Thompson const CeedQFunctionContext ctx, bool *has_valid_data) { 1180d0321e0SJeremy L Thompson int ierr; 1190d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 1200d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 1210d0321e0SJeremy L Thompson 122*52b3e6a7SJed Brown *has_valid_data = impl && (!!impl->h_data || !!impl->d_data); 1230d0321e0SJeremy L Thompson 1240d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1250d0321e0SJeremy L Thompson } 1260d0321e0SJeremy L Thompson 1270d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1280d0321e0SJeremy L Thompson // Check if ctx has borrowed data 1290d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1300d0321e0SJeremy L Thompson static inline int CeedQFunctionContextHasBorrowedDataOfType_Cuda( 13143c928f4SJeremy L Thompson const CeedQFunctionContext ctx, CeedMemType mem_type, 1320d0321e0SJeremy L Thompson bool *has_borrowed_data_of_type) { 1330d0321e0SJeremy L Thompson int ierr; 1340d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 1350d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 1360d0321e0SJeremy L Thompson 13743c928f4SJeremy L Thompson switch (mem_type) { 1380d0321e0SJeremy L Thompson case CEED_MEM_HOST: 1390d0321e0SJeremy L Thompson *has_borrowed_data_of_type = !!impl->h_data_borrowed; 1400d0321e0SJeremy L Thompson break; 1410d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 1420d0321e0SJeremy L Thompson *has_borrowed_data_of_type = !!impl->d_data_borrowed; 1430d0321e0SJeremy L Thompson break; 1440d0321e0SJeremy L Thompson } 1450d0321e0SJeremy L Thompson 1460d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1470d0321e0SJeremy L Thompson } 1480d0321e0SJeremy L Thompson 1490d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1500d0321e0SJeremy L Thompson // Check if data of given type needs sync 1510d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1520d0321e0SJeremy L Thompson static inline int CeedQFunctionContextNeedSync_Cuda( 15343c928f4SJeremy L Thompson const CeedQFunctionContext ctx, CeedMemType mem_type, bool *need_sync) { 1540d0321e0SJeremy L Thompson int ierr; 1550d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 1560d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 1570d0321e0SJeremy L Thompson 1580d0321e0SJeremy L Thompson bool has_valid_data = true; 1590d0321e0SJeremy L Thompson ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); 1600d0321e0SJeremy L Thompson CeedChkBackend(ierr); 16143c928f4SJeremy L Thompson switch (mem_type) { 1620d0321e0SJeremy L Thompson case CEED_MEM_HOST: 1630d0321e0SJeremy L Thompson *need_sync = has_valid_data && !impl->h_data; 1640d0321e0SJeremy L Thompson break; 1650d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 1660d0321e0SJeremy L Thompson *need_sync = has_valid_data && !impl->d_data; 1670d0321e0SJeremy L Thompson break; 1680d0321e0SJeremy L Thompson } 1690d0321e0SJeremy L Thompson 1700d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1710d0321e0SJeremy L Thompson } 1720d0321e0SJeremy L Thompson 1730d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1740d0321e0SJeremy L Thompson // Set data from host 1750d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 1760d0321e0SJeremy L Thompson static int CeedQFunctionContextSetDataHost_Cuda(const CeedQFunctionContext ctx, 17743c928f4SJeremy L Thompson const CeedCopyMode copy_mode, void *data) { 1780d0321e0SJeremy L Thompson int ierr; 1790d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 1800d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 1810d0321e0SJeremy L Thompson 1820d0321e0SJeremy L Thompson ierr = CeedFree(&impl->h_data_owned); CeedChkBackend(ierr); 18343c928f4SJeremy L Thompson switch (copy_mode) { 1840d0321e0SJeremy L Thompson case CEED_COPY_VALUES: { 185539ec17dSJeremy L Thompson size_t ctxsize; 186539ec17dSJeremy L Thompson ierr = CeedQFunctionContextGetContextSize(ctx, &ctxsize); CeedChkBackend(ierr); 187c470c2d9Snbeams ierr = CeedMallocArray(1, ctxsize, &impl->h_data_owned); 188c470c2d9Snbeams CeedChkBackend(ierr); 1890d0321e0SJeremy L Thompson impl->h_data_borrowed = NULL; 1900d0321e0SJeremy L Thompson impl->h_data = impl->h_data_owned; 191539ec17dSJeremy L Thompson memcpy(impl->h_data, data, ctxsize); 1920d0321e0SJeremy L Thompson } break; 1930d0321e0SJeremy L Thompson case CEED_OWN_POINTER: 1940d0321e0SJeremy L Thompson impl->h_data_owned = data; 1950d0321e0SJeremy L Thompson impl->h_data_borrowed = NULL; 1960d0321e0SJeremy L Thompson impl->h_data = data; 1970d0321e0SJeremy L Thompson break; 1980d0321e0SJeremy L Thompson case CEED_USE_POINTER: 1990d0321e0SJeremy L Thompson impl->h_data_borrowed = data; 2000d0321e0SJeremy L Thompson impl->h_data = data; 2010d0321e0SJeremy L Thompson break; 2020d0321e0SJeremy L Thompson } 2030d0321e0SJeremy L Thompson 2040d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2050d0321e0SJeremy L Thompson } 2060d0321e0SJeremy L Thompson 2070d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2080d0321e0SJeremy L Thompson // Set data from device 2090d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2100d0321e0SJeremy L Thompson static int CeedQFunctionContextSetDataDevice_Cuda( 21143c928f4SJeremy L Thompson const CeedQFunctionContext ctx, const CeedCopyMode copy_mode, void *data) { 2120d0321e0SJeremy L Thompson int ierr; 2130d0321e0SJeremy L Thompson Ceed ceed; 2140d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 2150d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 2160d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 2170d0321e0SJeremy L Thompson 2180d0321e0SJeremy L Thompson ierr = cudaFree(impl->d_data_owned); CeedChk_Cu(ceed, ierr); 2190d0321e0SJeremy L Thompson impl->d_data_owned = NULL; 22043c928f4SJeremy L Thompson switch (copy_mode) { 221539ec17dSJeremy L Thompson case CEED_COPY_VALUES: { 222539ec17dSJeremy L Thompson size_t ctxsize; 223539ec17dSJeremy L Thompson ierr = CeedQFunctionContextGetContextSize(ctx, &ctxsize); CeedChkBackend(ierr); 224539ec17dSJeremy L Thompson ierr = cudaMalloc((void **)&impl->d_data_owned, ctxsize); 2250d0321e0SJeremy L Thompson CeedChk_Cu(ceed, ierr); 2260d0321e0SJeremy L Thompson impl->d_data_borrowed = NULL; 2270d0321e0SJeremy L Thompson impl->d_data = impl->d_data_owned; 228539ec17dSJeremy L Thompson ierr = cudaMemcpy(impl->d_data, data, ctxsize, 2290d0321e0SJeremy L Thompson cudaMemcpyDeviceToDevice); CeedChk_Cu(ceed, ierr); 230539ec17dSJeremy L Thompson } break; 2310d0321e0SJeremy L Thompson case CEED_OWN_POINTER: 2320d0321e0SJeremy L Thompson impl->d_data_owned = data; 2330d0321e0SJeremy L Thompson impl->d_data_borrowed = NULL; 2340d0321e0SJeremy L Thompson impl->d_data = data; 2350d0321e0SJeremy L Thompson break; 2360d0321e0SJeremy L Thompson case CEED_USE_POINTER: 2370d0321e0SJeremy L Thompson impl->d_data_owned = NULL; 2380d0321e0SJeremy L Thompson impl->d_data_borrowed = data; 2390d0321e0SJeremy L Thompson impl->d_data = data; 2400d0321e0SJeremy L Thompson break; 2410d0321e0SJeremy L Thompson } 2420d0321e0SJeremy L Thompson 2430d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 2440d0321e0SJeremy L Thompson } 2450d0321e0SJeremy L Thompson 2460d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2470d0321e0SJeremy L Thompson // Set the data used by a user context, 2480d0321e0SJeremy L Thompson // freeing any previously allocated data if applicable 2490d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2500d0321e0SJeremy L Thompson static int CeedQFunctionContextSetData_Cuda(const CeedQFunctionContext ctx, 25143c928f4SJeremy L Thompson const CeedMemType mem_type, const CeedCopyMode copy_mode, void *data) { 2520d0321e0SJeremy L Thompson int ierr; 2530d0321e0SJeremy L Thompson Ceed ceed; 2540d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 2550d0321e0SJeremy L Thompson 2560d0321e0SJeremy L Thompson ierr = CeedQFunctionContextSetAllInvalid_Cuda(ctx); CeedChkBackend(ierr); 25743c928f4SJeremy L Thompson switch (mem_type) { 2580d0321e0SJeremy L Thompson case CEED_MEM_HOST: 25943c928f4SJeremy L Thompson return CeedQFunctionContextSetDataHost_Cuda(ctx, copy_mode, data); 2600d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 26143c928f4SJeremy L Thompson return CeedQFunctionContextSetDataDevice_Cuda(ctx, copy_mode, data); 2620d0321e0SJeremy L Thompson } 2630d0321e0SJeremy L Thompson 2640d0321e0SJeremy L Thompson return CEED_ERROR_UNSUPPORTED; 2650d0321e0SJeremy L Thompson } 2660d0321e0SJeremy L Thompson 2670d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2680d0321e0SJeremy L Thompson // Take data 2690d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 2700d0321e0SJeremy L Thompson static int CeedQFunctionContextTakeData_Cuda(const CeedQFunctionContext ctx, 27143c928f4SJeremy L Thompson const CeedMemType mem_type, void *data) { 2720d0321e0SJeremy L Thompson int ierr; 2730d0321e0SJeremy L Thompson Ceed ceed; 2740d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 2750d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 2760d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 2770d0321e0SJeremy L Thompson 27843c928f4SJeremy L Thompson // Sync data to requested mem_type 2790d0321e0SJeremy L Thompson bool need_sync = false; 28043c928f4SJeremy L Thompson ierr = CeedQFunctionContextNeedSync_Cuda(ctx, mem_type, &need_sync); 2810d0321e0SJeremy L Thompson CeedChkBackend(ierr); 2820d0321e0SJeremy L Thompson if (need_sync) { 28343c928f4SJeremy L Thompson ierr = CeedQFunctionContextSync_Cuda(ctx, mem_type); CeedChkBackend(ierr); 2840d0321e0SJeremy L Thompson } 2850d0321e0SJeremy L Thompson 2860d0321e0SJeremy L Thompson // Update pointer 28743c928f4SJeremy L Thompson switch (mem_type) { 2880d0321e0SJeremy L Thompson case CEED_MEM_HOST: 2890d0321e0SJeremy L Thompson *(void **)data = impl->h_data_borrowed; 2900d0321e0SJeremy L Thompson impl->h_data_borrowed = NULL; 2910d0321e0SJeremy L Thompson impl->h_data = NULL; 2920d0321e0SJeremy L Thompson break; 2930d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 2940d0321e0SJeremy L Thompson *(void **)data = impl->d_data_borrowed; 2950d0321e0SJeremy L Thompson impl->d_data_borrowed = NULL; 2960d0321e0SJeremy L Thompson impl->d_data = NULL; 2970d0321e0SJeremy L Thompson break; 2980d0321e0SJeremy L Thompson } 2990d0321e0SJeremy L Thompson 3000d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3010d0321e0SJeremy L Thompson } 3020d0321e0SJeremy L Thompson 3030d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 30428bfd0b7SJeremy L Thompson // Core logic for GetData. 30528bfd0b7SJeremy L Thompson // If a different memory type is most up to date, this will perform a copy 3060d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 30728bfd0b7SJeremy L Thompson static int CeedQFunctionContextGetDataCore_Cuda(const CeedQFunctionContext ctx, 30843c928f4SJeremy L Thompson const CeedMemType mem_type, void *data) { 3090d0321e0SJeremy L Thompson int ierr; 3100d0321e0SJeremy L Thompson Ceed ceed; 3110d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 3120d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 3130d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 3140d0321e0SJeremy L Thompson 31543c928f4SJeremy L Thompson // Sync data to requested mem_type 3160d0321e0SJeremy L Thompson bool need_sync = false; 31743c928f4SJeremy L Thompson ierr = CeedQFunctionContextNeedSync_Cuda(ctx, mem_type, &need_sync); 3180d0321e0SJeremy L Thompson CeedChkBackend(ierr); 3190d0321e0SJeremy L Thompson if (need_sync) { 32043c928f4SJeremy L Thompson ierr = CeedQFunctionContextSync_Cuda(ctx, mem_type); CeedChkBackend(ierr); 3210d0321e0SJeremy L Thompson } 3220d0321e0SJeremy L Thompson 3230d0321e0SJeremy L Thompson // Update pointer 32443c928f4SJeremy L Thompson switch (mem_type) { 3250d0321e0SJeremy L Thompson case CEED_MEM_HOST: 3260d0321e0SJeremy L Thompson *(void **)data = impl->h_data; 3270d0321e0SJeremy L Thompson break; 3280d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 3290d0321e0SJeremy L Thompson *(void **)data = impl->d_data; 3300d0321e0SJeremy L Thompson break; 3310d0321e0SJeremy L Thompson } 3320d0321e0SJeremy L Thompson 33328bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 33428bfd0b7SJeremy L Thompson } 33528bfd0b7SJeremy L Thompson 33628bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------ 33728bfd0b7SJeremy L Thompson // Get read-only access to the data 33828bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------ 33928bfd0b7SJeremy L Thompson static int CeedQFunctionContextGetDataRead_Cuda(const CeedQFunctionContext ctx, 34028bfd0b7SJeremy L Thompson const CeedMemType mem_type, void *data) { 34128bfd0b7SJeremy L Thompson return CeedQFunctionContextGetDataCore_Cuda(ctx, mem_type, data); 34228bfd0b7SJeremy L Thompson } 34328bfd0b7SJeremy L Thompson 34428bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------ 34528bfd0b7SJeremy L Thompson // Get read/write access to the data 34628bfd0b7SJeremy L Thompson //------------------------------------------------------------------------------ 34728bfd0b7SJeremy L Thompson static int CeedQFunctionContextGetData_Cuda(const CeedQFunctionContext ctx, 34828bfd0b7SJeremy L Thompson const CeedMemType mem_type, void *data) { 34928bfd0b7SJeremy L Thompson int ierr; 35028bfd0b7SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 35128bfd0b7SJeremy L Thompson ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 35228bfd0b7SJeremy L Thompson 35328bfd0b7SJeremy L Thompson ierr = CeedQFunctionContextGetDataCore_Cuda(ctx, mem_type, data); 35428bfd0b7SJeremy L Thompson CeedChkBackend(ierr); 35528bfd0b7SJeremy L Thompson 3560d0321e0SJeremy L Thompson // Mark only pointer for requested memory as valid 3570d0321e0SJeremy L Thompson ierr = CeedQFunctionContextSetAllInvalid_Cuda(ctx); CeedChkBackend(ierr); 35843c928f4SJeremy L Thompson switch (mem_type) { 3590d0321e0SJeremy L Thompson case CEED_MEM_HOST: 3600d0321e0SJeremy L Thompson impl->h_data = *(void **)data; 3610d0321e0SJeremy L Thompson break; 3620d0321e0SJeremy L Thompson case CEED_MEM_DEVICE: 3630d0321e0SJeremy L Thompson impl->d_data = *(void **)data; 3640d0321e0SJeremy L Thompson break; 3650d0321e0SJeremy L Thompson } 3660d0321e0SJeremy L Thompson 3670d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3680d0321e0SJeremy L Thompson } 3690d0321e0SJeremy L Thompson 3700d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3710d0321e0SJeremy L Thompson // Destroy the user context 3720d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3730d0321e0SJeremy L Thompson static int CeedQFunctionContextDestroy_Cuda(const CeedQFunctionContext ctx) { 3740d0321e0SJeremy L Thompson int ierr; 3750d0321e0SJeremy L Thompson Ceed ceed; 3760d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 3770d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 3780d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetBackendData(ctx, &impl); CeedChkBackend(ierr); 3790d0321e0SJeremy L Thompson 3800d0321e0SJeremy L Thompson ierr = cudaFree(impl->d_data_owned); CeedChk_Cu(ceed, ierr); 3810d0321e0SJeremy L Thompson ierr = CeedFree(&impl->h_data_owned); CeedChkBackend(ierr); 3820d0321e0SJeremy L Thompson ierr = CeedFree(&impl); CeedChkBackend(ierr); 3830d0321e0SJeremy L Thompson 3840d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 3850d0321e0SJeremy L Thompson } 3860d0321e0SJeremy L Thompson 3870d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3880d0321e0SJeremy L Thompson // QFunctionContext Create 3890d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 3900d0321e0SJeremy L Thompson int CeedQFunctionContextCreate_Cuda(CeedQFunctionContext ctx) { 3910d0321e0SJeremy L Thompson int ierr; 3920d0321e0SJeremy L Thompson CeedQFunctionContext_Cuda *impl; 3930d0321e0SJeremy L Thompson Ceed ceed; 3940d0321e0SJeremy L Thompson ierr = CeedQFunctionContextGetCeed(ctx, &ceed); CeedChkBackend(ierr); 3950d0321e0SJeremy L Thompson 3960d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "HasValidData", 3970d0321e0SJeremy L Thompson CeedQFunctionContextHasValidData_Cuda); 3980d0321e0SJeremy L Thompson CeedChkBackend(ierr); 3990d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, 4000d0321e0SJeremy L Thompson "HasBorrowedDataOfType", 4010d0321e0SJeremy L Thompson CeedQFunctionContextHasBorrowedDataOfType_Cuda); 4020d0321e0SJeremy L Thompson CeedChkBackend(ierr); 4030d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "SetData", 4040d0321e0SJeremy L Thompson CeedQFunctionContextSetData_Cuda); CeedChkBackend(ierr); 4050d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "TakeData", 4060d0321e0SJeremy L Thompson CeedQFunctionContextTakeData_Cuda); CeedChkBackend(ierr); 4070d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetData", 4080d0321e0SJeremy L Thompson CeedQFunctionContextGetData_Cuda); CeedChkBackend(ierr); 40928bfd0b7SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "GetDataRead", 41028bfd0b7SJeremy L Thompson CeedQFunctionContextGetDataRead_Cuda); CeedChkBackend(ierr); 4110d0321e0SJeremy L Thompson ierr = CeedSetBackendFunction(ceed, "QFunctionContext", ctx, "Destroy", 4120d0321e0SJeremy L Thompson CeedQFunctionContextDestroy_Cuda); CeedChkBackend(ierr); 4130d0321e0SJeremy L Thompson 4140d0321e0SJeremy L Thompson ierr = CeedCalloc(1, &impl); CeedChkBackend(ierr); 4150d0321e0SJeremy L Thompson ierr = CeedQFunctionContextSetBackendData(ctx, impl); CeedChkBackend(ierr); 4160d0321e0SJeremy L Thompson 4170d0321e0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4180d0321e0SJeremy L Thompson } 4190d0321e0SJeremy L Thompson //------------------------------------------------------------------------------ 420