1*777ff853SJeremy L Thompson // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at 2*777ff853SJeremy L Thompson // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights 3*777ff853SJeremy L Thompson // reserved. See files LICENSE and NOTICE for details. 4*777ff853SJeremy L Thompson // 5*777ff853SJeremy L Thompson // This file is part of CEED, a collection of benchmarks, miniapps, software 6*777ff853SJeremy L Thompson // libraries and APIs for efficient high-order finite element and spectral 7*777ff853SJeremy L Thompson // element discretizations for exascale applications. For more information and 8*777ff853SJeremy L Thompson // source code availability see http://github.com/ceed. 9*777ff853SJeremy L Thompson // 10*777ff853SJeremy L Thompson // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC, 11*777ff853SJeremy L Thompson // a collaborative effort of two U.S. Department of Energy organizations (Office 12*777ff853SJeremy L Thompson // of Science and the National Nuclear Security Administration) responsible for 13*777ff853SJeremy L Thompson // the planning and preparation of a capable exascale ecosystem, including 14*777ff853SJeremy L Thompson // software, applications, hardware, advanced system engineering and early 15*777ff853SJeremy L Thompson // testbed platforms, in support of the nation's exascale computing imperative. 16*777ff853SJeremy L Thompson 17*777ff853SJeremy L Thompson #include <ceed-impl.h> 18*777ff853SJeremy L Thompson #include <ceed-backend.h> 19*777ff853SJeremy L Thompson #include <limits.h> 20*777ff853SJeremy L Thompson 21*777ff853SJeremy L Thompson /// @file 22*777ff853SJeremy L Thompson /// Implementation of public CeedQFunctionContext interfaces 23*777ff853SJeremy L Thompson 24*777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 25*777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API 26*777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 27*777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend 28*777ff853SJeremy L Thompson /// @{ 29*777ff853SJeremy L Thompson 30*777ff853SJeremy L Thompson /** 31*777ff853SJeremy L Thompson @brief Get the Ceed associated with a CeedQFunctionContext 32*777ff853SJeremy L Thompson 33*777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 34*777ff853SJeremy L Thompson @param[out] ceed Variable to store Ceed 35*777ff853SJeremy L Thompson 36*777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 37*777ff853SJeremy L Thompson 38*777ff853SJeremy L Thompson @ref Backend 39*777ff853SJeremy L Thompson **/ 40*777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) { 41*777ff853SJeremy L Thompson *ceed = ctx->ceed; 42*777ff853SJeremy L Thompson return 0; 43*777ff853SJeremy L Thompson } 44*777ff853SJeremy L Thompson 45*777ff853SJeremy L Thompson /** 46*777ff853SJeremy L Thompson @brief Get the state of a CeedQFunctionContext 47*777ff853SJeremy L Thompson 48*777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to retrieve state 49*777ff853SJeremy L Thompson @param[out] state Variable to store state 50*777ff853SJeremy L Thompson 51*777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 52*777ff853SJeremy L Thompson 53*777ff853SJeremy L Thompson @ref Backend 54*777ff853SJeremy L Thompson **/ 55*777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) { 56*777ff853SJeremy L Thompson *state = ctx->state; 57*777ff853SJeremy L Thompson return 0; 58*777ff853SJeremy L Thompson } 59*777ff853SJeremy L Thompson 60*777ff853SJeremy L Thompson /** 61*777ff853SJeremy L Thompson @brief Get data size for a Context 62*777ff853SJeremy L Thompson 63*777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 64*777ff853SJeremy L Thompson @param[out] ctxsize Variable to store size of context data values 65*777ff853SJeremy L Thompson 66*777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 67*777ff853SJeremy L Thompson 68*777ff853SJeremy L Thompson @ref Backend 69*777ff853SJeremy L Thompson **/ 70*777ff853SJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, 71*777ff853SJeremy L Thompson size_t *ctxsize) { 72*777ff853SJeremy L Thompson *ctxsize = ctx->ctxsize; 73*777ff853SJeremy L Thompson return 0; 74*777ff853SJeremy L Thompson } 75*777ff853SJeremy L Thompson 76*777ff853SJeremy L Thompson /** 77*777ff853SJeremy L Thompson @brief Get backend data of a CeedQFunctionContext 78*777ff853SJeremy L Thompson 79*777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 80*777ff853SJeremy L Thompson @param[out] data Variable to store data 81*777ff853SJeremy L Thompson 82*777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 83*777ff853SJeremy L Thompson 84*777ff853SJeremy L Thompson @ref Backend 85*777ff853SJeremy L Thompson **/ 86*777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) { 87*777ff853SJeremy L Thompson *(void **)data = ctx->data; 88*777ff853SJeremy L Thompson return 0; 89*777ff853SJeremy L Thompson } 90*777ff853SJeremy L Thompson 91*777ff853SJeremy L Thompson /** 92*777ff853SJeremy L Thompson @brief Set backend data of a CeedQFunctionContext 93*777ff853SJeremy L Thompson 94*777ff853SJeremy L Thompson @param[out] ctx CeedQFunctionContext 95*777ff853SJeremy L Thompson @param data Data to set 96*777ff853SJeremy L Thompson 97*777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 98*777ff853SJeremy L Thompson 99*777ff853SJeremy L Thompson @ref Backend 100*777ff853SJeremy L Thompson **/ 101*777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) { 102*777ff853SJeremy L Thompson ctx->data = data; 103*777ff853SJeremy L Thompson return 0; 104*777ff853SJeremy L Thompson } 105*777ff853SJeremy L Thompson 106*777ff853SJeremy L Thompson /// @} 107*777ff853SJeremy L Thompson 108*777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 109*777ff853SJeremy L Thompson /// CeedQFunctionContext Public API 110*777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 111*777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser 112*777ff853SJeremy L Thompson /// @{ 113*777ff853SJeremy L Thompson 114*777ff853SJeremy L Thompson /** 115*777ff853SJeremy L Thompson @brief Create a CeedQFunctionContext for storing CeedQFunction user context data 116*777ff853SJeremy L Thompson 117*777ff853SJeremy L Thompson @param ceed A Ceed object where the CeedQFunctionContext will be created 118*777ff853SJeremy L Thompson @param[out] ctx Address of the variable where the newly created 119*777ff853SJeremy L Thompson CeedQFunctionContext will be stored 120*777ff853SJeremy L Thompson 121*777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 122*777ff853SJeremy L Thompson 123*777ff853SJeremy L Thompson @ref User 124*777ff853SJeremy L Thompson **/ 125*777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) { 126*777ff853SJeremy L Thompson int ierr; 127*777ff853SJeremy L Thompson 128*777ff853SJeremy L Thompson if (!ceed->QFunctionContextCreate) { 129*777ff853SJeremy L Thompson Ceed delegate; 130*777ff853SJeremy L Thompson ierr = CeedGetObjectDelegate(ceed, &delegate, "Context"); CeedChk(ierr); 131*777ff853SJeremy L Thompson 132*777ff853SJeremy L Thompson if (!delegate) 133*777ff853SJeremy L Thompson // LCOV_EXCL_START 134*777ff853SJeremy L Thompson return CeedError(ceed, 1, "Backend does not support ContextCreate"); 135*777ff853SJeremy L Thompson // LCOV_EXCL_STOP 136*777ff853SJeremy L Thompson 137*777ff853SJeremy L Thompson ierr = CeedQFunctionContextCreate(delegate, ctx); CeedChk(ierr); 138*777ff853SJeremy L Thompson return 0; 139*777ff853SJeremy L Thompson } 140*777ff853SJeremy L Thompson 141*777ff853SJeremy L Thompson ierr = CeedCalloc(1, ctx); CeedChk(ierr); 142*777ff853SJeremy L Thompson (*ctx)->ceed = ceed; 143*777ff853SJeremy L Thompson ceed->refcount++; 144*777ff853SJeremy L Thompson (*ctx)->refcount = 1; 145*777ff853SJeremy L Thompson ierr = ceed->QFunctionContextCreate(*ctx); CeedChk(ierr); 146*777ff853SJeremy L Thompson return 0; 147*777ff853SJeremy L Thompson } 148*777ff853SJeremy L Thompson 149*777ff853SJeremy L Thompson /** 150*777ff853SJeremy L Thompson @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated 151*777ff853SJeremy L Thompson data if applicable. The backend may copy values to a different 152*777ff853SJeremy L Thompson memtype, such as during @ref CeedQFunctionApply(). 153*777ff853SJeremy L Thompson See also @ref CeedQFunctionContextTakeData(). 154*777ff853SJeremy L Thompson 155*777ff853SJeremy L Thompson @param ctx CeedQFunctionContext 156*777ff853SJeremy L Thompson @param mtype Memory type of the data being passed 157*777ff853SJeremy L Thompson @param cmode Copy mode for the data 158*777ff853SJeremy L Thompson @param data Data to be used 159*777ff853SJeremy L Thompson 160*777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 161*777ff853SJeremy L Thompson 162*777ff853SJeremy L Thompson @ref User 163*777ff853SJeremy L Thompson **/ 164*777ff853SJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mtype, 165*777ff853SJeremy L Thompson CeedCopyMode cmode, 166*777ff853SJeremy L Thompson size_t size, void *data) { 167*777ff853SJeremy L Thompson int ierr; 168*777ff853SJeremy L Thompson 169*777ff853SJeremy L Thompson if (!ctx->SetData) 170*777ff853SJeremy L Thompson // LCOV_EXCL_START 171*777ff853SJeremy L Thompson return CeedError(ctx->ceed, 1, "Backend does not support ContextSetData"); 172*777ff853SJeremy L Thompson // LCOV_EXCL_STOP 173*777ff853SJeremy L Thompson 174*777ff853SJeremy L Thompson if (ctx->state % 2 == 1) 175*777ff853SJeremy L Thompson // LCOV_EXCL_START 176*777ff853SJeremy L Thompson return CeedError(ctx->ceed, 1, 177*777ff853SJeremy L Thompson "Cannot grant CeedQFunctionContext data access, the " 178*777ff853SJeremy L Thompson "access lock is already in use"); 179*777ff853SJeremy L Thompson // LCOV_EXCL_STOP 180*777ff853SJeremy L Thompson 181*777ff853SJeremy L Thompson ctx->ctxsize = size; 182*777ff853SJeremy L Thompson ierr = ctx->SetData(ctx, mtype, cmode, data); CeedChk(ierr); 183*777ff853SJeremy L Thompson ctx->state += 2; 184*777ff853SJeremy L Thompson 185*777ff853SJeremy L Thompson return 0; 186*777ff853SJeremy L Thompson } 187*777ff853SJeremy L Thompson 188*777ff853SJeremy L Thompson /** 189*777ff853SJeremy L Thompson @brief Get read/write access to a CeedQFunctionContext via the specified memory type. 190*777ff853SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 191*777ff853SJeremy L Thompson 192*777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to access 193*777ff853SJeremy L Thompson @param mtype Memory type on which to access the data. If the backend 194*777ff853SJeremy L Thompson uses a different memory type, this will perform a copy. 195*777ff853SJeremy L Thompson @param[out] data Data on memory type mtype 196*777ff853SJeremy L Thompson 197*777ff853SJeremy L Thompson @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions 198*777ff853SJeremy L Thompson provide access to array pointers in the desired memory space. Pairing 199*777ff853SJeremy L Thompson get/restore allows the Context to track access. 200*777ff853SJeremy L Thompson 201*777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 202*777ff853SJeremy L Thompson 203*777ff853SJeremy L Thompson @ref User 204*777ff853SJeremy L Thompson **/ 205*777ff853SJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mtype, 206*777ff853SJeremy L Thompson void *data) { 207*777ff853SJeremy L Thompson int ierr; 208*777ff853SJeremy L Thompson 209*777ff853SJeremy L Thompson if (!ctx->GetData) 210*777ff853SJeremy L Thompson // LCOV_EXCL_START 211*777ff853SJeremy L Thompson return CeedError(ctx->ceed, 1, "Backend does not support GetData"); 212*777ff853SJeremy L Thompson // LCOV_EXCL_STOP 213*777ff853SJeremy L Thompson 214*777ff853SJeremy L Thompson if (ctx->state % 2 == 1) 215*777ff853SJeremy L Thompson // LCOV_EXCL_START 216*777ff853SJeremy L Thompson return CeedError(ctx->ceed, 1, 217*777ff853SJeremy L Thompson "Cannot grant CeedQFunctionContext data access, the " 218*777ff853SJeremy L Thompson "access lock is already in use"); 219*777ff853SJeremy L Thompson // LCOV_EXCL_STOP 220*777ff853SJeremy L Thompson 221*777ff853SJeremy L Thompson ierr = ctx->GetData(ctx, mtype, data); CeedChk(ierr); 222*777ff853SJeremy L Thompson ctx->state += 1; 223*777ff853SJeremy L Thompson 224*777ff853SJeremy L Thompson return 0; 225*777ff853SJeremy L Thompson } 226*777ff853SJeremy L Thompson 227*777ff853SJeremy L Thompson /** 228*777ff853SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetData() 229*777ff853SJeremy L Thompson 230*777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to restore 231*777ff853SJeremy L Thompson @param data Data to restore 232*777ff853SJeremy L Thompson 233*777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 234*777ff853SJeremy L Thompson 235*777ff853SJeremy L Thompson @ref User 236*777ff853SJeremy L Thompson **/ 237*777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) { 238*777ff853SJeremy L Thompson int ierr; 239*777ff853SJeremy L Thompson 240*777ff853SJeremy L Thompson if (!ctx->RestoreData) 241*777ff853SJeremy L Thompson // LCOV_EXCL_START 242*777ff853SJeremy L Thompson return CeedError(ctx->ceed, 1, "Backend does not support RestoreData"); 243*777ff853SJeremy L Thompson // LCOV_EXCL_STOP 244*777ff853SJeremy L Thompson 245*777ff853SJeremy L Thompson if (ctx->state % 2 != 1) 246*777ff853SJeremy L Thompson // LCOV_EXCL_START 247*777ff853SJeremy L Thompson return CeedError(ctx->ceed, 1, 248*777ff853SJeremy L Thompson "Cannot restore CeedQFunctionContext array access, " 249*777ff853SJeremy L Thompson "access was not granted"); 250*777ff853SJeremy L Thompson // LCOV_EXCL_STOP 251*777ff853SJeremy L Thompson 252*777ff853SJeremy L Thompson ierr = ctx->RestoreData(ctx); CeedChk(ierr); 253*777ff853SJeremy L Thompson *(void **)data = NULL; 254*777ff853SJeremy L Thompson ctx->state += 1; 255*777ff853SJeremy L Thompson 256*777ff853SJeremy L Thompson return 0; 257*777ff853SJeremy L Thompson } 258*777ff853SJeremy L Thompson 259*777ff853SJeremy L Thompson /** 260*777ff853SJeremy L Thompson @brief View a CeedQFunctionContext 261*777ff853SJeremy L Thompson 262*777ff853SJeremy L Thompson @param[in] ctx CeedQFunctionContext to view 263*777ff853SJeremy L Thompson @param[in] stream Filestream to write to 264*777ff853SJeremy L Thompson 265*777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 266*777ff853SJeremy L Thompson 267*777ff853SJeremy L Thompson @ref User 268*777ff853SJeremy L Thompson **/ 269*777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) { 270*777ff853SJeremy L Thompson fprintf(stream, "CeedQFunctionContext\n"); 271*777ff853SJeremy L Thompson fprintf(stream, " Context Data Size: %ld\n", ctx->ctxsize); 272*777ff853SJeremy L Thompson return 0; 273*777ff853SJeremy L Thompson } 274*777ff853SJeremy L Thompson 275*777ff853SJeremy L Thompson /** 276*777ff853SJeremy L Thompson @brief Destroy a CeedQFunctionContext 277*777ff853SJeremy L Thompson 278*777ff853SJeremy L Thompson @param ctx CeedQFunctionContext to destroy 279*777ff853SJeremy L Thompson 280*777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 281*777ff853SJeremy L Thompson 282*777ff853SJeremy L Thompson @ref User 283*777ff853SJeremy L Thompson **/ 284*777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) { 285*777ff853SJeremy L Thompson int ierr; 286*777ff853SJeremy L Thompson 287*777ff853SJeremy L Thompson if (!*ctx || --(*ctx)->refcount > 0) 288*777ff853SJeremy L Thompson return 0; 289*777ff853SJeremy L Thompson 290*777ff853SJeremy L Thompson if ((*ctx) && ((*ctx)->state % 2) == 1) 291*777ff853SJeremy L Thompson // LCOV_EXCL_START 292*777ff853SJeremy L Thompson return CeedError((*ctx)->ceed, 1, 293*777ff853SJeremy L Thompson "Cannot destroy CeedQFunctionContext, the access " 294*777ff853SJeremy L Thompson "lock is in use"); 295*777ff853SJeremy L Thompson // LCOV_EXCL_STOP 296*777ff853SJeremy L Thompson 297*777ff853SJeremy L Thompson if ((*ctx)->Destroy) { 298*777ff853SJeremy L Thompson ierr = (*ctx)->Destroy(*ctx); CeedChk(ierr); 299*777ff853SJeremy L Thompson } 300*777ff853SJeremy L Thompson 301*777ff853SJeremy L Thompson ierr = CeedDestroy(&(*ctx)->ceed); CeedChk(ierr); 302*777ff853SJeremy L Thompson ierr = CeedFree(ctx); CeedChk(ierr); 303*777ff853SJeremy L Thompson return 0; 304*777ff853SJeremy L Thompson } 305*777ff853SJeremy L Thompson 306*777ff853SJeremy L Thompson /// @} 307