xref: /libCEED/interface/ceed-qfunctioncontext.c (revision 9c774eddf8c0b4f5416196d32c5355c9591a7190)
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 
17ec3da8bcSJed Brown #include <ceed/ceed.h>
18ec3da8bcSJed Brown #include <ceed/backend.h>
193d576824SJeremy L Thompson #include <ceed-impl.h>
203d576824SJeremy L Thompson #include <stdint.h>
213d576824SJeremy 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;
44e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
45777ff853SJeremy L Thompson }
46777ff853SJeremy L Thompson 
47777ff853SJeremy L Thompson /**
48*9c774eddSJeremy L Thompson   @brief Check for valid data in a CeedQFunctionContext
49*9c774eddSJeremy L Thompson 
50*9c774eddSJeremy L Thompson   @param ctx                  CeedQFunctionContext to check validity
51*9c774eddSJeremy L Thompson   @param[out] has_valid_data  Variable to store validity
52*9c774eddSJeremy L Thompson 
53*9c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
54*9c774eddSJeremy L Thompson 
55*9c774eddSJeremy L Thompson   @ref Backend
56*9c774eddSJeremy L Thompson **/
57*9c774eddSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx,
58*9c774eddSJeremy L Thompson                                      bool *has_valid_data) {
59*9c774eddSJeremy L Thompson   int ierr;
60*9c774eddSJeremy L Thompson 
61*9c774eddSJeremy L Thompson   if (!ctx->HasValidData)
62*9c774eddSJeremy L Thompson     // LCOV_EXCL_START
63*9c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
64*9c774eddSJeremy L Thompson                      "Backend does not support HasValidData");
65*9c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
66*9c774eddSJeremy L Thompson 
67*9c774eddSJeremy L Thompson   ierr = ctx->HasValidData(ctx, has_valid_data); CeedChk(ierr);
68*9c774eddSJeremy L Thompson 
69*9c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
70*9c774eddSJeremy L Thompson }
71*9c774eddSJeremy L Thompson 
72*9c774eddSJeremy L Thompson /**
73*9c774eddSJeremy L Thompson   @brief Check for borrowed data of a specific CeedMemType in a
74*9c774eddSJeremy L Thompson            CeedQFunctionContext
75*9c774eddSJeremy L Thompson 
76*9c774eddSJeremy L Thompson   @param ctx                             CeedQFunctionContext to check
77*9c774eddSJeremy L Thompson   @param mem_type                        Memory type to check
78*9c774eddSJeremy L Thompson   @param[out] has_borrowed_data_of_type  Variable to store result
79*9c774eddSJeremy L Thompson 
80*9c774eddSJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
81*9c774eddSJeremy L Thompson 
82*9c774eddSJeremy L Thompson   @ref Backend
83*9c774eddSJeremy L Thompson **/
84*9c774eddSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx,
85*9c774eddSJeremy L Thompson     CeedMemType mem_type, bool *has_borrowed_data_of_type) {
86*9c774eddSJeremy L Thompson   int ierr;
87*9c774eddSJeremy L Thompson 
88*9c774eddSJeremy L Thompson   if (!ctx->HasBorrowedDataOfType)
89*9c774eddSJeremy L Thompson     // LCOV_EXCL_START
90*9c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
91*9c774eddSJeremy L Thompson                      "Backend does not support HasBorrowedDataOfType");
92*9c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
93*9c774eddSJeremy L Thompson 
94*9c774eddSJeremy L Thompson   ierr = ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type);
95*9c774eddSJeremy L Thompson   CeedChk(ierr);
96*9c774eddSJeremy L Thompson 
97*9c774eddSJeremy L Thompson   return CEED_ERROR_SUCCESS;
98*9c774eddSJeremy L Thompson }
99*9c774eddSJeremy L Thompson 
100*9c774eddSJeremy L Thompson /**
101777ff853SJeremy L Thompson   @brief Get the state of a CeedQFunctionContext
102777ff853SJeremy L Thompson 
103777ff853SJeremy L Thompson   @param ctx         CeedQFunctionContext to retrieve state
104777ff853SJeremy L Thompson   @param[out] state  Variable to store state
105777ff853SJeremy L Thompson 
106777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
107777ff853SJeremy L Thompson 
108777ff853SJeremy L Thompson   @ref Backend
109777ff853SJeremy L Thompson **/
110777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) {
111777ff853SJeremy L Thompson   *state = ctx->state;
112e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
113777ff853SJeremy L Thompson }
114777ff853SJeremy L Thompson 
115777ff853SJeremy L Thompson /**
116777ff853SJeremy L Thompson   @brief Get backend data of a CeedQFunctionContext
117777ff853SJeremy L Thompson 
118777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
119777ff853SJeremy L Thompson   @param[out] data  Variable to store data
120777ff853SJeremy L Thompson 
121777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
122777ff853SJeremy L Thompson 
123777ff853SJeremy L Thompson   @ref Backend
124777ff853SJeremy L Thompson **/
125777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) {
126777ff853SJeremy L Thompson   *(void **)data = ctx->data;
127e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
128777ff853SJeremy L Thompson }
129777ff853SJeremy L Thompson 
130777ff853SJeremy L Thompson /**
131777ff853SJeremy L Thompson   @brief Set backend data of a CeedQFunctionContext
132777ff853SJeremy L Thompson 
133777ff853SJeremy L Thompson   @param[out] ctx  CeedQFunctionContext
134777ff853SJeremy L Thompson   @param data      Data to set
135777ff853SJeremy L Thompson 
136777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
137777ff853SJeremy L Thompson 
138777ff853SJeremy L Thompson   @ref Backend
139777ff853SJeremy L Thompson **/
140777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) {
141777ff853SJeremy L Thompson   ctx->data = data;
142e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
143777ff853SJeremy L Thompson }
144777ff853SJeremy L Thompson 
14534359f16Sjeremylt /**
14634359f16Sjeremylt   @brief Increment the reference counter for a CeedQFunctionContext
14734359f16Sjeremylt 
14834359f16Sjeremylt   @param ctx  CeedQFunctionContext to increment the reference counter
14934359f16Sjeremylt 
15034359f16Sjeremylt   @return An error code: 0 - success, otherwise - failure
15134359f16Sjeremylt 
15234359f16Sjeremylt   @ref Backend
15334359f16Sjeremylt **/
1549560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) {
15534359f16Sjeremylt   ctx->ref_count++;
15634359f16Sjeremylt   return CEED_ERROR_SUCCESS;
15734359f16Sjeremylt }
15834359f16Sjeremylt 
159777ff853SJeremy L Thompson /// @}
160777ff853SJeremy L Thompson 
161777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
162777ff853SJeremy L Thompson /// CeedQFunctionContext Public API
163777ff853SJeremy L Thompson /// ----------------------------------------------------------------------------
164777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser
165777ff853SJeremy L Thompson /// @{
166777ff853SJeremy L Thompson 
167777ff853SJeremy L Thompson /**
168777ff853SJeremy L Thompson   @brief Create a CeedQFunctionContext for storing CeedQFunction user context data
169777ff853SJeremy L Thompson 
170777ff853SJeremy L Thompson   @param ceed      A Ceed object where the CeedQFunctionContext will be created
171777ff853SJeremy L Thompson   @param[out] ctx  Address of the variable where the newly created
172777ff853SJeremy L Thompson                      CeedQFunctionContext will be stored
173777ff853SJeremy L Thompson 
174777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
175777ff853SJeremy L Thompson 
176777ff853SJeremy L Thompson   @ref User
177777ff853SJeremy L Thompson **/
178777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) {
179777ff853SJeremy L Thompson   int ierr;
180777ff853SJeremy L Thompson 
181777ff853SJeremy L Thompson   if (!ceed->QFunctionContextCreate) {
182777ff853SJeremy L Thompson     Ceed delegate;
183777ff853SJeremy L Thompson     ierr = CeedGetObjectDelegate(ceed, &delegate, "Context"); CeedChk(ierr);
184777ff853SJeremy L Thompson 
185777ff853SJeremy L Thompson     if (!delegate)
186777ff853SJeremy L Thompson       // LCOV_EXCL_START
187e15f9bd0SJeremy L Thompson       return CeedError(ceed, CEED_ERROR_UNSUPPORTED,
188e15f9bd0SJeremy L Thompson                        "Backend does not support ContextCreate");
189777ff853SJeremy L Thompson     // LCOV_EXCL_STOP
190777ff853SJeremy L Thompson 
191777ff853SJeremy L Thompson     ierr = CeedQFunctionContextCreate(delegate, ctx); CeedChk(ierr);
192e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
193777ff853SJeremy L Thompson   }
194777ff853SJeremy L Thompson 
195777ff853SJeremy L Thompson   ierr = CeedCalloc(1, ctx); CeedChk(ierr);
196777ff853SJeremy L Thompson   (*ctx)->ceed = ceed;
1979560d06aSjeremylt   ierr = CeedReference(ceed); CeedChk(ierr);
198d1d35e2fSjeremylt   (*ctx)->ref_count = 1;
199777ff853SJeremy L Thompson   ierr = ceed->QFunctionContextCreate(*ctx); CeedChk(ierr);
200e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
201777ff853SJeremy L Thompson }
202777ff853SJeremy L Thompson 
203777ff853SJeremy L Thompson /**
2049560d06aSjeremylt   @brief Copy the pointer to a CeedQFunctionContext. Both pointers should
2059560d06aSjeremylt            be destroyed with `CeedQFunctionContextDestroy()`;
2069560d06aSjeremylt            Note: If `*ctx_copy` is non-NULL, then it is assumed that
2079560d06aSjeremylt            `*ctx_copy` is a pointer to a CeedQFunctionContext. This
2089560d06aSjeremylt            CeedQFunctionContext will be destroyed if `*ctx_copy` is the
2099560d06aSjeremylt            only reference to this CeedQFunctionContext.
2109560d06aSjeremylt 
2119560d06aSjeremylt   @param ctx            CeedQFunctionContext to copy reference to
2129560d06aSjeremylt   @param[out] ctx_copy  Variable to store copied reference
2139560d06aSjeremylt 
2149560d06aSjeremylt   @return An error code: 0 - success, otherwise - failure
2159560d06aSjeremylt 
2169560d06aSjeremylt   @ref User
2179560d06aSjeremylt **/
2189560d06aSjeremylt int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx,
2199560d06aSjeremylt                                       CeedQFunctionContext *ctx_copy) {
2209560d06aSjeremylt   int ierr;
2219560d06aSjeremylt 
2229560d06aSjeremylt   ierr = CeedQFunctionContextReference(ctx); CeedChk(ierr);
2239560d06aSjeremylt   ierr = CeedQFunctionContextDestroy(ctx_copy); CeedChk(ierr);
2249560d06aSjeremylt   *ctx_copy = ctx;
2259560d06aSjeremylt   return CEED_ERROR_SUCCESS;
2269560d06aSjeremylt }
2279560d06aSjeremylt 
2289560d06aSjeremylt /**
229777ff853SJeremy L Thompson   @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated
230777ff853SJeremy L Thompson            data if applicable. The backend may copy values to a different
231777ff853SJeremy L Thompson            memtype, such as during @ref CeedQFunctionApply().
232777ff853SJeremy L Thompson            See also @ref CeedQFunctionContextTakeData().
233777ff853SJeremy L Thompson 
234777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext
235d1d35e2fSjeremylt   @param mem_type   Memory type of the data being passed
236d1d35e2fSjeremylt   @param copy_mode  Copy mode for the data
237891038deSjeremylt   @param size       Size of data, in bytes
238777ff853SJeremy L Thompson   @param data       Data to be used
239777ff853SJeremy L Thompson 
240777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
241777ff853SJeremy L Thompson 
242777ff853SJeremy L Thompson   @ref User
243777ff853SJeremy L Thompson **/
244d1d35e2fSjeremylt int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type,
245d1d35e2fSjeremylt                                 CeedCopyMode copy_mode,
246777ff853SJeremy L Thompson                                 size_t size, void *data) {
247777ff853SJeremy L Thompson   int ierr;
248777ff853SJeremy L Thompson 
249777ff853SJeremy L Thompson   if (!ctx->SetData)
250777ff853SJeremy L Thompson     // LCOV_EXCL_START
251e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
252e15f9bd0SJeremy L Thompson                      "Backend does not support ContextSetData");
253777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
254777ff853SJeremy L Thompson 
255777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
256777ff853SJeremy L Thompson     // LCOV_EXCL_START
257777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
258777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
259777ff853SJeremy L Thompson                      "access lock is already in use");
260777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
261777ff853SJeremy L Thompson 
262d1d35e2fSjeremylt   ctx->ctx_size = size;
263d1d35e2fSjeremylt   ierr = ctx->SetData(ctx, mem_type, copy_mode, data); CeedChk(ierr);
264777ff853SJeremy L Thompson   ctx->state += 2;
265e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
266777ff853SJeremy L Thompson }
267777ff853SJeremy L Thompson 
268777ff853SJeremy L Thompson /**
269891038deSjeremylt   @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type.
270891038deSjeremylt            The caller is responsible for managing and freeing the memory.
271891038deSjeremylt 
272891038deSjeremylt   @param ctx        CeedQFunctionContext to access
273891038deSjeremylt   @param mem_type   Memory type on which to access the data. If the backend
274891038deSjeremylt                       uses a different memory type, this will perform a copy.
275891038deSjeremylt   @param[out] data  Data on memory type mem_type
276891038deSjeremylt 
277891038deSjeremylt   @return An error code: 0 - success, otherwise - failure
278891038deSjeremylt 
279891038deSjeremylt   @ref User
280891038deSjeremylt **/
281891038deSjeremylt int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type,
282891038deSjeremylt                                  void *data) {
283891038deSjeremylt   int ierr;
284891038deSjeremylt 
285*9c774eddSJeremy L Thompson   bool has_valid_data = true;
286*9c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
287*9c774eddSJeremy L Thompson   if (!has_valid_data)
288*9c774eddSJeremy L Thompson     // LCOV_EXCL_START
289*9c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
290*9c774eddSJeremy L Thompson                      "CeedQFunctionContext has no valid data to take, must set data");
291*9c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
292*9c774eddSJeremy L Thompson 
293891038deSjeremylt   if (!ctx->TakeData)
294891038deSjeremylt     // LCOV_EXCL_START
295891038deSjeremylt     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
296891038deSjeremylt                      "Backend does not support TakeData");
297891038deSjeremylt   // LCOV_EXCL_STOP
298891038deSjeremylt 
299891038deSjeremylt   if (ctx->state % 2 == 1)
300891038deSjeremylt     // LCOV_EXCL_START
301891038deSjeremylt     return CeedError(ctx->ceed, 1,
302891038deSjeremylt                      "Cannot grant CeedQFunctionContext data access, the "
303891038deSjeremylt                      "access lock is already in use");
304891038deSjeremylt   // LCOV_EXCL_STOP
305891038deSjeremylt 
306*9c774eddSJeremy L Thompson   bool has_borrowed_data_of_type = true;
307*9c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type,
308*9c774eddSJeremy L Thompson          &has_borrowed_data_of_type); CeedChk(ierr);
309*9c774eddSJeremy L Thompson   if (!has_borrowed_data_of_type)
310*9c774eddSJeremy L Thompson     // LCOV_EXCL_START
311*9c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
312*9c774eddSJeremy L Thompson                      "CeedQFunctionContext has no borowed %s data, "
313*9c774eddSJeremy L Thompson                      "must set data with CeedQFunctionContextSetData",
314*9c774eddSJeremy L Thompson                      CeedMemTypes[mem_type]);
315*9c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
316*9c774eddSJeremy L Thompson 
317891038deSjeremylt   void *temp_data = NULL;
318891038deSjeremylt   ierr = ctx->TakeData(ctx, mem_type, &temp_data); CeedChk(ierr);
319891038deSjeremylt   if (data) (*(void **)data) = temp_data;
320891038deSjeremylt   return CEED_ERROR_SUCCESS;
321891038deSjeremylt }
322891038deSjeremylt 
323891038deSjeremylt /**
324777ff853SJeremy L Thompson   @brief Get read/write access to a CeedQFunctionContext via the specified memory type.
325777ff853SJeremy L Thompson            Restore access with @ref CeedQFunctionContextRestoreData().
326777ff853SJeremy L Thompson 
327777ff853SJeremy L Thompson   @param ctx        CeedQFunctionContext to access
328d1d35e2fSjeremylt   @param mem_type   Memory type on which to access the data. If the backend
329777ff853SJeremy L Thompson                       uses a different memory type, this will perform a copy.
330d1d35e2fSjeremylt   @param[out] data  Data on memory type mem_type
331777ff853SJeremy L Thompson 
332777ff853SJeremy L Thompson   @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions
333777ff853SJeremy L Thompson     provide access to array pointers in the desired memory space. Pairing
334777ff853SJeremy L Thompson     get/restore allows the Context to track access.
335777ff853SJeremy L Thompson 
336777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
337777ff853SJeremy L Thompson 
338777ff853SJeremy L Thompson   @ref User
339777ff853SJeremy L Thompson **/
340d1d35e2fSjeremylt int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type,
341777ff853SJeremy L Thompson                                 void *data) {
342777ff853SJeremy L Thompson   int ierr;
343777ff853SJeremy L Thompson 
344777ff853SJeremy L Thompson   if (!ctx->GetData)
345777ff853SJeremy L Thompson     // LCOV_EXCL_START
346e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
347e15f9bd0SJeremy L Thompson                      "Backend does not support GetData");
348777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
349777ff853SJeremy L Thompson 
350777ff853SJeremy L Thompson   if (ctx->state % 2 == 1)
351777ff853SJeremy L Thompson     // LCOV_EXCL_START
352777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
353777ff853SJeremy L Thompson                      "Cannot grant CeedQFunctionContext data access, the "
354777ff853SJeremy L Thompson                      "access lock is already in use");
355777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
356777ff853SJeremy L Thompson 
357*9c774eddSJeremy L Thompson   bool has_valid_data = true;
358*9c774eddSJeremy L Thompson   ierr = CeedQFunctionContextHasValidData(ctx, &has_valid_data); CeedChk(ierr);
359*9c774eddSJeremy L Thompson   if (!has_valid_data)
360*9c774eddSJeremy L Thompson     // LCOV_EXCL_START
361*9c774eddSJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_BACKEND,
362*9c774eddSJeremy L Thompson                      "CeedQFunctionContext has no valid data to get, must set data");
363*9c774eddSJeremy L Thompson   // LCOV_EXCL_STOP
364*9c774eddSJeremy L Thompson 
365d1d35e2fSjeremylt   ierr = ctx->GetData(ctx, mem_type, data); CeedChk(ierr);
366777ff853SJeremy L Thompson   ctx->state += 1;
367e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
368777ff853SJeremy L Thompson }
369777ff853SJeremy L Thompson 
370777ff853SJeremy L Thompson /**
371777ff853SJeremy L Thompson   @brief Restore data obtained using @ref CeedQFunctionContextGetData()
372777ff853SJeremy L Thompson 
373777ff853SJeremy L Thompson   @param ctx   CeedQFunctionContext to restore
374777ff853SJeremy L Thompson   @param data  Data to restore
375777ff853SJeremy L Thompson 
376777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
377777ff853SJeremy L Thompson 
378777ff853SJeremy L Thompson   @ref User
379777ff853SJeremy L Thompson **/
380777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) {
381777ff853SJeremy L Thompson   int ierr;
382777ff853SJeremy L Thompson 
383777ff853SJeremy L Thompson   if (!ctx->RestoreData)
384777ff853SJeremy L Thompson     // LCOV_EXCL_START
385e15f9bd0SJeremy L Thompson     return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED,
386e15f9bd0SJeremy L Thompson                      "Backend does not support RestoreData");
387777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
388777ff853SJeremy L Thompson 
389777ff853SJeremy L Thompson   if (ctx->state % 2 != 1)
390777ff853SJeremy L Thompson     // LCOV_EXCL_START
391777ff853SJeremy L Thompson     return CeedError(ctx->ceed, 1,
392777ff853SJeremy L Thompson                      "Cannot restore CeedQFunctionContext array access, "
393777ff853SJeremy L Thompson                      "access was not granted");
394777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
395777ff853SJeremy L Thompson 
396777ff853SJeremy L Thompson   ierr = ctx->RestoreData(ctx); CeedChk(ierr);
397777ff853SJeremy L Thompson   *(void **)data = NULL;
398777ff853SJeremy L Thompson   ctx->state += 1;
399e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
400777ff853SJeremy L Thompson }
401777ff853SJeremy L Thompson 
402777ff853SJeremy L Thompson /**
40380a9ef05SNatalie Beams   @brief Get data size for a Context
40480a9ef05SNatalie Beams 
40580a9ef05SNatalie Beams   @param ctx            CeedQFunctionContext
40680a9ef05SNatalie Beams   @param[out] ctx_size  Variable to store size of context data values
40780a9ef05SNatalie Beams 
40880a9ef05SNatalie Beams   @return An error code: 0 - success, otherwise - failure
40980a9ef05SNatalie Beams 
41080a9ef05SNatalie Beams   @ref User
41180a9ef05SNatalie Beams **/
41280a9ef05SNatalie Beams int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx,
41380a9ef05SNatalie Beams                                        size_t *ctx_size) {
41480a9ef05SNatalie Beams   *ctx_size = ctx->ctx_size;
41580a9ef05SNatalie Beams   return CEED_ERROR_SUCCESS;
41680a9ef05SNatalie Beams }
41780a9ef05SNatalie Beams 
41880a9ef05SNatalie Beams 
41980a9ef05SNatalie Beams /**
420777ff853SJeremy L Thompson   @brief View a CeedQFunctionContext
421777ff853SJeremy L Thompson 
422777ff853SJeremy L Thompson   @param[in] ctx     CeedQFunctionContext to view
423777ff853SJeremy L Thompson   @param[in] stream  Filestream to write to
424777ff853SJeremy L Thompson 
425777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
426777ff853SJeremy L Thompson 
427777ff853SJeremy L Thompson   @ref User
428777ff853SJeremy L Thompson **/
429777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) {
430777ff853SJeremy L Thompson   fprintf(stream, "CeedQFunctionContext\n");
431d1d35e2fSjeremylt   fprintf(stream, "  Context Data Size: %ld\n", ctx->ctx_size);
432e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
433777ff853SJeremy L Thompson }
434777ff853SJeremy L Thompson 
435777ff853SJeremy L Thompson /**
436777ff853SJeremy L Thompson   @brief Destroy a CeedQFunctionContext
437777ff853SJeremy L Thompson 
438777ff853SJeremy L Thompson   @param ctx  CeedQFunctionContext to destroy
439777ff853SJeremy L Thompson 
440777ff853SJeremy L Thompson   @return An error code: 0 - success, otherwise - failure
441777ff853SJeremy L Thompson 
442777ff853SJeremy L Thompson   @ref User
443777ff853SJeremy L Thompson **/
444777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) {
445777ff853SJeremy L Thompson   int ierr;
446777ff853SJeremy L Thompson 
447d1d35e2fSjeremylt   if (!*ctx || --(*ctx)->ref_count > 0)
448e15f9bd0SJeremy L Thompson     return CEED_ERROR_SUCCESS;
449777ff853SJeremy L Thompson 
450777ff853SJeremy L Thompson   if ((*ctx) && ((*ctx)->state % 2) == 1)
451777ff853SJeremy L Thompson     // LCOV_EXCL_START
452777ff853SJeremy L Thompson     return CeedError((*ctx)->ceed, 1,
453777ff853SJeremy L Thompson                      "Cannot destroy CeedQFunctionContext, the access "
454777ff853SJeremy L Thompson                      "lock is in use");
455777ff853SJeremy L Thompson   // LCOV_EXCL_STOP
456777ff853SJeremy L Thompson 
457777ff853SJeremy L Thompson   if ((*ctx)->Destroy) {
458777ff853SJeremy L Thompson     ierr = (*ctx)->Destroy(*ctx); CeedChk(ierr);
459777ff853SJeremy L Thompson   }
460777ff853SJeremy L Thompson   ierr = CeedDestroy(&(*ctx)->ceed); CeedChk(ierr);
461777ff853SJeremy L Thompson   ierr = CeedFree(ctx); CeedChk(ierr);
462e15f9bd0SJeremy L Thompson   return CEED_ERROR_SUCCESS;
463777ff853SJeremy L Thompson }
464777ff853SJeremy L Thompson 
465777ff853SJeremy L Thompson /// @}
466