xref: /libCEED/interface/ceed-qfunctioncontext.c (revision 777ff853944a0dbc06f7f09486fdf4674828e728)
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