xref: /libCEED/rust/libceed-sys/c-src/backends/hip-ref/ceed-hip-ref-restriction.c (revision 509d4af65d23546c690c9766d8b29e47dc3b3afb)
15aed82e4SJeremy L Thompson // Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
30d0321e0SJeremy L Thompson //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
50d0321e0SJeremy L Thompson //
63d8e8822SJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
70d0321e0SJeremy L Thompson 
849aac155SJeremy L Thompson #include <ceed.h>
90d0321e0SJeremy L Thompson #include <ceed/backend.h>
10437930d1SJeremy L Thompson #include <ceed/jit-tools.h>
110d0321e0SJeremy L Thompson #include <stdbool.h>
120d0321e0SJeremy L Thompson #include <stddef.h>
1344d7a66cSJeremy L Thompson #include <string.h>
14c85e8640SSebastian Grimberg #include <hip/hip_runtime.h>
152b730f8bSJeremy L Thompson 
1649aac155SJeremy L Thompson #include "../hip/ceed-hip-common.h"
170d0321e0SJeremy L Thompson #include "../hip/ceed-hip-compile.h"
182b730f8bSJeremy L Thompson #include "ceed-hip-ref.h"
190d0321e0SJeremy L Thompson 
200d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
21cf8cbdd6SSebastian Grimberg // Compile restriction kernels
22cf8cbdd6SSebastian Grimberg //------------------------------------------------------------------------------
23cf8cbdd6SSebastian Grimberg static inline int CeedElemRestrictionSetupCompile_Hip(CeedElemRestriction rstr) {
24cf8cbdd6SSebastian Grimberg   Ceed                     ceed;
25cf8cbdd6SSebastian Grimberg   bool                     is_deterministic;
2622070f95SJeremy L Thompson   char                    *restriction_kernel_source;
2722070f95SJeremy L Thompson   const char              *restriction_kernel_path;
28cf8cbdd6SSebastian Grimberg   CeedInt                  num_elem, num_comp, elem_size, comp_stride;
29cf8cbdd6SSebastian Grimberg   CeedRestrictionType      rstr_type;
30cf8cbdd6SSebastian Grimberg   CeedElemRestriction_Hip *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 HIP kernels
42cf8cbdd6SSebastian Grimberg   switch (rstr_type) {
43cf8cbdd6SSebastian Grimberg     case CEED_RESTRICTION_STRIDED: {
44cf8cbdd6SSebastian Grimberg       bool    has_backend_strides;
45*509d4af6SJeremy L Thompson       CeedInt strides[3] = {1, num_elem * elem_size, elem_size};
46cf8cbdd6SSebastian Grimberg 
47cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedElemRestrictionHasBackendStrides(rstr, &has_backend_strides));
48cf8cbdd6SSebastian Grimberg       if (!has_backend_strides) {
4956c48462SJeremy L Thompson         CeedCallBackend(CeedElemRestrictionGetStrides(rstr, strides));
50cf8cbdd6SSebastian Grimberg       }
51cf8cbdd6SSebastian Grimberg 
52cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetJitAbsolutePath(ceed, "ceed/jit-source/hip/hip-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_Hip(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_Hip(ceed, impl->module, "StridedNoTranspose", &impl->ApplyNoTranspose));
60cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetKernel_Hip(ceed, impl->module, "StridedTranspose", &impl->ApplyTranspose));
61cf8cbdd6SSebastian Grimberg     } break;
62cf8cbdd6SSebastian Grimberg     case CEED_RESTRICTION_STANDARD: {
63cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetJitAbsolutePath(ceed, "ceed/jit-source/hip/hip-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_Hip(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_Hip(ceed, impl->module, "OffsetNoTranspose", &impl->ApplyNoTranspose));
71cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetKernel_Hip(ceed, impl->module, "OffsetTranspose", &impl->ApplyTranspose));
72cf8cbdd6SSebastian Grimberg     } break;
73cf8cbdd6SSebastian Grimberg     case CEED_RESTRICTION_ORIENTED: {
7422070f95SJeremy L Thompson       const char *offset_kernel_path;
75*509d4af6SJeremy L Thompson       char      **file_paths     = NULL;
76*509d4af6SJeremy L Thompson       CeedInt     num_file_paths = 0;
77cf8cbdd6SSebastian Grimberg 
78cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetJitAbsolutePath(ceed, "ceed/jit-source/hip/hip-ref-restriction-oriented.h", &restriction_kernel_path));
79cf8cbdd6SSebastian Grimberg       CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "----- Loading Restriction Kernel Source -----\n");
80*509d4af6SJeremy L Thompson       CeedCallBackend(CeedLoadSourceAndInitializeBuffer(ceed, restriction_kernel_path, &num_file_paths, &file_paths, &restriction_kernel_source));
81cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetJitAbsolutePath(ceed, "ceed/jit-source/hip/hip-ref-restriction-offset.h", &offset_kernel_path));
82*509d4af6SJeremy L Thompson       CeedCallBackend(CeedLoadSourceToInitializedBuffer(ceed, offset_kernel_path, &num_file_paths, &file_paths, &restriction_kernel_source));
83cf8cbdd6SSebastian Grimberg       CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "----- Loading Restriction Kernel Source Complete! -----\n");
84cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedCompile_Hip(ceed, restriction_kernel_source, &impl->module, 6, "RSTR_ELEM_SIZE", elem_size, "RSTR_NUM_ELEM", num_elem,
85cf8cbdd6SSebastian Grimberg                                       "RSTR_NUM_COMP", num_comp, "RSTR_NUM_NODES", impl->num_nodes, "RSTR_COMP_STRIDE", comp_stride,
86cf8cbdd6SSebastian Grimberg                                       "USE_DETERMINISTIC", is_deterministic ? 1 : 0));
87cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetKernel_Hip(ceed, impl->module, "OrientedNoTranspose", &impl->ApplyNoTranspose));
88cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetKernel_Hip(ceed, impl->module, "OffsetNoTranspose", &impl->ApplyUnsignedNoTranspose));
89cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetKernel_Hip(ceed, impl->module, "OrientedTranspose", &impl->ApplyTranspose));
90cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetKernel_Hip(ceed, impl->module, "OffsetTranspose", &impl->ApplyUnsignedTranspose));
91*509d4af6SJeremy L Thompson       // Cleanup
92cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedFree(&offset_kernel_path));
93*509d4af6SJeremy L Thompson       for (CeedInt i = 0; i < num_file_paths; i++) CeedCall(CeedFree(&file_paths[i]));
94*509d4af6SJeremy L Thompson       CeedCall(CeedFree(&file_paths));
95cf8cbdd6SSebastian Grimberg     } break;
96cf8cbdd6SSebastian Grimberg     case CEED_RESTRICTION_CURL_ORIENTED: {
9722070f95SJeremy L Thompson       const char *offset_kernel_path;
98*509d4af6SJeremy L Thompson       char      **file_paths     = NULL;
99*509d4af6SJeremy L Thompson       CeedInt     num_file_paths = 0;
100cf8cbdd6SSebastian Grimberg 
101cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetJitAbsolutePath(ceed, "ceed/jit-source/hip/hip-ref-restriction-curl-oriented.h", &restriction_kernel_path));
102cf8cbdd6SSebastian Grimberg       CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "----- Loading Restriction Kernel Source -----\n");
103*509d4af6SJeremy L Thompson       CeedCallBackend(CeedLoadSourceAndInitializeBuffer(ceed, restriction_kernel_path, &num_file_paths, &file_paths, &restriction_kernel_source));
104cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetJitAbsolutePath(ceed, "ceed/jit-source/hip/hip-ref-restriction-offset.h", &offset_kernel_path));
105*509d4af6SJeremy L Thompson       CeedCallBackend(CeedLoadSourceToInitializedBuffer(ceed, offset_kernel_path, &num_file_paths, &file_paths, &restriction_kernel_source));
106cf8cbdd6SSebastian Grimberg       CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "----- Loading Restriction Kernel Source Complete! -----\n");
107cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedCompile_Hip(ceed, restriction_kernel_source, &impl->module, 6, "RSTR_ELEM_SIZE", elem_size, "RSTR_NUM_ELEM", num_elem,
108cf8cbdd6SSebastian Grimberg                                       "RSTR_NUM_COMP", num_comp, "RSTR_NUM_NODES", impl->num_nodes, "RSTR_COMP_STRIDE", comp_stride,
109cf8cbdd6SSebastian Grimberg                                       "USE_DETERMINISTIC", is_deterministic ? 1 : 0));
110cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetKernel_Hip(ceed, impl->module, "CurlOrientedNoTranspose", &impl->ApplyNoTranspose));
111cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetKernel_Hip(ceed, impl->module, "CurlOrientedUnsignedNoTranspose", &impl->ApplyUnsignedNoTranspose));
112cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetKernel_Hip(ceed, impl->module, "OffsetNoTranspose", &impl->ApplyUnorientedNoTranspose));
113cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetKernel_Hip(ceed, impl->module, "CurlOrientedTranspose", &impl->ApplyTranspose));
114cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetKernel_Hip(ceed, impl->module, "CurlOrientedUnsignedTranspose", &impl->ApplyUnsignedTranspose));
115cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedGetKernel_Hip(ceed, impl->module, "OffsetTranspose", &impl->ApplyUnorientedTranspose));
116*509d4af6SJeremy L Thompson       // Cleanup
117cf8cbdd6SSebastian Grimberg       CeedCallBackend(CeedFree(&offset_kernel_path));
118*509d4af6SJeremy L Thompson       for (CeedInt i = 0; i < num_file_paths; i++) CeedCall(CeedFree(&file_paths[i]));
119*509d4af6SJeremy L Thompson       CeedCall(CeedFree(&file_paths));
120cf8cbdd6SSebastian Grimberg     } break;
121cf8cbdd6SSebastian Grimberg     case CEED_RESTRICTION_POINTS: {
122cf8cbdd6SSebastian Grimberg       // LCOV_EXCL_START
123cf8cbdd6SSebastian Grimberg       return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement restriction CeedElemRestrictionAtPoints");
124cf8cbdd6SSebastian Grimberg       // LCOV_EXCL_STOP
125cf8cbdd6SSebastian Grimberg     } break;
126cf8cbdd6SSebastian Grimberg   }
127cf8cbdd6SSebastian Grimberg   CeedCallBackend(CeedFree(&restriction_kernel_path));
128cf8cbdd6SSebastian Grimberg   CeedCallBackend(CeedFree(&restriction_kernel_source));
129cf8cbdd6SSebastian Grimberg   return CEED_ERROR_SUCCESS;
130cf8cbdd6SSebastian Grimberg }
131cf8cbdd6SSebastian Grimberg 
132cf8cbdd6SSebastian Grimberg //------------------------------------------------------------------------------
133dce49693SSebastian Grimberg // Core apply restriction code
1340d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
135dce49693SSebastian Grimberg static inline int CeedElemRestrictionApply_Hip_Core(CeedElemRestriction rstr, CeedTransposeMode t_mode, bool use_signs, bool use_orients,
136dce49693SSebastian Grimberg                                                     CeedVector u, CeedVector v, CeedRequest *request) {
1370d0321e0SJeremy L Thompson   Ceed                     ceed;
138dce49693SSebastian Grimberg   CeedRestrictionType      rstr_type;
1390d0321e0SJeremy L Thompson   const CeedScalar        *d_u;
1400d0321e0SJeremy L Thompson   CeedScalar              *d_v;
141b7453713SJeremy L Thompson   CeedElemRestriction_Hip *impl;
142b7453713SJeremy L Thompson 
143dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
144dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
145dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetType(rstr, &rstr_type));
146cf8cbdd6SSebastian Grimberg 
147cf8cbdd6SSebastian Grimberg   // Assemble kernel if needed
148cf8cbdd6SSebastian Grimberg   if (!impl->module) {
149cf8cbdd6SSebastian Grimberg     CeedCallBackend(CeedElemRestrictionSetupCompile_Hip(rstr));
150cf8cbdd6SSebastian Grimberg   }
151b7453713SJeremy L Thompson 
152b7453713SJeremy L Thompson   // Get vectors
1532b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetArrayRead(u, CEED_MEM_DEVICE, &d_u));
154437930d1SJeremy L Thompson   if (t_mode == CEED_TRANSPOSE) {
1550d0321e0SJeremy L Thompson     // Sum into for transpose mode, e-vec to l-vec
1562b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorGetArray(v, CEED_MEM_DEVICE, &d_v));
1570d0321e0SJeremy L Thompson   } else {
1580d0321e0SJeremy L Thompson     // Overwrite for notranspose mode, l-vec to e-vec
1592b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorGetArrayWrite(v, CEED_MEM_DEVICE, &d_v));
1600d0321e0SJeremy L Thompson   }
1610d0321e0SJeremy L Thompson 
1620d0321e0SJeremy L Thompson   // Restrict
163437930d1SJeremy L Thompson   if (t_mode == CEED_NOTRANSPOSE) {
1640d0321e0SJeremy L Thompson     // L-vector -> E-vector
165cf8cbdd6SSebastian Grimberg     CeedInt elem_size;
166cf8cbdd6SSebastian Grimberg 
167cf8cbdd6SSebastian Grimberg     CeedCallBackend(CeedElemRestrictionGetElementSize(rstr, &elem_size));
168dce49693SSebastian Grimberg     const CeedInt block_size = elem_size < 256 ? (elem_size > 64 ? elem_size : 64) : 256;
169cf8cbdd6SSebastian Grimberg     const CeedInt grid       = CeedDivUpInt(impl->num_nodes, block_size);
17058549094SSebastian Grimberg 
171dce49693SSebastian Grimberg     switch (rstr_type) {
172dce49693SSebastian Grimberg       case CEED_RESTRICTION_STRIDED: {
173cf8cbdd6SSebastian Grimberg         void *args[] = {&d_u, &d_v};
17458549094SSebastian Grimberg 
175cf8cbdd6SSebastian Grimberg         CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyNoTranspose, grid, block_size, args));
176dce49693SSebastian Grimberg       } break;
177dce49693SSebastian Grimberg       case CEED_RESTRICTION_STANDARD: {
178a267acd1SJeremy L Thompson         void *args[] = {&impl->d_offsets, &d_u, &d_v};
179dce49693SSebastian Grimberg 
180cf8cbdd6SSebastian Grimberg         CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyNoTranspose, grid, block_size, args));
181dce49693SSebastian Grimberg       } break;
182dce49693SSebastian Grimberg       case CEED_RESTRICTION_ORIENTED: {
183dce49693SSebastian Grimberg         if (use_signs) {
184a267acd1SJeremy L Thompson           void *args[] = {&impl->d_offsets, &impl->d_orients, &d_u, &d_v};
185dce49693SSebastian Grimberg 
186cf8cbdd6SSebastian Grimberg           CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyNoTranspose, grid, block_size, args));
187dce49693SSebastian Grimberg         } else {
188a267acd1SJeremy L Thompson           void *args[] = {&impl->d_offsets, &d_u, &d_v};
189dce49693SSebastian Grimberg 
190cf8cbdd6SSebastian Grimberg           CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyUnsignedNoTranspose, grid, block_size, args));
191dce49693SSebastian Grimberg         }
192dce49693SSebastian Grimberg       } break;
193dce49693SSebastian Grimberg       case CEED_RESTRICTION_CURL_ORIENTED: {
194dce49693SSebastian Grimberg         if (use_signs && use_orients) {
195a267acd1SJeremy L Thompson           void *args[] = {&impl->d_offsets, &impl->d_curl_orients, &d_u, &d_v};
196dce49693SSebastian Grimberg 
197cf8cbdd6SSebastian Grimberg           CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyNoTranspose, grid, block_size, args));
198dce49693SSebastian Grimberg         } else if (use_orients) {
199a267acd1SJeremy L Thompson           void *args[] = {&impl->d_offsets, &impl->d_curl_orients, &d_u, &d_v};
200dce49693SSebastian Grimberg 
201cf8cbdd6SSebastian Grimberg           CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyUnsignedNoTranspose, grid, block_size, args));
202dce49693SSebastian Grimberg         } else {
203a267acd1SJeremy L Thompson           void *args[] = {&impl->d_offsets, &d_u, &d_v};
204dce49693SSebastian Grimberg 
205cf8cbdd6SSebastian Grimberg           CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyUnorientedNoTranspose, grid, block_size, args));
206dce49693SSebastian Grimberg         }
207dce49693SSebastian Grimberg       } break;
208b3d03e38SSebastian Grimberg       case CEED_RESTRICTION_POINTS: {
209b3d03e38SSebastian Grimberg         // LCOV_EXCL_START
210b3d03e38SSebastian Grimberg         return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement restriction CeedElemRestrictionAtPoints");
211b3d03e38SSebastian Grimberg         // LCOV_EXCL_STOP
212b3d03e38SSebastian Grimberg       } break;
2130d0321e0SJeremy L Thompson     }
2140d0321e0SJeremy L Thompson   } else {
2150d0321e0SJeremy L Thompson     // E-vector -> L-vector
216cf8cbdd6SSebastian Grimberg     const bool    is_deterministic = impl->d_l_vec_indices != NULL;
217dce49693SSebastian Grimberg     const CeedInt block_size       = 64;
218cf8cbdd6SSebastian Grimberg     const CeedInt grid             = CeedDivUpInt(impl->num_nodes, block_size);
219b7453713SJeremy L Thompson 
220dce49693SSebastian Grimberg     switch (rstr_type) {
221dce49693SSebastian Grimberg       case CEED_RESTRICTION_STRIDED: {
222cf8cbdd6SSebastian Grimberg         void *args[] = {&d_u, &d_v};
223dce49693SSebastian Grimberg 
224cf8cbdd6SSebastian Grimberg         CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyTranspose, grid, block_size, args));
225dce49693SSebastian Grimberg       } break;
226dce49693SSebastian Grimberg       case CEED_RESTRICTION_STANDARD: {
227cf8cbdd6SSebastian Grimberg         if (!is_deterministic) {
228a267acd1SJeremy L Thompson           void *args[] = {&impl->d_offsets, &d_u, &d_v};
22958549094SSebastian Grimberg 
230cf8cbdd6SSebastian Grimberg           CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyTranspose, grid, block_size, args));
2310d0321e0SJeremy L Thompson         } else {
23258549094SSebastian Grimberg           void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &d_u, &d_v};
23358549094SSebastian Grimberg 
234cf8cbdd6SSebastian Grimberg           CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyTranspose, grid, block_size, args));
23558549094SSebastian Grimberg         }
236dce49693SSebastian Grimberg       } break;
237dce49693SSebastian Grimberg       case CEED_RESTRICTION_ORIENTED: {
238dce49693SSebastian Grimberg         if (use_signs) {
239cf8cbdd6SSebastian Grimberg           if (!is_deterministic) {
240a267acd1SJeremy L Thompson             void *args[] = {&impl->d_offsets, &impl->d_orients, &d_u, &d_v};
24158549094SSebastian Grimberg 
242cf8cbdd6SSebastian Grimberg             CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyTranspose, grid, block_size, args));
243dce49693SSebastian Grimberg           } else {
2447aa91133SSebastian Grimberg             void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &impl->d_orients, &d_u, &d_v};
2457aa91133SSebastian Grimberg 
246cf8cbdd6SSebastian Grimberg             CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyTranspose, grid, block_size, args));
2477aa91133SSebastian Grimberg           }
2487aa91133SSebastian Grimberg         } else {
249cf8cbdd6SSebastian Grimberg           if (!is_deterministic) {
250a267acd1SJeremy L Thompson             void *args[] = {&impl->d_offsets, &d_u, &d_v};
251dce49693SSebastian Grimberg 
252cf8cbdd6SSebastian Grimberg             CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyUnsignedTranspose, grid, block_size, args));
253dce49693SSebastian Grimberg           } else {
254dce49693SSebastian Grimberg             void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &d_u, &d_v};
255dce49693SSebastian Grimberg 
256cf8cbdd6SSebastian Grimberg             CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyUnsignedTranspose, grid, block_size, args));
257dce49693SSebastian Grimberg           }
258dce49693SSebastian Grimberg         }
259dce49693SSebastian Grimberg       } break;
260dce49693SSebastian Grimberg       case CEED_RESTRICTION_CURL_ORIENTED: {
261dce49693SSebastian Grimberg         if (use_signs && use_orients) {
262cf8cbdd6SSebastian Grimberg           if (!is_deterministic) {
263a267acd1SJeremy L Thompson             void *args[] = {&impl->d_offsets, &impl->d_curl_orients, &d_u, &d_v};
264dce49693SSebastian Grimberg 
265cf8cbdd6SSebastian Grimberg             CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyTranspose, grid, block_size, args));
2667aa91133SSebastian 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_Hip(ceed, impl->ApplyTranspose, grid, block_size, args));
2707aa91133SSebastian Grimberg           }
271dce49693SSebastian Grimberg         } else if (use_orients) {
272cf8cbdd6SSebastian Grimberg           if (!is_deterministic) {
273a267acd1SJeremy L Thompson             void *args[] = {&impl->d_offsets, &impl->d_curl_orients, &d_u, &d_v};
274dce49693SSebastian Grimberg 
275cf8cbdd6SSebastian Grimberg             CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyUnsignedTranspose, grid, block_size, args));
276dce49693SSebastian Grimberg           } else {
2777aa91133SSebastian Grimberg             void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &impl->d_curl_orients, &d_u, &d_v};
2787aa91133SSebastian Grimberg 
279cf8cbdd6SSebastian Grimberg             CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyUnsignedTranspose, grid, block_size, args));
2807aa91133SSebastian Grimberg           }
2817aa91133SSebastian Grimberg         } else {
282cf8cbdd6SSebastian Grimberg           if (!is_deterministic) {
283a267acd1SJeremy L Thompson             void *args[] = {&impl->d_offsets, &d_u, &d_v};
284dce49693SSebastian Grimberg 
285cf8cbdd6SSebastian Grimberg             CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyUnorientedTranspose, grid, block_size, args));
286dce49693SSebastian Grimberg           } else {
287dce49693SSebastian Grimberg             void *args[] = {&impl->d_l_vec_indices, &impl->d_t_indices, &impl->d_t_offsets, &d_u, &d_v};
288dce49693SSebastian Grimberg 
289cf8cbdd6SSebastian Grimberg             CeedCallBackend(CeedRunKernel_Hip(ceed, impl->ApplyUnorientedTranspose, grid, block_size, args));
290dce49693SSebastian Grimberg           }
291dce49693SSebastian Grimberg         }
292dce49693SSebastian Grimberg       } break;
293b3d03e38SSebastian Grimberg       case CEED_RESTRICTION_POINTS: {
294b3d03e38SSebastian Grimberg         // LCOV_EXCL_START
295b3d03e38SSebastian Grimberg         return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement restriction CeedElemRestrictionAtPoints");
296b3d03e38SSebastian Grimberg         // LCOV_EXCL_STOP
297b3d03e38SSebastian Grimberg       } break;
2980d0321e0SJeremy L Thompson     }
2990d0321e0SJeremy L Thompson   }
3000d0321e0SJeremy L Thompson 
3012b730f8bSJeremy L Thompson   if (request != CEED_REQUEST_IMMEDIATE && request != CEED_REQUEST_ORDERED) *request = NULL;
3020d0321e0SJeremy L Thompson 
3030d0321e0SJeremy L Thompson   // Restore arrays
3042b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorRestoreArrayRead(u, &d_u));
3052b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorRestoreArray(v, &d_v));
3060d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3070d0321e0SJeremy L Thompson }
3080d0321e0SJeremy L Thompson 
3090d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
310dce49693SSebastian Grimberg // Apply restriction
311dce49693SSebastian Grimberg //------------------------------------------------------------------------------
312dce49693SSebastian Grimberg static int CeedElemRestrictionApply_Hip(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) {
313dce49693SSebastian Grimberg   return CeedElemRestrictionApply_Hip_Core(rstr, t_mode, true, true, u, v, request);
314dce49693SSebastian Grimberg }
315dce49693SSebastian Grimberg 
316dce49693SSebastian Grimberg //------------------------------------------------------------------------------
317dce49693SSebastian Grimberg // Apply unsigned restriction
318dce49693SSebastian Grimberg //------------------------------------------------------------------------------
319dce49693SSebastian Grimberg static int CeedElemRestrictionApplyUnsigned_Hip(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
320dce49693SSebastian Grimberg                                                 CeedRequest *request) {
321dce49693SSebastian Grimberg   return CeedElemRestrictionApply_Hip_Core(rstr, t_mode, false, true, u, v, request);
322dce49693SSebastian Grimberg }
323dce49693SSebastian Grimberg 
324dce49693SSebastian Grimberg //------------------------------------------------------------------------------
325dce49693SSebastian Grimberg // Apply unoriented restriction
326dce49693SSebastian Grimberg //------------------------------------------------------------------------------
327dce49693SSebastian Grimberg static int CeedElemRestrictionApplyUnoriented_Hip(CeedElemRestriction rstr, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
328dce49693SSebastian Grimberg                                                   CeedRequest *request) {
329dce49693SSebastian Grimberg   return CeedElemRestrictionApply_Hip_Core(rstr, t_mode, false, false, u, v, request);
330dce49693SSebastian Grimberg }
331dce49693SSebastian Grimberg 
332dce49693SSebastian Grimberg //------------------------------------------------------------------------------
3330d0321e0SJeremy L Thompson // Get offsets
3340d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
335472941f0SJeremy L Thompson static int CeedElemRestrictionGetOffsets_Hip(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) {
3360d0321e0SJeremy L Thompson   CeedElemRestriction_Hip *impl;
3370d0321e0SJeremy L Thompson 
338b7453713SJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
339472941f0SJeremy L Thompson   switch (mem_type) {
3400d0321e0SJeremy L Thompson     case CEED_MEM_HOST:
341a267acd1SJeremy L Thompson       *offsets = impl->h_offsets;
3420d0321e0SJeremy L Thompson       break;
3430d0321e0SJeremy L Thompson     case CEED_MEM_DEVICE:
344a267acd1SJeremy L Thompson       *offsets = impl->d_offsets;
3450d0321e0SJeremy L Thompson       break;
3460d0321e0SJeremy L Thompson   }
3470d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
3480d0321e0SJeremy L Thompson }
3490d0321e0SJeremy L Thompson 
3500d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
351dce49693SSebastian Grimberg // Get orientations
352dce49693SSebastian Grimberg //------------------------------------------------------------------------------
353dce49693SSebastian Grimberg static int CeedElemRestrictionGetOrientations_Hip(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) {
354dce49693SSebastian Grimberg   CeedElemRestriction_Hip *impl;
355dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
356dce49693SSebastian Grimberg 
357dce49693SSebastian Grimberg   switch (mem_type) {
358dce49693SSebastian Grimberg     case CEED_MEM_HOST:
359dce49693SSebastian Grimberg       *orients = impl->h_orients;
360dce49693SSebastian Grimberg       break;
361dce49693SSebastian Grimberg     case CEED_MEM_DEVICE:
362dce49693SSebastian Grimberg       *orients = impl->d_orients;
363dce49693SSebastian Grimberg       break;
364dce49693SSebastian Grimberg   }
365dce49693SSebastian Grimberg   return CEED_ERROR_SUCCESS;
366dce49693SSebastian Grimberg }
367dce49693SSebastian Grimberg 
368dce49693SSebastian Grimberg //------------------------------------------------------------------------------
369dce49693SSebastian Grimberg // Get curl-conforming orientations
370dce49693SSebastian Grimberg //------------------------------------------------------------------------------
371dce49693SSebastian Grimberg static int CeedElemRestrictionGetCurlOrientations_Hip(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt8 **curl_orients) {
372dce49693SSebastian Grimberg   CeedElemRestriction_Hip *impl;
373dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
374dce49693SSebastian Grimberg 
375dce49693SSebastian Grimberg   switch (mem_type) {
376dce49693SSebastian Grimberg     case CEED_MEM_HOST:
377dce49693SSebastian Grimberg       *curl_orients = impl->h_curl_orients;
378dce49693SSebastian Grimberg       break;
379dce49693SSebastian Grimberg     case CEED_MEM_DEVICE:
380dce49693SSebastian Grimberg       *curl_orients = impl->d_curl_orients;
381dce49693SSebastian Grimberg       break;
382dce49693SSebastian Grimberg   }
383dce49693SSebastian Grimberg   return CEED_ERROR_SUCCESS;
384dce49693SSebastian Grimberg }
385dce49693SSebastian Grimberg 
386dce49693SSebastian Grimberg //------------------------------------------------------------------------------
3870d0321e0SJeremy L Thompson // Destroy restriction
3880d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
389dce49693SSebastian Grimberg static int CeedElemRestrictionDestroy_Hip(CeedElemRestriction rstr) {
3900d0321e0SJeremy L Thompson   Ceed                     ceed;
391b7453713SJeremy L Thompson   CeedElemRestriction_Hip *impl;
392b7453713SJeremy L Thompson 
393dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
394dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
395cf8cbdd6SSebastian Grimberg   if (impl->module) {
3962b730f8bSJeremy L Thompson     CeedCallHip(ceed, hipModuleUnload(impl->module));
397cf8cbdd6SSebastian Grimberg   }
398a267acd1SJeremy L Thompson   CeedCallBackend(CeedFree(&impl->h_offsets_owned));
399f5d1e504SJeremy L Thompson   CeedCallHip(ceed, hipFree((CeedInt *)impl->d_offsets_owned));
400081aa29dSJeremy L Thompson   CeedCallHip(ceed, hipFree((CeedInt *)impl->d_t_offsets));
401081aa29dSJeremy L Thompson   CeedCallHip(ceed, hipFree((CeedInt *)impl->d_t_indices));
402081aa29dSJeremy L Thompson   CeedCallHip(ceed, hipFree((CeedInt *)impl->d_l_vec_indices));
403a267acd1SJeremy L Thompson   CeedCallBackend(CeedFree(&impl->h_orients_owned));
404f5d1e504SJeremy L Thompson   CeedCallHip(ceed, hipFree((bool *)impl->d_orients_owned));
405a267acd1SJeremy L Thompson   CeedCallBackend(CeedFree(&impl->h_curl_orients_owned));
406f5d1e504SJeremy L Thompson   CeedCallHip(ceed, hipFree((CeedInt8 *)impl->d_curl_orients_owned));
4072b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
4080d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4090d0321e0SJeremy L Thompson }
4100d0321e0SJeremy L Thompson 
4110d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
4120d0321e0SJeremy L Thompson // Create transpose offsets and indices
4130d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
414dce49693SSebastian Grimberg static int CeedElemRestrictionOffset_Hip(const CeedElemRestriction rstr, const CeedInt *indices) {
4150d0321e0SJeremy L Thompson   Ceed                     ceed;
416b7453713SJeremy L Thompson   bool                    *is_node;
417e79b91d9SJeremy L Thompson   CeedSize                 l_size;
418dce49693SSebastian Grimberg   CeedInt                  num_elem, elem_size, num_comp, num_nodes = 0;
419dce49693SSebastian Grimberg   CeedInt                 *ind_to_offset, *l_vec_indices, *t_offsets, *t_indices;
420b7453713SJeremy L Thompson   CeedElemRestriction_Hip *impl;
421b7453713SJeremy L Thompson 
422dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
423dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
424dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumElements(rstr, &num_elem));
425dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetElementSize(rstr, &elem_size));
426dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetLVectorSize(rstr, &l_size));
427dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumComponents(rstr, &num_comp));
428b7453713SJeremy L Thompson   const CeedInt size_indices = num_elem * elem_size;
4290d0321e0SJeremy L Thompson 
430437930d1SJeremy L Thompson   // Count num_nodes
4312b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(l_size, &is_node));
432dce49693SSebastian Grimberg 
4332b730f8bSJeremy L Thompson   for (CeedInt i = 0; i < size_indices; i++) is_node[indices[i]] = 1;
4342b730f8bSJeremy L Thompson   for (CeedInt i = 0; i < l_size; i++) num_nodes += is_node[i];
435437930d1SJeremy L Thompson   impl->num_nodes = num_nodes;
4360d0321e0SJeremy L Thompson 
4370d0321e0SJeremy L Thompson   // L-vector offsets array
4382b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(l_size, &ind_to_offset));
4392b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(num_nodes, &l_vec_indices));
440b7453713SJeremy L Thompson   for (CeedInt i = 0, j = 0; i < l_size; i++) {
441437930d1SJeremy L Thompson     if (is_node[i]) {
442437930d1SJeremy L Thompson       l_vec_indices[j] = i;
4430d0321e0SJeremy L Thompson       ind_to_offset[i] = j++;
4440d0321e0SJeremy L Thompson     }
4452b730f8bSJeremy L Thompson   }
4462b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&is_node));
4470d0321e0SJeremy L Thompson 
4480d0321e0SJeremy L Thompson   // Compute transpose offsets and indices
449437930d1SJeremy L Thompson   const CeedInt size_offsets = num_nodes + 1;
450b7453713SJeremy L Thompson 
4512b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(size_offsets, &t_offsets));
4522b730f8bSJeremy L Thompson   CeedCallBackend(CeedMalloc(size_indices, &t_indices));
4530d0321e0SJeremy L Thompson   // Count node multiplicity
4542b730f8bSJeremy L Thompson   for (CeedInt e = 0; e < num_elem; ++e) {
4552b730f8bSJeremy L Thompson     for (CeedInt i = 0; i < elem_size; ++i) ++t_offsets[ind_to_offset[indices[elem_size * e + i]] + 1];
4562b730f8bSJeremy L Thompson   }
4570d0321e0SJeremy L Thompson   // Convert to running sum
4582b730f8bSJeremy L Thompson   for (CeedInt i = 1; i < size_offsets; ++i) t_offsets[i] += t_offsets[i - 1];
4590d0321e0SJeremy L Thompson   // List all E-vec indices associated with L-vec node
460437930d1SJeremy L Thompson   for (CeedInt e = 0; e < num_elem; ++e) {
461437930d1SJeremy L Thompson     for (CeedInt i = 0; i < elem_size; ++i) {
462437930d1SJeremy L Thompson       const CeedInt lid = elem_size * e + i;
4630d0321e0SJeremy L Thompson       const CeedInt gid = indices[lid];
464b7453713SJeremy L Thompson 
465437930d1SJeremy L Thompson       t_indices[t_offsets[ind_to_offset[gid]]++] = lid;
4660d0321e0SJeremy L Thompson     }
4670d0321e0SJeremy L Thompson   }
4680d0321e0SJeremy L Thompson   // Reset running sum
4692b730f8bSJeremy L Thompson   for (int i = size_offsets - 1; i > 0; --i) t_offsets[i] = t_offsets[i - 1];
470437930d1SJeremy L Thompson   t_offsets[0] = 0;
4710d0321e0SJeremy L Thompson 
4720d0321e0SJeremy L Thompson   // Copy data to device
4730d0321e0SJeremy L Thompson   // -- L-vector indices
4742b730f8bSJeremy L Thompson   CeedCallHip(ceed, hipMalloc((void **)&impl->d_l_vec_indices, num_nodes * sizeof(CeedInt)));
475081aa29dSJeremy L Thompson   CeedCallHip(ceed, hipMemcpy((CeedInt *)impl->d_l_vec_indices, l_vec_indices, num_nodes * sizeof(CeedInt), hipMemcpyHostToDevice));
4760d0321e0SJeremy L Thompson   // -- Transpose offsets
4772b730f8bSJeremy L Thompson   CeedCallHip(ceed, hipMalloc((void **)&impl->d_t_offsets, size_offsets * sizeof(CeedInt)));
478081aa29dSJeremy L Thompson   CeedCallHip(ceed, hipMemcpy((CeedInt *)impl->d_t_offsets, t_offsets, size_offsets * sizeof(CeedInt), hipMemcpyHostToDevice));
4790d0321e0SJeremy L Thompson   // -- Transpose indices
4802b730f8bSJeremy L Thompson   CeedCallHip(ceed, hipMalloc((void **)&impl->d_t_indices, size_indices * sizeof(CeedInt)));
481081aa29dSJeremy L Thompson   CeedCallHip(ceed, hipMemcpy((CeedInt *)impl->d_t_indices, t_indices, size_indices * sizeof(CeedInt), hipMemcpyHostToDevice));
4820d0321e0SJeremy L Thompson 
4830d0321e0SJeremy L Thompson   // Cleanup
4842b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&ind_to_offset));
4852b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&l_vec_indices));
4862b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&t_offsets));
4872b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&t_indices));
4880d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
4890d0321e0SJeremy L Thompson }
4900d0321e0SJeremy L Thompson 
4910d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
4920d0321e0SJeremy L Thompson // Create restriction
4930d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
494a267acd1SJeremy L Thompson int CeedElemRestrictionCreate_Hip(CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients,
495dce49693SSebastian Grimberg                                   const CeedInt8 *curl_orients, CeedElemRestriction rstr) {
496b7453713SJeremy L Thompson   Ceed                     ceed, ceed_parent;
497dce49693SSebastian Grimberg   bool                     is_deterministic;
498cf8cbdd6SSebastian Grimberg   CeedInt                  num_elem, elem_size;
499b7453713SJeremy L Thompson   CeedRestrictionType      rstr_type;
5000d0321e0SJeremy L Thompson   CeedElemRestriction_Hip *impl;
501b7453713SJeremy L Thompson 
502dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
503ca735530SJeremy L Thompson   CeedCallBackend(CeedGetParent(ceed, &ceed_parent));
504ca735530SJeremy L Thompson   CeedCallBackend(CeedIsDeterministic(ceed_parent, &is_deterministic));
505dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumElements(rstr, &num_elem));
506dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetElementSize(rstr, &elem_size));
50722eb1385SJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetType(rstr, &rstr_type));
508dce49693SSebastian Grimberg   const CeedInt size = num_elem * elem_size;
5090d0321e0SJeremy L Thompson 
510dce49693SSebastian Grimberg   CeedCallBackend(CeedCalloc(1, &impl));
511dce49693SSebastian Grimberg   impl->num_nodes = size;
512dce49693SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionSetData(rstr, impl));
51322eb1385SJeremy L Thompson 
51422eb1385SJeremy L Thompson   // Set layouts
51522eb1385SJeremy L Thompson   {
51622eb1385SJeremy L Thompson     bool    has_backend_strides;
51722eb1385SJeremy L Thompson     CeedInt layout[3] = {1, size, elem_size};
51822eb1385SJeremy L Thompson 
519dce49693SSebastian Grimberg     CeedCallBackend(CeedElemRestrictionSetELayout(rstr, layout));
52022eb1385SJeremy L Thompson     if (rstr_type == CEED_RESTRICTION_STRIDED) {
52122eb1385SJeremy L Thompson       CeedCallBackend(CeedElemRestrictionHasBackendStrides(rstr, &has_backend_strides));
52222eb1385SJeremy L Thompson       if (has_backend_strides) {
52322eb1385SJeremy L Thompson         CeedCallBackend(CeedElemRestrictionSetLLayout(rstr, layout));
52422eb1385SJeremy L Thompson       }
52522eb1385SJeremy L Thompson     }
52622eb1385SJeremy L Thompson   }
5270d0321e0SJeremy L Thompson 
528dce49693SSebastian Grimberg   // Set up device offset/orientation arrays
529dce49693SSebastian Grimberg   if (rstr_type != CEED_RESTRICTION_STRIDED) {
530472941f0SJeremy L Thompson     switch (mem_type) {
5316574a04fSJeremy L Thompson       case CEED_MEM_HOST: {
532f5d1e504SJeremy L Thompson         CeedCallBackend(CeedSetHostCeedIntArray(offsets, copy_mode, size, &impl->h_offsets_owned, &impl->h_offsets_borrowed, &impl->h_offsets));
533a267acd1SJeremy L Thompson         CeedCallHip(ceed, hipMalloc((void **)&impl->d_offsets_owned, size * sizeof(CeedInt)));
534f5d1e504SJeremy L Thompson         CeedCallHip(ceed, hipMemcpy((CeedInt **)impl->d_offsets_owned, impl->h_offsets, size * sizeof(CeedInt), hipMemcpyHostToDevice));
535f5d1e504SJeremy L Thompson         impl->d_offsets = (CeedInt *)impl->d_offsets_owned;
536a267acd1SJeremy L Thompson         if (is_deterministic) CeedCallBackend(CeedElemRestrictionOffset_Hip(rstr, offsets));
537dce49693SSebastian Grimberg       } break;
5386574a04fSJeremy L Thompson       case CEED_MEM_DEVICE: {
539f5d1e504SJeremy L Thompson         CeedCallBackend(CeedSetDeviceCeedIntArray_Hip(ceed, offsets, copy_mode, size, &impl->d_offsets_owned, &impl->d_offsets_borrowed,
540f5d1e504SJeremy L Thompson                                                       (const CeedInt **)&impl->d_offsets));
541a267acd1SJeremy L Thompson         CeedCallBackend(CeedMalloc(size, &impl->h_offsets_owned));
542f5d1e504SJeremy L Thompson         CeedCallHip(ceed, hipMemcpy((CeedInt **)impl->h_offsets_owned, impl->d_offsets, size * sizeof(CeedInt), hipMemcpyDeviceToHost));
543a267acd1SJeremy L Thompson         impl->h_offsets = impl->h_offsets_owned;
544a267acd1SJeremy L Thompson         if (is_deterministic) CeedCallBackend(CeedElemRestrictionOffset_Hip(rstr, offsets));
545dce49693SSebastian Grimberg       } break;
546dce49693SSebastian Grimberg     }
547dce49693SSebastian Grimberg 
548dce49693SSebastian Grimberg     // Orientation data
549dce49693SSebastian Grimberg     if (rstr_type == CEED_RESTRICTION_ORIENTED) {
550dce49693SSebastian Grimberg       switch (mem_type) {
551dce49693SSebastian Grimberg         case CEED_MEM_HOST: {
552f5d1e504SJeremy L Thompson           CeedCallBackend(CeedSetHostBoolArray(orients, copy_mode, size, &impl->h_orients_owned, &impl->h_orients_borrowed, &impl->h_orients));
553a267acd1SJeremy L Thompson           CeedCallHip(ceed, hipMalloc((void **)&impl->d_orients_owned, size * sizeof(bool)));
554f5d1e504SJeremy L Thompson           CeedCallHip(ceed, hipMemcpy((bool *)impl->d_orients_owned, impl->h_orients, size * sizeof(bool), hipMemcpyHostToDevice));
555a267acd1SJeremy L Thompson           impl->d_orients = impl->d_orients_owned;
556dce49693SSebastian Grimberg         } break;
557dce49693SSebastian Grimberg         case CEED_MEM_DEVICE: {
558f5d1e504SJeremy L Thompson           CeedCallBackend(CeedSetDeviceBoolArray_Hip(ceed, orients, copy_mode, size, &impl->d_orients_owned, &impl->d_orients_borrowed,
559f5d1e504SJeremy L Thompson                                                      (const bool **)&impl->d_orients));
560a267acd1SJeremy L Thompson           CeedCallBackend(CeedMalloc(size, &impl->h_orients_owned));
561f5d1e504SJeremy L Thompson           CeedCallHip(ceed, hipMemcpy((bool *)impl->h_orients_owned, impl->d_orients, size * sizeof(bool), hipMemcpyDeviceToHost));
562a267acd1SJeremy L Thompson           impl->h_orients = impl->h_orients_owned;
563dce49693SSebastian Grimberg         } break;
564dce49693SSebastian Grimberg       }
565dce49693SSebastian Grimberg     } else if (rstr_type == CEED_RESTRICTION_CURL_ORIENTED) {
566dce49693SSebastian Grimberg       switch (mem_type) {
567dce49693SSebastian Grimberg         case CEED_MEM_HOST: {
568f5d1e504SJeremy L Thompson           CeedCallBackend(CeedSetHostCeedInt8Array(curl_orients, copy_mode, 3 * size, &impl->h_curl_orients_owned, &impl->h_curl_orients_borrowed,
569f5d1e504SJeremy L Thompson                                                    &impl->h_curl_orients));
570a267acd1SJeremy L Thompson           CeedCallHip(ceed, hipMalloc((void **)&impl->d_curl_orients_owned, 3 * size * sizeof(CeedInt8)));
571f5d1e504SJeremy L Thompson           CeedCallHip(ceed,
572f5d1e504SJeremy L Thompson                       hipMemcpy((CeedInt8 *)impl->d_curl_orients_owned, impl->h_curl_orients, 3 * size * sizeof(CeedInt8), hipMemcpyHostToDevice));
573a267acd1SJeremy L Thompson           impl->d_curl_orients = impl->d_curl_orients_owned;
574dce49693SSebastian Grimberg         } break;
575dce49693SSebastian Grimberg         case CEED_MEM_DEVICE: {
576f5d1e504SJeremy L Thompson           CeedCallBackend(CeedSetDeviceCeedInt8Array_Hip(ceed, curl_orients, copy_mode, 3 * size, &impl->d_curl_orients_owned,
577f5d1e504SJeremy L Thompson                                                          &impl->d_curl_orients_borrowed, (const CeedInt8 **)&impl->d_curl_orients));
578a267acd1SJeremy L Thompson           CeedCallBackend(CeedMalloc(3 * size, &impl->h_curl_orients_owned));
579f5d1e504SJeremy L Thompson           CeedCallHip(ceed,
580f5d1e504SJeremy L Thompson                       hipMemcpy((CeedInt8 *)impl->h_curl_orients_owned, impl->d_curl_orients, 3 * size * sizeof(CeedInt8), hipMemcpyDeviceToHost));
581a267acd1SJeremy L Thompson           impl->h_curl_orients = impl->h_curl_orients_owned;
582dce49693SSebastian Grimberg         } break;
583dce49693SSebastian Grimberg       }
584dce49693SSebastian Grimberg     }
5850d0321e0SJeremy L Thompson   }
5860d0321e0SJeremy L Thompson 
5870d0321e0SJeremy L Thompson   // Register backend functions
588dce49693SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "Apply", CeedElemRestrictionApply_Hip));
589dce49693SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "ApplyUnsigned", CeedElemRestrictionApplyUnsigned_Hip));
590dce49693SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "ApplyUnoriented", CeedElemRestrictionApplyUnoriented_Hip));
591dce49693SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "GetOffsets", CeedElemRestrictionGetOffsets_Hip));
592dce49693SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "GetOrientations", CeedElemRestrictionGetOrientations_Hip));
593dce49693SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "GetCurlOrientations", CeedElemRestrictionGetCurlOrientations_Hip));
594dce49693SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", rstr, "Destroy", CeedElemRestrictionDestroy_Hip));
5950d0321e0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
5960d0321e0SJeremy L Thompson }
5970d0321e0SJeremy L Thompson 
5980d0321e0SJeremy L Thompson //------------------------------------------------------------------------------
599