xref: /libCEED/rust/libceed-sys/c-src/backends/ref/ceed-ref-restriction.c (revision 07c0792432bfd53b68802266b3808e7065628bc2)
121617c04Sjeremylt // Copyright (c) 2017-2018, Lawrence Livermore National Security, LLC.
221617c04Sjeremylt // Produced at the Lawrence Livermore National Laboratory. LLNL-CODE-734707.
321617c04Sjeremylt // All Rights reserved. See files LICENSE and NOTICE for details.
421617c04Sjeremylt //
521617c04Sjeremylt // This file is part of CEED, a collection of benchmarks, miniapps, software
621617c04Sjeremylt // libraries and APIs for efficient high-order finite element and spectral
721617c04Sjeremylt // element discretizations for exascale applications. For more information and
821617c04Sjeremylt // source code availability see http://github.com/ceed.
921617c04Sjeremylt //
1021617c04Sjeremylt // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
1121617c04Sjeremylt // a collaborative effort of two U.S. Department of Energy organizations (Office
1221617c04Sjeremylt // of Science and the National Nuclear Security Administration) responsible for
1321617c04Sjeremylt // the planning and preparation of a capable exascale ecosystem, including
1421617c04Sjeremylt // software, applications, hardware, advanced system engineering and early
1521617c04Sjeremylt // testbed platforms, in support of the nation's exascale computing imperative.
1621617c04Sjeremylt 
1721617c04Sjeremylt #include "ceed-ref.h"
1821617c04Sjeremylt 
19f10650afSjeremylt //------------------------------------------------------------------------------
20f10650afSjeremylt // Core ElemRestriction Apply Code
21f10650afSjeremylt //------------------------------------------------------------------------------
22be9261b7Sjeremylt static inline int CeedElemRestrictionApply_Ref_Core(CeedElemRestriction r,
239c36149bSjeremylt     const CeedInt blksize, const CeedInt ncomp, CeedInt start, CeedInt stop,
2461dbc9d2Sjeremylt     CeedTransposeMode tmode, CeedInterlaceMode imode, CeedVector u,
259c36149bSjeremylt     CeedVector v, CeedRequest *request) {
2621617c04Sjeremylt   int ierr;
274ce2993fSjeremylt   CeedElemRestriction_Ref *impl;
287509a596Sjeremylt   ierr = CeedElemRestrictionGetData(r, (void *)&impl); CeedChk(ierr);
2921617c04Sjeremylt   const CeedScalar *uu;
3021617c04Sjeremylt   CeedScalar *vv;
319c36149bSjeremylt   CeedInt nelem, elemsize, nnodes, voffset;
324ce2993fSjeremylt   ierr = CeedElemRestrictionGetNumElements(r, &nelem); CeedChk(ierr);
334ce2993fSjeremylt   ierr = CeedElemRestrictionGetElementSize(r, &elemsize); CeedChk(ierr);
348795c945Sjeremylt   ierr = CeedElemRestrictionGetNumNodes(r, &nnodes); CeedChk(ierr);
35be9261b7Sjeremylt   voffset = start*blksize*elemsize*ncomp;
3621617c04Sjeremylt 
3721617c04Sjeremylt   ierr = CeedVectorGetArrayRead(u, CEED_MEM_HOST, &uu); CeedChk(ierr);
3821617c04Sjeremylt   ierr = CeedVectorGetArray(v, CEED_MEM_HOST, &vv); CeedChk(ierr);
397f90ec76Sjeremylt   // Restriction from L-vector to E-vector
4021617c04Sjeremylt   // Perform: v = r * u
418d94b059Sjeremylt   if (tmode == CEED_NOTRANSPOSE) {
428c91a0c9SJeremy L Thompson     // No indices provided, Identity Restriction
43e17b31afSThilina Rathnayake     if (!impl->indices) {
44523b8ea0Sjeremylt       bool backendstrides;
45523b8ea0Sjeremylt       ierr = CeedElemRestrictionGetBackendStridesStatus(r, &backendstrides);
46523b8ea0Sjeremylt       CeedChk(ierr);
47523b8ea0Sjeremylt       if (backendstrides) {
487f90ec76Sjeremylt         // CPU backend strides are {1, elemsize, elemsize*ncomp}
497f90ec76Sjeremylt         // This if branch is left separate to allow better inlining
50be9261b7Sjeremylt         for (CeedInt e = start*blksize; e < stop*blksize; e+=blksize)
51e1b98f6eSjeremylt           CeedPragmaSIMD
527509a596Sjeremylt           for (CeedInt k = 0; k < ncomp; k++)
531d79ecccSjeremylt             CeedPragmaSIMD
547509a596Sjeremylt             for (CeedInt n = 0; n < elemsize; n++)
557509a596Sjeremylt               CeedPragmaSIMD
567f90ec76Sjeremylt               for (CeedInt j = 0; j < blksize; j++)
577f90ec76Sjeremylt                 vv[e*elemsize*ncomp + (k*elemsize+n)*blksize + j - voffset]
587f90ec76Sjeremylt                   = uu[n + k*elemsize +
597f90ec76Sjeremylt                        CeedIntMin(e+j, nelem-1)*elemsize*ncomp];
607f90ec76Sjeremylt       } else {
617f90ec76Sjeremylt         // User provided strides
627f90ec76Sjeremylt         CeedInt strides[3];
637f90ec76Sjeremylt         ierr = CeedElemRestrictionGetStrides(r, &strides); CeedChk(ierr);
647f90ec76Sjeremylt         for (CeedInt e = start*blksize; e < stop*blksize; e+=blksize)
657f90ec76Sjeremylt           CeedPragmaSIMD
667f90ec76Sjeremylt           for (CeedInt k = 0; k < ncomp; k++)
677f90ec76Sjeremylt             CeedPragmaSIMD
687f90ec76Sjeremylt             for (CeedInt n = 0; n < elemsize; n++)
697f90ec76Sjeremylt               CeedPragmaSIMD
707f90ec76Sjeremylt               for (CeedInt j = 0; j < blksize; j++)
717509a596Sjeremylt                 vv[e*elemsize*ncomp + (k*elemsize+n)*blksize + j - voffset]
727509a596Sjeremylt                   = uu[n*strides[0] + k*strides[1] +
737509a596Sjeremylt                                     CeedIntMin(e+j, nelem-1)*strides[2]];
747509a596Sjeremylt       }
7521617c04Sjeremylt     } else {
768c91a0c9SJeremy L Thompson       // Indices provided, standard or blocked restriction
77ecf6354eSJed Brown       // vv has shape [elemsize, ncomp, nelem], row-major
788795c945Sjeremylt       // uu has shape [nnodes, ncomp]
79be9261b7Sjeremylt       for (CeedInt e = start*blksize; e < stop*blksize; e+=blksize)
80e1b98f6eSjeremylt         CeedPragmaSIMD
8121617c04Sjeremylt         for (CeedInt d = 0; d < ncomp; d++)
82e1b98f6eSjeremylt           CeedPragmaSIMD
8306cdd269SJed Brown           for (CeedInt i = 0; i < elemsize*blksize; i++)
841d79ecccSjeremylt             vv[elemsize*(d*blksize+ncomp*e) + i - voffset]
8561dbc9d2Sjeremylt               = uu[imode == CEED_NONINTERLACED
868795c945Sjeremylt                          ? impl->indices[i+elemsize*e]+nnodes*d
8706cdd269SJed Brown                          : d+ncomp*impl->indices[i+elemsize*e]];
8821617c04Sjeremylt     }
8921617c04Sjeremylt   } else {
907f90ec76Sjeremylt     // Restriction from E-vector to L-vector
918d94b059Sjeremylt     // Performing v += r^T * u
928c91a0c9SJeremy L Thompson     // No indices provided, Identity Restriction
93e17b31afSThilina Rathnayake     if (!impl->indices) {
94523b8ea0Sjeremylt       bool backendstrides;
95523b8ea0Sjeremylt       ierr = CeedElemRestrictionGetBackendStridesStatus(r, &backendstrides);
96523b8ea0Sjeremylt       CeedChk(ierr);
97523b8ea0Sjeremylt       if (backendstrides) {
987f90ec76Sjeremylt         // CPU backend strides are {1, elemsize, elemsize*ncomp}
997f90ec76Sjeremylt         // This if brach is left separate to allow better inlining
100523b8ea0Sjeremylt         for (CeedInt e = start*blksize; e < stop*blksize; e+=blksize)
101523b8ea0Sjeremylt           CeedPragmaSIMD
1027509a596Sjeremylt           for (CeedInt k = 0; k < ncomp; k++)
1037509a596Sjeremylt             CeedPragmaSIMD
1047509a596Sjeremylt             for (CeedInt n = 0; n < elemsize; n++)
1057f90ec76Sjeremylt               CeedPragmaSIMD
1067f90ec76Sjeremylt               for (CeedInt j = 0; j < CeedIntMin(blksize, nelem-e); j++)
1077f90ec76Sjeremylt                 vv[n + k*elemsize + (e+j)*elemsize*ncomp]
1087f90ec76Sjeremylt                 += uu[e*elemsize*ncomp + (k*elemsize+n)*blksize + j - voffset];
1097f90ec76Sjeremylt       } else {
1107f90ec76Sjeremylt         // User provided strides
1117f90ec76Sjeremylt         CeedInt strides[3];
1127f90ec76Sjeremylt         ierr = CeedElemRestrictionGetStrides(r, &strides); CeedChk(ierr);
1137f90ec76Sjeremylt         for (CeedInt e = start*blksize; e < stop*blksize; e+=blksize)
1147f90ec76Sjeremylt           CeedPragmaSIMD
1157f90ec76Sjeremylt           for (CeedInt k = 0; k < ncomp; k++)
1167f90ec76Sjeremylt             CeedPragmaSIMD
1177f90ec76Sjeremylt             for (CeedInt n = 0; n < elemsize; n++)
1187f90ec76Sjeremylt               CeedPragmaSIMD
1197f90ec76Sjeremylt               for (CeedInt j = 0; j < CeedIntMin(blksize, nelem-e); j++)
1207509a596Sjeremylt                 vv[n*strides[0] + k*strides[1] + (e+j)*strides[2]]
1217509a596Sjeremylt                 += uu[e*elemsize*ncomp + (k*elemsize+n)*blksize + j - voffset];
122523b8ea0Sjeremylt       }
12321617c04Sjeremylt     } else {
1248c91a0c9SJeremy L Thompson       // Indices provided, standard or blocked restriction
125ecf6354eSJed Brown       // uu has shape [elemsize, ncomp, nelem]
1268795c945Sjeremylt       // vv has shape [nnodes, ncomp]
127e1b98f6eSjeremylt       for (CeedInt e = start*blksize; e < stop*blksize; e+=blksize)
128170d5e71Sjeremylt         for (CeedInt d = 0; d < ncomp; d++)
12906cdd269SJed Brown           for (CeedInt i = 0; i < elemsize*blksize; i+=blksize)
1308d94b059Sjeremylt             // Iteration bound set to discard padding elements
1314ce2993fSjeremylt             for (CeedInt j = i; j < i+CeedIntMin(blksize, nelem-e); j++)
13261dbc9d2Sjeremylt               vv[imode == CEED_NONINTERLACED
1338795c945Sjeremylt                        ? impl->indices[j+e*elemsize]+nnodes*d
13406cdd269SJed Brown                        : d+ncomp*impl->indices[j+e*elemsize]]
135e1b98f6eSjeremylt               += uu[elemsize*(d*blksize+ncomp*e) + j - voffset];
13621617c04Sjeremylt     }
13721617c04Sjeremylt   }
13821617c04Sjeremylt   ierr = CeedVectorRestoreArrayRead(u, &uu); CeedChk(ierr);
13921617c04Sjeremylt   ierr = CeedVectorRestoreArray(v, &vv); CeedChk(ierr);
14021617c04Sjeremylt   if (request != CEED_REQUEST_IMMEDIATE && request != CEED_REQUEST_ORDERED)
14121617c04Sjeremylt     *request = NULL;
14221617c04Sjeremylt   return 0;
14321617c04Sjeremylt }
14421617c04Sjeremylt 
145f10650afSjeremylt //------------------------------------------------------------------------------
146f10650afSjeremylt // ElemRestriction Apply - Common Sizes
147f10650afSjeremylt //------------------------------------------------------------------------------
1481d79ecccSjeremylt static int CeedElemRestrictionApply_Ref_11(CeedElemRestriction r,
1494d2a38eeSjeremylt     CeedInt start, CeedInt stop, CeedTransposeMode tmode,
15061dbc9d2Sjeremylt     CeedInterlaceMode imode, CeedVector u, CeedVector v, CeedRequest *request) {
15161dbc9d2Sjeremylt   return CeedElemRestrictionApply_Ref_Core(r, 1, 1, start, stop, tmode, imode,
1529c36149bSjeremylt          u, v, request);
1534d2a38eeSjeremylt }
1544d2a38eeSjeremylt 
1551d79ecccSjeremylt static int CeedElemRestrictionApply_Ref_18(CeedElemRestriction r,
1564d2a38eeSjeremylt     CeedInt start, CeedInt stop, CeedTransposeMode tmode,
15761dbc9d2Sjeremylt     CeedInterlaceMode imode, CeedVector u, CeedVector v, CeedRequest *request) {
15861dbc9d2Sjeremylt   return CeedElemRestrictionApply_Ref_Core(r, 8, 1, start, stop, tmode, imode,
1599c36149bSjeremylt          u, v, request);
1609c36149bSjeremylt 
1619c36149bSjeremylt }
1629c36149bSjeremylt 
1631d79ecccSjeremylt static int CeedElemRestrictionApply_Ref_31(CeedElemRestriction r,
1649c36149bSjeremylt     CeedInt start, CeedInt stop, CeedTransposeMode tmode,
16561dbc9d2Sjeremylt     CeedInterlaceMode imode, CeedVector u, CeedVector v, CeedRequest *request) {
16661dbc9d2Sjeremylt   return CeedElemRestrictionApply_Ref_Core(r, 1, 3, start, stop, tmode, imode,
1679c36149bSjeremylt          u, v, request);
1689c36149bSjeremylt }
1699c36149bSjeremylt 
1701d79ecccSjeremylt static int CeedElemRestrictionApply_Ref_38(CeedElemRestriction r,
1719c36149bSjeremylt     CeedInt start, CeedInt stop, CeedTransposeMode tmode,
17261dbc9d2Sjeremylt     CeedInterlaceMode imode, CeedVector u, CeedVector v, CeedRequest *request) {
17361dbc9d2Sjeremylt   return CeedElemRestrictionApply_Ref_Core(r, 8, 3, start, stop, tmode, imode,
1749c36149bSjeremylt          u, v, request);
1754d2a38eeSjeremylt }
1764d2a38eeSjeremylt 
177f10650afSjeremylt //------------------------------------------------------------------------------
178f10650afSjeremylt // ElemRestriction Apply
179f10650afSjeremylt //------------------------------------------------------------------------------
180be9261b7Sjeremylt static int CeedElemRestrictionApply_Ref(CeedElemRestriction r,
181074cb416Sjeremylt                                         CeedTransposeMode tmode, CeedVector u,
182be9261b7Sjeremylt                                         CeedVector v, CeedRequest *request) {
183be9261b7Sjeremylt   int ierr;
1849c36149bSjeremylt   CeedInt numblk, ncomp, blksize;
1857509a596Sjeremylt   CeedInterlaceMode imode = CEED_NONINTERLACED;
1864d2a38eeSjeremylt   ierr = CeedElemRestrictionGetNumBlocks(r, &numblk); CeedChk(ierr);
1879c36149bSjeremylt   ierr = CeedElemRestrictionGetNumComponents(r, &ncomp); CeedChk(ierr);
1884d2a38eeSjeremylt   ierr = CeedElemRestrictionGetBlockSize(r, &blksize); CeedChk(ierr);
1897509a596Sjeremylt   CeedElemRestriction_Ref *impl;
1907509a596Sjeremylt   ierr = CeedElemRestrictionGetData(r, (void *)&impl); CeedChk(ierr);
1917509a596Sjeremylt   if (impl->indices)
19261dbc9d2Sjeremylt     ierr = CeedElemRestrictionGetIMode(r, &imode); CeedChk(ierr);
1934d2a38eeSjeremylt 
1949c36149bSjeremylt   CeedInt idx = -1;
1959c36149bSjeremylt   if (blksize < 10)
1969c36149bSjeremylt     idx = 10*ncomp + blksize;
1979c36149bSjeremylt   switch (idx) {
1989c36149bSjeremylt   case 11:
19961dbc9d2Sjeremylt     return CeedElemRestrictionApply_Ref_11(r, 0, numblk, tmode, imode,
2001d79ecccSjeremylt                                            u, v, request);
2019c36149bSjeremylt     break;
2029c36149bSjeremylt   case 18:
20361dbc9d2Sjeremylt     return CeedElemRestrictionApply_Ref_18(r, 0, numblk, tmode, imode,
2041d79ecccSjeremylt                                            u, v, request);
2059c36149bSjeremylt     break;
2069c36149bSjeremylt   case 31:
20761dbc9d2Sjeremylt     return CeedElemRestrictionApply_Ref_31(r, 0, numblk, tmode, imode,
2081d79ecccSjeremylt                                            u, v, request);
2099c36149bSjeremylt     break;
2109c36149bSjeremylt   case 38:
21161dbc9d2Sjeremylt     return CeedElemRestrictionApply_Ref_38(r, 0, numblk, tmode, imode,
2121d79ecccSjeremylt                                            u, v, request);
2139c36149bSjeremylt     break;
2149c36149bSjeremylt   default:
2154d2a38eeSjeremylt     // LCOV_EXCL_START
2169c36149bSjeremylt     return CeedElemRestrictionApply_Ref_Core(r, blksize, ncomp, 0, numblk,
21761dbc9d2Sjeremylt            tmode, imode, u, v, request);
2184d2a38eeSjeremylt     // LCOV_EXCL_STOP
219be9261b7Sjeremylt   }
2209c36149bSjeremylt }
221be9261b7Sjeremylt 
222f10650afSjeremylt //------------------------------------------------------------------------------
223f10650afSjeremylt // ElemRestriction Apply Block
224f10650afSjeremylt //------------------------------------------------------------------------------
225be9261b7Sjeremylt static int CeedElemRestrictionApplyBlock_Ref(CeedElemRestriction r,
226074cb416Sjeremylt     CeedInt block, CeedTransposeMode tmode, CeedVector u, CeedVector v,
227074cb416Sjeremylt     CeedRequest *request) {
2284d2a38eeSjeremylt   int ierr;
2299c36149bSjeremylt   CeedInt ncomp, blksize;
2307509a596Sjeremylt   CeedInterlaceMode imode = CEED_NONINTERLACED;
2319c36149bSjeremylt   ierr = CeedElemRestrictionGetNumComponents(r, &ncomp); CeedChk(ierr);
2324d2a38eeSjeremylt   ierr = CeedElemRestrictionGetBlockSize(r, &blksize); CeedChk(ierr);
2337509a596Sjeremylt   CeedElemRestriction_Ref *impl;
2347509a596Sjeremylt   ierr = CeedElemRestrictionGetData(r, (void *)&impl); CeedChk(ierr);
2357509a596Sjeremylt   if (impl->indices)
23661dbc9d2Sjeremylt     ierr = CeedElemRestrictionGetIMode(r, &imode); CeedChk(ierr);
2374d2a38eeSjeremylt 
2389c36149bSjeremylt   CeedInt idx = -1;
2399c36149bSjeremylt   if (blksize < 10)
2409c36149bSjeremylt     idx = 10*ncomp + blksize;
2419c36149bSjeremylt   switch (idx) {
2429c36149bSjeremylt   case 11:
24361dbc9d2Sjeremylt     return CeedElemRestrictionApply_Ref_11(r, block, block+1, tmode, imode,
2444d2a38eeSjeremylt                                            u, v, request);
2459c36149bSjeremylt     break;
2469c36149bSjeremylt   case 18:
24761dbc9d2Sjeremylt     return CeedElemRestrictionApply_Ref_18(r, block, block+1, tmode, imode,
2484d2a38eeSjeremylt                                            u, v, request);
2499c36149bSjeremylt     break;
2509c36149bSjeremylt   case 31:
25161dbc9d2Sjeremylt     return CeedElemRestrictionApply_Ref_31(r, block, block+1, tmode, imode,
2529c36149bSjeremylt                                            u, v, request);
2539c36149bSjeremylt     break;
2549c36149bSjeremylt   case 38:
25561dbc9d2Sjeremylt     return CeedElemRestrictionApply_Ref_38(r, block, block+1, tmode, imode,
2569c36149bSjeremylt                                            u, v, request);
2579c36149bSjeremylt     break;
2589c36149bSjeremylt   default:
2594d2a38eeSjeremylt     // LCOV_EXCL_START
2609c36149bSjeremylt     return CeedElemRestrictionApply_Ref_Core(r, blksize, ncomp, block, block+1,
26161dbc9d2Sjeremylt            tmode, imode, u, v, request);
2624d2a38eeSjeremylt     // LCOV_EXCL_STOP
263be9261b7Sjeremylt   }
2649c36149bSjeremylt }
265be9261b7Sjeremylt 
266f10650afSjeremylt //------------------------------------------------------------------------------
267f10650afSjeremylt // ElemRestriction Destroy
268f10650afSjeremylt //------------------------------------------------------------------------------
26921617c04Sjeremylt static int CeedElemRestrictionDestroy_Ref(CeedElemRestriction r) {
27021617c04Sjeremylt   int ierr;
271fe2413ffSjeremylt   CeedElemRestriction_Ref *impl;
272fe2413ffSjeremylt   ierr = CeedElemRestrictionGetData(r, (void *)&impl); CeedChk(ierr);
27321617c04Sjeremylt 
27421617c04Sjeremylt   ierr = CeedFree(&impl->indices_allocated); CeedChk(ierr);
275fe2413ffSjeremylt   ierr = CeedFree(&impl); CeedChk(ierr);
27621617c04Sjeremylt   return 0;
27721617c04Sjeremylt }
27821617c04Sjeremylt 
279f10650afSjeremylt //------------------------------------------------------------------------------
280f10650afSjeremylt // ElemRestriction Create
281f10650afSjeremylt //------------------------------------------------------------------------------
282667bc5fcSjeremylt int CeedElemRestrictionCreate_Ref(CeedMemType mtype, CeedCopyMode cmode,
283667bc5fcSjeremylt                                   const CeedInt *indices, CeedElemRestriction r) {
28421617c04Sjeremylt   int ierr;
28521617c04Sjeremylt   CeedElemRestriction_Ref *impl;
2864ce2993fSjeremylt   CeedInt elemsize, nelem;
2874ce2993fSjeremylt   ierr = CeedElemRestrictionGetNumElements(r, &nelem); CeedChk(ierr);
2884ce2993fSjeremylt   ierr = CeedElemRestrictionGetElementSize(r, &elemsize); CeedChk(ierr);
2894ce2993fSjeremylt   Ceed ceed;
2904ce2993fSjeremylt   ierr = CeedElemRestrictionGetCeed(r, &ceed); CeedChk(ierr);
29121617c04Sjeremylt 
29221617c04Sjeremylt   if (mtype != CEED_MEM_HOST)
293c042f62fSJeremy L Thompson     // LCOV_EXCL_START
2944ce2993fSjeremylt     return CeedError(ceed, 1, "Only MemType = HOST supported");
295c042f62fSJeremy L Thompson   // LCOV_EXCL_STOP
29621617c04Sjeremylt   ierr = CeedCalloc(1,&impl); CeedChk(ierr);
29721617c04Sjeremylt   switch (cmode) {
29821617c04Sjeremylt   case CEED_COPY_VALUES:
2994ce2993fSjeremylt     ierr = CeedMalloc(nelem*elemsize, &impl->indices_allocated);
30021617c04Sjeremylt     CeedChk(ierr);
30121617c04Sjeremylt     memcpy(impl->indices_allocated, indices,
3024ce2993fSjeremylt            nelem * elemsize * sizeof(indices[0]));
30321617c04Sjeremylt     impl->indices = impl->indices_allocated;
30421617c04Sjeremylt     break;
30521617c04Sjeremylt   case CEED_OWN_POINTER:
30621617c04Sjeremylt     impl->indices_allocated = (CeedInt *)indices;
30721617c04Sjeremylt     impl->indices = impl->indices_allocated;
30821617c04Sjeremylt     break;
30921617c04Sjeremylt   case CEED_USE_POINTER:
31021617c04Sjeremylt     impl->indices = indices;
31121617c04Sjeremylt   }
312fe2413ffSjeremylt 
313fe2413ffSjeremylt   ierr = CeedElemRestrictionSetData(r, (void *)&impl); CeedChk(ierr);
314fe2413ffSjeremylt   ierr = CeedSetBackendFunction(ceed, "ElemRestriction", r, "Apply",
315fe2413ffSjeremylt                                 CeedElemRestrictionApply_Ref); CeedChk(ierr);
316be9261b7Sjeremylt   ierr = CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyBlock",
317be9261b7Sjeremylt                                 CeedElemRestrictionApplyBlock_Ref);
318be9261b7Sjeremylt   CeedChk(ierr);
319fe2413ffSjeremylt   ierr = CeedSetBackendFunction(ceed, "ElemRestriction", r, "Destroy",
320fe2413ffSjeremylt                                 CeedElemRestrictionDestroy_Ref); CeedChk(ierr);
32121617c04Sjeremylt   return 0;
32221617c04Sjeremylt }
323f10650afSjeremylt //------------------------------------------------------------------------------
324*07c07924Sjeremylt 
325