xref: /libCEED/interface/ceed-qfunctioncontext.c (revision 3d576824e8d990e1f48c6609089904bee9170514)
1777ff853SJeremy L Thompson // Copyright (c) 2017, Lawrence Livermore National Security, LLC. Produced at
2777ff853SJeremy L Thompson // the Lawrence Livermore National Laboratory. LLNL-CODE-734707. All Rights
3777ff853SJeremy L Thompson // reserved. See files LICENSE and NOTICE for details.
4777ff853SJeremy L Thompson //
5777ff853SJeremy L Thompson // This file is part of CEED, a collection of benchmarks, miniapps, software
6777ff853SJeremy L Thompson // libraries and APIs for efficient high-order finite element and spectral
7777ff853SJeremy L Thompson // element discretizations for exascale applications. For more information and
8777ff853SJeremy L Thompson // source code availability see http://github.com/ceed.
9777ff853SJeremy L Thompson //
10777ff853SJeremy L Thompson // The CEED research is supported by the Exascale Computing Project 17-SC-20-SC,
11777ff853SJeremy L Thompson // a collaborative effort of two U.S. Department of Energy organizations (Office
12777ff853SJeremy L Thompson // of Science and the National Nuclear Security Administration) responsible for
13777ff853SJeremy L Thompson // the planning and preparation of a capable exascale ecosystem, including
14777ff853SJeremy L Thompson // software, applications, hardware, advanced system engineering and early
15777ff853SJeremy L Thompson // testbed platforms, in support of the nation's exascale computing imperative.
16777ff853SJeremy L Thompson 
17*3d576824SJeremy L Thompson #include <ceed.h>
18777ff853SJeremy L Thompson #include <ceed-backend.h>
19*3d576824SJeremy L Thompson #include <ceed-impl.h>
20*3d576824SJeremy L Thompson #include <stdint.h>
21*3d576824SJeremy L Thompson #include <stdio.h>
22777ff853SJeremy L Thompson 
23777ff853SJeremy L Thompson /// @file
24777ff853SJeremy L Thompson /// Implementation of public CeedQFunctionContext interfaces
25777ff853SJeremy L Thompson 
26777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
27777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API
28777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
29777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend
30777ff853SJeremy L Thompson /// @{
31777ff853SJeremy L Thompson 
32777ff853SJeremy L Thompson /**
33777ff853SJeremy L Thompson   @brief Get the Ceed associated with a CeedQFunctionContext
34777ff853SJeremy L Thompson 
35777ff853SJeremy L Thompson   @param ctx             CeedQFunctionContext
36777ff853SJeremy L Thompson   @param[out] ceed       Variable to store Ceed
37777ff853SJeremy L Thompson 
38777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
39777ff853SJeremy L Thompson 
40777ff853SJeremy L Thompson   @ref Backend
41777ff853SJeremy L Thompson **/
42777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) {
43777ff853SJeremy L Thompson   *ceed = ctx->ceed;
44777ff853SJeremy L Thompson   return 0;
45777ff853SJeremy L Thompson }
46777ff853SJeremy L Thompson 
47777ff853SJeremy L Thompson /**
48777ff853SJeremy L Thompson   @brief Get the state of a CeedQFunctionContext
49777ff853SJeremy L Thompson 
50777ff853SJeremy L Thompson   @param ctx           CeedQFunctionContext to retrieve state
51777ff853SJeremy L Thompson   @param[out] state    Variable to store state
52777ff853SJeremy L Thompson 
53777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
54777ff853SJeremy L Thompson 
55777ff853SJeremy L Thompson   @ref Backend
56777ff853SJeremy L Thompson **/
57777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) {
58777ff853SJeremy L Thompson   *state = ctx->state;
59777ff853SJeremy L Thompson   return 0;
60777ff853SJeremy L Thompson }
61777ff853SJeremy L Thompson 
62777ff853SJeremy L Thompson /**
63777ff853SJeremy L Thompson   @brief Get data size for a Context
64777ff853SJeremy L Thompson 
65777ff853SJeremy L Thompson   @param ctx             CeedQFunctionContext
66777ff853SJeremy L Thompson   @param[out] ctxsize    Variable to store size of context data values
67777ff853SJeremy L Thompson 
68777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
69777ff853SJeremy L Thompson 
70777ff853SJeremy L Thompson   @ref Backend
71777ff853SJeremy L Thompson **/
72777ff853SJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx,
73777ff853SJeremy L Thompson                                        size_t *ctxsize) {
74777ff853SJeremy L Thompson   *ctxsize = ctx->ctxsize;
75777ff853SJeremy L Thompson   return 0;
76777ff853SJeremy L Thompson }
77777ff853SJeremy L Thompson 
78777ff853SJeremy L Thompson /**
79777ff853SJeremy L Thompson   @brief Get backend data of a CeedQFunctionContext
80777ff853SJeremy L Thompson 
81777ff853SJeremy L Thompson   @param ctx             CeedQFunctionContext
82777ff853SJeremy L Thompson   @param[out] data       Variable to store data
83777ff853SJeremy L Thompson 
84777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
85777ff853SJeremy L Thompson 
86777ff853SJeremy L Thompson   @ref Backend
87777ff853SJeremy L Thompson **/
88777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) {
89777ff853SJeremy L Thompson   *(void **)data = ctx->data;
90777ff853SJeremy L Thompson   return 0;
91777ff853SJeremy L Thompson }
92777ff853SJeremy L Thompson 
93777ff853SJeremy L Thompson /**
94777ff853SJeremy L Thompson   @brief Set backend data of a CeedQFunctionContext
95777ff853SJeremy L Thompson 
96777ff853SJeremy L Thompson   @param[out] ctx        CeedQFunctionContext
97777ff853SJeremy L Thompson   @param data            Data to set
98777ff853SJeremy L Thompson 
99777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
100777ff853SJeremy L Thompson 
101777ff853SJeremy L Thompson   @ref Backend
102777ff853SJeremy L Thompson **/
103777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) {
104777ff853SJeremy L Thompson   ctx->data = data;
105777ff853SJeremy L Thompson   return 0;
106777ff853SJeremy L Thompson }
107777ff853SJeremy L Thompson 
108777ff853SJeremy L Thompson /// @}
109777ff853SJeremy L Thompson 
110777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
111777ff853SJeremy L Thompson /// CeedQFunctionContext Public API
112777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
113777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser
114777ff853SJeremy L Thompson /// @{
115777ff853SJeremy L Thompson 
116777ff853SJeremy L Thompson /**
117777ff853SJeremy L Thompson   @brief Create a CeedQFunctionContext for storing CeedQFunction user context data
118777ff853SJeremy L Thompson 
119777ff853SJeremy L Thompson   @param ceed       A Ceed object where the CeedQFunctionContext will be created
120777ff853SJeremy L Thompson   @param[out] ctx   Address of the variable where the newly created
121777ff853SJeremy L Thompson                       CeedQFunctionContext will be stored
122777ff853SJeremy L Thompson 
123777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
124777ff853SJeremy L Thompson 
125777ff853SJeremy L Thompson   @ref User
126777ff853SJeremy L Thompson **/
127777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) {
128777ff853SJeremy L Thompson   int ierr;
129777ff853SJeremy L Thompson 
130777ff853SJeremy L Thompson   if (!ceed->QFunctionContextCreate) {
131777ff853SJeremy L Thompson     Ceed delegate;
132777ff853SJeremy L Thompson     ierr = CeedGetObjectDelegate(ceed, &delegate, "Context"); CeedChk(ierr);
133777ff853SJeremy L Thompson 
134777ff853SJeremy L Thompson     if (!delegate)
135777ff853SJeremy L Thompson       // LCOV_EXCL_START
136777ff853SJeremy L Thompson       return CeedError(ceed, 1, "Backend does not support ContextCreate");
137777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
138777ff853SJeremy L Thompson 
139777ff853SJeremy L Thompson     ierr = CeedQFunctionContextCreate(delegate, ctx); CeedChk(ierr);
140777ff853SJeremy L Thompson     return 0;
141777ff853SJeremy L Thompson   }
142777ff853SJeremy L Thompson 
143777ff853SJeremy L Thompson   ierr = CeedCalloc(1, ctx); CeedChk(ierr);
144777ff853SJeremy L Thompson   (*ctx)->ceed = ceed;
145777ff853SJeremy L Thompson   ceed->refcount++;
146777ff853SJeremy L Thompson   (*ctx)->refcount = 1;
147777ff853SJeremy L Thompson   ierr = ceed->QFunctionContextCreate(*ctx); CeedChk(ierr);
148777ff853SJeremy L Thompson   return 0;
149777ff853SJeremy L Thompson }
150777ff853SJeremy L Thompson 
151777ff853SJeremy L Thompson /**
152777ff853SJeremy L Thompson   @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated
153777ff853SJeremy L Thompson            data if applicable. The backend may copy values to a different
154777ff853SJeremy L Thompson            memtype, such as during @ref CeedQFunctionApply().
155777ff853SJeremy L Thompson            See also @ref CeedQFunctionContextTakeData().
156777ff853SJeremy L Thompson 
157777ff853SJeremy L Thompson   @param ctx   CeedQFunctionContext
158777ff853SJeremy L Thompson   @param mtype Memory type of the data being passed
159777ff853SJeremy L Thompson   @param cmode Copy mode for the data
160777ff853SJeremy L Thompson   @param data  Data to be used
161777ff853SJeremy L Thompson 
162777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
163777ff853SJeremy L Thompson 
164777ff853SJeremy L Thompson   @ref User
165777ff853SJeremy L Thompson **/
166777ff853SJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mtype,
167777ff853SJeremy L Thompson                                 CeedCopyMode cmode,
168777ff853SJeremy L Thompson                                 size_t size, void *data) {
169777ff853SJeremy L Thompson   int ierr;
170777ff853SJeremy L Thompson 
171777ff853SJeremy L Thompson   if (!ctx->SetData)
172777ff853SJeremy L Thompson     // LCOV_EXCL_START
173777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1, "Backend does not support ContextSetData");
174777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
175777ff853SJeremy L Thompson 
176777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
177777ff853SJeremy L Thompson     // LCOV_EXCL_START
178777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
179777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
180777ff853SJeremy L Thompson                      "access lock is already in use");
181777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
182777ff853SJeremy L Thompson 
183777ff853SJeremy L Thompson   ctx->ctxsize = size;
184777ff853SJeremy L Thompson   ierr = ctx->SetData(ctx, mtype, cmode, data); CeedChk(ierr);
185777ff853SJeremy L Thompson   ctx->state += 2;
186777ff853SJeremy L Thompson 
187777ff853SJeremy L Thompson   return 0;
188777ff853SJeremy L Thompson }
189777ff853SJeremy L Thompson 
190777ff853SJeremy L Thompson /**
191777ff853SJeremy L Thompson   @brief Get read/write access to a CeedQFunctionContext via the specified memory type.
192777ff853SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
193777ff853SJeremy L Thompson 
194777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext to access
195777ff853SJeremy L Thompson   @param mtype      Memory type on which to access the data. If the backend
196777ff853SJeremy L Thompson                     uses a different memory type, this will perform a copy.
197777ff853SJeremy L Thompson   @param[out] data  Data on memory type mtype
198777ff853SJeremy L Thompson 
199777ff853SJeremy L Thompson   @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions
200777ff853SJeremy L Thompson     provide access to array pointers in the desired memory space. Pairing
201777ff853SJeremy L Thompson     get/restore allows the Context to track access.
202777ff853SJeremy L Thompson 
203777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
204777ff853SJeremy L Thompson 
205777ff853SJeremy L Thompson   @ref User
206777ff853SJeremy L Thompson **/
207777ff853SJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mtype,
208777ff853SJeremy L Thompson                                 void *data) {
209777ff853SJeremy L Thompson   int ierr;
210777ff853SJeremy L Thompson 
211777ff853SJeremy L Thompson   if (!ctx->GetData)
212777ff853SJeremy L Thompson     // LCOV_EXCL_START
213777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1, "Backend does not support GetData");
214777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
215777ff853SJeremy L Thompson 
216777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
217777ff853SJeremy L Thompson     // LCOV_EXCL_START
218777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
219777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
220777ff853SJeremy L Thompson                      "access lock is already in use");
221777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
222777ff853SJeremy L Thompson 
223777ff853SJeremy L Thompson   ierr = ctx->GetData(ctx, mtype, data); CeedChk(ierr);
224777ff853SJeremy L Thompson   ctx->state += 1;
225777ff853SJeremy L Thompson 
226777ff853SJeremy L Thompson   return 0;
227777ff853SJeremy L Thompson }
228777ff853SJeremy L Thompson 
229777ff853SJeremy L Thompson /**
230777ff853SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetData()
231777ff853SJeremy L Thompson 
232777ff853SJeremy L Thompson   @param ctx     CeedQFunctionContext to restore
233777ff853SJeremy L Thompson   @param data    Data to restore
234777ff853SJeremy L Thompson 
235777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
236777ff853SJeremy L Thompson 
237777ff853SJeremy L Thompson   @ref User
238777ff853SJeremy L Thompson **/
239777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
240777ff853SJeremy L Thompson   int ierr;
241777ff853SJeremy L Thompson 
242777ff853SJeremy L Thompson   if (!ctx->RestoreData)
243777ff853SJeremy L Thompson     // LCOV_EXCL_START
244777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1, "Backend does not support RestoreData");
245777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
246777ff853SJeremy L Thompson 
247777ff853SJeremy L Thompson   if (ctx->state % 2 != 1)
248777ff853SJeremy L Thompson     // LCOV_EXCL_START
249777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
250777ff853SJeremy L Thompson                      "Cannot restore CeedQFunctionContext array access, "
251777ff853SJeremy L Thompson                      "access was not granted");
252777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
253777ff853SJeremy L Thompson 
254777ff853SJeremy L Thompson   ierr = ctx->RestoreData(ctx); CeedChk(ierr);
255777ff853SJeremy L Thompson   *(void **)data = NULL;
256777ff853SJeremy L Thompson   ctx->state += 1;
257777ff853SJeremy L Thompson 
258777ff853SJeremy L Thompson   return 0;
259777ff853SJeremy L Thompson }
260777ff853SJeremy L Thompson 
261777ff853SJeremy L Thompson /**
262777ff853SJeremy L Thompson   @brief View a CeedQFunctionContext
263777ff853SJeremy L Thompson 
264777ff853SJeremy L Thompson   @param[in] ctx           CeedQFunctionContext to view
265777ff853SJeremy L Thompson   @param[in] stream        Filestream to write to
266777ff853SJeremy L Thompson 
267777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
268777ff853SJeremy L Thompson 
269777ff853SJeremy L Thompson   @ref User
270777ff853SJeremy L Thompson **/
271777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
272777ff853SJeremy L Thompson   fprintf(stream, "CeedQFunctionContext\n");
273777ff853SJeremy L Thompson   fprintf(stream, "  Context Data Size: %ld\n", ctx->ctxsize);
274777ff853SJeremy L Thompson   return 0;
275777ff853SJeremy L Thompson }
276777ff853SJeremy L Thompson 
277777ff853SJeremy L Thompson /**
278777ff853SJeremy L Thompson   @brief Destroy a CeedQFunctionContext
279777ff853SJeremy L Thompson 
280777ff853SJeremy L Thompson   @param ctx   CeedQFunctionContext to destroy
281777ff853SJeremy L Thompson 
282777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
283777ff853SJeremy L Thompson 
284777ff853SJeremy L Thompson   @ref User
285777ff853SJeremy L Thompson **/
286777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
287777ff853SJeremy L Thompson   int ierr;
288777ff853SJeremy L Thompson 
289777ff853SJeremy L Thompson   if (!*ctx || --(*ctx)->refcount > 0)
290777ff853SJeremy L Thompson     return 0;
291777ff853SJeremy L Thompson 
292777ff853SJeremy L Thompson   if ((*ctx) && ((*ctx)->state % 2) == 1)
293777ff853SJeremy L Thompson     // LCOV_EXCL_START
294777ff853SJeremy L Thompson     return CeedError((*ctx)->ceed, 1,
295777ff853SJeremy L Thompson                      "Cannot destroy CeedQFunctionContext, the access "
296777ff853SJeremy L Thompson                      "lock is in use");
297777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
298777ff853SJeremy L Thompson 
299777ff853SJeremy L Thompson   if ((*ctx)->Destroy) {
300777ff853SJeremy L Thompson     ierr = (*ctx)->Destroy(*ctx); CeedChk(ierr);
301777ff853SJeremy L Thompson   }
302777ff853SJeremy L Thompson 
303777ff853SJeremy L Thompson   ierr = CeedDestroy(&(*ctx)->ceed); CeedChk(ierr);
304777ff853SJeremy L Thompson   ierr = CeedFree(ctx); CeedChk(ierr);
305777ff853SJeremy L Thompson   return 0;
306777ff853SJeremy L Thompson }
307777ff853SJeremy L Thompson 
308777ff853SJeremy L Thompson /// @}
309