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