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, 23d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 24d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, 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; 31d979a051Sjeremylt CeedInt nelem, elemsize, voffset; 324ce2993fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &nelem); CeedChk(ierr); 334ce2993fSjeremylt ierr = CeedElemRestrictionGetElementSize(r, &elemsize); CeedChk(ierr); 34be9261b7Sjeremylt voffset = start*blksize*elemsize*ncomp; 3521617c04Sjeremylt 3621617c04Sjeremylt ierr = CeedVectorGetArrayRead(u, CEED_MEM_HOST, &uu); CeedChk(ierr); 3721617c04Sjeremylt ierr = CeedVectorGetArray(v, CEED_MEM_HOST, &vv); CeedChk(ierr); 387f90ec76Sjeremylt // Restriction from L-vector to E-vector 3921617c04Sjeremylt // Perform: v = r * u 408d94b059Sjeremylt if (tmode == CEED_NOTRANSPOSE) { 41d979a051Sjeremylt // No offsets provided, Identity Restriction 42d979a051Sjeremylt if (!impl->offsets) { 43523b8ea0Sjeremylt bool backendstrides; 44523b8ea0Sjeremylt ierr = CeedElemRestrictionGetBackendStridesStatus(r, &backendstrides); 45523b8ea0Sjeremylt CeedChk(ierr); 46523b8ea0Sjeremylt if (backendstrides) { 477f90ec76Sjeremylt // CPU backend strides are {1, elemsize, elemsize*ncomp} 487f90ec76Sjeremylt // This if branch is left separate to allow better inlining 49be9261b7Sjeremylt for (CeedInt e = start*blksize; e < stop*blksize; e+=blksize) 50e1b98f6eSjeremylt CeedPragmaSIMD 517509a596Sjeremylt for (CeedInt k = 0; k < ncomp; k++) 521d79ecccSjeremylt CeedPragmaSIMD 537509a596Sjeremylt for (CeedInt n = 0; n < elemsize; n++) 547509a596Sjeremylt CeedPragmaSIMD 557f90ec76Sjeremylt for (CeedInt j = 0; j < blksize; j++) 567f90ec76Sjeremylt vv[e*elemsize*ncomp + (k*elemsize+n)*blksize + j - voffset] 577f90ec76Sjeremylt = uu[n + k*elemsize + 587f90ec76Sjeremylt CeedIntMin(e+j, nelem-1)*elemsize*ncomp]; 597f90ec76Sjeremylt } else { 607f90ec76Sjeremylt // User provided strides 617f90ec76Sjeremylt CeedInt strides[3]; 627f90ec76Sjeremylt ierr = CeedElemRestrictionGetStrides(r, &strides); CeedChk(ierr); 637f90ec76Sjeremylt for (CeedInt e = start*blksize; e < stop*blksize; e+=blksize) 647f90ec76Sjeremylt CeedPragmaSIMD 657f90ec76Sjeremylt for (CeedInt k = 0; k < ncomp; k++) 667f90ec76Sjeremylt CeedPragmaSIMD 677f90ec76Sjeremylt for (CeedInt n = 0; n < elemsize; n++) 687f90ec76Sjeremylt CeedPragmaSIMD 697f90ec76Sjeremylt for (CeedInt j = 0; j < blksize; j++) 707509a596Sjeremylt vv[e*elemsize*ncomp + (k*elemsize+n)*blksize + j - voffset] 717509a596Sjeremylt = uu[n*strides[0] + k*strides[1] + 727509a596Sjeremylt CeedIntMin(e+j, nelem-1)*strides[2]]; 737509a596Sjeremylt } 7421617c04Sjeremylt } else { 75d979a051Sjeremylt // Offsets provided, standard or blocked restriction 76ecf6354eSJed Brown // vv has shape [elemsize, ncomp, nelem], row-major 778795c945Sjeremylt // uu has shape [nnodes, ncomp] 78be9261b7Sjeremylt for (CeedInt e = start*blksize; e < stop*blksize; e+=blksize) 79e1b98f6eSjeremylt CeedPragmaSIMD 80d979a051Sjeremylt for (CeedInt k = 0; k < ncomp; k++) 81e1b98f6eSjeremylt CeedPragmaSIMD 8206cdd269SJed Brown for (CeedInt i = 0; i < elemsize*blksize; i++) 83d979a051Sjeremylt vv[elemsize*(k*blksize+ncomp*e) + i - voffset] 84d979a051Sjeremylt = uu[impl->offsets[i+elemsize*e] + k*compstride]; 8521617c04Sjeremylt } 8621617c04Sjeremylt } else { 877f90ec76Sjeremylt // Restriction from E-vector to L-vector 888d94b059Sjeremylt // Performing v += r^T * u 89d979a051Sjeremylt // No offsets provided, Identity Restriction 90d979a051Sjeremylt if (!impl->offsets) { 91523b8ea0Sjeremylt bool backendstrides; 92523b8ea0Sjeremylt ierr = CeedElemRestrictionGetBackendStridesStatus(r, &backendstrides); 93523b8ea0Sjeremylt CeedChk(ierr); 94523b8ea0Sjeremylt if (backendstrides) { 957f90ec76Sjeremylt // CPU backend strides are {1, elemsize, elemsize*ncomp} 967f90ec76Sjeremylt // This if brach is left separate to allow better inlining 97523b8ea0Sjeremylt for (CeedInt e = start*blksize; e < stop*blksize; e+=blksize) 98523b8ea0Sjeremylt CeedPragmaSIMD 997509a596Sjeremylt for (CeedInt k = 0; k < ncomp; k++) 1007509a596Sjeremylt CeedPragmaSIMD 1017509a596Sjeremylt for (CeedInt n = 0; n < elemsize; n++) 1027f90ec76Sjeremylt CeedPragmaSIMD 1037f90ec76Sjeremylt for (CeedInt j = 0; j < CeedIntMin(blksize, nelem-e); j++) 1047f90ec76Sjeremylt vv[n + k*elemsize + (e+j)*elemsize*ncomp] 1057f90ec76Sjeremylt += uu[e*elemsize*ncomp + (k*elemsize+n)*blksize + j - voffset]; 1067f90ec76Sjeremylt } else { 1077f90ec76Sjeremylt // User provided strides 1087f90ec76Sjeremylt CeedInt strides[3]; 1097f90ec76Sjeremylt ierr = CeedElemRestrictionGetStrides(r, &strides); CeedChk(ierr); 1107f90ec76Sjeremylt for (CeedInt e = start*blksize; e < stop*blksize; e+=blksize) 1117f90ec76Sjeremylt CeedPragmaSIMD 1127f90ec76Sjeremylt for (CeedInt k = 0; k < ncomp; k++) 1137f90ec76Sjeremylt CeedPragmaSIMD 1147f90ec76Sjeremylt for (CeedInt n = 0; n < elemsize; n++) 1157f90ec76Sjeremylt CeedPragmaSIMD 1167f90ec76Sjeremylt for (CeedInt j = 0; j < CeedIntMin(blksize, nelem-e); j++) 1177509a596Sjeremylt vv[n*strides[0] + k*strides[1] + (e+j)*strides[2]] 1187509a596Sjeremylt += uu[e*elemsize*ncomp + (k*elemsize+n)*blksize + j - voffset]; 119523b8ea0Sjeremylt } 12021617c04Sjeremylt } else { 121d979a051Sjeremylt // Offsets provided, standard or blocked restriction 122ecf6354eSJed Brown // uu has shape [elemsize, ncomp, nelem] 1238795c945Sjeremylt // vv has shape [nnodes, ncomp] 124e1b98f6eSjeremylt for (CeedInt e = start*blksize; e < stop*blksize; e+=blksize) 125d979a051Sjeremylt for (CeedInt k = 0; k < ncomp; k++) 12606cdd269SJed Brown for (CeedInt i = 0; i < elemsize*blksize; i+=blksize) 1278d94b059Sjeremylt // Iteration bound set to discard padding elements 1284ce2993fSjeremylt for (CeedInt j = i; j < i+CeedIntMin(blksize, nelem-e); j++) 129d979a051Sjeremylt vv[impl->offsets[j+e*elemsize] + k*compstride] 130d979a051Sjeremylt += uu[elemsize*(k*blksize+ncomp*e) + j - voffset]; 13121617c04Sjeremylt } 13221617c04Sjeremylt } 13321617c04Sjeremylt ierr = CeedVectorRestoreArrayRead(u, &uu); CeedChk(ierr); 13421617c04Sjeremylt ierr = CeedVectorRestoreArray(v, &vv); CeedChk(ierr); 13521617c04Sjeremylt if (request != CEED_REQUEST_IMMEDIATE && request != CEED_REQUEST_ORDERED) 13621617c04Sjeremylt *request = NULL; 13721617c04Sjeremylt return 0; 13821617c04Sjeremylt } 13921617c04Sjeremylt 140f10650afSjeremylt //------------------------------------------------------------------------------ 141f10650afSjeremylt // ElemRestriction Apply - Common Sizes 142f10650afSjeremylt //------------------------------------------------------------------------------ 143d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_110(CeedElemRestriction r, 144d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 145d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 146d979a051Sjeremylt CeedVector v, CeedRequest *request) { 147d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 1, 1, compstride, start, stop, 148d979a051Sjeremylt tmode, u, v, request); 149d979a051Sjeremylt } 150d979a051Sjeremylt 151d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_111(CeedElemRestriction r, 152d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 153d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 154d979a051Sjeremylt CeedVector v, CeedRequest *request) { 155d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 1, 1, 1, start, stop, tmode, 1569c36149bSjeremylt u, v, request); 1574d2a38eeSjeremylt } 1584d2a38eeSjeremylt 159d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_180(CeedElemRestriction r, 160d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 161d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 162d979a051Sjeremylt CeedVector v, CeedRequest *request) { 163d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 1, 8, compstride, start, stop, 164d979a051Sjeremylt tmode, u, v, request); 1659c36149bSjeremylt } 1669c36149bSjeremylt 167d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_181(CeedElemRestriction r, 168d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 169d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 170d979a051Sjeremylt CeedVector v, CeedRequest *request) { 171d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 1, 8, 1, start, stop, tmode, 1729c36149bSjeremylt u, v, request); 1739c36149bSjeremylt } 1749c36149bSjeremylt 175d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_310(CeedElemRestriction r, 176d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 177d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 178d979a051Sjeremylt CeedVector v, CeedRequest *request) { 179d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 3, 1, compstride, start, stop, 180d979a051Sjeremylt tmode, u, v, request); 181d979a051Sjeremylt } 182d979a051Sjeremylt 183d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_311(CeedElemRestriction r, 184d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 185d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 186d979a051Sjeremylt CeedVector v, CeedRequest *request) { 187d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 3, 1, 1, start, stop, tmode, 188d979a051Sjeremylt u, v, request); 189d979a051Sjeremylt } 190d979a051Sjeremylt 191d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_380(CeedElemRestriction r, 192d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 193d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 194d979a051Sjeremylt CeedVector v, CeedRequest *request) { 195d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 3, 8, compstride, start, stop, 196d979a051Sjeremylt tmode, u, v, request); 197d979a051Sjeremylt } 198d979a051Sjeremylt 199d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_381(CeedElemRestriction r, 200d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 201d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 202d979a051Sjeremylt CeedVector v, CeedRequest *request) { 203d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 3, 8, 1, start, stop, tmode, 204d979a051Sjeremylt u, v, request); 205d979a051Sjeremylt } 206d979a051Sjeremylt 207d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_510(CeedElemRestriction r, 208d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 209d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 210d979a051Sjeremylt CeedVector v, CeedRequest *request) { 211d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 5, 1, compstride, start, stop, 212d979a051Sjeremylt tmode, u, v, request); 213d979a051Sjeremylt } 214d979a051Sjeremylt 215d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_511(CeedElemRestriction r, 216d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 217d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 218d979a051Sjeremylt CeedVector v, CeedRequest *request) { 219d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 5, 1, 1, start, stop, tmode, 220d979a051Sjeremylt u, v, request); 221d979a051Sjeremylt } 222d979a051Sjeremylt 223d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_580(CeedElemRestriction r, 224d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 225d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 226d979a051Sjeremylt CeedVector v, CeedRequest *request) { 227d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 5, 8, compstride, start, stop, 228d979a051Sjeremylt tmode, u, v, request); 229d979a051Sjeremylt } 230d979a051Sjeremylt 231d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_581(CeedElemRestriction r, 232d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 233d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 234d979a051Sjeremylt CeedVector v, CeedRequest *request) { 235d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 5, 8, 1, start, stop, tmode, 2369c36149bSjeremylt u, v, request); 2374d2a38eeSjeremylt } 2384d2a38eeSjeremylt 239f10650afSjeremylt //------------------------------------------------------------------------------ 240f10650afSjeremylt // ElemRestriction Apply 241f10650afSjeremylt //------------------------------------------------------------------------------ 242be9261b7Sjeremylt static int CeedElemRestrictionApply_Ref(CeedElemRestriction r, 243074cb416Sjeremylt CeedTransposeMode tmode, CeedVector u, 244be9261b7Sjeremylt CeedVector v, CeedRequest *request) { 245be9261b7Sjeremylt int ierr; 246d979a051Sjeremylt CeedInt numblk, blksize, ncomp, compstride; 2474d2a38eeSjeremylt ierr = CeedElemRestrictionGetNumBlocks(r, &numblk); CeedChk(ierr); 2484d2a38eeSjeremylt ierr = CeedElemRestrictionGetBlockSize(r, &blksize); CeedChk(ierr); 249d979a051Sjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &ncomp); CeedChk(ierr); 250d979a051Sjeremylt ierr = CeedElemRestrictionGetCompStride(r, &compstride); CeedChk(ierr); 2517509a596Sjeremylt CeedElemRestriction_Ref *impl; 2527509a596Sjeremylt ierr = CeedElemRestrictionGetData(r, (void *)&impl); CeedChk(ierr); 2534d2a38eeSjeremylt 254d979a051Sjeremylt return impl->Apply(r, ncomp, blksize, compstride, 0, numblk, tmode, u, v, 255d979a051Sjeremylt request); 2569c36149bSjeremylt } 257be9261b7Sjeremylt 258f10650afSjeremylt //------------------------------------------------------------------------------ 259f10650afSjeremylt // ElemRestriction Apply Block 260f10650afSjeremylt //------------------------------------------------------------------------------ 261be9261b7Sjeremylt static int CeedElemRestrictionApplyBlock_Ref(CeedElemRestriction r, 262074cb416Sjeremylt CeedInt block, CeedTransposeMode tmode, CeedVector u, CeedVector v, 263074cb416Sjeremylt CeedRequest *request) { 2644d2a38eeSjeremylt int ierr; 265d979a051Sjeremylt CeedInt blksize, ncomp, compstride; 2664d2a38eeSjeremylt ierr = CeedElemRestrictionGetBlockSize(r, &blksize); CeedChk(ierr); 267d979a051Sjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &ncomp); CeedChk(ierr); 268d979a051Sjeremylt ierr = CeedElemRestrictionGetCompStride(r, &compstride); CeedChk(ierr); 2697509a596Sjeremylt CeedElemRestriction_Ref *impl; 2707509a596Sjeremylt ierr = CeedElemRestrictionGetData(r, (void *)&impl); CeedChk(ierr); 2714d2a38eeSjeremylt 272d979a051Sjeremylt return impl->Apply(r, ncomp, blksize, compstride, block, block+1, tmode, u, v, 273d979a051Sjeremylt request); 2749c36149bSjeremylt } 275be9261b7Sjeremylt 276f10650afSjeremylt //------------------------------------------------------------------------------ 277f10650afSjeremylt // ElemRestriction Destroy 278f10650afSjeremylt //------------------------------------------------------------------------------ 27921617c04Sjeremylt static int CeedElemRestrictionDestroy_Ref(CeedElemRestriction r) { 28021617c04Sjeremylt int ierr; 281fe2413ffSjeremylt CeedElemRestriction_Ref *impl; 282fe2413ffSjeremylt ierr = CeedElemRestrictionGetData(r, (void *)&impl); CeedChk(ierr); 28321617c04Sjeremylt 284d979a051Sjeremylt ierr = CeedFree(&impl->offsets_allocated); CeedChk(ierr); 285fe2413ffSjeremylt ierr = CeedFree(&impl); CeedChk(ierr); 28621617c04Sjeremylt return 0; 28721617c04Sjeremylt } 28821617c04Sjeremylt 289f10650afSjeremylt //------------------------------------------------------------------------------ 290f10650afSjeremylt // ElemRestriction Create 291f10650afSjeremylt //------------------------------------------------------------------------------ 292667bc5fcSjeremylt int CeedElemRestrictionCreate_Ref(CeedMemType mtype, CeedCopyMode cmode, 293d979a051Sjeremylt const CeedInt *offsets, 294d979a051Sjeremylt CeedElemRestriction r) { 29521617c04Sjeremylt int ierr; 29621617c04Sjeremylt CeedElemRestriction_Ref *impl; 297d979a051Sjeremylt CeedInt nelem, elemsize, numblk, blksize, ncomp, compstride; 2984ce2993fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &nelem); CeedChk(ierr); 2994ce2993fSjeremylt ierr = CeedElemRestrictionGetElementSize(r, &elemsize); CeedChk(ierr); 300d979a051Sjeremylt ierr = CeedElemRestrictionGetNumBlocks(r, &numblk); CeedChk(ierr); 301d979a051Sjeremylt ierr = CeedElemRestrictionGetBlockSize(r, &blksize); CeedChk(ierr); 302d979a051Sjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &ncomp); CeedChk(ierr); 303d979a051Sjeremylt ierr = CeedElemRestrictionGetCompStride(r, &compstride); CeedChk(ierr); 3044ce2993fSjeremylt Ceed ceed; 3054ce2993fSjeremylt ierr = CeedElemRestrictionGetCeed(r, &ceed); CeedChk(ierr); 30621617c04Sjeremylt 30721617c04Sjeremylt if (mtype != CEED_MEM_HOST) 308c042f62fSJeremy L Thompson // LCOV_EXCL_START 3094ce2993fSjeremylt return CeedError(ceed, 1, "Only MemType = HOST supported"); 310c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 31121617c04Sjeremylt ierr = CeedCalloc(1, &impl); CeedChk(ierr); 3123661185eSjeremylt 3133661185eSjeremylt // Check indices for ref or memcheck backends 3143661185eSjeremylt if (offsets) { 3153661185eSjeremylt Ceed parentCeed = ceed, currCeed = NULL; 3163661185eSjeremylt while (parentCeed != currCeed) { 3173661185eSjeremylt currCeed = parentCeed; 3183661185eSjeremylt ierr = CeedGetParent(currCeed, &parentCeed); CeedChk(ierr); 3193661185eSjeremylt } 3203661185eSjeremylt const char *resource; 3213661185eSjeremylt ierr = CeedGetResource(parentCeed, &resource); CeedChk(ierr); 3223661185eSjeremylt if (!strcmp(resource, "/cpu/self/ref/serial") 3233661185eSjeremylt || !strcmp(resource, "/cpu/self/ref/blocked") 3243661185eSjeremylt || !strcmp(resource, "/cpu/self/memcheck/serial") 3253661185eSjeremylt || !strcmp(resource, "/cpu/self/memcheck/blocked")) { 3263661185eSjeremylt CeedInt lsize; 3273661185eSjeremylt ierr = CeedElemRestrictionGetLVectorSize(r, &lsize); CeedChk(ierr); 3283661185eSjeremylt 3293661185eSjeremylt for (CeedInt i = 0; i < nelem*elemsize; i++) 330*d3ea8f26SJeremy L Thompson if (offsets[i] < 0 || lsize <= offsets[i] + (ncomp - 1) * compstride) 3313661185eSjeremylt // LCOV_EXCL_START 3323661185eSjeremylt return CeedError(ceed, 1, "Restriction offset %d (%d) out of range " 3333661185eSjeremylt "[0, %d]", i, offsets[i], lsize); 3343661185eSjeremylt // LCOV_EXCL_STOP 3353661185eSjeremylt } 3363661185eSjeremylt } 3373661185eSjeremylt 3383661185eSjeremylt // Offsets data 33921617c04Sjeremylt switch (cmode) { 34021617c04Sjeremylt case CEED_COPY_VALUES: 341d979a051Sjeremylt ierr = CeedMalloc(nelem*elemsize, &impl->offsets_allocated); 34221617c04Sjeremylt CeedChk(ierr); 343d979a051Sjeremylt memcpy(impl->offsets_allocated, offsets, 344d979a051Sjeremylt nelem * elemsize * sizeof(offsets[0])); 345d979a051Sjeremylt impl->offsets = impl->offsets_allocated; 34621617c04Sjeremylt break; 34721617c04Sjeremylt case CEED_OWN_POINTER: 348d979a051Sjeremylt impl->offsets_allocated = (CeedInt *)offsets; 349d979a051Sjeremylt impl->offsets = impl->offsets_allocated; 35021617c04Sjeremylt break; 35121617c04Sjeremylt case CEED_USE_POINTER: 352d979a051Sjeremylt impl->offsets = offsets; 35321617c04Sjeremylt } 354fe2413ffSjeremylt 355fe2413ffSjeremylt ierr = CeedElemRestrictionSetData(r, (void *)&impl); CeedChk(ierr); 356fe2413ffSjeremylt ierr = CeedSetBackendFunction(ceed, "ElemRestriction", r, "Apply", 357fe2413ffSjeremylt CeedElemRestrictionApply_Ref); CeedChk(ierr); 358be9261b7Sjeremylt ierr = CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyBlock", 359be9261b7Sjeremylt CeedElemRestrictionApplyBlock_Ref); 360be9261b7Sjeremylt CeedChk(ierr); 361fe2413ffSjeremylt ierr = CeedSetBackendFunction(ceed, "ElemRestriction", r, "Destroy", 362fe2413ffSjeremylt CeedElemRestrictionDestroy_Ref); CeedChk(ierr); 363d979a051Sjeremylt 364d979a051Sjeremylt // Set apply function based upon ncomp, blksize, and compstride 365d979a051Sjeremylt CeedInt idx = -1; 366d979a051Sjeremylt if (blksize < 10) 367d979a051Sjeremylt idx = 100*ncomp + 10*blksize + (compstride == 1); 368d979a051Sjeremylt switch (idx) { 369d979a051Sjeremylt case 110: 370d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_110; 371d979a051Sjeremylt break; 372d979a051Sjeremylt case 111: 373d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_111; 374d979a051Sjeremylt break; 375d979a051Sjeremylt case 180: 376d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_180; 377d979a051Sjeremylt break; 378d979a051Sjeremylt case 181: 379d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_181; 380d979a051Sjeremylt break; 381d979a051Sjeremylt case 310: 382d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_310; 383d979a051Sjeremylt break; 384d979a051Sjeremylt case 311: 385d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_311; 386d979a051Sjeremylt break; 387d979a051Sjeremylt case 380: 388d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_380; 389d979a051Sjeremylt break; 390d979a051Sjeremylt case 381: 391d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_381; 392d979a051Sjeremylt break; 393d979a051Sjeremylt case 510: 394d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_510; 395d979a051Sjeremylt break; 396d979a051Sjeremylt case 511: 397d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_511; 398d979a051Sjeremylt break; 399d979a051Sjeremylt case 580: 400d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_580; 401d979a051Sjeremylt break; 402d979a051Sjeremylt case 581: 403d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_581; 404d979a051Sjeremylt break; 405d979a051Sjeremylt default: 406d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_Core; 407d979a051Sjeremylt break; 408d979a051Sjeremylt } 409d979a051Sjeremylt 41021617c04Sjeremylt return 0; 41121617c04Sjeremylt } 412f10650afSjeremylt //------------------------------------------------------------------------------ 413