xref: /libCEED/rust/libceed-sys/c-src/backends/ref/ceed-ref-restriction.c (revision 0305e208bc4684eaa3113a3ca8b7ffdd1d4cb7a9)
13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
321617c04Sjeremylt //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
521617c04Sjeremylt //
63d8e8822SJeremy L Thompson // This file is part of CEED:  http://github.com/ceed
721617c04Sjeremylt 
849aac155SJeremy L Thompson #include <ceed.h>
9ec3da8bcSJed Brown #include <ceed/backend.h>
103d576824SJeremy L Thompson #include <stdbool.h>
11fcbe8c06SSebastian Grimberg #include <stdlib.h>
123d576824SJeremy L Thompson #include <string.h>
132b730f8bSJeremy L Thompson 
1421617c04Sjeremylt #include "ceed-ref.h"
1521617c04Sjeremylt 
16f10650afSjeremylt //------------------------------------------------------------------------------
17f10650afSjeremylt // Core ElemRestriction Apply Code
18f10650afSjeremylt //------------------------------------------------------------------------------
192b730f8bSJeremy L Thompson static inline int CeedElemRestrictionApply_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
2077d1c127SSebastian Grimberg                                                     CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u,
213bdd4e5aSSebastian Grimberg                                                     CeedVector v, CeedRequest *request) {
224ce2993fSjeremylt   CeedElemRestriction_Ref *impl;
232b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
2421617c04Sjeremylt   const CeedScalar *uu;
2521617c04Sjeremylt   CeedScalar       *vv;
26d1d35e2fSjeremylt   CeedInt           num_elem, elem_size, v_offset;
272b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem));
282b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size));
29d1d35e2fSjeremylt   v_offset = start * blk_size * elem_size * num_comp;
30fcbe8c06SSebastian Grimberg   CeedRestrictionType rstr_type;
31fcbe8c06SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetType(r, &rstr_type));
3221617c04Sjeremylt 
332b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorGetArrayRead(u, CEED_MEM_HOST, &uu));
349c774eddSJeremy L Thompson   if (t_mode == CEED_TRANSPOSE) {
359c774eddSJeremy L Thompson     // Sum into for transpose mode, e-vec to l-vec
362b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorGetArray(v, CEED_MEM_HOST, &vv));
379c774eddSJeremy L Thompson   } else {
389c774eddSJeremy L Thompson     // Overwrite for notranspose mode, l-vec to e-vec
392b730f8bSJeremy L Thompson     CeedCallBackend(CeedVectorGetArrayWrite(v, CEED_MEM_HOST, &vv));
409c774eddSJeremy L Thompson   }
419475e044SSebastian Grimberg   if (t_mode == CEED_NOTRANSPOSE) {
427f90ec76Sjeremylt     // Restriction from L-vector to E-vector
4321617c04Sjeremylt     // Perform: v = r * u
44fcbe8c06SSebastian Grimberg     // vv has shape [elem_size, num_comp, num_elem], row-major
45fcbe8c06SSebastian Grimberg     // uu has shape [nnodes, num_comp]
46fcbe8c06SSebastian Grimberg     switch (rstr_type) {
47fcbe8c06SSebastian Grimberg       case CEED_RESTRICTION_STRIDED: {
48d979a051Sjeremylt         // No offsets provided, Identity Restriction
49d1d35e2fSjeremylt         bool has_backend_strides;
502b730f8bSJeremy L Thompson         CeedCallBackend(CeedElemRestrictionHasBackendStrides(r, &has_backend_strides));
51d1d35e2fSjeremylt         if (has_backend_strides) {
52d1d35e2fSjeremylt           // CPU backend strides are {1, elem_size, elem_size*num_comp}
537f90ec76Sjeremylt           // This if branch is left separate to allow better inlining
542b730f8bSJeremy L Thompson           for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
552b730f8bSJeremy L Thompson             CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
562b730f8bSJeremy L Thompson               CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) {
572b730f8bSJeremy L Thompson                 CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) {
582b730f8bSJeremy L Thompson                   vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] =
592b730f8bSJeremy L Thompson                       uu[n + k * elem_size + CeedIntMin(e + j, num_elem - 1) * elem_size * num_comp];
602b730f8bSJeremy L Thompson                 }
612b730f8bSJeremy L Thompson               }
622b730f8bSJeremy L Thompson             }
632b730f8bSJeremy L Thompson           }
647f90ec76Sjeremylt         } else {
657f90ec76Sjeremylt           // User provided strides
667f90ec76Sjeremylt           CeedInt strides[3];
672b730f8bSJeremy L Thompson           CeedCallBackend(CeedElemRestrictionGetStrides(r, &strides));
682b730f8bSJeremy L Thompson           for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
692b730f8bSJeremy L Thompson             CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
702b730f8bSJeremy L Thompson               CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) {
712b730f8bSJeremy L Thompson                 CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) {
722b730f8bSJeremy L Thompson                   vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] =
732b730f8bSJeremy L Thompson                       uu[n * strides[0] + k * strides[1] + CeedIntMin(e + j, num_elem - 1) * strides[2]];
742b730f8bSJeremy L Thompson                 }
752b730f8bSJeremy L Thompson               }
762b730f8bSJeremy L Thompson             }
772b730f8bSJeremy L Thompson           }
787509a596Sjeremylt         }
79fcbe8c06SSebastian Grimberg       } break;
80fcbe8c06SSebastian Grimberg       case CEED_RESTRICTION_DEFAULT:
81fcbe8c06SSebastian Grimberg         // Default restriction with offsets
822b730f8bSJeremy L Thompson         for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
832b730f8bSJeremy L Thompson           CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
842b730f8bSJeremy L Thompson             CeedPragmaSIMD for (CeedInt i = 0; i < elem_size * blk_size; i++) {
853bdd4e5aSSebastian Grimberg               vv[elem_size * (k * blk_size + num_comp * e) + i - v_offset] = uu[impl->offsets[i + elem_size * e] + k * comp_stride];
86fcbe8c06SSebastian Grimberg             }
87fcbe8c06SSebastian Grimberg           }
88fcbe8c06SSebastian Grimberg         }
89fcbe8c06SSebastian Grimberg         break;
90fcbe8c06SSebastian Grimberg       case CEED_RESTRICTION_ORIENTED:
91fcbe8c06SSebastian Grimberg         // Restriction with orientations
92fcbe8c06SSebastian Grimberg         for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
93fcbe8c06SSebastian Grimberg           CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
94fcbe8c06SSebastian Grimberg             CeedPragmaSIMD for (CeedInt i = 0; i < elem_size * blk_size; i++) {
95f30b1135SSebastian Grimberg               vv[elem_size * (k * blk_size + num_comp * e) + i - v_offset] =
96fcbe8c06SSebastian Grimberg                   uu[impl->offsets[i + elem_size * e] + k * comp_stride] * (use_orients && impl->orients[i + elem_size * e] ? -1.0 : 1.0);
97fcbe8c06SSebastian Grimberg             }
98fcbe8c06SSebastian Grimberg           }
99fcbe8c06SSebastian Grimberg         }
100fcbe8c06SSebastian Grimberg         break;
101fcbe8c06SSebastian Grimberg       case CEED_RESTRICTION_CURL_ORIENTED:
10277d1c127SSebastian Grimberg         // Restriction with tridiagonal transformation
103fcbe8c06SSebastian Grimberg         for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
104fcbe8c06SSebastian Grimberg           CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
105fcbe8c06SSebastian Grimberg             CeedPragmaSIMD for (CeedInt i = 0; i < elem_size * blk_size; i++) {
1069475e044SSebastian Grimberg               CeedInt ii = 3 * blk_size * (i / blk_size) + i % blk_size;
107fcbe8c06SSebastian Grimberg               if (use_orients) {
10877d1c127SSebastian Grimberg                 vv[elem_size * (k * blk_size + num_comp * e) + i - v_offset] =
1099475e044SSebastian Grimberg                     uu[impl->offsets[i + 0 * blk_size + elem_size * e] + k * comp_stride] *
1109475e044SSebastian Grimberg                         impl->curl_orients[ii + 1 * blk_size + 3 * elem_size * e] +
1119475e044SSebastian Grimberg                     (i >= blk_size ? uu[impl->offsets[i - 1 * blk_size + elem_size * e] + k * comp_stride] *
1129475e044SSebastian Grimberg                                          impl->curl_orients[ii + 0 * blk_size + 3 * elem_size * e]
1139475e044SSebastian Grimberg                                    : 0.0) +
1149475e044SSebastian Grimberg                     (i < (elem_size - 1) * blk_size ? uu[impl->offsets[i + 1 * blk_size + elem_size * e] + k * comp_stride] *
1159475e044SSebastian Grimberg                                                           impl->curl_orients[ii + 2 * blk_size + 3 * elem_size * e]
1169475e044SSebastian Grimberg                                                     : 0.0);
11777d1c127SSebastian Grimberg               } else {
11877d1c127SSebastian Grimberg                 vv[elem_size * (k * blk_size + num_comp * e) + i - v_offset] =
1199475e044SSebastian Grimberg                     uu[impl->offsets[i + 0 * blk_size + elem_size * e] + k * comp_stride] *
1209475e044SSebastian Grimberg                         abs(impl->curl_orients[ii + 1 * blk_size + 3 * elem_size * e]) +
1219475e044SSebastian Grimberg                     (i >= blk_size ? uu[impl->offsets[i - 1 * blk_size + elem_size * e] + k * comp_stride] *
1229475e044SSebastian Grimberg                                          abs(impl->curl_orients[ii + 0 * blk_size + 3 * elem_size * e])
1239475e044SSebastian Grimberg                                    : 0.0) +
1249475e044SSebastian Grimberg                     (i < (elem_size - 1) * blk_size ? uu[impl->offsets[i + 1 * blk_size + elem_size * e] + k * comp_stride] *
1259475e044SSebastian Grimberg                                                           abs(impl->curl_orients[ii + 2 * blk_size + 3 * elem_size * e])
1269475e044SSebastian Grimberg                                                     : 0.0);
1272b730f8bSJeremy L Thompson               }
1282b730f8bSJeremy L Thompson             }
1292b730f8bSJeremy L Thompson           }
130b435c5a6Srezgarshakeri         }
131fcbe8c06SSebastian Grimberg         break;
132fcbe8c06SSebastian Grimberg     }
13321617c04Sjeremylt   } else {
1347f90ec76Sjeremylt     // Restriction from E-vector to L-vector
1358d94b059Sjeremylt     // Performing v += r^T * u
1369475e044SSebastian Grimberg     // uu has shape [elem_size, num_comp, num_elem], row-major
137fcbe8c06SSebastian Grimberg     // vv has shape [nnodes, num_comp]
138fcbe8c06SSebastian Grimberg     switch (rstr_type) {
139fcbe8c06SSebastian Grimberg       case CEED_RESTRICTION_STRIDED: {
140d979a051Sjeremylt         // No offsets provided, Identity Restriction
141d1d35e2fSjeremylt         bool has_backend_strides;
1422b730f8bSJeremy L Thompson         CeedCallBackend(CeedElemRestrictionHasBackendStrides(r, &has_backend_strides));
143d1d35e2fSjeremylt         if (has_backend_strides) {
144d1d35e2fSjeremylt           // CPU backend strides are {1, elem_size, elem_size*num_comp}
1457f90ec76Sjeremylt           // This if brach is left separate to allow better inlining
1462b730f8bSJeremy L Thompson           for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
1472b730f8bSJeremy L Thompson             CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
1482b730f8bSJeremy L Thompson               CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) {
1492b730f8bSJeremy L Thompson                 CeedPragmaSIMD for (CeedInt j = 0; j < CeedIntMin(blk_size, num_elem - e); j++) {
1502b730f8bSJeremy L Thompson                   vv[n + k * elem_size + (e + j) * elem_size * num_comp] +=
1512b730f8bSJeremy L Thompson                       uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset];
1522b730f8bSJeremy L Thompson                 }
1532b730f8bSJeremy L Thompson               }
1542b730f8bSJeremy L Thompson             }
1552b730f8bSJeremy L Thompson           }
1567f90ec76Sjeremylt         } else {
1577f90ec76Sjeremylt           // User provided strides
1587f90ec76Sjeremylt           CeedInt strides[3];
1592b730f8bSJeremy L Thompson           CeedCallBackend(CeedElemRestrictionGetStrides(r, &strides));
1602b730f8bSJeremy L Thompson           for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
1612b730f8bSJeremy L Thompson             CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) {
1622b730f8bSJeremy L Thompson               CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) {
1632b730f8bSJeremy L Thompson                 CeedPragmaSIMD for (CeedInt j = 0; j < CeedIntMin(blk_size, num_elem - e); j++) {
1642b730f8bSJeremy L Thompson                   vv[n * strides[0] + k * strides[1] + (e + j) * strides[2]] +=
1652b730f8bSJeremy L Thompson                       uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset];
1662b730f8bSJeremy L Thompson                 }
1672b730f8bSJeremy L Thompson               }
1682b730f8bSJeremy L Thompson             }
1692b730f8bSJeremy L Thompson           }
170523b8ea0Sjeremylt         }
171fcbe8c06SSebastian Grimberg       } break;
172fcbe8c06SSebastian Grimberg       case CEED_RESTRICTION_DEFAULT:
173fcbe8c06SSebastian Grimberg         // Default restriction with offsets
1742b730f8bSJeremy L Thompson         for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
1752b730f8bSJeremy L Thompson           for (CeedInt k = 0; k < num_comp; k++) {
1762b730f8bSJeremy L Thompson             for (CeedInt i = 0; i < elem_size * blk_size; i += blk_size) {
1778d94b059Sjeremylt               // Iteration bound set to discard padding elements
1782b730f8bSJeremy L Thompson               for (CeedInt j = i; j < i + CeedIntMin(blk_size, num_elem - e); j++) {
1793bdd4e5aSSebastian Grimberg                 vv[impl->offsets[j + e * elem_size] + k * comp_stride] += uu[elem_size * (k * blk_size + num_comp * e) + j - v_offset];
180fcbe8c06SSebastian Grimberg               }
181fcbe8c06SSebastian Grimberg             }
182fcbe8c06SSebastian Grimberg           }
183fcbe8c06SSebastian Grimberg         }
184fcbe8c06SSebastian Grimberg         break;
185fcbe8c06SSebastian Grimberg       case CEED_RESTRICTION_ORIENTED:
186fcbe8c06SSebastian Grimberg         // Restriction with orientations
187fcbe8c06SSebastian Grimberg         for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
188fcbe8c06SSebastian Grimberg           for (CeedInt k = 0; k < num_comp; k++) {
189fcbe8c06SSebastian Grimberg             for (CeedInt i = 0; i < elem_size * blk_size; i += blk_size) {
190fcbe8c06SSebastian Grimberg               // Iteration bound set to discard padding elements
191fcbe8c06SSebastian Grimberg               for (CeedInt j = i; j < i + CeedIntMin(blk_size, num_elem - e); j++) {
192f30b1135SSebastian Grimberg                 vv[impl->offsets[j + e * elem_size] + k * comp_stride] +=
193fcbe8c06SSebastian Grimberg                     uu[elem_size * (k * blk_size + num_comp * e) + j - v_offset] * (use_orients && impl->orients[j + e * elem_size] ? -1.0 : 1.0);
194fcbe8c06SSebastian Grimberg               }
195fcbe8c06SSebastian Grimberg             }
196fcbe8c06SSebastian Grimberg           }
197fcbe8c06SSebastian Grimberg         }
198fcbe8c06SSebastian Grimberg         break;
199fcbe8c06SSebastian Grimberg       case CEED_RESTRICTION_CURL_ORIENTED:
20077d1c127SSebastian Grimberg         // Restriction with tridiagonal transformation
201fcbe8c06SSebastian Grimberg         for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) {
202fcbe8c06SSebastian Grimberg           for (CeedInt k = 0; k < num_comp; k++) {
203fcbe8c06SSebastian Grimberg             for (CeedInt i = 0; i < elem_size * blk_size; i += blk_size) {
204fcbe8c06SSebastian Grimberg               // Iteration bound set to discard padding elements
205fcbe8c06SSebastian Grimberg               for (CeedInt j = i; j < i + CeedIntMin(blk_size, num_elem - e); j++) {
2069475e044SSebastian Grimberg                 CeedInt jj = 3 * blk_size * (j / blk_size + 0) + j % blk_size;
207fcbe8c06SSebastian Grimberg                 if (use_orients) {
20877d1c127SSebastian Grimberg                   vv[impl->offsets[j + e * elem_size] + k * comp_stride] +=
2099475e044SSebastian Grimberg                       uu[elem_size * (k * blk_size + num_comp * e) + j + 0 * blk_size - v_offset] *
2109475e044SSebastian Grimberg                           impl->curl_orients[jj + 1 * blk_size + e * 3 * elem_size] +
2119475e044SSebastian Grimberg                       (j >= blk_size ? uu[elem_size * (k * blk_size + num_comp * e) + j - 1 * blk_size - v_offset] *
2129475e044SSebastian Grimberg                                            impl->curl_orients[jj - 1 * blk_size + e * 3 * elem_size]
2139475e044SSebastian Grimberg                                      : 0.0) +
2149475e044SSebastian Grimberg                       (j < (elem_size - 1) * blk_size ? uu[elem_size * (k * blk_size + num_comp * e) + j + 1 * blk_size - v_offset] *
2159475e044SSebastian Grimberg                                                             impl->curl_orients[jj + 3 * blk_size + e * 3 * elem_size]
2169475e044SSebastian Grimberg                                                       : 0.0);
21777d1c127SSebastian Grimberg                 } else {
21877d1c127SSebastian Grimberg                   vv[impl->offsets[j + e * elem_size] + k * comp_stride] +=
2199475e044SSebastian Grimberg                       uu[elem_size * (k * blk_size + num_comp * e) + j + 0 * blk_size - v_offset] *
2209475e044SSebastian Grimberg                           abs(impl->curl_orients[jj + 1 * blk_size + e * 3 * elem_size]) +
2219475e044SSebastian Grimberg                       (j >= blk_size ? uu[elem_size * (k * blk_size + num_comp * e) + j - 1 * blk_size - v_offset] *
2229475e044SSebastian Grimberg                                            abs(impl->curl_orients[jj - 1 * blk_size + e * 3 * elem_size])
2239475e044SSebastian Grimberg                                      : 0.0) +
2249475e044SSebastian Grimberg                       (j < (elem_size - 1) * blk_size ? uu[elem_size * (k * blk_size + num_comp * e) + j + 1 * blk_size - v_offset] *
2259475e044SSebastian Grimberg                                                             abs(impl->curl_orients[jj + 3 * blk_size + e * 3 * elem_size])
2269475e044SSebastian Grimberg                                                       : 0.0);
22721617c04Sjeremylt                 }
228b435c5a6Srezgarshakeri               }
2292b730f8bSJeremy L Thompson             }
2302b730f8bSJeremy L Thompson           }
2312b730f8bSJeremy L Thompson         }
232fcbe8c06SSebastian Grimberg         break;
233fcbe8c06SSebastian Grimberg     }
2342b730f8bSJeremy L Thompson   }
2352b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorRestoreArrayRead(u, &uu));
2362b730f8bSJeremy L Thompson   CeedCallBackend(CeedVectorRestoreArray(v, &vv));
2372b730f8bSJeremy L Thompson   if (request != CEED_REQUEST_IMMEDIATE && request != CEED_REQUEST_ORDERED) *request = NULL;
238e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
23921617c04Sjeremylt }
24021617c04Sjeremylt 
241f10650afSjeremylt //------------------------------------------------------------------------------
242f10650afSjeremylt // ElemRestriction Apply - Common Sizes
243f10650afSjeremylt //------------------------------------------------------------------------------
2442b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_110(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
24577d1c127SSebastian Grimberg                                             CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
2463bdd4e5aSSebastian Grimberg                                             CeedRequest *request) {
24777d1c127SSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 1, comp_stride, start, stop, use_orients, t_mode, u, v, request);
248d979a051Sjeremylt }
249d979a051Sjeremylt 
2502b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_111(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
25177d1c127SSebastian Grimberg                                             CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
2523bdd4e5aSSebastian Grimberg                                             CeedRequest *request) {
25377d1c127SSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 1, 1, start, stop, use_orients, t_mode, u, v, request);
2544d2a38eeSjeremylt }
2554d2a38eeSjeremylt 
2562b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_180(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
25777d1c127SSebastian Grimberg                                             CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
2583bdd4e5aSSebastian Grimberg                                             CeedRequest *request) {
25977d1c127SSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 8, comp_stride, start, stop, use_orients, t_mode, u, v, request);
2609c36149bSjeremylt }
2619c36149bSjeremylt 
2622b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_181(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
26377d1c127SSebastian Grimberg                                             CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
2643bdd4e5aSSebastian Grimberg                                             CeedRequest *request) {
26577d1c127SSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 1, 8, 1, start, stop, use_orients, t_mode, u, v, request);
2669c36149bSjeremylt }
2679c36149bSjeremylt 
2682b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_310(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
26977d1c127SSebastian Grimberg                                             CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
2703bdd4e5aSSebastian Grimberg                                             CeedRequest *request) {
27177d1c127SSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 1, comp_stride, start, stop, use_orients, t_mode, u, v, request);
272d979a051Sjeremylt }
273d979a051Sjeremylt 
2742b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_311(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
27577d1c127SSebastian Grimberg                                             CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
2763bdd4e5aSSebastian Grimberg                                             CeedRequest *request) {
27777d1c127SSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 1, 1, start, stop, use_orients, t_mode, u, v, request);
278d979a051Sjeremylt }
279d979a051Sjeremylt 
2802b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_380(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
28177d1c127SSebastian Grimberg                                             CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
2823bdd4e5aSSebastian Grimberg                                             CeedRequest *request) {
28377d1c127SSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 8, comp_stride, start, stop, use_orients, t_mode, u, v, request);
284d979a051Sjeremylt }
285d979a051Sjeremylt 
2862b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_381(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
28777d1c127SSebastian Grimberg                                             CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
2883bdd4e5aSSebastian Grimberg                                             CeedRequest *request) {
28977d1c127SSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 3, 8, 1, start, stop, use_orients, t_mode, u, v, request);
290d979a051Sjeremylt }
291d979a051Sjeremylt 
292bf4d1581Sjeremylt // LCOV_EXCL_START
2932b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_510(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
29477d1c127SSebastian Grimberg                                             CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
2953bdd4e5aSSebastian Grimberg                                             CeedRequest *request) {
29677d1c127SSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 1, comp_stride, start, stop, use_orients, t_mode, u, v, request);
297d979a051Sjeremylt }
298bf4d1581Sjeremylt // LCOV_EXCL_STOP
299d979a051Sjeremylt 
3002b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_511(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
30177d1c127SSebastian Grimberg                                             CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
3023bdd4e5aSSebastian Grimberg                                             CeedRequest *request) {
30377d1c127SSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 1, 1, start, stop, use_orients, t_mode, u, v, request);
304d979a051Sjeremylt }
305d979a051Sjeremylt 
306bf4d1581Sjeremylt // LCOV_EXCL_START
3072b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_580(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
30877d1c127SSebastian Grimberg                                             CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
3093bdd4e5aSSebastian Grimberg                                             CeedRequest *request) {
31077d1c127SSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 8, comp_stride, start, stop, use_orients, t_mode, u, v, request);
311d979a051Sjeremylt }
312bf4d1581Sjeremylt // LCOV_EXCL_STOP
313d979a051Sjeremylt 
3142b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_581(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride,
31577d1c127SSebastian Grimberg                                             CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
3163bdd4e5aSSebastian Grimberg                                             CeedRequest *request) {
31777d1c127SSebastian Grimberg   return CeedElemRestrictionApply_Ref_Core(r, 5, 8, 1, start, stop, use_orients, t_mode, u, v, request);
3184d2a38eeSjeremylt }
3194d2a38eeSjeremylt 
320f10650afSjeremylt //------------------------------------------------------------------------------
321f10650afSjeremylt // ElemRestriction Apply
322f10650afSjeremylt //------------------------------------------------------------------------------
3232b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) {
324d1d35e2fSjeremylt   CeedInt num_blk, blk_size, num_comp, comp_stride;
3252b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk));
3262b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
3272b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
3282b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
3297509a596Sjeremylt   CeedElemRestriction_Ref *impl;
3302b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
3314d2a38eeSjeremylt 
332f30b1135SSebastian Grimberg   return impl->Apply(r, num_comp, blk_size, comp_stride, 0, num_blk, true, t_mode, u, v, request);
333f30b1135SSebastian Grimberg }
334f30b1135SSebastian Grimberg 
335f30b1135SSebastian Grimberg //------------------------------------------------------------------------------
336f30b1135SSebastian Grimberg // ElemRestriction Apply Unsigned
337f30b1135SSebastian Grimberg //------------------------------------------------------------------------------
338f30b1135SSebastian Grimberg static int CeedElemRestrictionApplyUnsigned_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) {
339f30b1135SSebastian Grimberg   CeedInt num_blk, blk_size, num_comp, comp_stride;
340f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk));
341f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
342f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
343f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
344f30b1135SSebastian Grimberg   CeedElemRestriction_Ref *impl;
345f30b1135SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
346f30b1135SSebastian Grimberg 
347f30b1135SSebastian Grimberg   return impl->Apply(r, num_comp, blk_size, comp_stride, 0, num_blk, false, t_mode, u, v, request);
3489c36149bSjeremylt }
349be9261b7Sjeremylt 
350f10650afSjeremylt //------------------------------------------------------------------------------
351f10650afSjeremylt // ElemRestriction Apply Block
352f10650afSjeremylt //------------------------------------------------------------------------------
3532b730f8bSJeremy L Thompson static int CeedElemRestrictionApplyBlock_Ref(CeedElemRestriction r, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector v,
354074cb416Sjeremylt                                              CeedRequest *request) {
355d1d35e2fSjeremylt   CeedInt blk_size, num_comp, comp_stride;
3562b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
3572b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
3582b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
3597509a596Sjeremylt   CeedElemRestriction_Ref *impl;
3602b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
3614d2a38eeSjeremylt 
362f30b1135SSebastian Grimberg   return impl->Apply(r, num_comp, blk_size, comp_stride, block, block + 1, true, t_mode, u, v, request);
3639c36149bSjeremylt }
364be9261b7Sjeremylt 
365f10650afSjeremylt //------------------------------------------------------------------------------
366bd33150aSjeremylt // ElemRestriction Get Offsets
367bd33150aSjeremylt //------------------------------------------------------------------------------
3682b730f8bSJeremy L Thompson static int CeedElemRestrictionGetOffsets_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) {
369bd33150aSjeremylt   CeedElemRestriction_Ref *impl;
3702b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
371bd33150aSjeremylt   Ceed ceed;
3722b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
373bd33150aSjeremylt 
3746574a04fSJeremy L Thompson   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory");
375bd33150aSjeremylt 
376bd33150aSjeremylt   *offsets = impl->offsets;
377e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
378bd33150aSjeremylt }
379bd33150aSjeremylt 
380bd33150aSjeremylt //------------------------------------------------------------------------------
38177d1c127SSebastian Grimberg // ElemRestriction Get Orientations
38277d1c127SSebastian Grimberg //------------------------------------------------------------------------------
38377d1c127SSebastian Grimberg static int CeedElemRestrictionGetOrientations_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) {
38477d1c127SSebastian Grimberg   CeedElemRestriction_Ref *impl;
38577d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
38677d1c127SSebastian Grimberg   Ceed ceed;
38777d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
38877d1c127SSebastian Grimberg 
389fcbe8c06SSebastian Grimberg   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory");
39077d1c127SSebastian Grimberg 
39177d1c127SSebastian Grimberg   *orients = impl->orients;
39277d1c127SSebastian Grimberg   return CEED_ERROR_SUCCESS;
39377d1c127SSebastian Grimberg }
39477d1c127SSebastian Grimberg 
39577d1c127SSebastian Grimberg //------------------------------------------------------------------------------
39677d1c127SSebastian Grimberg // ElemRestriction Get Curl-Conforming Orientations
39777d1c127SSebastian Grimberg //------------------------------------------------------------------------------
39877d1c127SSebastian Grimberg static int CeedElemRestrictionGetCurlOrientations_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **curl_orients) {
39977d1c127SSebastian Grimberg   CeedElemRestriction_Ref *impl;
40077d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl));
40177d1c127SSebastian Grimberg   Ceed ceed;
40277d1c127SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed));
40377d1c127SSebastian Grimberg 
404fcbe8c06SSebastian Grimberg   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory");
40577d1c127SSebastian Grimberg 
40677d1c127SSebastian Grimberg   *curl_orients = impl->curl_orients;
40777d1c127SSebastian Grimberg   return CEED_ERROR_SUCCESS;
40877d1c127SSebastian Grimberg }
40977d1c127SSebastian Grimberg 
41077d1c127SSebastian Grimberg //------------------------------------------------------------------------------
411f10650afSjeremylt // ElemRestriction Destroy
412f10650afSjeremylt //------------------------------------------------------------------------------
41321617c04Sjeremylt static int CeedElemRestrictionDestroy_Ref(CeedElemRestriction r) {
414fe2413ffSjeremylt   CeedElemRestriction_Ref *impl;
4152b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetData(r, &impl));
41621617c04Sjeremylt 
4172b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl->offsets_allocated));
41877d1c127SSebastian Grimberg   CeedCallBackend(CeedFree(&impl->orients_allocated));
41977d1c127SSebastian Grimberg   CeedCallBackend(CeedFree(&impl->curl_orients_allocated));
4202b730f8bSJeremy L Thompson   CeedCallBackend(CeedFree(&impl));
421e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
42221617c04Sjeremylt }
42321617c04Sjeremylt 
424f10650afSjeremylt //------------------------------------------------------------------------------
425f10650afSjeremylt // ElemRestriction Create
426f10650afSjeremylt //------------------------------------------------------------------------------
427fcbe8c06SSebastian Grimberg int CeedElemRestrictionCreate_Ref(CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients,
428fcbe8c06SSebastian Grimberg                                   const CeedInt *curl_orients, CeedElemRestriction r) {
42921617c04Sjeremylt   CeedElemRestriction_Ref *impl;
430d1d35e2fSjeremylt   CeedInt                  num_elem, elem_size, num_blk, blk_size, num_comp, comp_stride;
4312b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem));
4322b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size));
4332b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk));
4342b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size));
4352b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp));
4362b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride));
4374ce2993fSjeremylt   Ceed ceed;
4382b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionGetCeed(r, &ceed));
43921617c04Sjeremylt 
4406574a04fSJeremy L Thompson   CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Only MemType = HOST supported");
4412b730f8bSJeremy L Thompson   CeedCallBackend(CeedCalloc(1, &impl));
4423661185eSjeremylt 
44392fe105eSJeremy L Thompson   // Offsets data
444fcbe8c06SSebastian Grimberg   CeedRestrictionType rstr_type;
445fcbe8c06SSebastian Grimberg   CeedCallBackend(CeedElemRestrictionGetType(r, &rstr_type));
446fcbe8c06SSebastian Grimberg   if (rstr_type != CEED_RESTRICTION_STRIDED) {
44792fe105eSJeremy L Thompson     // Check indices for ref or memcheck backends
448d1d35e2fSjeremylt     Ceed parent_ceed = ceed, curr_ceed = NULL;
449d1d35e2fSjeremylt     while (parent_ceed != curr_ceed) {
450d1d35e2fSjeremylt       curr_ceed = parent_ceed;
4512b730f8bSJeremy L Thompson       CeedCallBackend(CeedGetParent(curr_ceed, &parent_ceed));
4523661185eSjeremylt     }
4533661185eSjeremylt     const char *resource;
4542b730f8bSJeremy L Thompson     CeedCallBackend(CeedGetResource(parent_ceed, &resource));
4552b730f8bSJeremy L Thompson     if (!strcmp(resource, "/cpu/self/ref/serial") || !strcmp(resource, "/cpu/self/ref/blocked") || !strcmp(resource, "/cpu/self/memcheck/serial") ||
456d1d35e2fSjeremylt         !strcmp(resource, "/cpu/self/memcheck/blocked")) {
457e79b91d9SJeremy L Thompson       CeedSize l_size;
4582b730f8bSJeremy L Thompson       CeedCallBackend(CeedElemRestrictionGetLVectorSize(r, &l_size));
4593661185eSjeremylt 
4602b730f8bSJeremy L Thompson       for (CeedInt i = 0; i < num_elem * elem_size; i++) {
4616574a04fSJeremy L Thompson         CeedCheck(offsets[i] >= 0 && offsets[i] + (num_comp - 1) * comp_stride < l_size, ceed, CEED_ERROR_BACKEND,
4626574a04fSJeremy L Thompson                   "Restriction offset %" CeedInt_FMT " (%" CeedInt_FMT ") out of range [0, %" CeedInt_FMT "]", i, offsets[i], l_size);
4632b730f8bSJeremy L Thompson       }
4642b730f8bSJeremy L Thompson     }
4653661185eSjeremylt 
46692fe105eSJeremy L Thompson     // Copy data
467d1d35e2fSjeremylt     switch (copy_mode) {
46821617c04Sjeremylt       case CEED_COPY_VALUES:
4692b730f8bSJeremy L Thompson         CeedCallBackend(CeedMalloc(num_elem * elem_size, &impl->offsets_allocated));
4702b730f8bSJeremy L Thompson         memcpy(impl->offsets_allocated, offsets, num_elem * elem_size * sizeof(offsets[0]));
471d979a051Sjeremylt         impl->offsets = impl->offsets_allocated;
47221617c04Sjeremylt         break;
47321617c04Sjeremylt       case CEED_OWN_POINTER:
474d979a051Sjeremylt         impl->offsets_allocated = (CeedInt *)offsets;
475d979a051Sjeremylt         impl->offsets           = impl->offsets_allocated;
47621617c04Sjeremylt         break;
47721617c04Sjeremylt       case CEED_USE_POINTER:
478d979a051Sjeremylt         impl->offsets = offsets;
47921617c04Sjeremylt     }
480fcbe8c06SSebastian Grimberg 
481fcbe8c06SSebastian Grimberg     // Orientation data
482fcbe8c06SSebastian Grimberg     if (rstr_type == CEED_RESTRICTION_ORIENTED) {
483*0305e208SSebastian Grimberg       CeedCheck(orients != NULL, ceed, CEED_ERROR_BACKEND, "No orients array provided for oriented restriction");
484fcbe8c06SSebastian Grimberg       switch (copy_mode) {
485fcbe8c06SSebastian Grimberg         case CEED_COPY_VALUES:
486fcbe8c06SSebastian Grimberg           CeedCallBackend(CeedMalloc(num_elem * elem_size, &impl->orients_allocated));
487fcbe8c06SSebastian Grimberg           memcpy(impl->orients_allocated, orients, num_elem * elem_size * sizeof(orients[0]));
488fcbe8c06SSebastian Grimberg           impl->orients = impl->orients_allocated;
489fcbe8c06SSebastian Grimberg           break;
490fcbe8c06SSebastian Grimberg         case CEED_OWN_POINTER:
491fcbe8c06SSebastian Grimberg           impl->orients_allocated = (bool *)orients;
492fcbe8c06SSebastian Grimberg           impl->orients           = impl->orients_allocated;
493fcbe8c06SSebastian Grimberg           break;
494fcbe8c06SSebastian Grimberg         case CEED_USE_POINTER:
495fcbe8c06SSebastian Grimberg           impl->orients = orients;
496fcbe8c06SSebastian Grimberg       }
497fcbe8c06SSebastian Grimberg     } else if (rstr_type == CEED_RESTRICTION_CURL_ORIENTED) {
498*0305e208SSebastian Grimberg       CeedCheck(curl_orients != NULL, ceed, CEED_ERROR_BACKEND, "No curl_orients array provided for oriented restriction");
499fcbe8c06SSebastian Grimberg       switch (copy_mode) {
500fcbe8c06SSebastian Grimberg         case CEED_COPY_VALUES:
501fcbe8c06SSebastian Grimberg           CeedCallBackend(CeedMalloc(num_elem * 3 * elem_size, &impl->curl_orients_allocated));
502fcbe8c06SSebastian Grimberg           memcpy(impl->curl_orients_allocated, curl_orients, num_elem * 3 * elem_size * sizeof(curl_orients[0]));
503fcbe8c06SSebastian Grimberg           impl->curl_orients = impl->curl_orients_allocated;
504fcbe8c06SSebastian Grimberg           break;
505fcbe8c06SSebastian Grimberg         case CEED_OWN_POINTER:
506fcbe8c06SSebastian Grimberg           impl->curl_orients_allocated = (CeedInt *)curl_orients;
507fcbe8c06SSebastian Grimberg           impl->curl_orients           = impl->curl_orients_allocated;
508fcbe8c06SSebastian Grimberg           break;
509fcbe8c06SSebastian Grimberg         case CEED_USE_POINTER:
510fcbe8c06SSebastian Grimberg           impl->curl_orients = curl_orients;
511fcbe8c06SSebastian Grimberg       }
512fcbe8c06SSebastian Grimberg     }
51392fe105eSJeremy L Thompson   }
514fe2413ffSjeremylt 
5152b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionSetData(r, impl));
516d1d35e2fSjeremylt   CeedInt layout[3] = {1, elem_size, elem_size * num_comp};
5172b730f8bSJeremy L Thompson   CeedCallBackend(CeedElemRestrictionSetELayout(r, layout));
5182b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "Apply", CeedElemRestrictionApply_Ref));
519f30b1135SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyUnsigned", CeedElemRestrictionApplyUnsigned_Ref));
5202b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyBlock", CeedElemRestrictionApplyBlock_Ref));
5212b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetOffsets", CeedElemRestrictionGetOffsets_Ref));
52277d1c127SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetOrientations", CeedElemRestrictionGetOrientations_Ref));
52377d1c127SSebastian Grimberg   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetCurlOrientations", CeedElemRestrictionGetCurlOrientations_Ref));
5242b730f8bSJeremy L Thompson   CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "Destroy", CeedElemRestrictionDestroy_Ref));
525d979a051Sjeremylt 
526d1d35e2fSjeremylt   // Set apply function based upon num_comp, blk_size, and comp_stride
527d979a051Sjeremylt   CeedInt idx = -1;
5282b730f8bSJeremy L Thompson   if (blk_size < 10) idx = 100 * num_comp + 10 * blk_size + (comp_stride == 1);
529d979a051Sjeremylt   switch (idx) {
530d979a051Sjeremylt     case 110:
531d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_110;
532d979a051Sjeremylt       break;
533d979a051Sjeremylt     case 111:
534d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_111;
535d979a051Sjeremylt       break;
536d979a051Sjeremylt     case 180:
537d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_180;
538d979a051Sjeremylt       break;
539d979a051Sjeremylt     case 181:
540d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_181;
541d979a051Sjeremylt       break;
542d979a051Sjeremylt     case 310:
543d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_310;
544d979a051Sjeremylt       break;
545d979a051Sjeremylt     case 311:
546d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_311;
547d979a051Sjeremylt       break;
548d979a051Sjeremylt     case 380:
549d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_380;
550d979a051Sjeremylt       break;
551d979a051Sjeremylt     case 381:
552d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_381;
553d979a051Sjeremylt       break;
554bf4d1581Sjeremylt     // LCOV_EXCL_START
555d979a051Sjeremylt     case 510:
556d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_510;
557d979a051Sjeremylt       break;
558bf4d1581Sjeremylt     // LCOV_EXCL_STOP
559d979a051Sjeremylt     case 511:
560d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_511;
561d979a051Sjeremylt       break;
562bf4d1581Sjeremylt     // LCOV_EXCL_START
563d979a051Sjeremylt     case 580:
564d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_580;
565d979a051Sjeremylt       break;
566bf4d1581Sjeremylt     // LCOV_EXCL_STOP
567d979a051Sjeremylt     case 581:
568d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_581;
569d979a051Sjeremylt       break;
570d979a051Sjeremylt     default:
571d979a051Sjeremylt       impl->Apply = CeedElemRestrictionApply_Ref_Core;
572d979a051Sjeremylt       break;
573d979a051Sjeremylt   }
574d979a051Sjeremylt 
575e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
57621617c04Sjeremylt }
577fc0567d9Srezgarshakeri 
578fc0567d9Srezgarshakeri //------------------------------------------------------------------------------
579