1d275d636SJeremy L Thompson // Copyright (c) 2017-2025, 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 CeedElemRestriction_Cuda *impl; 30cf8cbdd6SSebastian Grimberg 31cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 32cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 33b20a4af9SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetType(rstr, &rstr_type)); 34cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 35cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 36cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCompStride(rstr, &comp_stride)); 37b20a4af9SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 38b20a4af9SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetMaxPointsInElement(rstr, &elem_size)); 39b20a4af9SJeremy L Thompson } else { 40b20a4af9SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 41b20a4af9SJeremy L Thompson } 42cf8cbdd6SSebastian Grimberg is_deterministic = impl->d_l_vec_indices != NULL; 43cf8cbdd6SSebastian Grimberg 44cf8cbdd6SSebastian Grimberg // Compile CUDA kernels 45cf8cbdd6SSebastian Grimberg switch (rstr_type) { 46cf8cbdd6SSebastian Grimberg case CEED_RESTRICTION_STRIDED: { 479c25dd66SJeremy L Thompson const char restriction_kernel_source[] = "// Strided restriction source\n#include <ceed/jit-source/cuda/cuda-ref-restriction-strided.h>\n"; 48cf8cbdd6SSebastian Grimberg bool has_backend_strides; 49509d4af6SJeremy L Thompson CeedInt strides[3] = {1, num_elem * elem_size, elem_size}; 50cf8cbdd6SSebastian Grimberg 51cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionHasBackendStrides(rstr, &has_backend_strides)); 52cf8cbdd6SSebastian Grimberg if (!has_backend_strides) { 5356c48462SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetStrides(rstr, strides)); 54cf8cbdd6SSebastian Grimberg } 55cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedCompile_Cuda(ceed, restriction_kernel_source, &impl->module, 6, "RSTR_ELEM_SIZE", elem_size, "RSTR_NUM_ELEM", num_elem, 56cf8cbdd6SSebastian Grimberg "RSTR_NUM_COMP", num_comp, "RSTR_STRIDE_NODES", strides[0], "RSTR_STRIDE_COMP", strides[1], "RSTR_STRIDE_ELEM", 57cf8cbdd6SSebastian Grimberg strides[2])); 58cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "StridedNoTranspose", &impl->ApplyNoTranspose)); 59cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "StridedTranspose", &impl->ApplyTranspose)); 60cf8cbdd6SSebastian Grimberg } break; 61cf8cbdd6SSebastian Grimberg case CEED_RESTRICTION_STANDARD: { 629c25dd66SJeremy L Thompson const char restriction_kernel_source[] = "// Standard restriction source\n#include <ceed/jit-source/cuda/cuda-ref-restriction-offset.h>\n"; 639c25dd66SJeremy L Thompson 64cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedCompile_Cuda(ceed, restriction_kernel_source, &impl->module, 6, "RSTR_ELEM_SIZE", elem_size, "RSTR_NUM_ELEM", num_elem, 65cf8cbdd6SSebastian Grimberg "RSTR_NUM_COMP", num_comp, "RSTR_NUM_NODES", impl->num_nodes, "RSTR_COMP_STRIDE", comp_stride, 66cf8cbdd6SSebastian Grimberg "USE_DETERMINISTIC", is_deterministic ? 1 : 0)); 67cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetNoTranspose", &impl->ApplyNoTranspose)); 68cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetTranspose", &impl->ApplyTranspose)); 69cf8cbdd6SSebastian Grimberg } break; 709c25dd66SJeremy L Thompson case CEED_RESTRICTION_POINTS: { 719c25dd66SJeremy L Thompson const char restriction_kernel_source[] = 729c25dd66SJeremy L Thompson "// AtPoints restriction source\n#include <ceed/jit-source/cuda/cuda-ref-restriction-at-points.h>\n\n" 739c25dd66SJeremy L Thompson "// Standard restriction source\n#include <ceed/jit-source/cuda/cuda-ref-restriction-offset.h>\n"; 74cf8cbdd6SSebastian Grimberg 759c25dd66SJeremy L Thompson CeedCallBackend(CeedCompile_Cuda(ceed, restriction_kernel_source, &impl->module, 6, "RSTR_ELEM_SIZE", elem_size, "RSTR_NUM_ELEM", num_elem, 769c25dd66SJeremy L Thompson "RSTR_NUM_COMP", num_comp, "RSTR_NUM_NODES", impl->num_nodes, "RSTR_COMP_STRIDE", comp_stride, 779c25dd66SJeremy L Thompson "USE_DETERMINISTIC", is_deterministic ? 1 : 0)); 789c25dd66SJeremy L Thompson CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetNoTranspose", &impl->ApplyNoTranspose)); 799c25dd66SJeremy L Thompson CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "AtPointsTranspose", &impl->ApplyTranspose)); 809c25dd66SJeremy L Thompson } break; 819c25dd66SJeremy L Thompson case CEED_RESTRICTION_ORIENTED: { 829c25dd66SJeremy L Thompson const char restriction_kernel_source[] = 839c25dd66SJeremy L Thompson "// Oriented restriction source\n#include <ceed/jit-source/cuda/cuda-ref-restriction-oriented.h>\n\n" 849c25dd66SJeremy L Thompson "// Standard restriction source\n#include <ceed/jit-source/cuda/cuda-ref-restriction-offset.h>\n"; 859c25dd66SJeremy L Thompson 86cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedCompile_Cuda(ceed, restriction_kernel_source, &impl->module, 6, "RSTR_ELEM_SIZE", elem_size, "RSTR_NUM_ELEM", num_elem, 87cf8cbdd6SSebastian Grimberg "RSTR_NUM_COMP", num_comp, "RSTR_NUM_NODES", impl->num_nodes, "RSTR_COMP_STRIDE", comp_stride, 88cf8cbdd6SSebastian Grimberg "USE_DETERMINISTIC", is_deterministic ? 1 : 0)); 89cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OrientedNoTranspose", &impl->ApplyNoTranspose)); 90cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetNoTranspose", &impl->ApplyUnsignedNoTranspose)); 91cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OrientedTranspose", &impl->ApplyTranspose)); 92cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetTranspose", &impl->ApplyUnsignedTranspose)); 93cf8cbdd6SSebastian Grimberg } break; 94cf8cbdd6SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: { 959c25dd66SJeremy L Thompson const char restriction_kernel_source[] = 969c25dd66SJeremy L Thompson "// Curl oriented restriction source\n#include <ceed/jit-source/cuda/cuda-ref-restriction-curl-oriented.h>\n\n" 979c25dd66SJeremy L Thompson "// Standard restriction source\n#include <ceed/jit-source/cuda/cuda-ref-restriction-offset.h>\n"; 98cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedCompile_Cuda(ceed, restriction_kernel_source, &impl->module, 6, "RSTR_ELEM_SIZE", elem_size, "RSTR_NUM_ELEM", num_elem, 99cf8cbdd6SSebastian Grimberg "RSTR_NUM_COMP", num_comp, "RSTR_NUM_NODES", impl->num_nodes, "RSTR_COMP_STRIDE", comp_stride, 100cf8cbdd6SSebastian Grimberg "USE_DETERMINISTIC", is_deterministic ? 1 : 0)); 101cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "CurlOrientedNoTranspose", &impl->ApplyNoTranspose)); 102cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "CurlOrientedUnsignedNoTranspose", &impl->ApplyUnsignedNoTranspose)); 103cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetNoTranspose", &impl->ApplyUnorientedNoTranspose)); 104cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "CurlOrientedTranspose", &impl->ApplyTranspose)); 105cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "CurlOrientedUnsignedTranspose", &impl->ApplyUnsignedTranspose)); 106cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedGetKernel_Cuda(ceed, impl->module, "OffsetTranspose", &impl->ApplyUnorientedTranspose)); 107cf8cbdd6SSebastian Grimberg } break; 108cf8cbdd6SSebastian Grimberg } 1099bc66399SJeremy L Thompson CeedCallBackend(CeedDestroy(&ceed)); 110cf8cbdd6SSebastian Grimberg return CEED_ERROR_SUCCESS; 111cf8cbdd6SSebastian Grimberg } 112cf8cbdd6SSebastian Grimberg 113cf8cbdd6SSebastian Grimberg //------------------------------------------------------------------------------ 114dce49693SSebastian Grimberg // Core apply restriction code 115ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 116dce49693SSebastian Grimberg static inline int CeedElemRestrictionApply_Cuda_Core(CeedElemRestriction rstr, CeedTransposeMode t_mode, bool use_signs, bool use_orients, 117dce49693SSebastian Grimberg CeedVector u, CeedVector v, CeedRequest *request) { 118ff1e7120SSebastian Grimberg Ceed ceed; 119dce49693SSebastian Grimberg CeedRestrictionType rstr_type; 120ff1e7120SSebastian Grimberg const CeedScalar *d_u; 121ff1e7120SSebastian Grimberg CeedScalar *d_v; 122ca735530SJeremy L Thompson CeedElemRestriction_Cuda *impl; 123ca735530SJeremy L Thompson 124dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 125dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 126dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetType(rstr, &rstr_type)); 127cf8cbdd6SSebastian Grimberg 128cf8cbdd6SSebastian Grimberg // Assemble kernel if needed 129cf8cbdd6SSebastian Grimberg if (!impl->module) { 130cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionSetupCompile_Cuda(rstr)); 131cf8cbdd6SSebastian Grimberg } 132ca735530SJeremy L Thompson 133ca735530SJeremy L Thompson // Get vectors 134ff1e7120SSebastian Grimberg CeedCallBackend(CeedVectorGetArrayRead(u, CEED_MEM_DEVICE, &d_u)); 135ff1e7120SSebastian Grimberg if (t_mode == CEED_TRANSPOSE) { 136ff1e7120SSebastian Grimberg // Sum into for transpose mode, e-vec to l-vec 137ff1e7120SSebastian Grimberg CeedCallBackend(CeedVectorGetArray(v, CEED_MEM_DEVICE, &d_v)); 138ff1e7120SSebastian Grimberg } else { 139ff1e7120SSebastian Grimberg // Overwrite for notranspose mode, l-vec to e-vec 140ff1e7120SSebastian Grimberg CeedCallBackend(CeedVectorGetArrayWrite(v, CEED_MEM_DEVICE, &d_v)); 141ff1e7120SSebastian Grimberg } 142ff1e7120SSebastian Grimberg 143ff1e7120SSebastian Grimberg // Restrict 144ff1e7120SSebastian Grimberg if (t_mode == CEED_NOTRANSPOSE) { 145ff1e7120SSebastian Grimberg // L-vector -> E-vector 146cf8cbdd6SSebastian Grimberg CeedInt elem_size; 147cf8cbdd6SSebastian Grimberg 148cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 149dce49693SSebastian Grimberg const CeedInt block_size = elem_size < 1024 ? (elem_size > 32 ? elem_size : 32) : 1024; 150cf8cbdd6SSebastian Grimberg const CeedInt grid = CeedDivUpInt(impl->num_nodes, block_size); 15158549094SSebastian Grimberg 152dce49693SSebastian Grimberg switch (rstr_type) { 153dce49693SSebastian Grimberg case CEED_RESTRICTION_STRIDED: { 154cf8cbdd6SSebastian Grimberg void *args[] = {&d_u, &d_v}; 15558549094SSebastian Grimberg 156cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyNoTranspose, grid, block_size, args)); 157dce49693SSebastian Grimberg } break; 158b20a4af9SJeremy L Thompson case CEED_RESTRICTION_POINTS: 159dce49693SSebastian Grimberg case CEED_RESTRICTION_STANDARD: { 160a267acd1SJeremy L Thompson void *args[] = {&impl->d_offsets, &d_u, &d_v}; 161dce49693SSebastian Grimberg 162cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyNoTranspose, grid, block_size, args)); 163dce49693SSebastian Grimberg } break; 164dce49693SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: { 165dce49693SSebastian Grimberg if (use_signs) { 166a267acd1SJeremy L Thompson void *args[] = {&impl->d_offsets, &impl->d_orients, &d_u, &d_v}; 167dce49693SSebastian Grimberg 168cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyNoTranspose, grid, block_size, args)); 169dce49693SSebastian Grimberg } else { 170a267acd1SJeremy L Thompson void *args[] = {&impl->d_offsets, &d_u, &d_v}; 171dce49693SSebastian Grimberg 172cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnsignedNoTranspose, grid, block_size, args)); 173dce49693SSebastian Grimberg } 174dce49693SSebastian Grimberg } break; 175dce49693SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: { 176dce49693SSebastian Grimberg if (use_signs && use_orients) { 177a267acd1SJeremy L Thompson void *args[] = {&impl->d_offsets, &impl->d_curl_orients, &d_u, &d_v}; 178dce49693SSebastian Grimberg 179cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyNoTranspose, grid, block_size, args)); 180dce49693SSebastian Grimberg } else if (use_orients) { 181a267acd1SJeremy L Thompson void *args[] = {&impl->d_offsets, &impl->d_curl_orients, &d_u, &d_v}; 182dce49693SSebastian Grimberg 183cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnsignedNoTranspose, grid, block_size, args)); 184dce49693SSebastian Grimberg } else { 185a267acd1SJeremy L Thompson void *args[] = {&impl->d_offsets, &d_u, &d_v}; 186dce49693SSebastian Grimberg 187cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnorientedNoTranspose, grid, block_size, args)); 188dce49693SSebastian Grimberg } 189dce49693SSebastian Grimberg } break; 190ff1e7120SSebastian Grimberg } 191ff1e7120SSebastian Grimberg } else { 192ff1e7120SSebastian Grimberg // E-vector -> L-vector 193cf8cbdd6SSebastian Grimberg const bool is_deterministic = impl->d_l_vec_indices != NULL; 194dce49693SSebastian Grimberg const CeedInt block_size = 32; 195cf8cbdd6SSebastian Grimberg const CeedInt grid = CeedDivUpInt(impl->num_nodes, block_size); 196ca735530SJeremy L Thompson 197dce49693SSebastian Grimberg switch (rstr_type) { 198dce49693SSebastian Grimberg case CEED_RESTRICTION_STRIDED: { 199cf8cbdd6SSebastian Grimberg void *args[] = {&d_u, &d_v}; 200dce49693SSebastian Grimberg 201cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 202dce49693SSebastian Grimberg } break; 2030b63de31SJeremy L Thompson case CEED_RESTRICTION_POINTS: { 2040b63de31SJeremy L Thompson if (!is_deterministic) { 2050b63de31SJeremy L Thompson void *args[] = {&impl->d_offsets, &impl->d_points_per_elem, &d_u, &d_v}; 2060b63de31SJeremy L Thompson 2070b63de31SJeremy L Thompson CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 2080b63de31SJeremy L Thompson } else { 2090b63de31SJeremy L Thompson void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_points_per_elem, &impl->d_t_offsets, &d_u, &d_v}; 2100b63de31SJeremy L Thompson 2110b63de31SJeremy L Thompson CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 2120b63de31SJeremy L Thompson } 2130b63de31SJeremy L Thompson } break; 214dce49693SSebastian Grimberg case CEED_RESTRICTION_STANDARD: { 215cf8cbdd6SSebastian Grimberg if (!is_deterministic) { 216a267acd1SJeremy L Thompson void *args[] = {&impl->d_offsets, &d_u, &d_v}; 21758549094SSebastian Grimberg 218cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 219ff1e7120SSebastian Grimberg } else { 22058549094SSebastian Grimberg void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &d_u, &d_v}; 22158549094SSebastian Grimberg 222cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 22358549094SSebastian Grimberg } 224dce49693SSebastian Grimberg } break; 225dce49693SSebastian Grimberg case CEED_RESTRICTION_ORIENTED: { 226dce49693SSebastian Grimberg if (use_signs) { 227cf8cbdd6SSebastian Grimberg if (!is_deterministic) { 228a267acd1SJeremy L Thompson void *args[] = {&impl->d_offsets, &impl->d_orients, &d_u, &d_v}; 22958549094SSebastian Grimberg 230cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 231dce49693SSebastian Grimberg } else { 2327aa91133SSebastian Grimberg void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &impl->d_orients, &d_u, &d_v}; 2337aa91133SSebastian Grimberg 234cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 2357aa91133SSebastian Grimberg } 2367aa91133SSebastian Grimberg } else { 237cf8cbdd6SSebastian Grimberg if (!is_deterministic) { 238a267acd1SJeremy L Thompson void *args[] = {&impl->d_offsets, &d_u, &d_v}; 239dce49693SSebastian Grimberg 240cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnsignedTranspose, grid, block_size, args)); 241dce49693SSebastian Grimberg } else { 242dce49693SSebastian Grimberg void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &d_u, &d_v}; 243dce49693SSebastian Grimberg 244cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnsignedTranspose, grid, block_size, args)); 245dce49693SSebastian Grimberg } 246dce49693SSebastian Grimberg } 247dce49693SSebastian Grimberg } break; 248dce49693SSebastian Grimberg case CEED_RESTRICTION_CURL_ORIENTED: { 249dce49693SSebastian Grimberg if (use_signs && use_orients) { 250cf8cbdd6SSebastian Grimberg if (!is_deterministic) { 251a267acd1SJeremy L Thompson void *args[] = {&impl->d_offsets, &impl->d_curl_orients, &d_u, &d_v}; 252dce49693SSebastian Grimberg 253cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 2547aa91133SSebastian Grimberg } else { 2557aa91133SSebastian Grimberg void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &impl->d_curl_orients, &d_u, &d_v}; 2567aa91133SSebastian Grimberg 257cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyTranspose, grid, block_size, args)); 2587aa91133SSebastian Grimberg } 259dce49693SSebastian Grimberg } else if (use_orients) { 260cf8cbdd6SSebastian Grimberg if (!is_deterministic) { 261a267acd1SJeremy L Thompson void *args[] = {&impl->d_offsets, &impl->d_curl_orients, &d_u, &d_v}; 262dce49693SSebastian Grimberg 263cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnsignedTranspose, grid, block_size, args)); 264dce49693SSebastian Grimberg } else { 2657aa91133SSebastian Grimberg void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &impl->d_curl_orients, &d_u, &d_v}; 2667aa91133SSebastian Grimberg 267cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnsignedTranspose, grid, block_size, args)); 2687aa91133SSebastian Grimberg } 2697aa91133SSebastian Grimberg } else { 270cf8cbdd6SSebastian Grimberg if (!is_deterministic) { 271a267acd1SJeremy L Thompson void *args[] = {&impl->d_offsets, &d_u, &d_v}; 272dce49693SSebastian Grimberg 273cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnorientedTranspose, grid, block_size, args)); 274dce49693SSebastian Grimberg } else { 275dce49693SSebastian Grimberg void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &d_u, &d_v}; 276dce49693SSebastian Grimberg 277cf8cbdd6SSebastian Grimberg CeedCallBackend(CeedRunKernel_Cuda(ceed, impl->ApplyUnorientedTranspose, grid, block_size, args)); 278dce49693SSebastian Grimberg } 279dce49693SSebastian Grimberg } 280dce49693SSebastian Grimberg } break; 281ff1e7120SSebastian Grimberg } 282ff1e7120SSebastian Grimberg } 283ff1e7120SSebastian Grimberg 284ff1e7120SSebastian Grimberg if (request != CEED_REQUEST_IMMEDIATE && request != CEED_REQUEST_ORDERED) *request = NULL; 285ff1e7120SSebastian Grimberg 286ff1e7120SSebastian Grimberg // Restore arrays 287ff1e7120SSebastian Grimberg CeedCallBackend(CeedVectorRestoreArrayRead(u, &d_u)); 288ff1e7120SSebastian Grimberg CeedCallBackend(CeedVectorRestoreArray(v, &d_v)); 2899bc66399SJeremy L Thompson CeedCallBackend(CeedDestroy(&ceed)); 290ff1e7120SSebastian Grimberg return CEED_ERROR_SUCCESS; 291ff1e7120SSebastian Grimberg } 292ff1e7120SSebastian Grimberg 293ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 294dce49693SSebastian Grimberg // Apply restriction 295dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 296dce49693SSebastian Grimberg static int CeedElemRestrictionApply_Cuda(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 297dce49693SSebastian Grimberg return CeedElemRestrictionApply_Cuda_Core(rstr, t_mode, true, true, u, v, request); 298dce49693SSebastian Grimberg } 299dce49693SSebastian Grimberg 300dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 301dce49693SSebastian Grimberg // Apply unsigned restriction 302dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 303dce49693SSebastian Grimberg static int CeedElemRestrictionApplyUnsigned_Cuda(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 304dce49693SSebastian Grimberg CeedRequest *request) { 305dce49693SSebastian Grimberg return CeedElemRestrictionApply_Cuda_Core(rstr, t_mode, false, true, u, v, request); 306dce49693SSebastian Grimberg } 307dce49693SSebastian Grimberg 308dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 309dce49693SSebastian Grimberg // Apply unoriented restriction 310dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 311dce49693SSebastian Grimberg static int CeedElemRestrictionApplyUnoriented_Cuda(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 312dce49693SSebastian Grimberg CeedRequest *request) { 313dce49693SSebastian Grimberg return CeedElemRestrictionApply_Cuda_Core(rstr, t_mode, false, false, u, v, request); 314dce49693SSebastian Grimberg } 315dce49693SSebastian Grimberg 316dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 317ff1e7120SSebastian Grimberg // Get offsets 318ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 319ff1e7120SSebastian Grimberg static int CeedElemRestrictionGetOffsets_Cuda(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 320ff1e7120SSebastian Grimberg CeedElemRestriction_Cuda *impl; 321b20a4af9SJeremy L Thompson CeedRestrictionType rstr_type; 322ff1e7120SSebastian Grimberg 323ca735530SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 324b20a4af9SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetType(rstr, &rstr_type)); 325ff1e7120SSebastian Grimberg switch (mem_type) { 326ff1e7120SSebastian Grimberg case CEED_MEM_HOST: 327b20a4af9SJeremy L Thompson *offsets = rstr_type == CEED_RESTRICTION_POINTS ? impl->h_offsets_at_points : impl->h_offsets; 328ff1e7120SSebastian Grimberg break; 329ff1e7120SSebastian Grimberg case CEED_MEM_DEVICE: 330b20a4af9SJeremy L Thompson *offsets = rstr_type == CEED_RESTRICTION_POINTS ? impl->d_offsets_at_points : impl->d_offsets; 331ff1e7120SSebastian Grimberg break; 332ff1e7120SSebastian Grimberg } 333ff1e7120SSebastian Grimberg return CEED_ERROR_SUCCESS; 334ff1e7120SSebastian Grimberg } 335ff1e7120SSebastian Grimberg 336ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 337dce49693SSebastian Grimberg // Get orientations 338dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 339dce49693SSebastian Grimberg static int CeedElemRestrictionGetOrientations_Cuda(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 340dce49693SSebastian Grimberg CeedElemRestriction_Cuda *impl; 341dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 342dce49693SSebastian Grimberg 343dce49693SSebastian Grimberg switch (mem_type) { 344dce49693SSebastian Grimberg case CEED_MEM_HOST: 345dce49693SSebastian Grimberg *orients = impl->h_orients; 346dce49693SSebastian Grimberg break; 347dce49693SSebastian Grimberg case CEED_MEM_DEVICE: 348dce49693SSebastian Grimberg *orients = impl->d_orients; 349dce49693SSebastian Grimberg break; 350dce49693SSebastian Grimberg } 351dce49693SSebastian Grimberg return CEED_ERROR_SUCCESS; 352dce49693SSebastian Grimberg } 353dce49693SSebastian Grimberg 354dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 355dce49693SSebastian Grimberg // Get curl-conforming orientations 356dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 357dce49693SSebastian Grimberg static int CeedElemRestrictionGetCurlOrientations_Cuda(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) { 358dce49693SSebastian Grimberg CeedElemRestriction_Cuda *impl; 359dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 360dce49693SSebastian Grimberg 361dce49693SSebastian Grimberg switch (mem_type) { 362dce49693SSebastian Grimberg case CEED_MEM_HOST: 363dce49693SSebastian Grimberg *curl_orients = impl->h_curl_orients; 364dce49693SSebastian Grimberg break; 365dce49693SSebastian Grimberg case CEED_MEM_DEVICE: 366dce49693SSebastian Grimberg *curl_orients = impl->d_curl_orients; 367dce49693SSebastian Grimberg break; 368dce49693SSebastian Grimberg } 369dce49693SSebastian Grimberg return CEED_ERROR_SUCCESS; 370dce49693SSebastian Grimberg } 371dce49693SSebastian Grimberg 372dce49693SSebastian Grimberg //------------------------------------------------------------------------------ 373b20a4af9SJeremy L Thompson // Get offset for padded AtPoints E-layout 374b20a4af9SJeremy L Thompson //------------------------------------------------------------------------------ 375b20a4af9SJeremy L Thompson static int CeedElemRestrictionGetAtPointsElementOffset_Cuda(CeedElemRestriction rstr, CeedInt elem, CeedSize *elem_offset) { 376b20a4af9SJeremy L Thompson CeedInt layout[3]; 377b20a4af9SJeremy L Thompson 378b20a4af9SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetELayout(rstr, layout)); 379b20a4af9SJeremy L Thompson *elem_offset = 0 * layout[0] + 0 * layout[1] + elem * layout[2]; 380b20a4af9SJeremy L Thompson return CEED_ERROR_SUCCESS; 381b20a4af9SJeremy L Thompson } 382b20a4af9SJeremy L Thompson 383b20a4af9SJeremy L Thompson //------------------------------------------------------------------------------ 384ff1e7120SSebastian Grimberg // Destroy restriction 385ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 386dce49693SSebastian Grimberg static int CeedElemRestrictionDestroy_Cuda(CeedElemRestriction rstr) { 387ff1e7120SSebastian Grimberg Ceed ceed; 388ca735530SJeremy L Thompson CeedElemRestriction_Cuda *impl; 389ca735530SJeremy L Thompson 390dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 391dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 392cf8cbdd6SSebastian Grimberg if (impl->module) { 393ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cuModuleUnload(impl->module)); 394cf8cbdd6SSebastian Grimberg } 395a267acd1SJeremy L Thompson CeedCallBackend(CeedFree(&impl->h_offsets_owned)); 396f5d1e504SJeremy L Thompson CeedCallCuda(ceed, cudaFree((CeedInt *)impl->d_offsets_owned)); 397081aa29dSJeremy L Thompson CeedCallCuda(ceed, cudaFree((CeedInt *)impl->d_t_offsets)); 398081aa29dSJeremy L Thompson CeedCallCuda(ceed, cudaFree((CeedInt *)impl->d_t_indices)); 399081aa29dSJeremy L Thompson CeedCallCuda(ceed, cudaFree((CeedInt *)impl->d_l_vec_indices)); 400a267acd1SJeremy L Thompson CeedCallBackend(CeedFree(&impl->h_orients_owned)); 401f5d1e504SJeremy L Thompson CeedCallCuda(ceed, cudaFree((bool *)impl->d_orients_owned)); 402a267acd1SJeremy L Thompson CeedCallBackend(CeedFree(&impl->h_curl_orients_owned)); 403f5d1e504SJeremy L Thompson CeedCallCuda(ceed, cudaFree((CeedInt8 *)impl->d_curl_orients_owned)); 404b20a4af9SJeremy L Thompson CeedCallBackend(CeedFree(&impl->h_offsets_at_points_owned)); 405b20a4af9SJeremy L Thompson CeedCallCuda(ceed, cudaFree((CeedInt *)impl->d_offsets_at_points_owned)); 4060b63de31SJeremy L Thompson CeedCallBackend(CeedFree(&impl->h_points_per_elem_owned)); 4070b63de31SJeremy L Thompson CeedCallCuda(ceed, cudaFree((CeedInt *)impl->d_points_per_elem_owned)); 408ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&impl)); 4099bc66399SJeremy L Thompson CeedCallBackend(CeedDestroy(&ceed)); 410ff1e7120SSebastian Grimberg return CEED_ERROR_SUCCESS; 411ff1e7120SSebastian Grimberg } 412ff1e7120SSebastian Grimberg 413ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 414ff1e7120SSebastian Grimberg // Create transpose offsets and indices 415ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 416b20a4af9SJeremy L Thompson static int CeedElemRestrictionOffset_Cuda(const CeedElemRestriction rstr, const CeedInt elem_size, const CeedInt *indices) { 417ff1e7120SSebastian Grimberg Ceed ceed; 418ca735530SJeremy L Thompson bool *is_node; 419ff1e7120SSebastian Grimberg CeedSize l_size; 420b20a4af9SJeremy L Thompson CeedInt num_elem, num_comp, num_nodes = 0; 421ca735530SJeremy L Thompson CeedInt *ind_to_offset, *l_vec_indices, *t_offsets, *t_indices; 422b20a4af9SJeremy L Thompson CeedRestrictionType rstr_type; 423ca735530SJeremy L Thompson CeedElemRestriction_Cuda *impl; 424ca735530SJeremy L Thompson 425dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 426dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 427dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 428b20a4af9SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetType(rstr, &rstr_type)); 429dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetLVectorSize(rstr, &l_size)); 430dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 431ca735530SJeremy L Thompson const CeedInt size_indices = num_elem * elem_size; 432ff1e7120SSebastian Grimberg 433ff1e7120SSebastian Grimberg // Count num_nodes 434ff1e7120SSebastian Grimberg CeedCallBackend(CeedCalloc(l_size, &is_node)); 435ca735530SJeremy L Thompson 436ff1e7120SSebastian Grimberg for (CeedInt i = 0; i < size_indices; i++) is_node[indices[i]] = 1; 437ff1e7120SSebastian Grimberg for (CeedInt i = 0; i < l_size; i++) num_nodes += is_node[i]; 438ff1e7120SSebastian Grimberg impl->num_nodes = num_nodes; 439ff1e7120SSebastian Grimberg 440ff1e7120SSebastian Grimberg // L-vector offsets array 441ff1e7120SSebastian Grimberg CeedCallBackend(CeedCalloc(l_size, &ind_to_offset)); 442ff1e7120SSebastian Grimberg CeedCallBackend(CeedCalloc(num_nodes, &l_vec_indices)); 443ca735530SJeremy L Thompson for (CeedInt i = 0, j = 0; i < l_size; i++) { 444ff1e7120SSebastian Grimberg if (is_node[i]) { 445ff1e7120SSebastian Grimberg l_vec_indices[j] = i; 446ff1e7120SSebastian Grimberg ind_to_offset[i] = j++; 447ff1e7120SSebastian Grimberg } 448ff1e7120SSebastian Grimberg } 449ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&is_node)); 450ff1e7120SSebastian Grimberg 451ff1e7120SSebastian Grimberg // Compute transpose offsets and indices 452ff1e7120SSebastian Grimberg const CeedInt size_offsets = num_nodes + 1; 453ca735530SJeremy L Thompson 454ff1e7120SSebastian Grimberg CeedCallBackend(CeedCalloc(size_offsets, &t_offsets)); 455ff1e7120SSebastian Grimberg CeedCallBackend(CeedMalloc(size_indices, &t_indices)); 456ff1e7120SSebastian Grimberg // Count node multiplicity 457ff1e7120SSebastian Grimberg for (CeedInt e = 0; e < num_elem; ++e) { 458ff1e7120SSebastian Grimberg for (CeedInt i = 0; i < elem_size; ++i) ++t_offsets[ind_to_offset[indices[elem_size * e + i]] + 1]; 459ff1e7120SSebastian Grimberg } 460ff1e7120SSebastian Grimberg // Convert to running sum 461ff1e7120SSebastian Grimberg for (CeedInt i = 1; i < size_offsets; ++i) t_offsets[i] += t_offsets[i - 1]; 462ff1e7120SSebastian Grimberg // List all E-vec indices associated with L-vec node 463ff1e7120SSebastian Grimberg for (CeedInt e = 0; e < num_elem; ++e) { 464ff1e7120SSebastian Grimberg for (CeedInt i = 0; i < elem_size; ++i) { 465ff1e7120SSebastian Grimberg const CeedInt lid = elem_size * e + i; 466ff1e7120SSebastian Grimberg const CeedInt gid = indices[lid]; 467ca735530SJeremy L Thompson 468ff1e7120SSebastian Grimberg t_indices[t_offsets[ind_to_offset[gid]]++] = lid; 469ff1e7120SSebastian Grimberg } 470ff1e7120SSebastian Grimberg } 471ff1e7120SSebastian Grimberg // Reset running sum 472ff1e7120SSebastian Grimberg for (int i = size_offsets - 1; i > 0; --i) t_offsets[i] = t_offsets[i - 1]; 473ff1e7120SSebastian Grimberg t_offsets[0] = 0; 474ff1e7120SSebastian Grimberg 475ff1e7120SSebastian Grimberg // Copy data to device 476ff1e7120SSebastian Grimberg // -- L-vector indices 477ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_l_vec_indices, num_nodes * sizeof(CeedInt))); 478081aa29dSJeremy L Thompson CeedCallCuda(ceed, cudaMemcpy((CeedInt *)impl->d_l_vec_indices, l_vec_indices, num_nodes * sizeof(CeedInt), cudaMemcpyHostToDevice)); 479ff1e7120SSebastian Grimberg // -- Transpose offsets 480ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_t_offsets, size_offsets * sizeof(CeedInt))); 481081aa29dSJeremy L Thompson CeedCallCuda(ceed, cudaMemcpy((CeedInt *)impl->d_t_offsets, t_offsets, size_offsets * sizeof(CeedInt), cudaMemcpyHostToDevice)); 482ff1e7120SSebastian Grimberg // -- Transpose indices 483ff1e7120SSebastian Grimberg CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_t_indices, size_indices * sizeof(CeedInt))); 484081aa29dSJeremy L Thompson CeedCallCuda(ceed, cudaMemcpy((CeedInt *)impl->d_t_indices, t_indices, size_indices * sizeof(CeedInt), cudaMemcpyHostToDevice)); 485ff1e7120SSebastian Grimberg 486ff1e7120SSebastian Grimberg // Cleanup 487ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&ind_to_offset)); 488ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&l_vec_indices)); 489ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&t_offsets)); 490ff1e7120SSebastian Grimberg CeedCallBackend(CeedFree(&t_indices)); 4919bc66399SJeremy L Thompson CeedCallBackend(CeedDestroy(&ceed)); 492ff1e7120SSebastian Grimberg return CEED_ERROR_SUCCESS; 493ff1e7120SSebastian Grimberg } 494ff1e7120SSebastian Grimberg 495ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 496ff1e7120SSebastian Grimberg // Create restriction 497ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 498a267acd1SJeremy L Thompson int CeedElemRestrictionCreate_Cuda(CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 499dce49693SSebastian Grimberg const CeedInt8 *curl_orients, CeedElemRestriction rstr) { 500ca735530SJeremy L Thompson Ceed ceed, ceed_parent; 501dce49693SSebastian Grimberg bool is_deterministic; 502b20a4af9SJeremy L Thompson CeedInt num_elem, num_comp, elem_size; 503ca735530SJeremy L Thompson CeedRestrictionType rstr_type; 504ff1e7120SSebastian Grimberg CeedElemRestriction_Cuda *impl; 505ca735530SJeremy L Thompson 506dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 507ca735530SJeremy L Thompson CeedCallBackend(CeedGetParent(ceed, &ceed_parent)); 508ca735530SJeremy L Thompson CeedCallBackend(CeedIsDeterministic(ceed_parent, &is_deterministic)); 5099bc66399SJeremy L Thompson CeedCallBackend(CeedDestroy(&ceed_parent)); 510dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumElements(rstr, &num_elem)); 511b20a4af9SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetNumComponents(rstr, &num_comp)); 512dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetElementSize(rstr, &elem_size)); 51322eb1385SJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetType(rstr, &rstr_type)); 514b20a4af9SJeremy L Thompson // Use max number of points as elem size for AtPoints restrictions 515b20a4af9SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 516b20a4af9SJeremy L Thompson CeedInt max_points = 0; 517b20a4af9SJeremy L Thompson 518b20a4af9SJeremy L Thompson for (CeedInt i = 0; i < num_elem; i++) { 519b20a4af9SJeremy L Thompson max_points = CeedIntMax(max_points, offsets[i + 1] - offsets[i]); 520b20a4af9SJeremy L Thompson } 521b20a4af9SJeremy L Thompson elem_size = max_points; 522b20a4af9SJeremy L Thompson } 523ca735530SJeremy L Thompson const CeedInt size = num_elem * elem_size; 524ff1e7120SSebastian Grimberg 525dce49693SSebastian Grimberg CeedCallBackend(CeedCalloc(1, &impl)); 526dce49693SSebastian Grimberg impl->num_nodes = size; 527dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionSetData(rstr, impl)); 52822eb1385SJeremy L Thompson 52922eb1385SJeremy L Thompson // Set layouts 53022eb1385SJeremy L Thompson { 53122eb1385SJeremy L Thompson bool has_backend_strides; 53222eb1385SJeremy L Thompson CeedInt layout[3] = {1, size, elem_size}; 53322eb1385SJeremy L Thompson 534dce49693SSebastian Grimberg CeedCallBackend(CeedElemRestrictionSetELayout(rstr, layout)); 53522eb1385SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_STRIDED) { 53622eb1385SJeremy L Thompson CeedCallBackend(CeedElemRestrictionHasBackendStrides(rstr, &has_backend_strides)); 53722eb1385SJeremy L Thompson if (has_backend_strides) { 53822eb1385SJeremy L Thompson CeedCallBackend(CeedElemRestrictionSetLLayout(rstr, layout)); 53922eb1385SJeremy L Thompson } 54022eb1385SJeremy L Thompson } 54122eb1385SJeremy L Thompson } 542ff1e7120SSebastian Grimberg 543b20a4af9SJeremy L Thompson // Pad AtPoints indices 544b20a4af9SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 545b20a4af9SJeremy L Thompson CeedSize offsets_len = elem_size * num_elem, at_points_size = num_elem + 1; 5460b63de31SJeremy L Thompson CeedInt max_points = elem_size, *offsets_padded, *points_per_elem; 547b20a4af9SJeremy L Thompson 548b20a4af9SJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "only MemType Host supported when creating AtPoints restriction"); 549b20a4af9SJeremy L Thompson CeedCallBackend(CeedMalloc(offsets_len, &offsets_padded)); 5500b63de31SJeremy L Thompson CeedCallBackend(CeedMalloc(num_elem, &points_per_elem)); 551b20a4af9SJeremy L Thompson for (CeedInt i = 0; i < num_elem; i++) { 552b20a4af9SJeremy L Thompson CeedInt num_points = offsets[i + 1] - offsets[i]; 553*dbab1186SZach Atkins CeedInt last_point = 0; 554b20a4af9SJeremy L Thompson 5550b63de31SJeremy L Thompson points_per_elem[i] = num_points; 556b20a4af9SJeremy L Thompson at_points_size += num_points; 557b20a4af9SJeremy L Thompson // -- Copy all points in element 558b20a4af9SJeremy L Thompson for (CeedInt j = 0; j < num_points; j++) { 5598be297eeSJeremy L Thompson offsets_padded[i * max_points + j] = offsets[offsets[i] + j] * num_comp; 5608c76f877SZach Atkins last_point = offsets_padded[i * max_points + j]; 561b20a4af9SJeremy L Thompson } 562b20a4af9SJeremy L Thompson // -- Replicate out last point in element 563b20a4af9SJeremy L Thompson for (CeedInt j = num_points; j < max_points; j++) { 5648c76f877SZach Atkins offsets_padded[i * max_points + j] = last_point; 565b20a4af9SJeremy L Thompson } 566b20a4af9SJeremy L Thompson } 567b20a4af9SJeremy L Thompson CeedCallBackend(CeedSetHostCeedIntArray(offsets, copy_mode, at_points_size, &impl->h_offsets_at_points_owned, &impl->h_offsets_at_points_borrowed, 568b20a4af9SJeremy L Thompson &impl->h_offsets_at_points)); 569b20a4af9SJeremy L Thompson CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_offsets_at_points_owned, at_points_size * sizeof(CeedInt))); 570b20a4af9SJeremy L Thompson CeedCallCuda(ceed, cudaMemcpy((CeedInt **)impl->d_offsets_at_points_owned, impl->h_offsets_at_points, at_points_size * sizeof(CeedInt), 571b20a4af9SJeremy L Thompson cudaMemcpyHostToDevice)); 572b20a4af9SJeremy L Thompson impl->d_offsets_at_points = (CeedInt *)impl->d_offsets_at_points_owned; 573b20a4af9SJeremy L Thompson 574b20a4af9SJeremy L Thompson // -- Use padded offsets for the rest of the setup 575b20a4af9SJeremy L Thompson offsets = (const CeedInt *)offsets_padded; 576b20a4af9SJeremy L Thompson copy_mode = CEED_OWN_POINTER; 5772e88d319SJeremy L Thompson CeedCallBackend(CeedElemRestrictionSetAtPointsEVectorSize(rstr, elem_size * num_elem * num_comp)); 5780b63de31SJeremy L Thompson 5790b63de31SJeremy L Thompson // -- Points per element 5800b63de31SJeremy L Thompson CeedCallBackend(CeedSetHostCeedIntArray(points_per_elem, CEED_OWN_POINTER, num_elem, &impl->h_points_per_elem_owned, 5810b63de31SJeremy L Thompson &impl->h_points_per_elem_borrowed, &impl->h_points_per_elem)); 5820b63de31SJeremy L Thompson CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_points_per_elem_owned, num_elem * sizeof(CeedInt))); 5830b63de31SJeremy L Thompson CeedCallCuda(ceed, 5840b63de31SJeremy L Thompson cudaMemcpy((CeedInt **)impl->d_points_per_elem_owned, impl->h_points_per_elem, num_elem * sizeof(CeedInt), cudaMemcpyHostToDevice)); 5850b63de31SJeremy L Thompson impl->d_points_per_elem = (CeedInt *)impl->d_points_per_elem_owned; 586b20a4af9SJeremy L Thompson } 587b20a4af9SJeremy L Thompson 588dce49693SSebastian Grimberg // Set up device offset/orientation arrays 589dce49693SSebastian Grimberg if (rstr_type != CEED_RESTRICTION_STRIDED) { 590ff1e7120SSebastian Grimberg switch (mem_type) { 591ff1e7120SSebastian Grimberg case CEED_MEM_HOST: { 592f5d1e504SJeremy L Thompson CeedCallBackend(CeedSetHostCeedIntArray(offsets, copy_mode, size, &impl->h_offsets_owned, &impl->h_offsets_borrowed, &impl->h_offsets)); 593a267acd1SJeremy L Thompson CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_offsets_owned, size * sizeof(CeedInt))); 594f5d1e504SJeremy L Thompson CeedCallCuda(ceed, cudaMemcpy((CeedInt *)impl->d_offsets_owned, impl->h_offsets, size * sizeof(CeedInt), cudaMemcpyHostToDevice)); 595f5d1e504SJeremy L Thompson impl->d_offsets = (CeedInt *)impl->d_offsets_owned; 596b20a4af9SJeremy L Thompson if (is_deterministic) CeedCallBackend(CeedElemRestrictionOffset_Cuda(rstr, elem_size, offsets)); 597dce49693SSebastian Grimberg } break; 598ff1e7120SSebastian Grimberg case CEED_MEM_DEVICE: { 599f5d1e504SJeremy L Thompson CeedCallBackend(CeedSetDeviceCeedIntArray_Cuda(ceed, offsets, copy_mode, size, &impl->d_offsets_owned, &impl->d_offsets_borrowed, 600f5d1e504SJeremy L Thompson (const CeedInt **)&impl->d_offsets)); 601a267acd1SJeremy L Thompson CeedCallBackend(CeedMalloc(size, &impl->h_offsets_owned)); 602f5d1e504SJeremy L Thompson CeedCallCuda(ceed, cudaMemcpy((CeedInt *)impl->h_offsets_owned, impl->d_offsets, size * sizeof(CeedInt), cudaMemcpyDeviceToHost)); 603a267acd1SJeremy L Thompson impl->h_offsets = impl->h_offsets_owned; 604b20a4af9SJeremy L Thompson if (is_deterministic) CeedCallBackend(CeedElemRestrictionOffset_Cuda(rstr, elem_size, offsets)); 605dce49693SSebastian Grimberg } break; 606ff1e7120SSebastian Grimberg } 607ff1e7120SSebastian Grimberg 608dce49693SSebastian Grimberg // Orientation data 609dce49693SSebastian Grimberg if (rstr_type == CEED_RESTRICTION_ORIENTED) { 610dce49693SSebastian Grimberg switch (mem_type) { 611dce49693SSebastian Grimberg case CEED_MEM_HOST: { 612f5d1e504SJeremy L Thompson CeedCallBackend(CeedSetHostBoolArray(orients, copy_mode, size, &impl->h_orients_owned, &impl->h_orients_borrowed, &impl->h_orients)); 613a267acd1SJeremy L Thompson CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_orients_owned, size * sizeof(bool))); 614f5d1e504SJeremy L Thompson CeedCallCuda(ceed, cudaMemcpy((bool *)impl->d_orients_owned, impl->h_orients, size * sizeof(bool), cudaMemcpyHostToDevice)); 615a267acd1SJeremy L Thompson impl->d_orients = impl->d_orients_owned; 616dce49693SSebastian Grimberg } break; 617dce49693SSebastian Grimberg case CEED_MEM_DEVICE: { 618f5d1e504SJeremy L Thompson CeedCallBackend(CeedSetDeviceBoolArray_Cuda(ceed, orients, copy_mode, size, &impl->d_orients_owned, &impl->d_orients_borrowed, 619f5d1e504SJeremy L Thompson (const bool **)&impl->d_orients)); 620a267acd1SJeremy L Thompson CeedCallBackend(CeedMalloc(size, &impl->h_orients_owned)); 621f5d1e504SJeremy L Thompson CeedCallCuda(ceed, cudaMemcpy((bool *)impl->h_orients_owned, impl->d_orients, size * sizeof(bool), cudaMemcpyDeviceToHost)); 622a267acd1SJeremy L Thompson impl->h_orients = impl->h_orients_owned; 623dce49693SSebastian Grimberg } break; 624dce49693SSebastian Grimberg } 625dce49693SSebastian Grimberg } else if (rstr_type == CEED_RESTRICTION_CURL_ORIENTED) { 626dce49693SSebastian Grimberg switch (mem_type) { 627dce49693SSebastian Grimberg case CEED_MEM_HOST: { 628f5d1e504SJeremy L Thompson CeedCallBackend(CeedSetHostCeedInt8Array(curl_orients, copy_mode, 3 * size, &impl->h_curl_orients_owned, &impl->h_curl_orients_borrowed, 629f5d1e504SJeremy L Thompson &impl->h_curl_orients)); 630a267acd1SJeremy L Thompson CeedCallCuda(ceed, cudaMalloc((void **)&impl->d_curl_orients_owned, 3 * size * sizeof(CeedInt8))); 631f5d1e504SJeremy L Thompson CeedCallCuda(ceed, 632f5d1e504SJeremy L Thompson cudaMemcpy((CeedInt8 *)impl->d_curl_orients_owned, impl->h_curl_orients, 3 * size * sizeof(CeedInt8), cudaMemcpyHostToDevice)); 633a267acd1SJeremy L Thompson impl->d_curl_orients = impl->d_curl_orients_owned; 634dce49693SSebastian Grimberg } break; 635dce49693SSebastian Grimberg case CEED_MEM_DEVICE: { 636f5d1e504SJeremy L Thompson CeedCallBackend(CeedSetDeviceCeedInt8Array_Cuda(ceed, curl_orients, copy_mode, 3 * size, &impl->d_curl_orients_owned, 637f5d1e504SJeremy L Thompson &impl->d_curl_orients_borrowed, (const CeedInt8 **)&impl->d_curl_orients)); 638a267acd1SJeremy L Thompson CeedCallBackend(CeedMalloc(3 * size, &impl->h_curl_orients_owned)); 639f5d1e504SJeremy L Thompson CeedCallCuda(ceed, 640f5d1e504SJeremy L Thompson cudaMemcpy((CeedInt8 *)impl->h_curl_orients_owned, impl->d_curl_orients, 3 * size * sizeof(CeedInt8), cudaMemcpyDeviceToHost)); 641a267acd1SJeremy L Thompson impl->h_curl_orients = impl->h_curl_orients_owned; 642dce49693SSebastian Grimberg } break; 643dce49693SSebastian Grimberg } 644dce49693SSebastian Grimberg } 645dce49693SSebastian Grimberg } 646ca735530SJeremy L Thompson 647ff1e7120SSebastian Grimberg // Register backend functions 648dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "Apply", CeedElemRestrictionApply_Cuda)); 649dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "ApplyUnsigned", CeedElemRestrictionApplyUnsigned_Cuda)); 650dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "ApplyUnoriented", CeedElemRestrictionApplyUnoriented_Cuda)); 651dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "GetOffsets", CeedElemRestrictionGetOffsets_Cuda)); 652dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "GetOrientations", CeedElemRestrictionGetOrientations_Cuda)); 653dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "GetCurlOrientations", CeedElemRestrictionGetCurlOrientations_Cuda)); 654b20a4af9SJeremy L Thompson if (rstr_type == CEED_RESTRICTION_POINTS) { 6551a8516d0SJames Wright CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "GetAtPointsElementOffset", 6561a8516d0SJames Wright CeedElemRestrictionGetAtPointsElementOffset_Cuda)); 657b20a4af9SJeremy L Thompson } 658dce49693SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "Destroy", CeedElemRestrictionDestroy_Cuda)); 6599bc66399SJeremy L Thompson CeedCallBackend(CeedDestroy(&ceed)); 660ff1e7120SSebastian Grimberg return CEED_ERROR_SUCCESS; 661ff1e7120SSebastian Grimberg } 662ff1e7120SSebastian Grimberg 663ff1e7120SSebastian Grimberg //------------------------------------------------------------------------------ 664