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