1 // Copyright (c) 2017-2022, Lawrence Livermore National Security, LLC and other CEED contributors. 2 // All Rights Reserved. See the top-level LICENSE and NOTICE files for details. 3 // 4 // SPDX-License-Identifier: BSD-2-Clause 5 // 6 // This file is part of CEED: http://github.com/ceed 7 8 #include <ceed.h> 9 #include <ceed/backend.h> 10 #include <stdbool.h> 11 #include <string.h> 12 13 #include "ceed-ref.h" 14 15 //------------------------------------------------------------------------------ 16 // Core ElemRestriction Apply Code 17 //------------------------------------------------------------------------------ 18 static inline int CeedElemRestrictionApply_Ref_Core(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 19 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 20 CeedRequest *request) { 21 CeedElemRestriction_Ref *impl; 22 CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 23 const CeedScalar *uu; 24 CeedScalar *vv; 25 CeedInt num_elem, elem_size, v_offset; 26 CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem)); 27 CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size)); 28 v_offset = start * blk_size * elem_size * num_comp; 29 30 bool is_oriented; 31 CeedCallBackend(CeedElemRestrictionIsOriented(r, &is_oriented)); 32 CeedCallBackend(CeedVectorGetArrayRead(u, CEED_MEM_HOST, &uu)); 33 if (t_mode == CEED_TRANSPOSE) { 34 // Sum into for transpose mode, e-vec to l-vec 35 CeedCallBackend(CeedVectorGetArray(v, CEED_MEM_HOST, &vv)); 36 } else { 37 // Overwrite for notranspose mode, l-vec to e-vec 38 CeedCallBackend(CeedVectorGetArrayWrite(v, CEED_MEM_HOST, &vv)); 39 } 40 // Restriction from L-vector to E-vector 41 // Perform: v = r * u 42 if (t_mode == CEED_NOTRANSPOSE) { 43 // No offsets provided, Identity Restriction 44 if (!impl->offsets) { 45 bool has_backend_strides; 46 CeedCallBackend(CeedElemRestrictionHasBackendStrides(r, &has_backend_strides)); 47 if (has_backend_strides) { 48 // CPU backend strides are {1, elem_size, elem_size*num_comp} 49 // This if branch is left separate to allow better inlining 50 for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) { 51 CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) { 52 CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) { 53 CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) { 54 vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] = 55 uu[n + k * elem_size + CeedIntMin(e + j, num_elem - 1) * elem_size * num_comp]; 56 } 57 } 58 } 59 } 60 } else { 61 // User provided strides 62 CeedInt strides[3]; 63 CeedCallBackend(CeedElemRestrictionGetStrides(r, &strides)); 64 for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) { 65 CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) { 66 CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) { 67 CeedPragmaSIMD for (CeedInt j = 0; j < blk_size; j++) { 68 vv[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset] = 69 uu[n * strides[0] + k * strides[1] + CeedIntMin(e + j, num_elem - 1) * strides[2]]; 70 } 71 } 72 } 73 } 74 } 75 } else { 76 // Offsets provided, standard or blocked restriction 77 // vv has shape [elem_size, num_comp, num_elem], row-major 78 // uu has shape [nnodes, num_comp] 79 for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) { 80 CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) { 81 CeedPragmaSIMD for (CeedInt i = 0; i < elem_size * blk_size; i++) { 82 if (!use_orient || !impl->orient) { 83 // Unsigned restriction 84 vv[elem_size * (k * blk_size + num_comp * e) + i - v_offset] = 85 uu[impl->offsets[i + elem_size * e] + k * comp_stride]; 86 } else { 87 // Signed restriction 88 vv[elem_size * (k * blk_size + num_comp * e) + i - v_offset] = 89 uu[impl->offsets[i + elem_size * e] + k * comp_stride] * (impl->orient[i + elem_size * e] ? -1.0 : 1.0); 90 } 91 } 92 } 93 } 94 } 95 } else { 96 // Restriction from E-vector to L-vector 97 // Performing v += r^T * u 98 // No offsets provided, Identity Restriction 99 if (!impl->offsets) { 100 bool has_backend_strides; 101 CeedCallBackend(CeedElemRestrictionHasBackendStrides(r, &has_backend_strides)); 102 if (has_backend_strides) { 103 // CPU backend strides are {1, elem_size, elem_size*num_comp} 104 // This if brach is left separate to allow better inlining 105 for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) { 106 CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) { 107 CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) { 108 CeedPragmaSIMD for (CeedInt j = 0; j < CeedIntMin(blk_size, num_elem - e); j++) { 109 vv[n + k * elem_size + (e + j) * elem_size * num_comp] += 110 uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset]; 111 } 112 } 113 } 114 } 115 } else { 116 // User provided strides 117 CeedInt strides[3]; 118 CeedCallBackend(CeedElemRestrictionGetStrides(r, &strides)); 119 for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) { 120 CeedPragmaSIMD for (CeedInt k = 0; k < num_comp; k++) { 121 CeedPragmaSIMD for (CeedInt n = 0; n < elem_size; n++) { 122 CeedPragmaSIMD for (CeedInt j = 0; j < CeedIntMin(blk_size, num_elem - e); j++) { 123 vv[n * strides[0] + k * strides[1] + (e + j) * strides[2]] += 124 uu[e * elem_size * num_comp + (k * elem_size + n) * blk_size + j - v_offset]; 125 } 126 } 127 } 128 } 129 } 130 } else { 131 // Offsets provided, standard or blocked restriction 132 // uu has shape [elem_size, num_comp, num_elem] 133 // vv has shape [nnodes, num_comp] 134 for (CeedInt e = start * blk_size; e < stop * blk_size; e += blk_size) { 135 for (CeedInt k = 0; k < num_comp; k++) { 136 for (CeedInt i = 0; i < elem_size * blk_size; i += blk_size) { 137 // Iteration bound set to discard padding elements 138 for (CeedInt j = i; j < i + CeedIntMin(blk_size, num_elem - e); j++) { 139 if (!use_orient || !impl->orient) { 140 // Unsigned restriction 141 vv[impl->offsets[j + e * elem_size] + k * comp_stride] += 142 uu[elem_size * (k * blk_size + num_comp * e) + j - v_offset]; 143 } else { 144 // Signed restriction 145 vv[impl->offsets[j + e * elem_size] + k * comp_stride] += 146 uu[elem_size * (k * blk_size + num_comp * e) + j - v_offset] * (impl->orient[j + e * elem_size] ? -1.0 : 1.0); 147 } 148 } 149 } 150 } 151 } 152 } 153 } 154 CeedCallBackend(CeedVectorRestoreArrayRead(u, &uu)); 155 CeedCallBackend(CeedVectorRestoreArray(v, &vv)); 156 if (request != CEED_REQUEST_IMMEDIATE && request != CEED_REQUEST_ORDERED) *request = NULL; 157 return CEED_ERROR_SUCCESS; 158 } 159 160 //------------------------------------------------------------------------------ 161 // ElemRestriction Apply - Common Sizes 162 //------------------------------------------------------------------------------ 163 static int CeedElemRestrictionApply_Ref_110(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 164 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 165 return CeedElemRestrictionApply_Ref_Core(r, 1, 1, comp_stride, start, stop, use_orient, t_mode, u, v, request); 166 } 167 168 static int CeedElemRestrictionApply_Ref_111(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 169 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 170 return CeedElemRestrictionApply_Ref_Core(r, 1, 1, 1, start, stop, use_orient, t_mode, u, v, request); 171 } 172 173 static int CeedElemRestrictionApply_Ref_180(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 174 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 175 return CeedElemRestrictionApply_Ref_Core(r, 1, 8, comp_stride, start, stop, use_orient, t_mode, u, v, request); 176 } 177 178 static int CeedElemRestrictionApply_Ref_181(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 179 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 180 return CeedElemRestrictionApply_Ref_Core(r, 1, 8, 1, start, stop, use_orient, t_mode, u, v, request); 181 } 182 183 static int CeedElemRestrictionApply_Ref_310(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 184 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 185 return CeedElemRestrictionApply_Ref_Core(r, 3, 1, comp_stride, start, stop, use_orient, t_mode, u, v, request); 186 } 187 188 static int CeedElemRestrictionApply_Ref_311(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 189 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 190 return CeedElemRestrictionApply_Ref_Core(r, 3, 1, 1, start, stop, use_orient, t_mode, u, v, request); 191 } 192 193 static int CeedElemRestrictionApply_Ref_380(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 194 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 195 return CeedElemRestrictionApply_Ref_Core(r, 3, 8, comp_stride, start, stop, use_orient, t_mode, u, v, request); 196 } 197 198 static int CeedElemRestrictionApply_Ref_381(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 199 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 200 return CeedElemRestrictionApply_Ref_Core(r, 3, 8, 1, start, stop, use_orient, t_mode, u, v, request); 201 } 202 203 // LCOV_EXCL_START 204 static int CeedElemRestrictionApply_Ref_510(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 205 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 206 return CeedElemRestrictionApply_Ref_Core(r, 5, 1, comp_stride, start, stop, use_orient, t_mode, u, v, request); 207 } 208 // LCOV_EXCL_STOP 209 210 static int CeedElemRestrictionApply_Ref_511(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 211 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 212 return CeedElemRestrictionApply_Ref_Core(r, 5, 1, 1, start, stop, use_orient, t_mode, u, v, request); 213 } 214 215 // LCOV_EXCL_START 216 static int CeedElemRestrictionApply_Ref_580(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 217 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 218 return CeedElemRestrictionApply_Ref_Core(r, 5, 8, comp_stride, start, stop, use_orient, t_mode, u, v, request); 219 } 220 // LCOV_EXCL_STOP 221 222 static int CeedElemRestrictionApply_Ref_581(CeedElemRestriction r, const CeedInt num_comp, const CeedInt blk_size, const CeedInt comp_stride, 223 CeedInt start, CeedInt stop, bool use_orient, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 224 return CeedElemRestrictionApply_Ref_Core(r, 5, 8, 1, start, stop, use_orient, t_mode, u, v, request); 225 } 226 227 //------------------------------------------------------------------------------ 228 // ElemRestriction Apply 229 //------------------------------------------------------------------------------ 230 static int CeedElemRestrictionApply_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 231 CeedInt num_blk, blk_size, num_comp, comp_stride; 232 CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk)); 233 CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size)); 234 CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp)); 235 CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride)); 236 CeedElemRestriction_Ref *impl; 237 CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 238 239 return impl->Apply(r, num_comp, blk_size, comp_stride, 0, num_blk, true, t_mode, u, v, request); 240 } 241 242 //------------------------------------------------------------------------------ 243 // ElemRestriction Apply Unsigned 244 //------------------------------------------------------------------------------ 245 static int CeedElemRestrictionApplyUnsigned_Ref(CeedElemRestriction r, CeedTransposeMode t_mode, CeedVector u, CeedVector v, CeedRequest *request) { 246 CeedInt num_blk, blk_size, num_comp, comp_stride; 247 CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk)); 248 CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size)); 249 CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp)); 250 CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride)); 251 CeedElemRestriction_Ref *impl; 252 CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 253 254 return impl->Apply(r, num_comp, blk_size, comp_stride, 0, num_blk, false, t_mode, u, v, request); 255 } 256 257 //------------------------------------------------------------------------------ 258 // ElemRestriction Apply Block 259 //------------------------------------------------------------------------------ 260 static int CeedElemRestrictionApplyBlock_Ref(CeedElemRestriction r, CeedInt block, CeedTransposeMode t_mode, CeedVector u, CeedVector v, 261 CeedRequest *request) { 262 CeedInt blk_size, num_comp, comp_stride; 263 CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size)); 264 CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp)); 265 CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride)); 266 CeedElemRestriction_Ref *impl; 267 CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 268 269 return impl->Apply(r, num_comp, blk_size, comp_stride, block, block + 1, true, t_mode, u, v, request); 270 } 271 272 //------------------------------------------------------------------------------ 273 // ElemRestriction Get Offsets 274 //------------------------------------------------------------------------------ 275 static int CeedElemRestrictionGetOffsets_Ref(CeedElemRestriction rstr, CeedMemType mem_type, const CeedInt **offsets) { 276 CeedElemRestriction_Ref *impl; 277 CeedCallBackend(CeedElemRestrictionGetData(rstr, &impl)); 278 Ceed ceed; 279 CeedCallBackend(CeedElemRestrictionGetCeed(rstr, &ceed)); 280 281 CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Can only provide to HOST memory"); 282 283 *offsets = impl->offsets; 284 return CEED_ERROR_SUCCESS; 285 } 286 287 //------------------------------------------------------------------------------ 288 // ElemRestriction Destroy 289 //------------------------------------------------------------------------------ 290 static int CeedElemRestrictionDestroy_Ref(CeedElemRestriction r) { 291 CeedElemRestriction_Ref *impl; 292 CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 293 294 CeedCallBackend(CeedFree(&impl->offsets_allocated)); 295 CeedCallBackend(CeedFree(&impl->orient_allocated)); 296 CeedCallBackend(CeedFree(&impl)); 297 return CEED_ERROR_SUCCESS; 298 } 299 300 //------------------------------------------------------------------------------ 301 // ElemRestriction Create 302 //------------------------------------------------------------------------------ 303 int CeedElemRestrictionCreate_Ref(CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, CeedElemRestriction r) { 304 CeedElemRestriction_Ref *impl; 305 CeedInt num_elem, elem_size, num_blk, blk_size, num_comp, comp_stride; 306 CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem)); 307 CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size)); 308 CeedCallBackend(CeedElemRestrictionGetNumBlocks(r, &num_blk)); 309 CeedCallBackend(CeedElemRestrictionGetBlockSize(r, &blk_size)); 310 CeedCallBackend(CeedElemRestrictionGetNumComponents(r, &num_comp)); 311 CeedCallBackend(CeedElemRestrictionGetCompStride(r, &comp_stride)); 312 Ceed ceed; 313 CeedCallBackend(CeedElemRestrictionGetCeed(r, &ceed)); 314 315 CeedCheck(mem_type == CEED_MEM_HOST, ceed, CEED_ERROR_BACKEND, "Only MemType = HOST supported"); 316 CeedCallBackend(CeedCalloc(1, &impl)); 317 318 // Offsets data 319 bool is_strided; 320 CeedCallBackend(CeedElemRestrictionIsStrided(r, &is_strided)); 321 if (!is_strided) { 322 // Check indices for ref or memcheck backends 323 Ceed parent_ceed = ceed, curr_ceed = NULL; 324 while (parent_ceed != curr_ceed) { 325 curr_ceed = parent_ceed; 326 CeedCallBackend(CeedGetParent(curr_ceed, &parent_ceed)); 327 } 328 const char *resource; 329 CeedCallBackend(CeedGetResource(parent_ceed, &resource)); 330 if (!strcmp(resource, "/cpu/self/ref/serial") || !strcmp(resource, "/cpu/self/ref/blocked") || !strcmp(resource, "/cpu/self/memcheck/serial") || 331 !strcmp(resource, "/cpu/self/memcheck/blocked")) { 332 CeedSize l_size; 333 CeedCallBackend(CeedElemRestrictionGetLVectorSize(r, &l_size)); 334 335 for (CeedInt i = 0; i < num_elem * elem_size; i++) { 336 CeedCheck(offsets[i] >= 0 && offsets[i] + (num_comp - 1) * comp_stride < l_size, ceed, CEED_ERROR_BACKEND, 337 "Restriction offset %" CeedInt_FMT " (%" CeedInt_FMT ") out of range [0, %" CeedInt_FMT "]", i, offsets[i], l_size); 338 } 339 } 340 341 // Copy data 342 switch (copy_mode) { 343 case CEED_COPY_VALUES: 344 CeedCallBackend(CeedMalloc(num_elem * elem_size, &impl->offsets_allocated)); 345 memcpy(impl->offsets_allocated, offsets, num_elem * elem_size * sizeof(offsets[0])); 346 impl->offsets = impl->offsets_allocated; 347 break; 348 case CEED_OWN_POINTER: 349 impl->offsets_allocated = (CeedInt *)offsets; 350 impl->offsets = impl->offsets_allocated; 351 break; 352 case CEED_USE_POINTER: 353 impl->offsets = offsets; 354 } 355 } 356 357 CeedCallBackend(CeedElemRestrictionSetData(r, impl)); 358 CeedInt layout[3] = {1, elem_size, elem_size * num_comp}; 359 CeedCallBackend(CeedElemRestrictionSetELayout(r, layout)); 360 CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "Apply", CeedElemRestrictionApply_Ref)); 361 CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyUnsigned", CeedElemRestrictionApplyUnsigned_Ref)); 362 CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "ApplyBlock", CeedElemRestrictionApplyBlock_Ref)); 363 CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "GetOffsets", CeedElemRestrictionGetOffsets_Ref)); 364 CeedCallBackend(CeedSetBackendFunction(ceed, "ElemRestriction", r, "Destroy", CeedElemRestrictionDestroy_Ref)); 365 366 // Set apply function based upon num_comp, blk_size, and comp_stride 367 CeedInt idx = -1; 368 if (blk_size < 10) idx = 100 * num_comp + 10 * blk_size + (comp_stride == 1); 369 switch (idx) { 370 case 110: 371 impl->Apply = CeedElemRestrictionApply_Ref_110; 372 break; 373 case 111: 374 impl->Apply = CeedElemRestrictionApply_Ref_111; 375 break; 376 case 180: 377 impl->Apply = CeedElemRestrictionApply_Ref_180; 378 break; 379 case 181: 380 impl->Apply = CeedElemRestrictionApply_Ref_181; 381 break; 382 case 310: 383 impl->Apply = CeedElemRestrictionApply_Ref_310; 384 break; 385 case 311: 386 impl->Apply = CeedElemRestrictionApply_Ref_311; 387 break; 388 case 380: 389 impl->Apply = CeedElemRestrictionApply_Ref_380; 390 break; 391 case 381: 392 impl->Apply = CeedElemRestrictionApply_Ref_381; 393 break; 394 // LCOV_EXCL_START 395 case 510: 396 impl->Apply = CeedElemRestrictionApply_Ref_510; 397 break; 398 // LCOV_EXCL_STOP 399 case 511: 400 impl->Apply = CeedElemRestrictionApply_Ref_511; 401 break; 402 // LCOV_EXCL_START 403 case 580: 404 impl->Apply = CeedElemRestrictionApply_Ref_580; 405 break; 406 // LCOV_EXCL_STOP 407 case 581: 408 impl->Apply = CeedElemRestrictionApply_Ref_581; 409 break; 410 default: 411 impl->Apply = CeedElemRestrictionApply_Ref_Core; 412 break; 413 } 414 415 return CEED_ERROR_SUCCESS; 416 } 417 418 //------------------------------------------------------------------------------ 419 // ElemRestriction Create Oriented 420 //------------------------------------------------------------------------------ 421 int CeedElemRestrictionCreateOriented_Ref(CeedMemType mem_type, CeedCopyMode copy_mode, const CeedInt *offsets, const bool *orient, 422 CeedElemRestriction r) { 423 // Set up for normal restriction with explicit offsets. This sets up dispatch to 424 // CeedElemRestrictionApply_Ref_* and manages the impl->offsets array copy/allocation. 425 CeedElemRestriction_Ref *impl; 426 CeedInt num_elem, elem_size; 427 CeedCallBackend(CeedElemRestrictionCreate_Ref(mem_type, copy_mode, offsets, r)); 428 CeedCallBackend(CeedElemRestrictionGetData(r, &impl)); 429 CeedCallBackend(CeedElemRestrictionGetNumElements(r, &num_elem)); 430 CeedCallBackend(CeedElemRestrictionGetElementSize(r, &elem_size)); 431 432 // Copy data 433 switch (copy_mode) { 434 case CEED_COPY_VALUES: 435 CeedCallBackend(CeedMalloc(num_elem * elem_size, &impl->orient_allocated)); 436 memcpy(impl->orient_allocated, orient, num_elem * elem_size * sizeof(orient[0])); 437 impl->orient = impl->orient_allocated; 438 break; 439 case CEED_OWN_POINTER: 440 impl->orient_allocated = (bool *)orient; 441 impl->orient = impl->orient_allocated; 442 break; 443 case CEED_USE_POINTER: 444 impl->orient = orient; 445 } 446 447 return CEED_ERROR_SUCCESS; 448 } 449 450 //------------------------------------------------------------------------------ 451