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 207bf4d1581Sjeremylt // LCOV_EXCL_START 208d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_510(CeedElemRestriction r, 209d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 210d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 211d979a051Sjeremylt CeedVector v, CeedRequest *request) { 212d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 5, 1, compstride, start, stop, 213d979a051Sjeremylt tmode, u, v, request); 214d979a051Sjeremylt } 215bf4d1581Sjeremylt // LCOV_EXCL_STOP 216d979a051Sjeremylt 217d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_511(CeedElemRestriction r, 218d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 219d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 220d979a051Sjeremylt CeedVector v, CeedRequest *request) { 221d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 5, 1, 1, start, stop, tmode, 222d979a051Sjeremylt u, v, request); 223d979a051Sjeremylt } 224d979a051Sjeremylt 225bf4d1581Sjeremylt // LCOV_EXCL_START 226d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_580(CeedElemRestriction r, 227d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 228d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 229d979a051Sjeremylt CeedVector v, CeedRequest *request) { 230d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 5, 8, compstride, start, stop, 231d979a051Sjeremylt tmode, u, v, request); 232d979a051Sjeremylt } 233bf4d1581Sjeremylt // LCOV_EXCL_STOP 234d979a051Sjeremylt 235d979a051Sjeremylt static int CeedElemRestrictionApply_Ref_581(CeedElemRestriction r, 236d979a051Sjeremylt const CeedInt ncomp, const CeedInt blksize, const CeedInt compstride, 237d979a051Sjeremylt CeedInt start, CeedInt stop, CeedTransposeMode tmode, CeedVector u, 238d979a051Sjeremylt CeedVector v, CeedRequest *request) { 239d979a051Sjeremylt return CeedElemRestrictionApply_Ref_Core(r, 5, 8, 1, start, stop, tmode, 2409c36149bSjeremylt u, v, request); 2414d2a38eeSjeremylt } 2424d2a38eeSjeremylt 243f10650afSjeremylt //------------------------------------------------------------------------------ 244f10650afSjeremylt // ElemRestriction Apply 245f10650afSjeremylt //------------------------------------------------------------------------------ 246be9261b7Sjeremylt static int CeedElemRestrictionApply_Ref(CeedElemRestriction r, 247074cb416Sjeremylt CeedTransposeMode tmode, CeedVector u, 248be9261b7Sjeremylt CeedVector v, CeedRequest *request) { 249be9261b7Sjeremylt int ierr; 250d979a051Sjeremylt CeedInt numblk, blksize, ncomp, compstride; 2514d2a38eeSjeremylt ierr = CeedElemRestrictionGetNumBlocks(r, &numblk); CeedChk(ierr); 2524d2a38eeSjeremylt ierr = CeedElemRestrictionGetBlockSize(r, &blksize); CeedChk(ierr); 253d979a051Sjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &ncomp); CeedChk(ierr); 254d979a051Sjeremylt ierr = CeedElemRestrictionGetCompStride(r, &compstride); CeedChk(ierr); 2557509a596Sjeremylt CeedElemRestriction_Ref *impl; 2567509a596Sjeremylt ierr = CeedElemRestrictionGetData(r, (void *)&impl); CeedChk(ierr); 2574d2a38eeSjeremylt 258d979a051Sjeremylt return impl->Apply(r, ncomp, blksize, compstride, 0, numblk, tmode, u, v, 259d979a051Sjeremylt request); 2609c36149bSjeremylt } 261be9261b7Sjeremylt 262f10650afSjeremylt //------------------------------------------------------------------------------ 263f10650afSjeremylt // ElemRestriction Apply Block 264f10650afSjeremylt //------------------------------------------------------------------------------ 265be9261b7Sjeremylt static int CeedElemRestrictionApplyBlock_Ref(CeedElemRestriction r, 266074cb416Sjeremylt CeedInt block, CeedTransposeMode tmode, CeedVector u, CeedVector v, 267074cb416Sjeremylt CeedRequest *request) { 2684d2a38eeSjeremylt int ierr; 269d979a051Sjeremylt CeedInt blksize, ncomp, compstride; 2704d2a38eeSjeremylt ierr = CeedElemRestrictionGetBlockSize(r, &blksize); CeedChk(ierr); 271d979a051Sjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &ncomp); CeedChk(ierr); 272d979a051Sjeremylt ierr = CeedElemRestrictionGetCompStride(r, &compstride); CeedChk(ierr); 2737509a596Sjeremylt CeedElemRestriction_Ref *impl; 2747509a596Sjeremylt ierr = CeedElemRestrictionGetData(r, (void *)&impl); CeedChk(ierr); 2754d2a38eeSjeremylt 276d979a051Sjeremylt return impl->Apply(r, ncomp, blksize, compstride, block, block+1, tmode, u, v, 277d979a051Sjeremylt request); 2789c36149bSjeremylt } 279be9261b7Sjeremylt 280f10650afSjeremylt //------------------------------------------------------------------------------ 281bd33150aSjeremylt // ElemRestriction Get Offsets 282bd33150aSjeremylt //------------------------------------------------------------------------------ 283bd33150aSjeremylt static int CeedElemRestrictionGetOffsets_Ref(CeedElemRestriction rstr, 284bd33150aSjeremylt CeedMemType mtype, const CeedInt **offsets) { 285bd33150aSjeremylt int ierr; 286bd33150aSjeremylt CeedElemRestriction_Ref *impl; 287bd33150aSjeremylt ierr = CeedElemRestrictionGetData(rstr, (void *)&impl); CeedChk(ierr); 288bd33150aSjeremylt Ceed ceed; 289bd33150aSjeremylt ierr = CeedElemRestrictionGetCeed(rstr, &ceed); CeedChk(ierr); 290bd33150aSjeremylt 291bd33150aSjeremylt if (mtype != CEED_MEM_HOST) 292bd33150aSjeremylt // LCOV_EXCL_START 293bd33150aSjeremylt return CeedError(ceed, 1, "Can only provide to HOST memory"); 294bd33150aSjeremylt // LCOV_EXCL_STOP 295bd33150aSjeremylt 296bd33150aSjeremylt *offsets = impl->offsets; 297bd33150aSjeremylt return 0; 298bd33150aSjeremylt } 299bd33150aSjeremylt 300bd33150aSjeremylt //------------------------------------------------------------------------------ 301f10650afSjeremylt // ElemRestriction Destroy 302f10650afSjeremylt //------------------------------------------------------------------------------ 30321617c04Sjeremylt static int CeedElemRestrictionDestroy_Ref(CeedElemRestriction r) { 30421617c04Sjeremylt int ierr; 305fe2413ffSjeremylt CeedElemRestriction_Ref *impl; 306fe2413ffSjeremylt ierr = CeedElemRestrictionGetData(r, (void *)&impl); CeedChk(ierr); 30721617c04Sjeremylt 308d979a051Sjeremylt ierr = CeedFree(&impl->offsets_allocated); CeedChk(ierr); 309fe2413ffSjeremylt ierr = CeedFree(&impl); CeedChk(ierr); 31021617c04Sjeremylt return 0; 31121617c04Sjeremylt } 31221617c04Sjeremylt 313f10650afSjeremylt //------------------------------------------------------------------------------ 314f10650afSjeremylt // ElemRestriction Create 315f10650afSjeremylt //------------------------------------------------------------------------------ 316667bc5fcSjeremylt int CeedElemRestrictionCreate_Ref(CeedMemType mtype, CeedCopyMode cmode, 317d979a051Sjeremylt const CeedInt *offsets, 318d979a051Sjeremylt CeedElemRestriction r) { 31921617c04Sjeremylt int ierr; 32021617c04Sjeremylt CeedElemRestriction_Ref *impl; 321d979a051Sjeremylt CeedInt nelem, elemsize, numblk, blksize, ncomp, compstride; 3224ce2993fSjeremylt ierr = CeedElemRestrictionGetNumElements(r, &nelem); CeedChk(ierr); 3234ce2993fSjeremylt ierr = CeedElemRestrictionGetElementSize(r, &elemsize); CeedChk(ierr); 324d979a051Sjeremylt ierr = CeedElemRestrictionGetNumBlocks(r, &numblk); CeedChk(ierr); 325d979a051Sjeremylt ierr = CeedElemRestrictionGetBlockSize(r, &blksize); CeedChk(ierr); 326d979a051Sjeremylt ierr = CeedElemRestrictionGetNumComponents(r, &ncomp); CeedChk(ierr); 327d979a051Sjeremylt ierr = CeedElemRestrictionGetCompStride(r, &compstride); CeedChk(ierr); 3284ce2993fSjeremylt Ceed ceed; 3294ce2993fSjeremylt ierr = CeedElemRestrictionGetCeed(r, &ceed); CeedChk(ierr); 33021617c04Sjeremylt 33121617c04Sjeremylt if (mtype != CEED_MEM_HOST) 332c042f62fSJeremy L Thompson // LCOV_EXCL_START 3334ce2993fSjeremylt return CeedError(ceed, 1, "Only MemType = HOST supported"); 334c042f62fSJeremy L Thompson // LCOV_EXCL_STOP 33521617c04Sjeremylt ierr = CeedCalloc(1, &impl); CeedChk(ierr); 3363661185eSjeremylt 33792fe105eSJeremy L Thompson // Offsets data 338*7a528612SJeremy L Thompson bool isStrided; 339*7a528612SJeremy L Thompson ierr = CeedElemRestrictionGetStridedStatus(r, &isStrided); CeedChk(ierr); 340*7a528612SJeremy L Thompson if (!isStrided) { 34192fe105eSJeremy L Thompson // Check indices for ref or memcheck backends 3423661185eSjeremylt Ceed parentCeed = ceed, currCeed = NULL; 3433661185eSjeremylt while (parentCeed != currCeed) { 3443661185eSjeremylt currCeed = parentCeed; 3453661185eSjeremylt ierr = CeedGetParent(currCeed, &parentCeed); CeedChk(ierr); 3463661185eSjeremylt } 3473661185eSjeremylt const char *resource; 3483661185eSjeremylt ierr = CeedGetResource(parentCeed, &resource); CeedChk(ierr); 3493661185eSjeremylt if (!strcmp(resource, "/cpu/self/ref/serial") 3503661185eSjeremylt || !strcmp(resource, "/cpu/self/ref/blocked") 3513661185eSjeremylt || !strcmp(resource, "/cpu/self/memcheck/serial") 3523661185eSjeremylt || !strcmp(resource, "/cpu/self/memcheck/blocked")) { 3533661185eSjeremylt CeedInt lsize; 3543661185eSjeremylt ierr = CeedElemRestrictionGetLVectorSize(r, &lsize); CeedChk(ierr); 3553661185eSjeremylt 3563661185eSjeremylt for (CeedInt i = 0; i < nelem*elemsize; i++) 357d3ea8f26SJeremy L Thompson if (offsets[i] < 0 || lsize <= offsets[i] + (ncomp - 1) * compstride) 3583661185eSjeremylt // LCOV_EXCL_START 3593661185eSjeremylt return CeedError(ceed, 1, "Restriction offset %d (%d) out of range " 3603661185eSjeremylt "[0, %d]", i, offsets[i], lsize); 3613661185eSjeremylt // LCOV_EXCL_STOP 3623661185eSjeremylt } 3633661185eSjeremylt 36492fe105eSJeremy L Thompson // Copy data 36521617c04Sjeremylt switch (cmode) { 36621617c04Sjeremylt case CEED_COPY_VALUES: 367d979a051Sjeremylt ierr = CeedMalloc(nelem*elemsize, &impl->offsets_allocated); 36821617c04Sjeremylt CeedChk(ierr); 369d979a051Sjeremylt memcpy(impl->offsets_allocated, offsets, 370d979a051Sjeremylt nelem * elemsize * sizeof(offsets[0])); 371d979a051Sjeremylt impl->offsets = impl->offsets_allocated; 37221617c04Sjeremylt break; 37321617c04Sjeremylt case CEED_OWN_POINTER: 374d979a051Sjeremylt impl->offsets_allocated = (CeedInt *)offsets; 375d979a051Sjeremylt impl->offsets = impl->offsets_allocated; 37621617c04Sjeremylt break; 37721617c04Sjeremylt case CEED_USE_POINTER: 378d979a051Sjeremylt impl->offsets = offsets; 37921617c04Sjeremylt } 38092fe105eSJeremy L Thompson } 381fe2413ffSjeremylt 382fe2413ffSjeremylt ierr = CeedElemRestrictionSetData(r, (void *)&impl); CeedChk(ierr); 383fe2413ffSjeremylt ierr = CeedSetBackendFunction(ceed, "ElemRestriction", r, "Apply", 384fe2413ffSjeremylt CeedElemRestrictionApply_Ref); CeedChk(ierr); 385be9261b7Sjeremylt ierr = CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyBlock", 386be9261b7Sjeremylt CeedElemRestrictionApplyBlock_Ref); 387be9261b7Sjeremylt CeedChk(ierr); 388bd33150aSjeremylt ierr = CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetOffsets", 389bd33150aSjeremylt CeedElemRestrictionGetOffsets_Ref); 390bd33150aSjeremylt CeedChk(ierr); 391fe2413ffSjeremylt ierr = CeedSetBackendFunction(ceed, "ElemRestriction", r, "Destroy", 392fe2413ffSjeremylt CeedElemRestrictionDestroy_Ref); CeedChk(ierr); 393d979a051Sjeremylt 394d979a051Sjeremylt // Set apply function based upon ncomp, blksize, and compstride 395d979a051Sjeremylt CeedInt idx = -1; 396d979a051Sjeremylt if (blksize < 10) 397d979a051Sjeremylt idx = 100*ncomp + 10*blksize + (compstride == 1); 398d979a051Sjeremylt switch (idx) { 399d979a051Sjeremylt case 110: 400d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_110; 401d979a051Sjeremylt break; 402d979a051Sjeremylt case 111: 403d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_111; 404d979a051Sjeremylt break; 405d979a051Sjeremylt case 180: 406d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_180; 407d979a051Sjeremylt break; 408d979a051Sjeremylt case 181: 409d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_181; 410d979a051Sjeremylt break; 411d979a051Sjeremylt case 310: 412d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_310; 413d979a051Sjeremylt break; 414d979a051Sjeremylt case 311: 415d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_311; 416d979a051Sjeremylt break; 417d979a051Sjeremylt case 380: 418d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_380; 419d979a051Sjeremylt break; 420d979a051Sjeremylt case 381: 421d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_381; 422d979a051Sjeremylt break; 423bf4d1581Sjeremylt // LCOV_EXCL_START 424d979a051Sjeremylt case 510: 425d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_510; 426d979a051Sjeremylt break; 427bf4d1581Sjeremylt // LCOV_EXCL_STOP 428d979a051Sjeremylt case 511: 429d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_511; 430d979a051Sjeremylt break; 431bf4d1581Sjeremylt // LCOV_EXCL_START 432d979a051Sjeremylt case 580: 433d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_580; 434d979a051Sjeremylt break; 435bf4d1581Sjeremylt // LCOV_EXCL_STOP 436d979a051Sjeremylt case 581: 437d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_581; 438d979a051Sjeremylt break; 439d979a051Sjeremylt default: 440d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_Core; 441d979a051Sjeremylt break; 442d979a051Sjeremylt } 443d979a051Sjeremylt 44421617c04Sjeremylt return 0; 44521617c04Sjeremylt } 446f10650afSjeremylt //------------------------------------------------------------------------------ 447