1ff1e7120SSebastian Grimberg // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 2ff1e7120SSebastian Grimberg // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3ff1e7120SSebastian Grimberg // 4ff1e7120SSebastian Grimberg // SPDX-License-Identifier: BSD-2-Clause 5ff1e7120SSebastian Grimberg // 6ff1e7120SSebastian Grimberg // This file is part of CEED: http://github.com/ceed 7ff1e7120SSebastian Grimberg 8ff1e7120SSebastian Grimberg #include <ceed.h> 9ff1e7120SSebastian Grimberg #include <ceed/backend.h> 10ff1e7120SSebastian Grimberg #include <ceed/jit-tools.h> 11ff1e7120SSebastian Grimberg #include <cuda.h> 12ff1e7120SSebastian Grimberg #include <cuda_runtime.h> 13ff1e7120SSebastian Grimberg #include <stdbool.h> 14ff1e7120SSebastian Grimberg #include <stddef.h> 15ff1e7120SSebastian Grimberg #include <string.h> 16ff1e7120SSebastian Grimberg 17ff1e7120SSebastian Grimberg #include "../cuda/ceed-cuda-common.h" 18ff1e7120SSebastian Grimberg #include "../cuda/ceed-cuda-compile.h" 19ff1e7120SSebastian Grimberg #include "ceed-cuda-ref.h" 20ff1e7120SSebastian Grimberg 21ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 22cf8cbdd6SSebastian Grimberg // Compile restriction kernels 23cf8cbdd6SSebastian Grimberg //------------------------------------------------------------------------------ 24cf8cbdd6SSebastian Grimberg static inline int CeedElemRestrictionSetupCompile_Cuda(CeedElemRestriction rstr) { 25cf8cbdd6SSebastian Grimberg Ceed ceed; 26cf8cbdd6SSebastian Grimberg bool is_deterministic; 27cf8cbdd6SSebastian Grimberg CeedInt num_elem, num_comp, elem_size, comp_stride; 28cf8cbdd6SSebastian Grimberg CeedRestrictionType rstr_type; 29cf8cbdd6SSebastian Grimberg char *restriction_kernel_path, *restriction_kernel_source; 30cf8cbdd6SSebastian Grimberg CeedElemRestriction_Cuda *impl; 31cf8cbdd6SSebastian Grimberg 32cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 33cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 34cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 35cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 36cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 37cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCompStride(rstr, &comp_stride)); 38cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetType(rstr, &rstr_type)); 39cf8cbdd6SSebastian Grimberg is_deterministic = impl->d_l_vec_indices != NULL; 40cf8cbdd6SSebastian Grimberg 41cf8cbdd6SSebastian Grimberg // Compile CUDA kernels 42cf8cbdd6SSebastian Grimberg switch (rstr_type) { 43cf8cbdd6SSebastian Grimberg case CEED_RESTRICTION_STRIDED: { 44cf8cbdd6SSebastian Grimberg CeedInt strides[3] = {1, num_elem * elem_size, elem_size}; 45cf8cbdd6SSebastian Grimberg bool has_backend_strides; 46cf8cbdd6SSebastian Grimberg 47cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionHasBackendStrides(rstr, &has_backend_strides)); 48cf8cbdd6SSebastian Grimberg if (!has_backend_strides) { 49*56c48462SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetStrides(rstr, strides)); 50cf8cbdd6SSebastian Grimberg } 51cf8cbdd6SSebastian Grimberg 52cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetJitAbsolutePath(ceed, "ceed/jit-source/cuda/cuda-ref-restriction-strided.h", &restriction_kernel_path)); 53cf8cbdd6SSebastian Grimberg CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "----- Loading Restriction Kernel Source -----\n"); 54cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedLoadSourceToBuffer(ceed, restriction_kernel_path, &restriction_kernel_source)); 55cf8cbdd6SSebastian Grimberg CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "----- Loading Restriction Kernel Source Complete! -----\n"); 56cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedCompile_Cuda(ceed, restriction_kernel_source, &impl->module, 6, "RSTR_ELEM_SIZE", elem_size, "RSTR_NUM_ELEM", num_elem, 57cf8cbdd6SSebastian Grimberg "RSTR_NUM_COMP", num_comp, "RSTR_STRIDE_NODES", strides[0], "RSTR_STRIDE_COMP", strides[1], "RSTR_STRIDE_ELEM", 58cf8cbdd6SSebastian Grimberg strides[2])); 59cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "StridedNoTranspose", &impl->ApplyNoTranspose)); 60cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "StridedTranspose", &impl->ApplyTranspose)); 61cf8cbdd6SSebastian Grimberg } break; 62cf8cbdd6SSebastian Grimberg case CEED_RESTRICTION_STANDARD: { 63cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetJitAbsolutePath(ceed, "ceed/jit-source/cuda/cuda-ref-restriction-offset.h", &restriction_kernel_path)); 64cf8cbdd6SSebastian Grimberg CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "----- Loading Restriction Kernel Source -----\n"); 65cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedLoadSourceToBuffer(ceed, restriction_kernel_path, &restriction_kernel_source)); 66cf8cbdd6SSebastian Grimberg CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "----- Loading Restriction Kernel Source Complete! -----\n"); 67cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedCompile_Cuda(ceed, restriction_kernel_source, &impl->module, 6, "RSTR_ELEM_SIZE", elem_size, "RSTR_NUM_ELEM", num_elem, 68cf8cbdd6SSebastian Grimberg "RSTR_NUM_COMP", num_comp, "RSTR_NUM_NODES", impl->num_nodes, "RSTR_COMP_STRIDE", comp_stride, 69cf8cbdd6SSebastian Grimberg "USE_DETERMINISTIC", is_deterministic ? 1 : 0)); 70cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetNoTranspose", &impl->ApplyNoTranspose)); 71cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetTranspose", &impl->ApplyTranspose)); 72cf8cbdd6SSebastian Grimberg } break; 73cf8cbdd6SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: { 74cf8cbdd6SSebastian Grimberg char *offset_kernel_path; 75cf8cbdd6SSebastian Grimberg 76cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetJitAbsolutePath(ceed, "ceed/jit-source/cuda/cuda-ref-restriction-oriented.h", &restriction_kernel_path)); 77cf8cbdd6SSebastian Grimberg CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "----- Loading Restriction Kernel Source -----\n"); 78cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedLoadSourceToBuffer(ceed, restriction_kernel_path, &restriction_kernel_source)); 79cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetJitAbsolutePath(ceed, "ceed/jit-source/cuda/cuda-ref-restriction-offset.h", &offset_kernel_path)); 80cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedLoadSourceToInitializedBuffer(ceed, offset_kernel_path, &restriction_kernel_source)); 81cf8cbdd6SSebastian Grimberg CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "----- Loading Restriction Kernel Source Complete! -----\n"); 82cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedCompile_Cuda(ceed, restriction_kernel_source, &impl->module, 6, "RSTR_ELEM_SIZE", elem_size, "RSTR_NUM_ELEM", num_elem, 83cf8cbdd6SSebastian Grimberg "RSTR_NUM_COMP", num_comp, "RSTR_NUM_NODES", impl->num_nodes, "RSTR_COMP_STRIDE", comp_stride, 84cf8cbdd6SSebastian Grimberg "USE_DETERMINISTIC", is_deterministic ? 1 : 0)); 85cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OrientedNoTranspose", &impl->ApplyNoTranspose)); 86cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetNoTranspose", &impl->ApplyUnsignedNoTranspose)); 87cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OrientedTranspose", &impl->ApplyTranspose)); 88cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetTranspose", &impl->ApplyUnsignedTranspose)); 89cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedFree(&offset_kernel_path)); 90cf8cbdd6SSebastian Grimberg } break; 91cf8cbdd6SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: { 92cf8cbdd6SSebastian Grimberg char *offset_kernel_path; 93cf8cbdd6SSebastian Grimberg 94cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetJitAbsolutePath(ceed, "ceed/jit-source/cuda/cuda-ref-restriction-curl-oriented.h", &restriction_kernel_path)); 95cf8cbdd6SSebastian Grimberg CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "----- Loading Restriction Kernel Source -----\n"); 96cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedLoadSourceToBuffer(ceed, restriction_kernel_path, &restriction_kernel_source)); 97cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetJitAbsolutePath(ceed, "ceed/jit-source/cuda/cuda-ref-restriction-offset.h", &offset_kernel_path)); 98cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedLoadSourceToInitializedBuffer(ceed, offset_kernel_path, &restriction_kernel_source)); 99cf8cbdd6SSebastian Grimberg CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "----- Loading Restriction Kernel Source Complete! -----\n"); 100cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedCompile_Cuda(ceed, restriction_kernel_source, &impl->module, 6, "RSTR_ELEM_SIZE", elem_size, "RSTR_NUM_ELEM", num_elem, 101cf8cbdd6SSebastian Grimberg "RSTR_NUM_COMP", num_comp, "RSTR_NUM_NODES", impl->num_nodes, "RSTR_COMP_STRIDE", comp_stride, 102cf8cbdd6SSebastian Grimberg "USE_DETERMINISTIC", is_deterministic ? 1 : 0)); 103cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "CurlOrientedNoTranspose", &impl->ApplyNoTranspose)); 104cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "CurlOrientedUnsignedNoTranspose", &impl->ApplyUnsignedNoTranspose)); 105cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetNoTranspose", &impl->ApplyUnorientedNoTranspose)); 106cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "CurlOrientedTranspose", &impl->ApplyTranspose)); 107cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "CurlOrientedUnsignedTranspose", &impl->ApplyUnsignedTranspose)); 108cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetTranspose", &impl->ApplyUnorientedTranspose)); 109cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedFree(&offset_kernel_path)); 110cf8cbdd6SSebastian Grimberg } break; 111cf8cbdd6SSebastian Grimberg case CEED_RESTRICTION_POINTS: { 112cf8cbdd6SSebastian Grimberg // LCOV_EXCL_START 113cf8cbdd6SSebastian Grimberg return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement restriction CeedElemRestrictionAtPoints"); 114cf8cbdd6SSebastian Grimberg // LCOV_EXCL_STOP 115cf8cbdd6SSebastian Grimberg } break; 116cf8cbdd6SSebastian Grimberg } 117cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedFree(&restriction_kernel_path)); 118cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedFree(&restriction_kernel_source)); 119cf8cbdd6SSebastian Grimberg return CEED_ERROR_SUCCESS; 120cf8cbdd6SSebastian Grimberg } 121cf8cbdd6SSebastian Grimberg 122cf8cbdd6SSebastian Grimberg //------------------------------------------------------------------------------ 123dce49693SSebastian Grimberg // Core apply restriction code 124ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 125dce49693SSebastian Grimberg static inline int CeedElemRestrictionApply_Cuda_Core(CeedElemRestriction rstr, CeedTransposeMode t_mode, bool use_signs, bool use_orients, 126dce49693SSebastian Grimberg CeedVector u, CeedVector v, CeedRequest *request) { 127ff1e7120SSebastian Grimberg Ceed ceed; 128dce49693SSebastian Grimberg CeedRestrictionType rstr_type; 129ff1e7120SSebastian Grimberg const CeedScalar *d_u; 130ff1e7120SSebastian Grimberg CeedScalar *d_v; 131ca735530SJeremy L Thompson CeedElemRestriction_Cuda *impl; 132ca735530SJeremy L Thompson 133dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 134dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 135dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetType(rstr, &rstr_type)); 136cf8cbdd6SSebastian Grimberg 137cf8cbdd6SSebastian Grimberg // Assemble kernel if needed 138cf8cbdd6SSebastian Grimberg if (!impl->module) { 139cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionSetupCompile_Cuda(rstr)); 140cf8cbdd6SSebastian Grimberg } 141ca735530SJeremy L Thompson 142ca735530SJeremy L Thompson // Get vectors 143ff1e7120SSebastian Grimberg CeedCallBackend(CeedVectorGetArrayRead(u, CEED_MEM_DEVICE, &d_u)); 144ff1e7120SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 145ff1e7120SSebastian Grimberg // Sum into for transpose mode, e-vec to l-vec 146ff1e7120SSebastian Grimberg CeedCallBackend(CeedVectorGetArray(v, CEED_MEM_DEVICE, &d_v)); 147ff1e7120SSebastian Grimberg } else { 148ff1e7120SSebastian Grimberg // Overwrite for notranspose mode, l-vec to e-vec 149ff1e7120SSebastian Grimberg CeedCallBackend(CeedVectorGetArrayWrite(v, CEED_MEM_DEVICE, &d_v)); 150ff1e7120SSebastian Grimberg } 151ff1e7120SSebastian Grimberg 152ff1e7120SSebastian Grimberg // Restrict 153ff1e7120SSebastian Grimberg if (t_mode == CEED_NOTRANSPOSE) { 154ff1e7120SSebastian Grimberg // L-vector -> E-vector 155cf8cbdd6SSebastian Grimberg CeedInt elem_size; 156cf8cbdd6SSebastian Grimberg 157cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 158dce49693SSebastian Grimberg const CeedInt block_size = elem_size < 1024 ? (elem_size > 32 ? elem_size : 32) : 1024; 159cf8cbdd6SSebastian Grimberg const CeedInt grid = CeedDivUpInt(impl->num_nodes, block_size); 16058549094SSebastian Grimberg 161dce49693SSebastian Grimberg switch (rstr_type) { 162dce49693SSebastian Grimberg case CEED_RESTRICTION_STRIDED: { 163cf8cbdd6SSebastian Grimberg void *args[] = {&d_u, &d_v}; 16458549094SSebastian Grimberg 165cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyNoTranspose, grid, block_size, args)); 166dce49693SSebastian Grimberg } break; 167dce49693SSebastian Grimberg case CEED_RESTRICTION_STANDARD: { 168cf8cbdd6SSebastian Grimberg void *args[] = {&impl->d_ind, &d_u, &d_v}; 169dce49693SSebastian Grimberg 170cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyNoTranspose, grid, block_size, args)); 171dce49693SSebastian Grimberg } break; 172dce49693SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: { 173dce49693SSebastian Grimberg if (use_signs) { 174cf8cbdd6SSebastian Grimberg void *args[] = {&impl->d_ind, &impl->d_orients, &d_u, &d_v}; 175dce49693SSebastian Grimberg 176cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyNoTranspose, grid, block_size, args)); 177dce49693SSebastian Grimberg } else { 178cf8cbdd6SSebastian Grimberg void *args[] = {&impl->d_ind, &d_u, &d_v}; 179dce49693SSebastian Grimberg 180cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnsignedNoTranspose, grid, block_size, args)); 181dce49693SSebastian Grimberg } 182dce49693SSebastian Grimberg } break; 183dce49693SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: { 184dce49693SSebastian Grimberg if (use_signs && use_orients) { 185cf8cbdd6SSebastian Grimberg void *args[] = {&impl->d_ind, &impl->d_curl_orients, &d_u, &d_v}; 186dce49693SSebastian Grimberg 187cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyNoTranspose, grid, block_size, args)); 188dce49693SSebastian Grimberg } else if (use_orients) { 189cf8cbdd6SSebastian Grimberg void *args[] = {&impl->d_ind, &impl->d_curl_orients, &d_u, &d_v}; 190dce49693SSebastian Grimberg 191cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnsignedNoTranspose, grid, block_size, args)); 192dce49693SSebastian Grimberg } else { 193cf8cbdd6SSebastian Grimberg void *args[] = {&impl->d_ind, &d_u, &d_v}; 194dce49693SSebastian Grimberg 195cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnorientedNoTranspose, grid, block_size, args)); 196dce49693SSebastian Grimberg } 197dce49693SSebastian Grimberg } break; 198b3d03e38SSebastian Grimberg case CEED_RESTRICTION_POINTS: { 199b3d03e38SSebastian Grimberg // LCOV_EXCL_START 200b3d03e38SSebastian Grimberg return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement restriction CeedElemRestrictionAtPoints"); 201b3d03e38SSebastian Grimberg // LCOV_EXCL_STOP 202b3d03e38SSebastian Grimberg } break; 203ff1e7120SSebastian Grimberg } 204ff1e7120SSebastian Grimberg } else { 205ff1e7120SSebastian Grimberg // E-vector -> L-vector 206cf8cbdd6SSebastian Grimberg const bool is_deterministic = impl->d_l_vec_indices != NULL; 207dce49693SSebastian Grimberg const CeedInt block_size = 32; 208cf8cbdd6SSebastian Grimberg const CeedInt grid = CeedDivUpInt(impl->num_nodes, block_size); 209ca735530SJeremy L Thompson 210dce49693SSebastian Grimberg switch (rstr_type) { 211dce49693SSebastian Grimberg case CEED_RESTRICTION_STRIDED: { 212cf8cbdd6SSebastian Grimberg void *args[] = {&d_u, &d_v}; 213dce49693SSebastian Grimberg 214cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 215dce49693SSebastian Grimberg } break; 216dce49693SSebastian Grimberg case CEED_RESTRICTION_STANDARD: { 217cf8cbdd6SSebastian Grimberg if (!is_deterministic) { 218cf8cbdd6SSebastian Grimberg void *args[] = {&impl->d_ind, &d_u, &d_v}; 21958549094SSebastian Grimberg 220cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 221ff1e7120SSebastian Grimberg } else { 22258549094SSebastian Grimberg void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &d_u, &d_v}; 22358549094SSebastian Grimberg 224cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 22558549094SSebastian Grimberg } 226dce49693SSebastian Grimberg } break; 227dce49693SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: { 228dce49693SSebastian Grimberg if (use_signs) { 229cf8cbdd6SSebastian Grimberg if (!is_deterministic) { 230cf8cbdd6SSebastian Grimberg void *args[] = {&impl->d_ind, &impl->d_orients, &d_u, &d_v}; 23158549094SSebastian Grimberg 232cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 233dce49693SSebastian Grimberg } else { 2347aa91133SSebastian Grimberg void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &impl->d_orients, &d_u, &d_v}; 2357aa91133SSebastian Grimberg 236cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 2377aa91133SSebastian Grimberg } 2387aa91133SSebastian Grimberg } else { 239cf8cbdd6SSebastian Grimberg if (!is_deterministic) { 240cf8cbdd6SSebastian Grimberg void *args[] = {&impl->d_ind, &d_u, &d_v}; 241dce49693SSebastian Grimberg 242cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnsignedTranspose, grid, block_size, args)); 243dce49693SSebastian Grimberg } else { 244dce49693SSebastian Grimberg void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &d_u, &d_v}; 245dce49693SSebastian Grimberg 246cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnsignedTranspose, grid, block_size, args)); 247dce49693SSebastian Grimberg } 248dce49693SSebastian Grimberg } 249dce49693SSebastian Grimberg } break; 250dce49693SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: { 251dce49693SSebastian Grimberg if (use_signs && use_orients) { 252cf8cbdd6SSebastian Grimberg if (!is_deterministic) { 253cf8cbdd6SSebastian Grimberg void *args[] = {&impl->d_ind, &impl->d_curl_orients, &d_u, &d_v}; 254dce49693SSebastian Grimberg 255cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 2567aa91133SSebastian Grimberg } else { 2577aa91133SSebastian Grimberg void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &impl->d_curl_orients, &d_u, &d_v}; 2587aa91133SSebastian Grimberg 259cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 2607aa91133SSebastian Grimberg } 261dce49693SSebastian Grimberg } else if (use_orients) { 262cf8cbdd6SSebastian Grimberg if (!is_deterministic) { 263cf8cbdd6SSebastian Grimberg void *args[] = {&impl->d_ind, &impl->d_curl_orients, &d_u, &d_v}; 264dce49693SSebastian Grimberg 265cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnsignedTranspose, grid, block_size, args)); 266dce49693SSebastian Grimberg } else { 2677aa91133SSebastian Grimberg void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &impl->d_curl_orients, &d_u, &d_v}; 2687aa91133SSebastian Grimberg 269cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnsignedTranspose, grid, block_size, args)); 2707aa91133SSebastian Grimberg } 2717aa91133SSebastian Grimberg } else { 272cf8cbdd6SSebastian Grimberg if (!is_deterministic) { 273cf8cbdd6SSebastian Grimberg void *args[] = {&impl->d_ind, &d_u, &d_v}; 274dce49693SSebastian Grimberg 275cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnorientedTranspose, grid, block_size, args)); 276dce49693SSebastian Grimberg } else { 277dce49693SSebastian Grimberg void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &d_u, &d_v}; 278dce49693SSebastian Grimberg 279cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnorientedTranspose, grid, block_size, args)); 280dce49693SSebastian Grimberg } 281dce49693SSebastian Grimberg } 282dce49693SSebastian Grimberg } break; 283b3d03e38SSebastian Grimberg case CEED_RESTRICTION_POINTS: { 284b3d03e38SSebastian Grimberg // LCOV_EXCL_START 285b3d03e38SSebastian Grimberg return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement restriction CeedElemRestrictionAtPoints"); 286b3d03e38SSebastian Grimberg // LCOV_EXCL_STOP 287b3d03e38SSebastian Grimberg } break; 288ff1e7120SSebastian Grimberg } 289ff1e7120SSebastian Grimberg } 290ff1e7120SSebastian Grimberg 291ff1e7120SSebastian Grimberg if (request != CEED_REQUEST_IMMEDIATE && request != CEED_REQUEST_ORDERED) *request = NULL; 292ff1e7120SSebastian Grimberg 293ff1e7120SSebastian Grimberg // Restore arrays 294ff1e7120SSebastian Grimberg CeedCallBackend(CeedVectorRestoreArrayRead(u, &d_u)); 295ff1e7120SSebastian Grimberg CeedCallBackend(CeedVectorRestoreArray(v, &d_v)); 296ff1e7120SSebastian Grimberg return CEED_ERROR_SUCCESS; 297ff1e7120SSebastian Grimberg } 298ff1e7120SSebastian Grimberg 299ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 300dce49693SSebastian Grimberg // Apply restriction 301dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 302dce49693SSebastian Grimberg static int CeedElemRestrictionApply_Cuda(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 303dce49693SSebastian Grimberg return CeedElemRestrictionApply_Cuda_Core(rstr, t_mode, true, true, u, v, request); 304dce49693SSebastian Grimberg } 305dce49693SSebastian Grimberg 306dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 307dce49693SSebastian Grimberg // Apply unsigned restriction 308dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 309dce49693SSebastian Grimberg static int CeedElemRestrictionApplyUnsigned_Cuda(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 310dce49693SSebastian Grimberg CeedRequest *request) { 311dce49693SSebastian Grimberg return CeedElemRestrictionApply_Cuda_Core(rstr, t_mode, false, true, u, v, request); 312dce49693SSebastian Grimberg } 313dce49693SSebastian Grimberg 314dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 315dce49693SSebastian Grimberg // Apply unoriented restriction 316dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 317dce49693SSebastian Grimberg static int CeedElemRestrictionApplyUnoriented_Cuda(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 318dce49693SSebastian Grimberg CeedRequest *request) { 319dce49693SSebastian Grimberg return CeedElemRestrictionApply_Cuda_Core(rstr, t_mode, false, false, u, v, request); 320dce49693SSebastian Grimberg } 321dce49693SSebastian Grimberg 322dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 323ff1e7120SSebastian Grimberg // Get offsets 324ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 325ff1e7120SSebastian Grimberg static int CeedElemRestrictionGetOffsets_Cuda(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 326ff1e7120SSebastian Grimberg CeedElemRestriction_Cuda *impl; 327ff1e7120SSebastian Grimberg 328ca735530SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 329ff1e7120SSebastian Grimberg switch (mem_type) { 330ff1e7120SSebastian Grimberg case CEED_MEM_HOST: 331ff1e7120SSebastian Grimberg *offsets = impl->h_ind; 332ff1e7120SSebastian Grimberg break; 333ff1e7120SSebastian Grimberg case CEED_MEM_DEVICE: 334ff1e7120SSebastian Grimberg *offsets = impl->d_ind; 335ff1e7120SSebastian Grimberg break; 336ff1e7120SSebastian Grimberg } 337ff1e7120SSebastian Grimberg return CEED_ERROR_SUCCESS; 338ff1e7120SSebastian Grimberg } 339ff1e7120SSebastian Grimberg 340ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 341dce49693SSebastian Grimberg // Get orientations 342dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 343dce49693SSebastian Grimberg static int CeedElemRestrictionGetOrientations_Cuda(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 344dce49693SSebastian Grimberg CeedElemRestriction_Cuda *impl; 345dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 346dce49693SSebastian Grimberg 347dce49693SSebastian Grimberg switch (mem_type) { 348dce49693SSebastian Grimberg case CEED_MEM_HOST: 349dce49693SSebastian Grimberg *orients = impl->h_orients; 350dce49693SSebastian Grimberg break; 351dce49693SSebastian Grimberg case CEED_MEM_DEVICE: 352dce49693SSebastian Grimberg *orients = impl->d_orients; 353dce49693SSebastian Grimberg break; 354dce49693SSebastian Grimberg } 355dce49693SSebastian Grimberg return CEED_ERROR_SUCCESS; 356dce49693SSebastian Grimberg } 357dce49693SSebastian Grimberg 358dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 359dce49693SSebastian Grimberg // Get curl-conforming orientations 360dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 361dce49693SSebastian Grimberg static int CeedElemRestrictionGetCurlOrientations_Cuda(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) { 362dce49693SSebastian Grimberg CeedElemRestriction_Cuda *impl; 363dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 364dce49693SSebastian Grimberg 365dce49693SSebastian Grimberg switch (mem_type) { 366dce49693SSebastian Grimberg case CEED_MEM_HOST: 367dce49693SSebastian Grimberg *curl_orients = impl->h_curl_orients; 368dce49693SSebastian Grimberg break; 369dce49693SSebastian Grimberg case CEED_MEM_DEVICE: 370dce49693SSebastian Grimberg *curl_orients = impl->d_curl_orients; 371dce49693SSebastian Grimberg break; 372dce49693SSebastian Grimberg } 373dce49693SSebastian Grimberg return CEED_ERROR_SUCCESS; 374dce49693SSebastian Grimberg } 375dce49693SSebastian Grimberg 376dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 377ff1e7120SSebastian Grimberg // Destroy restriction 378ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 379dce49693SSebastian Grimberg static int CeedElemRestrictionDestroy_Cuda(CeedElemRestriction rstr) { 380ff1e7120SSebastian Grimberg Ceed ceed; 381ca735530SJeremy L Thompson CeedElemRestriction_Cuda *impl; 382ca735530SJeremy L Thompson 383dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 384dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 385cf8cbdd6SSebastian Grimberg if (impl->module) { 386ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cuModuleUnload(impl->module)); 387cf8cbdd6SSebastian Grimberg } 388ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&impl->h_ind_allocated)); 389ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaFree(impl->d_ind_allocated)); 390ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaFree(impl->d_t_offsets)); 391ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaFree(impl->d_t_indices)); 392ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaFree(impl->d_l_vec_indices)); 393dce49693SSebastian Grimberg CeedCallBackend(CeedFree(&impl->h_orients_allocated)); 394dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaFree(impl->d_orients_allocated)); 395dce49693SSebastian Grimberg CeedCallBackend(CeedFree(&impl->h_curl_orients_allocated)); 396dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaFree(impl->d_curl_orients_allocated)); 397ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&impl)); 398ff1e7120SSebastian Grimberg return CEED_ERROR_SUCCESS; 399ff1e7120SSebastian Grimberg } 400ff1e7120SSebastian Grimberg 401ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 402ff1e7120SSebastian Grimberg // Create transpose offsets and indices 403ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 404dce49693SSebastian Grimberg static int CeedElemRestrictionOffset_Cuda(const CeedElemRestriction rstr, const CeedInt *indices) { 405ff1e7120SSebastian Grimberg Ceed ceed; 406ca735530SJeremy L Thompson bool *is_node; 407ff1e7120SSebastian Grimberg CeedSize l_size; 408ca735530SJeremy L Thompson CeedInt num_elem, elem_size, num_comp, num_nodes = 0; 409ca735530SJeremy L Thompson CeedInt *ind_to_offset, *l_vec_indices, *t_offsets, *t_indices; 410ca735530SJeremy L Thompson CeedElemRestriction_Cuda *impl; 411ca735530SJeremy L Thompson 412dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 413dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 414dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 415dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 416dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetLVectorSize(rstr, &l_size)); 417dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 418ca735530SJeremy L Thompson const CeedInt size_indices = num_elem * elem_size; 419ff1e7120SSebastian Grimberg 420ff1e7120SSebastian Grimberg // Count num_nodes 421ff1e7120SSebastian Grimberg CeedCallBackend(CeedCalloc(l_size, &is_node)); 422ca735530SJeremy L Thompson 423ff1e7120SSebastian Grimberg for (CeedInt i = 0; i < size_indices; i++) is_node[indices[i]] = 1; 424ff1e7120SSebastian Grimberg for (CeedInt i = 0; i < l_size; i++) num_nodes += is_node[i]; 425ff1e7120SSebastian Grimberg impl->num_nodes = num_nodes; 426ff1e7120SSebastian Grimberg 427ff1e7120SSebastian Grimberg // L-vector offsets array 428ff1e7120SSebastian Grimberg CeedCallBackend(CeedCalloc(l_size, &ind_to_offset)); 429ff1e7120SSebastian Grimberg CeedCallBackend(CeedCalloc(num_nodes, &l_vec_indices)); 430ca735530SJeremy L Thompson for (CeedInt i = 0, j = 0; i < l_size; i++) { 431ff1e7120SSebastian Grimberg if (is_node[i]) { 432ff1e7120SSebastian Grimberg l_vec_indices[j] = i; 433ff1e7120SSebastian Grimberg ind_to_offset[i] = j++; 434ff1e7120SSebastian Grimberg } 435ff1e7120SSebastian Grimberg } 436ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&is_node)); 437ff1e7120SSebastian Grimberg 438ff1e7120SSebastian Grimberg // Compute transpose offsets and indices 439ff1e7120SSebastian Grimberg const CeedInt size_offsets = num_nodes + 1; 440ca735530SJeremy L Thompson 441ff1e7120SSebastian Grimberg CeedCallBackend(CeedCalloc(size_offsets, &t_offsets)); 442ff1e7120SSebastian Grimberg CeedCallBackend(CeedMalloc(size_indices, &t_indices)); 443ff1e7120SSebastian Grimberg // Count node multiplicity 444ff1e7120SSebastian Grimberg for (CeedInt e = 0; e < num_elem; ++e) { 445ff1e7120SSebastian Grimberg for (CeedInt i = 0; i < elem_size; ++i) ++t_offsets[ind_to_offset[indices[elem_size * e + i]] + 1]; 446ff1e7120SSebastian Grimberg } 447ff1e7120SSebastian Grimberg // Convert to running sum 448ff1e7120SSebastian Grimberg for (CeedInt i = 1; i < size_offsets; ++i) t_offsets[i] += t_offsets[i - 1]; 449ff1e7120SSebastian Grimberg // List all E-vec indices associated with L-vec node 450ff1e7120SSebastian Grimberg for (CeedInt e = 0; e < num_elem; ++e) { 451ff1e7120SSebastian Grimberg for (CeedInt i = 0; i < elem_size; ++i) { 452ff1e7120SSebastian Grimberg const CeedInt lid = elem_size * e + i; 453ff1e7120SSebastian Grimberg const CeedInt gid = indices[lid]; 454ca735530SJeremy L Thompson 455ff1e7120SSebastian Grimberg t_indices[t_offsets[ind_to_offset[gid]]++] = lid; 456ff1e7120SSebastian Grimberg } 457ff1e7120SSebastian Grimberg } 458ff1e7120SSebastian Grimberg // Reset running sum 459ff1e7120SSebastian Grimberg for (int i = size_offsets - 1; i > 0; --i) t_offsets[i] = t_offsets[i - 1]; 460ff1e7120SSebastian Grimberg t_offsets[0] = 0; 461ff1e7120SSebastian Grimberg 462ff1e7120SSebastian Grimberg // Copy data to device 463ff1e7120SSebastian Grimberg // -- L-vector indices 464ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_l_vec_indices, num_nodes * sizeof(CeedInt))); 465ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMemcpy(impl->d_l_vec_indices, l_vec_indices, num_nodes * sizeof(CeedInt), cudaMemcpyHostToDevice)); 466ff1e7120SSebastian Grimberg // -- Transpose offsets 467ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_t_offsets, size_offsets * sizeof(CeedInt))); 468ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMemcpy(impl->d_t_offsets, t_offsets, size_offsets * sizeof(CeedInt), cudaMemcpyHostToDevice)); 469ff1e7120SSebastian Grimberg // -- Transpose indices 470ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_t_indices, size_indices * sizeof(CeedInt))); 471ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMemcpy(impl->d_t_indices, t_indices, size_indices * sizeof(CeedInt), cudaMemcpyHostToDevice)); 472ff1e7120SSebastian Grimberg 473ff1e7120SSebastian Grimberg // Cleanup 474ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&ind_to_offset)); 475ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&l_vec_indices)); 476ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&t_offsets)); 477ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&t_indices)); 478ff1e7120SSebastian Grimberg return CEED_ERROR_SUCCESS; 479ff1e7120SSebastian Grimberg } 480ff1e7120SSebastian Grimberg 481ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 482ff1e7120SSebastian Grimberg // Create restriction 483ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 484fcbe8c06SSebastian Grimberg int CeedElemRestrictionCreate_Cuda(CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *indices, const bool *orients, 485dce49693SSebastian Grimberg const CeedInt8 *curl_orients, CeedElemRestriction rstr) { 486ca735530SJeremy L Thompson Ceed ceed, ceed_parent; 487dce49693SSebastian Grimberg bool is_deterministic; 488cf8cbdd6SSebastian Grimberg CeedInt num_elem, elem_size; 489ca735530SJeremy L Thompson CeedRestrictionType rstr_type; 490ff1e7120SSebastian Grimberg CeedElemRestriction_Cuda *impl; 491ca735530SJeremy L Thompson 492dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 493ca735530SJeremy L Thompson CeedCallBackend(CeedGetParent(ceed, &ceed_parent)); 494ca735530SJeremy L Thompson CeedCallBackend(CeedIsDeterministic(ceed_parent, &is_deterministic)); 495dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 496dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 49722eb1385SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetType(rstr, &rstr_type)); 498ca735530SJeremy L Thompson const CeedInt size = num_elem * elem_size; 499ff1e7120SSebastian Grimberg 500dce49693SSebastian Grimberg CeedCallBackend(CeedCalloc(1, &impl)); 501dce49693SSebastian Grimberg impl->num_nodes = size; 502ff1e7120SSebastian Grimberg impl->h_ind = NULL; 503ff1e7120SSebastian Grimberg impl->h_ind_allocated = NULL; 504ff1e7120SSebastian Grimberg impl->d_ind = NULL; 505ff1e7120SSebastian Grimberg impl->d_ind_allocated = NULL; 506ff1e7120SSebastian Grimberg impl->d_t_indices = NULL; 507ff1e7120SSebastian Grimberg impl->d_t_offsets = NULL; 508dce49693SSebastian Grimberg impl->h_orients = NULL; 509dce49693SSebastian Grimberg impl->h_orients_allocated = NULL; 510dce49693SSebastian Grimberg impl->d_orients = NULL; 511dce49693SSebastian Grimberg impl->d_orients_allocated = NULL; 512dce49693SSebastian Grimberg impl->h_curl_orients = NULL; 513dce49693SSebastian Grimberg impl->h_curl_orients_allocated = NULL; 514dce49693SSebastian Grimberg impl->d_curl_orients = NULL; 515dce49693SSebastian Grimberg impl->d_curl_orients_allocated = NULL; 516dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionSetData(rstr, impl)); 51722eb1385SJeremy L Thompson 51822eb1385SJeremy L Thompson // Set layouts 51922eb1385SJeremy L Thompson { 52022eb1385SJeremy L Thompson bool has_backend_strides; 52122eb1385SJeremy L Thompson CeedInt layout[3] = {1, size, elem_size}; 52222eb1385SJeremy L Thompson 523dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionSetELayout(rstr, layout)); 52422eb1385SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_STRIDED) { 52522eb1385SJeremy L Thompson CeedCallBackend(CeedElemRestrictionHasBackendStrides(rstr, &has_backend_strides)); 52622eb1385SJeremy L Thompson if (has_backend_strides) { 52722eb1385SJeremy L Thompson CeedCallBackend(CeedElemRestrictionSetLLayout(rstr, layout)); 52822eb1385SJeremy L Thompson } 52922eb1385SJeremy L Thompson } 53022eb1385SJeremy L Thompson } 531ff1e7120SSebastian Grimberg 532dce49693SSebastian Grimberg // Set up device offset/orientation arrays 533dce49693SSebastian Grimberg if (rstr_type != CEED_RESTRICTION_STRIDED) { 534ff1e7120SSebastian Grimberg switch (mem_type) { 535ff1e7120SSebastian Grimberg case CEED_MEM_HOST: { 536ff1e7120SSebastian Grimberg switch (copy_mode) { 537ff1e7120SSebastian Grimberg case CEED_OWN_POINTER: 538ff1e7120SSebastian Grimberg impl->h_ind_allocated = (CeedInt *)indices; 539ff1e7120SSebastian Grimberg impl->h_ind = (CeedInt *)indices; 540ff1e7120SSebastian Grimberg break; 541ff1e7120SSebastian Grimberg case CEED_USE_POINTER: 542ff1e7120SSebastian Grimberg impl->h_ind = (CeedInt *)indices; 543ff1e7120SSebastian Grimberg break; 544ff1e7120SSebastian Grimberg case CEED_COPY_VALUES: 545dce49693SSebastian Grimberg CeedCallBackend(CeedMalloc(size, &impl->h_ind_allocated)); 546dce49693SSebastian Grimberg memcpy(impl->h_ind_allocated, indices, size * sizeof(CeedInt)); 547ff1e7120SSebastian Grimberg impl->h_ind = impl->h_ind_allocated; 548ff1e7120SSebastian Grimberg break; 549ff1e7120SSebastian Grimberg } 550ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_ind, size * sizeof(CeedInt))); 551ff1e7120SSebastian Grimberg impl->d_ind_allocated = impl->d_ind; // We own the device memory 552ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMemcpy(impl->d_ind, indices, size * sizeof(CeedInt), cudaMemcpyHostToDevice)); 553dce49693SSebastian Grimberg if (is_deterministic) CeedCallBackend(CeedElemRestrictionOffset_Cuda(rstr, indices)); 554dce49693SSebastian Grimberg } break; 555ff1e7120SSebastian Grimberg case CEED_MEM_DEVICE: { 556ff1e7120SSebastian Grimberg switch (copy_mode) { 557ff1e7120SSebastian Grimberg case CEED_COPY_VALUES: 558ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_ind, size * sizeof(CeedInt))); 559ff1e7120SSebastian Grimberg impl->d_ind_allocated = impl->d_ind; // We own the device memory 560ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMemcpy(impl->d_ind, indices, size * sizeof(CeedInt), cudaMemcpyDeviceToDevice)); 561ff1e7120SSebastian Grimberg break; 562ff1e7120SSebastian Grimberg case CEED_OWN_POINTER: 563ff1e7120SSebastian Grimberg impl->d_ind = (CeedInt *)indices; 564ff1e7120SSebastian Grimberg impl->d_ind_allocated = impl->d_ind; 565ff1e7120SSebastian Grimberg break; 566ff1e7120SSebastian Grimberg case CEED_USE_POINTER: 567ff1e7120SSebastian Grimberg impl->d_ind = (CeedInt *)indices; 568ff1e7120SSebastian Grimberg break; 569ff1e7120SSebastian Grimberg } 570dce49693SSebastian Grimberg CeedCallBackend(CeedMalloc(size, &impl->h_ind_allocated)); 571dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaMemcpy(impl->h_ind_allocated, impl->d_ind, size * sizeof(CeedInt), cudaMemcpyDeviceToHost)); 572dce49693SSebastian Grimberg impl->h_ind = impl->h_ind_allocated; 573dce49693SSebastian Grimberg if (is_deterministic) CeedCallBackend(CeedElemRestrictionOffset_Cuda(rstr, indices)); 574dce49693SSebastian Grimberg } break; 575ff1e7120SSebastian Grimberg } 576ff1e7120SSebastian Grimberg 577dce49693SSebastian Grimberg // Orientation data 578dce49693SSebastian Grimberg if (rstr_type == CEED_RESTRICTION_ORIENTED) { 579dce49693SSebastian Grimberg switch (mem_type) { 580dce49693SSebastian Grimberg case CEED_MEM_HOST: { 581dce49693SSebastian Grimberg switch (copy_mode) { 582dce49693SSebastian Grimberg case CEED_OWN_POINTER: 583dce49693SSebastian Grimberg impl->h_orients_allocated = (bool *)orients; 584dce49693SSebastian Grimberg impl->h_orients = (bool *)orients; 585dce49693SSebastian Grimberg break; 586dce49693SSebastian Grimberg case CEED_USE_POINTER: 587dce49693SSebastian Grimberg impl->h_orients = (bool *)orients; 588dce49693SSebastian Grimberg break; 589dce49693SSebastian Grimberg case CEED_COPY_VALUES: 590dce49693SSebastian Grimberg CeedCallBackend(CeedMalloc(size, &impl->h_orients_allocated)); 591dce49693SSebastian Grimberg memcpy(impl->h_orients_allocated, orients, size * sizeof(bool)); 592dce49693SSebastian Grimberg impl->h_orients = impl->h_orients_allocated; 593dce49693SSebastian Grimberg break; 594dce49693SSebastian Grimberg } 595dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_orients, size * sizeof(bool))); 596dce49693SSebastian Grimberg impl->d_orients_allocated = impl->d_orients; // We own the device memory 597dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaMemcpy(impl->d_orients, orients, size * sizeof(bool), cudaMemcpyHostToDevice)); 598dce49693SSebastian Grimberg } break; 599dce49693SSebastian Grimberg case CEED_MEM_DEVICE: { 600dce49693SSebastian Grimberg switch (copy_mode) { 601dce49693SSebastian Grimberg case CEED_COPY_VALUES: 602dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_orients, size * sizeof(bool))); 603dce49693SSebastian Grimberg impl->d_orients_allocated = impl->d_orients; // We own the device memory 604dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaMemcpy(impl->d_orients, orients, size * sizeof(bool), cudaMemcpyDeviceToDevice)); 605dce49693SSebastian Grimberg break; 606dce49693SSebastian Grimberg case CEED_OWN_POINTER: 607dce49693SSebastian Grimberg impl->d_orients = (bool *)orients; 608dce49693SSebastian Grimberg impl->d_orients_allocated = impl->d_orients; 609dce49693SSebastian Grimberg break; 610dce49693SSebastian Grimberg case CEED_USE_POINTER: 611dce49693SSebastian Grimberg impl->d_orients = (bool *)orients; 612dce49693SSebastian Grimberg break; 613dce49693SSebastian Grimberg } 614dce49693SSebastian Grimberg CeedCallBackend(CeedMalloc(size, &impl->h_orients_allocated)); 615dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaMemcpy(impl->h_orients_allocated, impl->d_orients, size * sizeof(bool), cudaMemcpyDeviceToHost)); 616dce49693SSebastian Grimberg impl->h_orients = impl->h_orients_allocated; 617dce49693SSebastian Grimberg } break; 618dce49693SSebastian Grimberg } 619dce49693SSebastian Grimberg } else if (rstr_type == CEED_RESTRICTION_CURL_ORIENTED) { 620dce49693SSebastian Grimberg switch (mem_type) { 621dce49693SSebastian Grimberg case CEED_MEM_HOST: { 622dce49693SSebastian Grimberg switch (copy_mode) { 623dce49693SSebastian Grimberg case CEED_OWN_POINTER: 624dce49693SSebastian Grimberg impl->h_curl_orients_allocated = (CeedInt8 *)curl_orients; 625dce49693SSebastian Grimberg impl->h_curl_orients = (CeedInt8 *)curl_orients; 626dce49693SSebastian Grimberg break; 627dce49693SSebastian Grimberg case CEED_USE_POINTER: 628dce49693SSebastian Grimberg impl->h_curl_orients = (CeedInt8 *)curl_orients; 629dce49693SSebastian Grimberg break; 630dce49693SSebastian Grimberg case CEED_COPY_VALUES: 631dce49693SSebastian Grimberg CeedCallBackend(CeedMalloc(3 * size, &impl->h_curl_orients_allocated)); 632dce49693SSebastian Grimberg memcpy(impl->h_curl_orients_allocated, curl_orients, 3 * size * sizeof(CeedInt8)); 633dce49693SSebastian Grimberg impl->h_curl_orients = impl->h_curl_orients_allocated; 634dce49693SSebastian Grimberg break; 635dce49693SSebastian Grimberg } 636dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_curl_orients, 3 * size * sizeof(CeedInt8))); 637dce49693SSebastian Grimberg impl->d_curl_orients_allocated = impl->d_curl_orients; // We own the device memory 638dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaMemcpy(impl->d_curl_orients, curl_orients, 3 * size * sizeof(CeedInt8), cudaMemcpyHostToDevice)); 639dce49693SSebastian Grimberg } break; 640dce49693SSebastian Grimberg case CEED_MEM_DEVICE: { 641dce49693SSebastian Grimberg switch (copy_mode) { 642dce49693SSebastian Grimberg case CEED_COPY_VALUES: 643dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_curl_orients, 3 * size * sizeof(CeedInt8))); 644dce49693SSebastian Grimberg impl->d_curl_orients_allocated = impl->d_curl_orients; // We own the device memory 645dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaMemcpy(impl->d_curl_orients, curl_orients, 3 * size * sizeof(CeedInt8), cudaMemcpyDeviceToDevice)); 646dce49693SSebastian Grimberg break; 647dce49693SSebastian Grimberg case CEED_OWN_POINTER: 648dce49693SSebastian Grimberg impl->d_curl_orients = (CeedInt8 *)curl_orients; 649dce49693SSebastian Grimberg impl->d_curl_orients_allocated = impl->d_curl_orients; 650dce49693SSebastian Grimberg break; 651dce49693SSebastian Grimberg case CEED_USE_POINTER: 652dce49693SSebastian Grimberg impl->d_curl_orients = (CeedInt8 *)curl_orients; 653dce49693SSebastian Grimberg break; 654dce49693SSebastian Grimberg } 655dce49693SSebastian Grimberg CeedCallBackend(CeedMalloc(3 * size, &impl->h_curl_orients_allocated)); 656dce49693SSebastian Grimberg CeedCallCuda(ceed, cudaMemcpy(impl->h_curl_orients_allocated, impl->d_curl_orients, 3 * size * sizeof(CeedInt8), cudaMemcpyDeviceToHost)); 657dce49693SSebastian Grimberg impl->h_curl_orients = impl->h_curl_orients_allocated; 658dce49693SSebastian Grimberg } break; 659dce49693SSebastian Grimberg } 660dce49693SSebastian Grimberg } 661dce49693SSebastian Grimberg } 662ca735530SJeremy L Thompson 663ff1e7120SSebastian Grimberg // Register backend functions 664dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "Apply", CeedElemRestrictionApply_Cuda)); 665dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "ApplyUnsigned", CeedElemRestrictionApplyUnsigned_Cuda)); 666dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "ApplyUnoriented", CeedElemRestrictionApplyUnoriented_Cuda)); 667dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "GetOffsets", CeedElemRestrictionGetOffsets_Cuda)); 668dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "GetOrientations", CeedElemRestrictionGetOrientations_Cuda)); 669dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "GetCurlOrientations", CeedElemRestrictionGetCurlOrientations_Cuda)); 670dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "Destroy", CeedElemRestrictionDestroy_Cuda)); 671ff1e7120SSebastian Grimberg return CEED_ERROR_SUCCESS; 672ff1e7120SSebastian Grimberg } 673ff1e7120SSebastian Grimberg 674ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 675