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> 113d576824SJeremy L Thompson #include <string.h> 122b730f8bSJeremy L Thompson 1321617c04Sjeremylt #include "ceed-ref.h" 1421617c04Sjeremylt 15f10650afSjeremylt //------------------------------------------------------------------------------ 16f10650afSjeremylt // Core ElemRestriction Apply Code 17f10650afSjeremylt //------------------------------------------------------------------------------ 182b730f8bSJeremy L Thompson static inline int CeedElemRestrictionApply_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 19*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, 203bdd4e5aSSebastian Grimberg CeedVector v, CeedRequest *request) { 214ce2993fSjeremylt CeedElemRestriction_Ref *impl; 222b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 2321617c04Sjeremylt const CeedScalar *uu; 2421617c04Sjeremylt CeedScalar *vv; 25d1d35e2fSjeremylt CeedInt num_elem, elem_size, v_offset; 262b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem)); 272b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size)); 28d1d35e2fSjeremylt v_offset = start * blk_size * elem_size * num_comp; 29*77d1c127SSebastian Grimberg bool is_oriented, is_curl_oriented; 30*77d1c127SSebastian Grimberg is_oriented = (impl->orients != NULL); 31*77d1c127SSebastian Grimberg is_curl_oriented = (impl->curl_orients != NULL); 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 } 417f90ec76Sjeremylt // Restriction from L-vector to E-vector 4221617c04Sjeremylt // Perform: v = r * u 43d1d35e2fSjeremylt if (t_mode == CEED_NOTRANSPOSE) { 44d979a051Sjeremylt // No offsets provided, Identity Restriction 45d979a051Sjeremylt if (!impl->offsets) { 46d1d35e2fSjeremylt bool has_backend_strides; 472b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionHasBackendStrides(r, &has_backend_strides)); 48d1d35e2fSjeremylt if (has_backend_strides) { 49d1d35e2fSjeremylt // CPU backend strides are {1, elem_size, elem_size*num_comp} 507f90ec76Sjeremylt // This if branch is left separate to allow better inlining 512b730f8bSJeremy L Thompson for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) { 522b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) { 532b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) { 542b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) { 552b730f8bSJeremy L Thompson vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] = 562b730f8bSJeremy L Thompson uu[n + k * elem_size + CeedIntMin(e + j, num_elem - 1) * elem_size * num_comp]; 572b730f8bSJeremy L Thompson } 582b730f8bSJeremy L Thompson } 592b730f8bSJeremy L Thompson } 602b730f8bSJeremy L Thompson } 617f90ec76Sjeremylt } else { 627f90ec76Sjeremylt // User provided strides 637f90ec76Sjeremylt CeedInt strides[3]; 642b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetStrides(r, &strides)); 652b730f8bSJeremy L Thompson for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) { 662b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) { 672b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) { 682b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) { 692b730f8bSJeremy L Thompson vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] = 702b730f8bSJeremy L Thompson uu[n * strides[0] + k * strides[1] + CeedIntMin(e + j, num_elem - 1) * strides[2]]; 712b730f8bSJeremy L Thompson } 722b730f8bSJeremy L Thompson } 732b730f8bSJeremy L Thompson } 742b730f8bSJeremy L Thompson } 757509a596Sjeremylt } 7621617c04Sjeremylt } else { 77d979a051Sjeremylt // Offsets provided, standard or blocked restriction 78d1d35e2fSjeremylt // vv has shape [elem_size, num_comp, num_elem], row-major 79d1d35e2fSjeremylt // uu has shape [nnodes, num_comp] 802b730f8bSJeremy L Thompson for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) { 812b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) { 822b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt i = 0; i < elem_size * blk_size; i++) { 83*77d1c127SSebastian Grimberg if (!use_orients || (!is_oriented && !is_curl_oriented)) { 84f30b1135SSebastian Grimberg // Unsigned restriction 853bdd4e5aSSebastian Grimberg vv[elem_size * (k * blk_size + num_comp * e) + i - v_offset] = uu[impl->offsets[i + elem_size * e] + k * comp_stride]; 86*77d1c127SSebastian Grimberg } else if (!is_curl_oriented) { 87f30b1135SSebastian Grimberg // Signed restriction 88f30b1135SSebastian Grimberg vv[elem_size * (k * blk_size + num_comp * e) + i - v_offset] = 89*77d1c127SSebastian Grimberg uu[impl->offsets[i + elem_size * e] + k * comp_stride] * (impl->orients[i + elem_size * e] ? -1.0 : 1.0); 90*77d1c127SSebastian Grimberg } else { 91*77d1c127SSebastian Grimberg // Restriction with tridiagonal transformation 92*77d1c127SSebastian Grimberg CeedInt ii = i % elem_size; 93*77d1c127SSebastian Grimberg if (ii == 0) { 94*77d1c127SSebastian Grimberg vv[elem_size * (k * blk_size + num_comp * e) + i - v_offset] = 95*77d1c127SSebastian Grimberg uu[impl->offsets[i + 0 + elem_size * e] + k * comp_stride] * impl->curl_orients[3 * i + 1 + 3 * elem_size * e] + 96*77d1c127SSebastian Grimberg uu[impl->offsets[i + 1 + elem_size * e] + k * comp_stride] * impl->curl_orients[3 * i + 2 + 3 * elem_size * e]; 97*77d1c127SSebastian Grimberg } else if (ii == elem_size - 1) { 98*77d1c127SSebastian Grimberg vv[elem_size * (k * blk_size + num_comp * e) + i - v_offset] = 99*77d1c127SSebastian Grimberg uu[impl->offsets[i - 1 + elem_size * e] + k * comp_stride] * impl->curl_orients[3 * i + 0 + 3 * elem_size * e] + 100*77d1c127SSebastian Grimberg uu[impl->offsets[i + 0 + elem_size * e] + k * comp_stride] * impl->curl_orients[3 * i + 1 + 3 * elem_size * e]; 101*77d1c127SSebastian Grimberg } else { 102*77d1c127SSebastian Grimberg vv[elem_size * (k * blk_size + num_comp * e) + i - v_offset] = 103*77d1c127SSebastian Grimberg uu[impl->offsets[i - 1 + elem_size * e] + k * comp_stride] * impl->curl_orients[3 * i + 0 + 3 * elem_size * e] + 104*77d1c127SSebastian Grimberg uu[impl->offsets[i + 0 + elem_size * e] + k * comp_stride] * impl->curl_orients[3 * i + 1 + 3 * elem_size * e] + 105*77d1c127SSebastian Grimberg uu[impl->offsets[i + 1 + elem_size * e] + k * comp_stride] * impl->curl_orients[3 * i + 2 + 3 * elem_size * e]; 106*77d1c127SSebastian Grimberg } 107f30b1135SSebastian Grimberg } 1082b730f8bSJeremy L Thompson } 1092b730f8bSJeremy L Thompson } 1102b730f8bSJeremy L Thompson } 111b435c5a6Srezgarshakeri } 11221617c04Sjeremylt } else { 1137f90ec76Sjeremylt // Restriction from E-vector to L-vector 1148d94b059Sjeremylt // Performing v += r^T * u 115d979a051Sjeremylt // No offsets provided, Identity Restriction 116d979a051Sjeremylt if (!impl->offsets) { 117d1d35e2fSjeremylt bool has_backend_strides; 1182b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionHasBackendStrides(r, &has_backend_strides)); 119d1d35e2fSjeremylt if (has_backend_strides) { 120d1d35e2fSjeremylt // CPU backend strides are {1, elem_size, elem_size*num_comp} 1217f90ec76Sjeremylt // This if brach is left separate to allow better inlining 1222b730f8bSJeremy L Thompson for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) { 1232b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) { 1242b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) { 1252b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt j = 0; j < CeedIntMin(blk_size, num_elem - e); j++) { 1262b730f8bSJeremy L Thompson vv[n + k * elem_size + (e + j) * elem_size * num_comp] += 1272b730f8bSJeremy L Thompson uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset]; 1282b730f8bSJeremy L Thompson } 1292b730f8bSJeremy L Thompson } 1302b730f8bSJeremy L Thompson } 1312b730f8bSJeremy L Thompson } 1327f90ec76Sjeremylt } else { 1337f90ec76Sjeremylt // User provided strides 1347f90ec76Sjeremylt CeedInt strides[3]; 1352b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetStrides(r, &strides)); 1362b730f8bSJeremy L Thompson for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) { 1372b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) { 1382b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) { 1392b730f8bSJeremy L Thompson CeedPragmaSIMD for (CeedInt j = 0; j < CeedIntMin(blk_size, num_elem - e); j++) { 1402b730f8bSJeremy L Thompson vv[n * strides[0] + k * strides[1] + (e + j) * strides[2]] += 1412b730f8bSJeremy L Thompson uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset]; 1422b730f8bSJeremy L Thompson } 1432b730f8bSJeremy L Thompson } 1442b730f8bSJeremy L Thompson } 1452b730f8bSJeremy L Thompson } 146523b8ea0Sjeremylt } 14721617c04Sjeremylt } else { 148d979a051Sjeremylt // Offsets provided, standard or blocked restriction 149d1d35e2fSjeremylt // uu has shape [elem_size, num_comp, num_elem] 150d1d35e2fSjeremylt // vv has shape [nnodes, num_comp] 1512b730f8bSJeremy L Thompson for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) { 1522b730f8bSJeremy L Thompson for (CeedInt k = 0; k < num_comp; k++) { 1532b730f8bSJeremy L Thompson for (CeedInt i = 0; i < elem_size * blk_size; i += blk_size) { 1548d94b059Sjeremylt // Iteration bound set to discard padding elements 1552b730f8bSJeremy L Thompson for (CeedInt j = i; j < i + CeedIntMin(blk_size, num_elem - e); j++) { 156*77d1c127SSebastian Grimberg if (!use_orients || (!is_oriented && !is_curl_oriented)) { 157f30b1135SSebastian Grimberg // Unsigned restriction 1583bdd4e5aSSebastian Grimberg vv[impl->offsets[j + e * elem_size] + k * comp_stride] += uu[elem_size * (k * blk_size + num_comp * e) + j - v_offset]; 159*77d1c127SSebastian Grimberg } else if (!is_curl_oriented) { 160f30b1135SSebastian Grimberg // Signed restriction 161f30b1135SSebastian Grimberg vv[impl->offsets[j + e * elem_size] + k * comp_stride] += 162*77d1c127SSebastian Grimberg uu[elem_size * (k * blk_size + num_comp * e) + j - v_offset] * (impl->orients[j + e * elem_size] ? -1.0 : 1.0); 163*77d1c127SSebastian Grimberg } else { 164*77d1c127SSebastian Grimberg // Restriction with tridiagonal transformation 165*77d1c127SSebastian Grimberg CeedInt jj = j % elem_size; 166*77d1c127SSebastian Grimberg if (jj == 0) { 167*77d1c127SSebastian Grimberg vv[impl->offsets[j + e * elem_size] + k * comp_stride] += 168*77d1c127SSebastian Grimberg uu[elem_size * (k * blk_size + num_comp * e) + j + 0 - v_offset] * impl->curl_orients[(j + 0) * 3 + 1 + e * 3 * elem_size] + 169*77d1c127SSebastian Grimberg uu[elem_size * (k * blk_size + num_comp * e) + j + 1 - v_offset] * impl->curl_orients[(j + 1) * 3 + 0 + e * 3 * elem_size]; 170*77d1c127SSebastian Grimberg } else if (jj == elem_size - 1) { 171*77d1c127SSebastian Grimberg vv[impl->offsets[j + e * elem_size] + k * comp_stride] += 172*77d1c127SSebastian Grimberg uu[elem_size * (k * blk_size + num_comp * e) + j - 1 - v_offset] * impl->curl_orients[(j - 1) * 3 + 2 + e * 3 * elem_size] + 173*77d1c127SSebastian Grimberg uu[elem_size * (k * blk_size + num_comp * e) + j + 0 - v_offset] * impl->curl_orients[(j + 0) * 3 + 1 + e * 3 * elem_size]; 174*77d1c127SSebastian Grimberg } else { 175*77d1c127SSebastian Grimberg vv[impl->offsets[j + e * elem_size] + k * comp_stride] += 176*77d1c127SSebastian Grimberg uu[elem_size * (k * blk_size + num_comp * e) + j - 1 - v_offset] * impl->curl_orients[(j - 1) * 3 + 2 + e * 3 * elem_size] + 177*77d1c127SSebastian Grimberg uu[elem_size * (k * blk_size + num_comp * e) + j + 0 - v_offset] * impl->curl_orients[(j + 0) * 3 + 1 + e * 3 * elem_size] + 178*77d1c127SSebastian Grimberg uu[elem_size * (k * blk_size + num_comp * e) + j + 1 - v_offset] * impl->curl_orients[(j + 1) * 3 + 0 + e * 3 * elem_size]; 179*77d1c127SSebastian Grimberg } 180f30b1135SSebastian Grimberg } 18121617c04Sjeremylt } 182b435c5a6Srezgarshakeri } 1832b730f8bSJeremy L Thompson } 1842b730f8bSJeremy L Thompson } 1852b730f8bSJeremy L Thompson } 1862b730f8bSJeremy L Thompson } 1872b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorRestoreArrayRead(u, &uu)); 1882b730f8bSJeremy L Thompson CeedCallBackend(CeedVectorRestoreArray(v, &vv)); 1892b730f8bSJeremy L Thompson if (request != CEED_REQUEST_IMMEDIATE && request != CEED_REQUEST_ORDERED) *request = NULL; 190e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 19121617c04Sjeremylt } 19221617c04Sjeremylt 193f10650afSjeremylt //------------------------------------------------------------------------------ 194f10650afSjeremylt // ElemRestriction Apply - Common Sizes 195f10650afSjeremylt //------------------------------------------------------------------------------ 1962b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_110(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 197*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 1983bdd4e5aSSebastian Grimberg CeedRequest *request) { 199*77d1c127SSebastian Grimberg return CeedElemRestrictionApply_Ref_Core(r, 1, 1, comp_stride, start, stop, use_orients, t_mode, u, v, request); 200d979a051Sjeremylt } 201d979a051Sjeremylt 2022b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_111(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 203*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 2043bdd4e5aSSebastian Grimberg CeedRequest *request) { 205*77d1c127SSebastian Grimberg return CeedElemRestrictionApply_Ref_Core(r, 1, 1, 1, start, stop, use_orients, t_mode, u, v, request); 2064d2a38eeSjeremylt } 2074d2a38eeSjeremylt 2082b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_180(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 209*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 2103bdd4e5aSSebastian Grimberg CeedRequest *request) { 211*77d1c127SSebastian Grimberg return CeedElemRestrictionApply_Ref_Core(r, 1, 8, comp_stride, start, stop, use_orients, t_mode, u, v, request); 2129c36149bSjeremylt } 2139c36149bSjeremylt 2142b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_181(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 215*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 2163bdd4e5aSSebastian Grimberg CeedRequest *request) { 217*77d1c127SSebastian Grimberg return CeedElemRestrictionApply_Ref_Core(r, 1, 8, 1, start, stop, use_orients, t_mode, u, v, request); 2189c36149bSjeremylt } 2199c36149bSjeremylt 2202b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_310(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 221*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 2223bdd4e5aSSebastian Grimberg CeedRequest *request) { 223*77d1c127SSebastian Grimberg return CeedElemRestrictionApply_Ref_Core(r, 3, 1, comp_stride, start, stop, use_orients, t_mode, u, v, request); 224d979a051Sjeremylt } 225d979a051Sjeremylt 2262b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_311(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 227*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 2283bdd4e5aSSebastian Grimberg CeedRequest *request) { 229*77d1c127SSebastian Grimberg return CeedElemRestrictionApply_Ref_Core(r, 3, 1, 1, start, stop, use_orients, t_mode, u, v, request); 230d979a051Sjeremylt } 231d979a051Sjeremylt 2322b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_380(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 233*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 2343bdd4e5aSSebastian Grimberg CeedRequest *request) { 235*77d1c127SSebastian Grimberg return CeedElemRestrictionApply_Ref_Core(r, 3, 8, comp_stride, start, stop, use_orients, t_mode, u, v, request); 236d979a051Sjeremylt } 237d979a051Sjeremylt 2382b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_381(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 239*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 2403bdd4e5aSSebastian Grimberg CeedRequest *request) { 241*77d1c127SSebastian Grimberg return CeedElemRestrictionApply_Ref_Core(r, 3, 8, 1, start, stop, use_orients, t_mode, u, v, request); 242d979a051Sjeremylt } 243d979a051Sjeremylt 244bf4d1581Sjeremylt // LCOV_EXCL_START 2452b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_510(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 246*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 2473bdd4e5aSSebastian Grimberg CeedRequest *request) { 248*77d1c127SSebastian Grimberg return CeedElemRestrictionApply_Ref_Core(r, 5, 1, comp_stride, start, stop, use_orients, t_mode, u, v, request); 249d979a051Sjeremylt } 250bf4d1581Sjeremylt // LCOV_EXCL_STOP 251d979a051Sjeremylt 2522b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_511(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 253*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 2543bdd4e5aSSebastian Grimberg CeedRequest *request) { 255*77d1c127SSebastian Grimberg return CeedElemRestrictionApply_Ref_Core(r, 5, 1, 1, start, stop, use_orients, t_mode, u, v, request); 256d979a051Sjeremylt } 257d979a051Sjeremylt 258bf4d1581Sjeremylt // LCOV_EXCL_START 2592b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_580(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 260*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 2613bdd4e5aSSebastian Grimberg CeedRequest *request) { 262*77d1c127SSebastian Grimberg return CeedElemRestrictionApply_Ref_Core(r, 5, 8, comp_stride, start, stop, use_orients, t_mode, u, v, request); 263d979a051Sjeremylt } 264bf4d1581Sjeremylt // LCOV_EXCL_STOP 265d979a051Sjeremylt 2662b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref_581(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 267*77d1c127SSebastian Grimberg CeedInt start, CeedInt stop, bool use_orients, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 2683bdd4e5aSSebastian Grimberg CeedRequest *request) { 269*77d1c127SSebastian Grimberg return CeedElemRestrictionApply_Ref_Core(r, 5, 8, 1, start, stop, use_orients, t_mode, u, v, request); 2704d2a38eeSjeremylt } 2714d2a38eeSjeremylt 272f10650afSjeremylt //------------------------------------------------------------------------------ 273f10650afSjeremylt // ElemRestriction Apply 274f10650afSjeremylt //------------------------------------------------------------------------------ 2752b730f8bSJeremy L Thompson static int CeedElemRestrictionApply_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 276d1d35e2fSjeremylt CeedInt num_blk, blk_size, num_comp, comp_stride; 2772b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk)); 2782b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size)); 2792b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp)); 2802b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride)); 2817509a596Sjeremylt CeedElemRestriction_Ref *impl; 2822b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 2834d2a38eeSjeremylt 284f30b1135SSebastian Grimberg return impl->Apply(r, num_comp, blk_size, comp_stride, 0, num_blk, true, t_mode, u, v, request); 285f30b1135SSebastian Grimberg } 286f30b1135SSebastian Grimberg 287f30b1135SSebastian Grimberg //------------------------------------------------------------------------------ 288f30b1135SSebastian Grimberg // ElemRestriction Apply Unsigned 289f30b1135SSebastian Grimberg //------------------------------------------------------------------------------ 290f30b1135SSebastian Grimberg static int CeedElemRestrictionApplyUnsigned_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 291f30b1135SSebastian Grimberg CeedInt num_blk, blk_size, num_comp, comp_stride; 292f30b1135SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk)); 293f30b1135SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size)); 294f30b1135SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp)); 295f30b1135SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride)); 296f30b1135SSebastian Grimberg CeedElemRestriction_Ref *impl; 297f30b1135SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 298f30b1135SSebastian Grimberg 299f30b1135SSebastian Grimberg return impl->Apply(r, num_comp, blk_size, comp_stride, 0, num_blk, false, t_mode, u, v, request); 3009c36149bSjeremylt } 301be9261b7Sjeremylt 302f10650afSjeremylt //------------------------------------------------------------------------------ 303f10650afSjeremylt // ElemRestriction Apply Block 304f10650afSjeremylt //------------------------------------------------------------------------------ 3052b730f8bSJeremy L Thompson static int CeedElemRestrictionApplyBlock_Ref(CeedElemRestriction r, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 306074cb416Sjeremylt CeedRequest *request) { 307d1d35e2fSjeremylt CeedInt blk_size, num_comp, comp_stride; 3082b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size)); 3092b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp)); 3102b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride)); 3117509a596Sjeremylt CeedElemRestriction_Ref *impl; 3122b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 3134d2a38eeSjeremylt 314f30b1135SSebastian Grimberg return impl->Apply(r, num_comp, blk_size, comp_stride, block, block + 1, true, t_mode, u, v, request); 3159c36149bSjeremylt } 316be9261b7Sjeremylt 317f10650afSjeremylt //------------------------------------------------------------------------------ 318bd33150aSjeremylt // ElemRestriction Get Offsets 319bd33150aSjeremylt //------------------------------------------------------------------------------ 3202b730f8bSJeremy L Thompson static int CeedElemRestrictionGetOffsets_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 321bd33150aSjeremylt CeedElemRestriction_Ref *impl; 3222b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 323bd33150aSjeremylt Ceed ceed; 3242b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 325bd33150aSjeremylt 3266574a04fSJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory"); 327bd33150aSjeremylt 328bd33150aSjeremylt *offsets = impl->offsets; 329e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 330bd33150aSjeremylt } 331bd33150aSjeremylt 332bd33150aSjeremylt //------------------------------------------------------------------------------ 333*77d1c127SSebastian Grimberg // ElemRestriction Get Orientations 334*77d1c127SSebastian Grimberg //------------------------------------------------------------------------------ 335*77d1c127SSebastian Grimberg static int CeedElemRestrictionGetOrientations_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const bool **orients) { 336*77d1c127SSebastian Grimberg CeedElemRestriction_Ref *impl; 337*77d1c127SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 338*77d1c127SSebastian Grimberg Ceed ceed; 339*77d1c127SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 340*77d1c127SSebastian Grimberg 341*77d1c127SSebastian Grimberg if (mem_type != CEED_MEM_HOST) { 342*77d1c127SSebastian Grimberg // LCOV_EXCL_START 343*77d1c127SSebastian Grimberg return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory"); 344*77d1c127SSebastian Grimberg // LCOV_EXCL_STOP 345*77d1c127SSebastian Grimberg } 346*77d1c127SSebastian Grimberg 347*77d1c127SSebastian Grimberg *orients = impl->orients; 348*77d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 349*77d1c127SSebastian Grimberg } 350*77d1c127SSebastian Grimberg 351*77d1c127SSebastian Grimberg //------------------------------------------------------------------------------ 352*77d1c127SSebastian Grimberg // ElemRestriction Get Curl-Conforming Orientations 353*77d1c127SSebastian Grimberg //------------------------------------------------------------------------------ 354*77d1c127SSebastian Grimberg static int CeedElemRestrictionGetCurlOrientations_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **curl_orients) { 355*77d1c127SSebastian Grimberg CeedElemRestriction_Ref *impl; 356*77d1c127SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 357*77d1c127SSebastian Grimberg Ceed ceed; 358*77d1c127SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 359*77d1c127SSebastian Grimberg 360*77d1c127SSebastian Grimberg if (mem_type != CEED_MEM_HOST) { 361*77d1c127SSebastian Grimberg // LCOV_EXCL_START 362*77d1c127SSebastian Grimberg return CeedError(ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory"); 363*77d1c127SSebastian Grimberg // LCOV_EXCL_STOP 364*77d1c127SSebastian Grimberg } 365*77d1c127SSebastian Grimberg 366*77d1c127SSebastian Grimberg *curl_orients = impl->curl_orients; 367*77d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 368*77d1c127SSebastian Grimberg } 369*77d1c127SSebastian Grimberg 370*77d1c127SSebastian Grimberg //------------------------------------------------------------------------------ 371f10650afSjeremylt // ElemRestriction Destroy 372f10650afSjeremylt //------------------------------------------------------------------------------ 37321617c04Sjeremylt static int CeedElemRestrictionDestroy_Ref(CeedElemRestriction r) { 374fe2413ffSjeremylt CeedElemRestriction_Ref *impl; 3752b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 37621617c04Sjeremylt 3772b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl->offsets_allocated)); 378*77d1c127SSebastian Grimberg CeedCallBackend(CeedFree(&impl->orients_allocated)); 379*77d1c127SSebastian Grimberg CeedCallBackend(CeedFree(&impl->curl_orients_allocated)); 3802b730f8bSJeremy L Thompson CeedCallBackend(CeedFree(&impl)); 381e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 38221617c04Sjeremylt } 38321617c04Sjeremylt 384f10650afSjeremylt //------------------------------------------------------------------------------ 385f10650afSjeremylt // ElemRestriction Create 386f10650afSjeremylt //------------------------------------------------------------------------------ 3872b730f8bSJeremy L Thompson int CeedElemRestrictionCreate_Ref(CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction r) { 38821617c04Sjeremylt CeedElemRestriction_Ref *impl; 389d1d35e2fSjeremylt CeedInt num_elem, elem_size, num_blk, blk_size, num_comp, comp_stride; 3902b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem)); 3912b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size)); 3922b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk)); 3932b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size)); 3942b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp)); 3952b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride)); 3964ce2993fSjeremylt Ceed ceed; 3972b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetCeed(r, &ceed)); 39821617c04Sjeremylt 3996574a04fSJeremy L Thompson CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Only MemType = HOST supported"); 4002b730f8bSJeremy L Thompson CeedCallBackend(CeedCalloc(1, &impl)); 4013661185eSjeremylt 40292fe105eSJeremy L Thompson // Offsets data 403d1d35e2fSjeremylt bool is_strided; 4042b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionIsStrided(r, &is_strided)); 405d1d35e2fSjeremylt if (!is_strided) { 40692fe105eSJeremy L Thompson // Check indices for ref or memcheck backends 407d1d35e2fSjeremylt Ceed parent_ceed = ceed, curr_ceed = NULL; 408d1d35e2fSjeremylt while (parent_ceed != curr_ceed) { 409d1d35e2fSjeremylt curr_ceed = parent_ceed; 4102b730f8bSJeremy L Thompson CeedCallBackend(CeedGetParent(curr_ceed, &parent_ceed)); 4113661185eSjeremylt } 4123661185eSjeremylt const char *resource; 4132b730f8bSJeremy L Thompson CeedCallBackend(CeedGetResource(parent_ceed, &resource)); 4142b730f8bSJeremy L Thompson if (!strcmp(resource, "/cpu/self/ref/serial") || !strcmp(resource, "/cpu/self/ref/blocked") || !strcmp(resource, "/cpu/self/memcheck/serial") || 415d1d35e2fSjeremylt !strcmp(resource, "/cpu/self/memcheck/blocked")) { 416e79b91d9SJeremy L Thompson CeedSize l_size; 4172b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetLVectorSize(r, &l_size)); 4183661185eSjeremylt 4192b730f8bSJeremy L Thompson for (CeedInt i = 0; i < num_elem * elem_size; i++) { 4206574a04fSJeremy L Thompson CeedCheck(offsets[i] >= 0 && offsets[i] + (num_comp - 1) * comp_stride < l_size, ceed, CEED_ERROR_BACKEND, 4216574a04fSJeremy L Thompson "Restriction offset %" CeedInt_FMT " (%" CeedInt_FMT ") out of range [0, %" CeedInt_FMT "]", i, offsets[i], l_size); 4222b730f8bSJeremy L Thompson } 4232b730f8bSJeremy L Thompson } 4243661185eSjeremylt 42592fe105eSJeremy L Thompson // Copy data 426d1d35e2fSjeremylt switch (copy_mode) { 42721617c04Sjeremylt case CEED_COPY_VALUES: 4282b730f8bSJeremy L Thompson CeedCallBackend(CeedMalloc(num_elem * elem_size, &impl->offsets_allocated)); 4292b730f8bSJeremy L Thompson memcpy(impl->offsets_allocated, offsets, num_elem * elem_size * sizeof(offsets[0])); 430d979a051Sjeremylt impl->offsets = impl->offsets_allocated; 43121617c04Sjeremylt break; 43221617c04Sjeremylt case CEED_OWN_POINTER: 433d979a051Sjeremylt impl->offsets_allocated = (CeedInt *)offsets; 434d979a051Sjeremylt impl->offsets = impl->offsets_allocated; 43521617c04Sjeremylt break; 43621617c04Sjeremylt case CEED_USE_POINTER: 437d979a051Sjeremylt impl->offsets = offsets; 43821617c04Sjeremylt } 43992fe105eSJeremy L Thompson } 440fe2413ffSjeremylt 4412b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionSetData(r, impl)); 442d1d35e2fSjeremylt CeedInt layout[3] = {1, elem_size, elem_size * num_comp}; 4432b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionSetELayout(r, layout)); 4442b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "Apply", CeedElemRestrictionApply_Ref)); 445f30b1135SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyUnsigned", CeedElemRestrictionApplyUnsigned_Ref)); 4462b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyBlock", CeedElemRestrictionApplyBlock_Ref)); 4472b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetOffsets", CeedElemRestrictionGetOffsets_Ref)); 448*77d1c127SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetOrientations", CeedElemRestrictionGetOrientations_Ref)); 449*77d1c127SSebastian Grimberg CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetCurlOrientations", CeedElemRestrictionGetCurlOrientations_Ref)); 4502b730f8bSJeremy L Thompson CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "Destroy", CeedElemRestrictionDestroy_Ref)); 451d979a051Sjeremylt 452d1d35e2fSjeremylt // Set apply function based upon num_comp, blk_size, and comp_stride 453d979a051Sjeremylt CeedInt idx = -1; 4542b730f8bSJeremy L Thompson if (blk_size < 10) idx = 100 * num_comp + 10 * blk_size + (comp_stride == 1); 455d979a051Sjeremylt switch (idx) { 456d979a051Sjeremylt case 110: 457d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_110; 458d979a051Sjeremylt break; 459d979a051Sjeremylt case 111: 460d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_111; 461d979a051Sjeremylt break; 462d979a051Sjeremylt case 180: 463d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_180; 464d979a051Sjeremylt break; 465d979a051Sjeremylt case 181: 466d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_181; 467d979a051Sjeremylt break; 468d979a051Sjeremylt case 310: 469d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_310; 470d979a051Sjeremylt break; 471d979a051Sjeremylt case 311: 472d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_311; 473d979a051Sjeremylt break; 474d979a051Sjeremylt case 380: 475d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_380; 476d979a051Sjeremylt break; 477d979a051Sjeremylt case 381: 478d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_381; 479d979a051Sjeremylt break; 480bf4d1581Sjeremylt // LCOV_EXCL_START 481d979a051Sjeremylt case 510: 482d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_510; 483d979a051Sjeremylt break; 484bf4d1581Sjeremylt // LCOV_EXCL_STOP 485d979a051Sjeremylt case 511: 486d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_511; 487d979a051Sjeremylt break; 488bf4d1581Sjeremylt // LCOV_EXCL_START 489d979a051Sjeremylt case 580: 490d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_580; 491d979a051Sjeremylt break; 492bf4d1581Sjeremylt // LCOV_EXCL_STOP 493d979a051Sjeremylt case 581: 494d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_581; 495d979a051Sjeremylt break; 496d979a051Sjeremylt default: 497d979a051Sjeremylt impl->Apply = CeedElemRestrictionApply_Ref_Core; 498d979a051Sjeremylt break; 499d979a051Sjeremylt } 500d979a051Sjeremylt 501e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 50221617c04Sjeremylt } 503fc0567d9Srezgarshakeri 504fc0567d9Srezgarshakeri //------------------------------------------------------------------------------ 505fc0567d9Srezgarshakeri // ElemRestriction Create Oriented 506fc0567d9Srezgarshakeri //------------------------------------------------------------------------------ 507*77d1c127SSebastian Grimberg int CeedElemRestrictionCreateOriented_Ref(CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orients, 508fc0567d9Srezgarshakeri CeedElemRestriction r) { 509fc0567d9Srezgarshakeri // Set up for normal restriction with explicit offsets. This sets up dispatch to 510fc0567d9Srezgarshakeri // CeedElemRestrictionApply_Ref_* and manages the impl->offsets array copy/allocation. 511*77d1c127SSebastian Grimberg CeedCallBackend(CeedElemRestrictionCreate_Ref(mem_type, copy_mode, offsets, r)); 512*77d1c127SSebastian Grimberg 513f30b1135SSebastian Grimberg CeedElemRestriction_Ref *impl; 514f30b1135SSebastian Grimberg CeedInt num_elem, elem_size; 5152b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 5162b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem)); 5172b730f8bSJeremy L Thompson CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size)); 518f30b1135SSebastian Grimberg 519f30b1135SSebastian Grimberg // Copy data 520fc0567d9Srezgarshakeri switch (copy_mode) { 521fc0567d9Srezgarshakeri case CEED_COPY_VALUES: 522*77d1c127SSebastian Grimberg CeedCallBackend(CeedMalloc(num_elem * elem_size, &impl->orients_allocated)); 523*77d1c127SSebastian Grimberg memcpy(impl->orients_allocated, orients, num_elem * elem_size * sizeof(orients[0])); 524*77d1c127SSebastian Grimberg impl->orients = impl->orients_allocated; 525fc0567d9Srezgarshakeri break; 526fc0567d9Srezgarshakeri case CEED_OWN_POINTER: 527*77d1c127SSebastian Grimberg impl->orients_allocated = (bool *)orients; 528*77d1c127SSebastian Grimberg impl->orients = impl->orients_allocated; 529fc0567d9Srezgarshakeri break; 530fc0567d9Srezgarshakeri case CEED_USE_POINTER: 531*77d1c127SSebastian Grimberg impl->orients = orients; 532*77d1c127SSebastian Grimberg } 533*77d1c127SSebastian Grimberg 534*77d1c127SSebastian Grimberg return CEED_ERROR_SUCCESS; 535*77d1c127SSebastian Grimberg } 536*77d1c127SSebastian Grimberg 537*77d1c127SSebastian Grimberg //------------------------------------------------------------------------------ 538*77d1c127SSebastian Grimberg // ElemRestriction Create Curl-Conforming Oriented 539*77d1c127SSebastian Grimberg //------------------------------------------------------------------------------ 540*77d1c127SSebastian Grimberg int CeedElemRestrictionCreateCurlOriented_Ref(CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const CeedInt *curl_orients, 541*77d1c127SSebastian Grimberg CeedElemRestriction r) { 542*77d1c127SSebastian Grimberg // Set up for normal restriction with explicit offsets. This sets up dispatch to 543*77d1c127SSebastian Grimberg // CeedElemRestrictionApply_Ref_* and manages the impl->offsets array copy/allocation. 544*77d1c127SSebastian Grimberg CeedCallBackend(CeedElemRestrictionCreate_Ref(mem_type, copy_mode, offsets, r)); 545*77d1c127SSebastian Grimberg 546*77d1c127SSebastian Grimberg CeedElemRestriction_Ref *impl; 547*77d1c127SSebastian Grimberg CeedInt num_elem, elem_size; 548*77d1c127SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 549*77d1c127SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem)); 550*77d1c127SSebastian Grimberg CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size)); 551*77d1c127SSebastian Grimberg 552*77d1c127SSebastian Grimberg // Orientation data 553*77d1c127SSebastian Grimberg switch (copy_mode) { 554*77d1c127SSebastian Grimberg case CEED_COPY_VALUES: 555*77d1c127SSebastian Grimberg CeedCallBackend(CeedMalloc(num_elem * 3 * elem_size, &impl->curl_orients_allocated)); 556*77d1c127SSebastian Grimberg memcpy(impl->curl_orients_allocated, curl_orients, num_elem * 3 * elem_size * sizeof(curl_orients[0])); 557*77d1c127SSebastian Grimberg impl->curl_orients = impl->curl_orients_allocated; 558*77d1c127SSebastian Grimberg break; 559*77d1c127SSebastian Grimberg case CEED_OWN_POINTER: 560*77d1c127SSebastian Grimberg impl->curl_orients_allocated = (CeedInt *)curl_orients; 561*77d1c127SSebastian Grimberg impl->curl_orients = impl->curl_orients_allocated; 562*77d1c127SSebastian Grimberg break; 563*77d1c127SSebastian Grimberg case CEED_USE_POINTER: 564*77d1c127SSebastian Grimberg impl->curl_orients = curl_orients; 565fc0567d9Srezgarshakeri } 566f30b1135SSebastian Grimberg 567fc0567d9Srezgarshakeri return CEED_ERROR_SUCCESS; 568fc0567d9Srezgarshakeri } 5692a86cc9dSSebastian Grimberg 570f10650afSjeremylt //------------------------------------------------------------------------------ 571