19ba83ac0SJeremy L Thompson // Copyright (c) 2017-2026, Lawrence Livermore National Security, LLC and other CEED contributors.
23d8e8822SJeremy L Thompson // All Rights Reserved. See the top-level LICENSE and NOTICE files for details.
3d7b241e6Sjeremylt //
43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause
5d7b241e6Sjeremylt //
63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed
7d7b241e6Sjeremylt
8d7b241e6Sjeremylt #define _POSIX_C_SOURCE 200112
93d576824SJeremy L Thompson #include <ceed-impl.h>
1049aac155SJeremy L Thompson #include <ceed.h>
112b730f8bSJeremy L Thompson #include <ceed/backend.h>
12aedaa0e5Sjeremylt #include <limits.h>
13d7b241e6Sjeremylt #include <stdarg.h>
1449aac155SJeremy L Thompson #include <stdbool.h>
156e79d475Sjeremylt #include <stddef.h>
16d7b241e6Sjeremylt #include <stdio.h>
17d7b241e6Sjeremylt #include <stdlib.h>
18d7b241e6Sjeremylt #include <string.h>
19d7b241e6Sjeremylt
20d7b241e6Sjeremylt /// @cond DOXYGEN_SKIP
21d7b241e6Sjeremylt static CeedRequest ceed_request_immediate;
22d7b241e6Sjeremylt static CeedRequest ceed_request_ordered;
23d7b241e6Sjeremylt
24d7b241e6Sjeremylt static struct {
25d7b241e6Sjeremylt char prefix[CEED_MAX_RESOURCE_LEN];
26d7b241e6Sjeremylt int (*init)(const char *resource, Ceed f);
27d7b241e6Sjeremylt unsigned int priority;
28d7b241e6Sjeremylt } backends[32];
29d7b241e6Sjeremylt static size_t num_backends;
30fe2413ffSjeremylt
31eaae1aeaSJames Wright #define CEED_FTABLE_ENTRY(class, method) {#class #method, offsetof(struct class##_private, method)}
32d7b241e6Sjeremylt /// @endcond
33d7b241e6Sjeremylt
34d7b241e6Sjeremylt /// @file
35d7b241e6Sjeremylt /// Implementation of core components of Ceed library
367a982d89SJeremy L. Thompson
377a982d89SJeremy L. Thompson /// @addtogroup CeedUser
38d7b241e6Sjeremylt /// @{
39d7b241e6Sjeremylt
40dfdf5a53Sjeremylt /**
41dfdf5a53Sjeremylt @brief Request immediate completion
42dfdf5a53Sjeremylt
43ca94c3ddSJeremy L Thompson This predefined constant is passed as the @ref CeedRequest argument to interfaces when the caller wishes for the operation to be performed immediately.
44ca94c3ddSJeremy L Thompson The code
45dfdf5a53Sjeremylt
46dfdf5a53Sjeremylt @code
47dfdf5a53Sjeremylt CeedOperatorApply(op, ..., CEED_REQUEST_IMMEDIATE);
48dfdf5a53Sjeremylt @endcode
49dfdf5a53Sjeremylt
50dfdf5a53Sjeremylt is semantically equivalent to
51dfdf5a53Sjeremylt
52dfdf5a53Sjeremylt @code
53dfdf5a53Sjeremylt CeedRequest request;
54dfdf5a53Sjeremylt CeedOperatorApply(op, ..., &request);
55dfdf5a53Sjeremylt CeedRequestWait(&request);
56dfdf5a53Sjeremylt @endcode
57dfdf5a53Sjeremylt
58dfdf5a53Sjeremylt @sa CEED_REQUEST_ORDERED
59dfdf5a53Sjeremylt **/
60d7b241e6Sjeremylt CeedRequest *const CEED_REQUEST_IMMEDIATE = &ceed_request_immediate;
61d7b241e6Sjeremylt
62d7b241e6Sjeremylt /**
63b11c1e72Sjeremylt @brief Request ordered completion
64d7b241e6Sjeremylt
65ca94c3ddSJeremy L Thompson This predefined constant is passed as the @ref CeedRequest argument to interfaces when the caller wishes for the operation to be completed in the order that it is submitted to the device.
66ca94c3ddSJeremy L Thompson It is typically used in a construct such as:
67d7b241e6Sjeremylt
68d7b241e6Sjeremylt @code
69d7b241e6Sjeremylt CeedRequest request;
70d7b241e6Sjeremylt CeedOperatorApply(op1, ..., CEED_REQUEST_ORDERED);
71d7b241e6Sjeremylt CeedOperatorApply(op2, ..., &request);
72d7b241e6Sjeremylt // other optional work
738b2d6f4aSMatthew Knepley CeedRequestWait(&request);
74d7b241e6Sjeremylt @endcode
75d7b241e6Sjeremylt
76ea61e9acSJeremy L Thompson which allows the sequence to complete asynchronously but does not start `op2` until `op1` has completed.
77d7b241e6Sjeremylt
78ea61e9acSJeremy L Thompson @todo The current implementation is overly strict, offering equivalent semantics to @ref CEED_REQUEST_IMMEDIATE.
79d7b241e6Sjeremylt
80d7b241e6Sjeremylt @sa CEED_REQUEST_IMMEDIATE
81d7b241e6Sjeremylt */
82d7b241e6Sjeremylt CeedRequest *const CEED_REQUEST_ORDERED = &ceed_request_ordered;
83d7b241e6Sjeremylt
84b11c1e72Sjeremylt /**
85ca94c3ddSJeremy L Thompson @brief Wait for a @ref CeedRequest to complete.
86dfdf5a53Sjeremylt
87ca94c3ddSJeremy L Thompson Calling @ref CeedRequestWait() on a `NULL` request is a no-op.
887a982d89SJeremy L. Thompson
89ca94c3ddSJeremy L Thompson @param[in,out] req Address of @ref CeedRequest to wait for; zeroed on completion.
907a982d89SJeremy L. Thompson
917a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
927a982d89SJeremy L. Thompson
937a982d89SJeremy L. Thompson @ref User
94b11c1e72Sjeremylt **/
CeedRequestWait(CeedRequest * req)957a982d89SJeremy L. Thompson int CeedRequestWait(CeedRequest *req) {
962b730f8bSJeremy L Thompson if (!*req) return CEED_ERROR_SUCCESS;
972b730f8bSJeremy L Thompson return CeedError(NULL, CEED_ERROR_UNSUPPORTED, "CeedRequestWait not implemented");
98683faae0SJed Brown }
997a982d89SJeremy L. Thompson
1007a982d89SJeremy L. Thompson /// @}
1017a982d89SJeremy L. Thompson
1027a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
1037a982d89SJeremy L. Thompson /// Ceed Library Internal Functions
1047a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
1057a982d89SJeremy L. Thompson /// @addtogroup CeedDeveloper
1067a982d89SJeremy L. Thompson /// @{
107d7b241e6Sjeremylt
1086a406739SJeremy L Thompson /**
1096a406739SJeremy L Thompson @brief Register a Ceed backend internally.
1104385fb7fSSebastian Grimberg
111ca94c3ddSJeremy L Thompson Note: Backends should call @ref CeedRegister() instead.
1126a406739SJeremy L Thompson
113ea61e9acSJeremy L Thompson @param[in] prefix Prefix of resources for this backend to respond to.
114ea61e9acSJeremy L Thompson For example, the reference backend responds to "/cpu/self".
115ca94c3ddSJeremy L Thompson @param[in] init Initialization function called by @ref CeedInit() when the backend is selected to drive the requested resource
116ea61e9acSJeremy L Thompson @param[in] priority Integer priority.
117ca94c3ddSJeremy L Thompson Lower values are preferred in case the resource requested by @ref CeedInit() has non-unique best prefix match.
1186a406739SJeremy L Thompson
1196a406739SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1206a406739SJeremy L Thompson
1216a406739SJeremy L Thompson @ref Developer
1226a406739SJeremy L Thompson **/
CeedRegisterImpl(const char * prefix,int (* init)(const char *,Ceed),unsigned int priority)1232b730f8bSJeremy L Thompson int CeedRegisterImpl(const char *prefix, int (*init)(const char *, Ceed), unsigned int priority) {
12458c07c4fSSebastian Grimberg int ierr = 0;
1256a406739SJeremy L Thompson
12658c07c4fSSebastian Grimberg CeedPragmaCritical(CeedRegisterImpl) {
12758c07c4fSSebastian Grimberg if (num_backends < sizeof(backends) / sizeof(backends[0])) {
1286a406739SJeremy L Thompson strncpy(backends[num_backends].prefix, prefix, CEED_MAX_RESOURCE_LEN);
1296a406739SJeremy L Thompson backends[num_backends].prefix[CEED_MAX_RESOURCE_LEN - 1] = 0;
1306a406739SJeremy L Thompson backends[num_backends].init = init;
1316a406739SJeremy L Thompson backends[num_backends].priority = priority;
1326a406739SJeremy L Thompson num_backends++;
13358c07c4fSSebastian Grimberg } else {
13458c07c4fSSebastian Grimberg ierr = 1;
13558c07c4fSSebastian Grimberg }
13658c07c4fSSebastian Grimberg }
13758c07c4fSSebastian Grimberg CeedCheck(ierr == 0, NULL, CEED_ERROR_MAJOR, "Too many backends");
1386a406739SJeremy L Thompson return CEED_ERROR_SUCCESS;
1396a406739SJeremy L Thompson }
1406a406739SJeremy L Thompson
14173501bfeSJeremy L Thompson /**
14273501bfeSJeremy L Thompson @brief Create a work vector space for a `ceed`
14373501bfeSJeremy L Thompson
14473501bfeSJeremy L Thompson @param[in,out] ceed `Ceed` to create work vector space for
14573501bfeSJeremy L Thompson
14673501bfeSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
14773501bfeSJeremy L Thompson
14873501bfeSJeremy L Thompson @ref Developer
14973501bfeSJeremy L Thompson **/
CeedWorkVectorsCreate(Ceed ceed)15073501bfeSJeremy L Thompson static int CeedWorkVectorsCreate(Ceed ceed) {
15173501bfeSJeremy L Thompson CeedCall(CeedCalloc(1, &ceed->work_vectors));
15273501bfeSJeremy L Thompson return CEED_ERROR_SUCCESS;
15373501bfeSJeremy L Thompson }
15473501bfeSJeremy L Thompson
15573501bfeSJeremy L Thompson /**
15673501bfeSJeremy L Thompson @brief Destroy a work vector space for a `ceed`
15773501bfeSJeremy L Thompson
15873501bfeSJeremy L Thompson @param[in,out] ceed `Ceed` to destroy work vector space for
15973501bfeSJeremy L Thompson
16073501bfeSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
16173501bfeSJeremy L Thompson
16273501bfeSJeremy L Thompson @ref Developer
16373501bfeSJeremy L Thompson **/
CeedWorkVectorsDestroy(Ceed ceed)16473501bfeSJeremy L Thompson static int CeedWorkVectorsDestroy(Ceed ceed) {
16573501bfeSJeremy L Thompson if (!ceed->work_vectors) return CEED_ERROR_SUCCESS;
16673501bfeSJeremy L Thompson for (CeedSize i = 0; i < ceed->work_vectors->num_vecs; i++) {
16773501bfeSJeremy L Thompson CeedCheck(!ceed->work_vectors->is_in_use[i], ceed, CEED_ERROR_ACCESS, "Work vector %" CeedSize_FMT " checked out but not returned");
168b0f67a9cSJeremy L Thompson // Note: increase ref_count to prevent Ceed destructor from triggering again
169b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)ceed));
170b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)ceed));
17173501bfeSJeremy L Thompson CeedCall(CeedVectorDestroy(&ceed->work_vectors->vecs[i]));
172b0f67a9cSJeremy L Thompson // Note: restore ref_count
173b0f67a9cSJeremy L Thompson CeedObjectDereference((CeedObject)ceed);
17473501bfeSJeremy L Thompson }
17573501bfeSJeremy L Thompson CeedCall(CeedFree(&ceed->work_vectors->is_in_use));
17673501bfeSJeremy L Thompson CeedCall(CeedFree(&ceed->work_vectors->vecs));
17773501bfeSJeremy L Thompson CeedCall(CeedFree(&ceed->work_vectors));
17873501bfeSJeremy L Thompson return CEED_ERROR_SUCCESS;
17973501bfeSJeremy L Thompson }
18073501bfeSJeremy L Thompson
181b0f67a9cSJeremy L Thompson /**
182b0f67a9cSJeremy L Thompson @brief View a `Ceed` passed as a `CeedObject`
183b0f67a9cSJeremy L Thompson
184b0f67a9cSJeremy L Thompson @param[in] ceed `Ceed` to view
185b0f67a9cSJeremy L Thompson @param[in] stream Filestream to write to
186b0f67a9cSJeremy L Thompson
187b0f67a9cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
188b0f67a9cSJeremy L Thompson
189b0f67a9cSJeremy L Thompson @ref Developer
190b0f67a9cSJeremy L Thompson **/
CeedView_Object(CeedObject ceed,FILE * stream)191b0f67a9cSJeremy L Thompson static int CeedView_Object(CeedObject ceed, FILE *stream) {
192b0f67a9cSJeremy L Thompson CeedCall(CeedView((Ceed)ceed, stream));
193b0f67a9cSJeremy L Thompson return CEED_ERROR_SUCCESS;
194b0f67a9cSJeremy L Thompson }
195b0f67a9cSJeremy L Thompson
1966c328a79SJeremy L Thompson /**
1976c328a79SJeremy L Thompson @brief Destroy a `Ceed` passed as a `CeedObject`
1986c328a79SJeremy L Thompson
1996c328a79SJeremy L Thompson @param[in,out] ceed Address of `Ceed` context to destroy
2006c328a79SJeremy L Thompson
2016c328a79SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
2026c328a79SJeremy L Thompson
2036c328a79SJeremy L Thompson @ref Developer
2046c328a79SJeremy L Thompson **/
CeedDestroy_Object(CeedObject * ceed)2056c328a79SJeremy L Thompson static int CeedDestroy_Object(CeedObject *ceed) {
2066c328a79SJeremy L Thompson CeedCall(CeedDestroy((Ceed *)ceed));
2076c328a79SJeremy L Thompson return CEED_ERROR_SUCCESS;
2086c328a79SJeremy L Thompson }
2096c328a79SJeremy L Thompson
2107a982d89SJeremy L. Thompson /// @}
211d7b241e6Sjeremylt
2127a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2137a982d89SJeremy L. Thompson /// Ceed Backend API
2147a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
2157a982d89SJeremy L. Thompson /// @addtogroup CeedBackend
2167a982d89SJeremy L. Thompson /// @{
217d7b241e6Sjeremylt
218b11c1e72Sjeremylt /**
219ca94c3ddSJeremy L Thompson @brief Return value of `CEED_DEBUG` environment variable
22060f9e2d6SJeremy L Thompson
221ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context
22260f9e2d6SJeremy L Thompson
223ca94c3ddSJeremy L Thompson @return Boolean value: true - debugging mode enabled
2243f21f6b1SJeremy L Thompson false - debugging mode disabled
22560f9e2d6SJeremy L Thompson
22660f9e2d6SJeremy L Thompson @ref Backend
22760f9e2d6SJeremy L Thompson **/
228fc6bbcedSJeremy L Thompson // LCOV_EXCL_START
CeedDebugFlag(const Ceed ceed)2292b730f8bSJeremy L Thompson bool CeedDebugFlag(const Ceed ceed) { return ceed->is_debug; }
230fc6bbcedSJeremy L Thompson // LCOV_EXCL_STOP
23160f9e2d6SJeremy L Thompson
23260f9e2d6SJeremy L Thompson /**
233ca94c3ddSJeremy L Thompson @brief Return value of `CEED_DEBUG` environment variable
23460f9e2d6SJeremy L Thompson
235ca94c3ddSJeremy L Thompson @return Boolean value: true - debugging mode enabled
2363f21f6b1SJeremy L Thompson false - debugging mode disabled
2373f21f6b1SJeremy L Thompson
2383f21f6b1SJeremy L Thompson @ref Backend
2393f21f6b1SJeremy L Thompson **/
2403f21f6b1SJeremy L Thompson // LCOV_EXCL_START
CeedDebugFlagEnv(void)2411c66c397SJeremy L Thompson bool CeedDebugFlagEnv(void) { return getenv("CEED_DEBUG") || getenv("DEBUG") || getenv("DBG"); }
2423f21f6b1SJeremy L Thompson // LCOV_EXCL_STOP
2433f21f6b1SJeremy L Thompson
2443f21f6b1SJeremy L Thompson /**
2453f21f6b1SJeremy L Thompson @brief Print debugging information in color
2463f21f6b1SJeremy L Thompson
247ca94c3ddSJeremy L Thompson @param[in] color Color to print
248ca94c3ddSJeremy L Thompson @param[in] format Printing format
24960f9e2d6SJeremy L Thompson
25060f9e2d6SJeremy L Thompson @ref Backend
25160f9e2d6SJeremy L Thompson **/
252fc6bbcedSJeremy L Thompson // LCOV_EXCL_START
CeedDebugImpl256(const unsigned char color,const char * format,...)2533f21f6b1SJeremy L Thompson void CeedDebugImpl256(const unsigned char color, const char *format, ...) {
25460f9e2d6SJeremy L Thompson va_list args;
25560f9e2d6SJeremy L Thompson va_start(args, format);
25660f9e2d6SJeremy L Thompson fflush(stdout);
2572b730f8bSJeremy L Thompson if (color != CEED_DEBUG_COLOR_NONE) fprintf(stdout, "\033[38;5;%dm", color);
25860f9e2d6SJeremy L Thompson vfprintf(stdout, format, args);
2592b730f8bSJeremy L Thompson if (color != CEED_DEBUG_COLOR_NONE) fprintf(stdout, "\033[m");
26060f9e2d6SJeremy L Thompson fprintf(stdout, "\n");
26160f9e2d6SJeremy L Thompson fflush(stdout);
26260f9e2d6SJeremy L Thompson va_end(args);
26360f9e2d6SJeremy L Thompson }
264fc6bbcedSJeremy L Thompson // LCOV_EXCL_STOP
26560f9e2d6SJeremy L Thompson
26660f9e2d6SJeremy L Thompson /**
267ca94c3ddSJeremy L Thompson @brief Allocate an array on the host; use @ref CeedMalloc().
268b11c1e72Sjeremylt
269ea61e9acSJeremy L Thompson Memory usage can be tracked by the library.
270ea61e9acSJeremy L Thompson This ensures sufficient alignment for vectorization and should be used for large allocations.
271b11c1e72Sjeremylt
272ea61e9acSJeremy L Thompson @param[in] n Number of units to allocate
273ea61e9acSJeremy L Thompson @param[in] unit Size of each unit
274ca94c3ddSJeremy L Thompson @param[out] p Address of pointer to hold the result
275b11c1e72Sjeremylt
276b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure
277b11c1e72Sjeremylt
2787a982d89SJeremy L. Thompson @ref Backend
279ca94c3ddSJeremy L Thompson
280ca94c3ddSJeremy L Thompson @sa CeedFree()
281b11c1e72Sjeremylt **/
CeedMallocArray(size_t n,size_t unit,void * p)282d7b241e6Sjeremylt int CeedMallocArray(size_t n, size_t unit, void *p) {
283d7b241e6Sjeremylt int ierr = posix_memalign((void **)p, CEED_ALIGN, n * unit);
2846574a04fSJeremy L Thompson CeedCheck(ierr == 0, NULL, CEED_ERROR_MAJOR, "posix_memalign failed to allocate %zd members of size %zd\n", n, unit);
285e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
286d7b241e6Sjeremylt }
287d7b241e6Sjeremylt
288b11c1e72Sjeremylt /**
289ca94c3ddSJeremy L Thompson @brief Allocate a cleared (zeroed) array on the host; use @ref CeedCalloc().
290b11c1e72Sjeremylt
291b11c1e72Sjeremylt Memory usage can be tracked by the library.
292b11c1e72Sjeremylt
293ea61e9acSJeremy L Thompson @param[in] n Number of units to allocate
294ea61e9acSJeremy L Thompson @param[in] unit Size of each unit
295ca94c3ddSJeremy L Thompson @param[out] p Address of pointer to hold the result
296b11c1e72Sjeremylt
297b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure
298b11c1e72Sjeremylt
2997a982d89SJeremy L. Thompson @ref Backend
300ca94c3ddSJeremy L Thompson
301ca94c3ddSJeremy L Thompson @sa CeedFree()
302b11c1e72Sjeremylt **/
CeedCallocArray(size_t n,size_t unit,void * p)303d7b241e6Sjeremylt int CeedCallocArray(size_t n, size_t unit, void *p) {
304d7b241e6Sjeremylt *(void **)p = calloc(n, unit);
3056574a04fSJeremy L Thompson CeedCheck(!n || !unit || *(void **)p, NULL, CEED_ERROR_MAJOR, "calloc failed to allocate %zd members of size %zd\n", n, unit);
306e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
307d7b241e6Sjeremylt }
308d7b241e6Sjeremylt
309b11c1e72Sjeremylt /**
310ca94c3ddSJeremy L Thompson @brief Reallocate an array on the host; use @ref CeedRealloc().
311b11c1e72Sjeremylt
312b11c1e72Sjeremylt Memory usage can be tracked by the library.
313b11c1e72Sjeremylt
314ea61e9acSJeremy L Thompson @param[in] n Number of units to allocate
315ea61e9acSJeremy L Thompson @param[in] unit Size of each unit
316ca94c3ddSJeremy L Thompson @param[out] p Address of pointer to hold the result
317b11c1e72Sjeremylt
318b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure
319b11c1e72Sjeremylt
3207a982d89SJeremy L. Thompson @ref Backend
321ca94c3ddSJeremy L Thompson
322ca94c3ddSJeremy L Thompson @sa CeedFree()
323b11c1e72Sjeremylt **/
CeedReallocArray(size_t n,size_t unit,void * p)324d7b241e6Sjeremylt int CeedReallocArray(size_t n, size_t unit, void *p) {
325d7b241e6Sjeremylt *(void **)p = realloc(*(void **)p, n * unit);
3266574a04fSJeremy L Thompson CeedCheck(!n || !unit || *(void **)p, NULL, CEED_ERROR_MAJOR, "realloc failed to allocate %zd members of size %zd\n", n, unit);
327e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
328d7b241e6Sjeremylt }
329d7b241e6Sjeremylt
330f7e22acaSJeremy L Thompson /**
331ca94c3ddSJeremy L Thompson @brief Allocate a cleared string buffer on the host.
332f7e22acaSJeremy L Thompson
333f7e22acaSJeremy L Thompson Memory usage can be tracked by the library.
334f7e22acaSJeremy L Thompson
335ea61e9acSJeremy L Thompson @param[in] source Pointer to string to be copied
336ea61e9acSJeremy L Thompson @param[out] copy Pointer to variable to hold newly allocated string copy
337f7e22acaSJeremy L Thompson
338f7e22acaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
339f7e22acaSJeremy L Thompson
340f7e22acaSJeremy L Thompson @ref Backend
341ca94c3ddSJeremy L Thompson
342ca94c3ddSJeremy L Thompson @sa CeedFree()
343f7e22acaSJeremy L Thompson **/
CeedStringAllocCopy(const char * source,char ** copy)344f7e22acaSJeremy L Thompson int CeedStringAllocCopy(const char *source, char **copy) {
345f7e22acaSJeremy L Thompson size_t len = strlen(source);
3462b730f8bSJeremy L Thompson CeedCall(CeedCalloc(len + 1, copy));
347d602d780SJeremy L Thompson memcpy(*copy, source, len);
348f7e22acaSJeremy L Thompson return CEED_ERROR_SUCCESS;
349f7e22acaSJeremy L Thompson }
350f7e22acaSJeremy L Thompson
351ca94c3ddSJeremy L Thompson /** Free memory allocated using @ref CeedMalloc() or @ref CeedCalloc()
35234138859Sjeremylt
353ca94c3ddSJeremy L Thompson @param[in,out] p Address of pointer to memory.
354ca94c3ddSJeremy L Thompson This argument is of type `void*` to avoid needing a cast, but is the address of the pointer (which is zeroed) rather than the pointer.
355ca94c3ddSJeremy L Thompson
356ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
357ca94c3ddSJeremy L Thompson
358ca94c3ddSJeremy L Thompson @ref Backend
35934138859Sjeremylt **/
CeedFree(void * p)360d7b241e6Sjeremylt int CeedFree(void *p) {
361d7b241e6Sjeremylt free(*(void **)p);
362d7b241e6Sjeremylt *(void **)p = NULL;
363e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
364d7b241e6Sjeremylt }
365d7b241e6Sjeremylt
366f5d1e504SJeremy L Thompson /** Internal helper to manage handoff of user `source_array` to backend with proper @ref CeedCopyMode behavior.
367f5d1e504SJeremy L Thompson
368f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user
369f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data
370f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle
37117afdf5cSJames Wright @param[in] size_unit Size of array element in bytes
372f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated
373f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data
374f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data
375f5d1e504SJeremy L Thompson
376f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
377f5d1e504SJeremy L Thompson
378f5d1e504SJeremy L Thompson @ref Backend
379f5d1e504SJeremy L Thompson **/
CeedSetHostGenericArray(const void * source_array,CeedCopyMode copy_mode,size_t size_unit,CeedSize num_values,void * target_array_owned,void * target_array_borrowed,void * target_array)380f5d1e504SJeremy L Thompson static inline int CeedSetHostGenericArray(const void *source_array, CeedCopyMode copy_mode, size_t size_unit, CeedSize num_values,
381f5d1e504SJeremy L Thompson void *target_array_owned, void *target_array_borrowed, void *target_array) {
382f5d1e504SJeremy L Thompson switch (copy_mode) {
383f5d1e504SJeremy L Thompson case CEED_COPY_VALUES:
384cc3bdf8cSJeremy L Thompson if (!*(void **)target_array) {
385cc3bdf8cSJeremy L Thompson if (*(void **)target_array_borrowed) {
386cc3bdf8cSJeremy L Thompson *(void **)target_array = *(void **)target_array_borrowed;
387cc3bdf8cSJeremy L Thompson } else {
388f5d1e504SJeremy L Thompson if (!*(void **)target_array_owned) CeedCall(CeedCallocArray(num_values, size_unit, target_array_owned));
389f5d1e504SJeremy L Thompson *(void **)target_array = *(void **)target_array_owned;
390cc3bdf8cSJeremy L Thompson }
391cc3bdf8cSJeremy L Thompson }
392cc3bdf8cSJeremy L Thompson if (source_array) memcpy(*(void **)target_array, source_array, size_unit * num_values);
393f5d1e504SJeremy L Thompson break;
394f5d1e504SJeremy L Thompson case CEED_OWN_POINTER:
395f5d1e504SJeremy L Thompson CeedCall(CeedFree(target_array_owned));
396f5d1e504SJeremy L Thompson *(void **)target_array_owned = (void *)source_array;
397f5d1e504SJeremy L Thompson *(void **)target_array_borrowed = NULL;
398f5d1e504SJeremy L Thompson *(void **)target_array = *(void **)target_array_owned;
399f5d1e504SJeremy L Thompson break;
400f5d1e504SJeremy L Thompson case CEED_USE_POINTER:
401f5d1e504SJeremy L Thompson CeedCall(CeedFree(target_array_owned));
402f5d1e504SJeremy L Thompson *(void **)target_array_owned = NULL;
403f5d1e504SJeremy L Thompson *(void **)target_array_borrowed = (void *)source_array;
404f5d1e504SJeremy L Thompson *(void **)target_array = *(void **)target_array_borrowed;
405f5d1e504SJeremy L Thompson }
406f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS;
407f5d1e504SJeremy L Thompson }
408f5d1e504SJeremy L Thompson
409f5d1e504SJeremy L Thompson /** Manage handoff of user `bool` `source_array` to backend with proper @ref CeedCopyMode behavior.
410f5d1e504SJeremy L Thompson
411f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user
412f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data
413f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle
414f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated
415f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data
416f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data
417f5d1e504SJeremy L Thompson
418f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
419f5d1e504SJeremy L Thompson
420f5d1e504SJeremy L Thompson @ref Backend
421f5d1e504SJeremy L Thompson **/
CeedSetHostBoolArray(const bool * source_array,CeedCopyMode copy_mode,CeedSize num_values,const bool ** target_array_owned,const bool ** target_array_borrowed,const bool ** target_array)422f5d1e504SJeremy L Thompson int CeedSetHostBoolArray(const bool *source_array, CeedCopyMode copy_mode, CeedSize num_values, const bool **target_array_owned,
423f5d1e504SJeremy L Thompson const bool **target_array_borrowed, const bool **target_array) {
424f5d1e504SJeremy L Thompson CeedCall(CeedSetHostGenericArray(source_array, copy_mode, sizeof(bool), num_values, target_array_owned, target_array_borrowed, target_array));
425f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS;
426f5d1e504SJeremy L Thompson }
427f5d1e504SJeremy L Thompson
428f5d1e504SJeremy L Thompson /** Manage handoff of user `CeedInt8` `source_array` to backend with proper @ref CeedCopyMode behavior.
429f5d1e504SJeremy L Thompson
430f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user
431f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data
432f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle
433f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated
434f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data
435f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data
436f5d1e504SJeremy L Thompson
437f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
438f5d1e504SJeremy L Thompson
439f5d1e504SJeremy L Thompson @ref Backend
440f5d1e504SJeremy L Thompson **/
CeedSetHostCeedInt8Array(const CeedInt8 * source_array,CeedCopyMode copy_mode,CeedSize num_values,const CeedInt8 ** target_array_owned,const CeedInt8 ** target_array_borrowed,const CeedInt8 ** target_array)441f5d1e504SJeremy L Thompson int CeedSetHostCeedInt8Array(const CeedInt8 *source_array, CeedCopyMode copy_mode, CeedSize num_values, const CeedInt8 **target_array_owned,
442f5d1e504SJeremy L Thompson const CeedInt8 **target_array_borrowed, const CeedInt8 **target_array) {
443f5d1e504SJeremy L Thompson CeedCall(CeedSetHostGenericArray(source_array, copy_mode, sizeof(CeedInt8), num_values, target_array_owned, target_array_borrowed, target_array));
444f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS;
445f5d1e504SJeremy L Thompson }
446f5d1e504SJeremy L Thompson
447f5d1e504SJeremy L Thompson /** Manage handoff of user `CeedInt` `source_array` to backend with proper @ref CeedCopyMode behavior.
448f5d1e504SJeremy L Thompson
449f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user
450f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data
451f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle
452f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated
453f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data
454f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data
455f5d1e504SJeremy L Thompson
456f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
457f5d1e504SJeremy L Thompson
458f5d1e504SJeremy L Thompson @ref Backend
459f5d1e504SJeremy L Thompson **/
CeedSetHostCeedIntArray(const CeedInt * source_array,CeedCopyMode copy_mode,CeedSize num_values,const CeedInt ** target_array_owned,const CeedInt ** target_array_borrowed,const CeedInt ** target_array)460f5d1e504SJeremy L Thompson int CeedSetHostCeedIntArray(const CeedInt *source_array, CeedCopyMode copy_mode, CeedSize num_values, const CeedInt **target_array_owned,
461f5d1e504SJeremy L Thompson const CeedInt **target_array_borrowed, const CeedInt **target_array) {
462f5d1e504SJeremy L Thompson CeedCall(CeedSetHostGenericArray(source_array, copy_mode, sizeof(CeedInt), num_values, target_array_owned, target_array_borrowed, target_array));
463f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS;
464f5d1e504SJeremy L Thompson }
465f5d1e504SJeremy L Thompson
466f5d1e504SJeremy L Thompson /** Manage handoff of user `CeedScalar` `source_array` to backend with proper @ref CeedCopyMode behavior.
467f5d1e504SJeremy L Thompson
468f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user
469f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data
470f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle
471f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated
472f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data
473f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data
474f5d1e504SJeremy L Thompson
475f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
476f5d1e504SJeremy L Thompson
477f5d1e504SJeremy L Thompson @ref Backend
478f5d1e504SJeremy L Thompson **/
CeedSetHostCeedScalarArray(const CeedScalar * source_array,CeedCopyMode copy_mode,CeedSize num_values,const CeedScalar ** target_array_owned,const CeedScalar ** target_array_borrowed,const CeedScalar ** target_array)479f5d1e504SJeremy L Thompson int CeedSetHostCeedScalarArray(const CeedScalar *source_array, CeedCopyMode copy_mode, CeedSize num_values, const CeedScalar **target_array_owned,
480f5d1e504SJeremy L Thompson const CeedScalar **target_array_borrowed, const CeedScalar **target_array) {
481f5d1e504SJeremy L Thompson CeedCall(CeedSetHostGenericArray(source_array, copy_mode, sizeof(CeedScalar), num_values, target_array_owned, target_array_borrowed, target_array));
482f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS;
483f5d1e504SJeremy L Thompson }
484f5d1e504SJeremy L Thompson
485d7b241e6Sjeremylt /**
486ca94c3ddSJeremy L Thompson @brief Register a `Ceed` backend
487d7b241e6Sjeremylt
488ea61e9acSJeremy L Thompson @param[in] prefix Prefix of resources for this backend to respond to.
489ea61e9acSJeremy L Thompson For example, the reference backend responds to "/cpu/self".
490ca94c3ddSJeremy L Thompson @param[in] init Initialization function called by @ref CeedInit() when the backend is selected to drive the requested resource
491ea61e9acSJeremy L Thompson @param[in] priority Integer priority.
492ca94c3ddSJeremy L Thompson Lower values are preferred in case the resource requested by @ref CeedInit() has non-unique best prefix match.
493b11c1e72Sjeremylt
494b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure
495dfdf5a53Sjeremylt
4967a982d89SJeremy L. Thompson @ref Backend
497b11c1e72Sjeremylt **/
CeedRegister(const char * prefix,int (* init)(const char *,Ceed),unsigned int priority)4982b730f8bSJeremy L Thompson int CeedRegister(const char *prefix, int (*init)(const char *, Ceed), unsigned int priority) {
49910243053SJeremy L Thompson CeedDebugEnv("Backend Register: %s", prefix);
5006a406739SJeremy L Thompson CeedRegisterImpl(prefix, init, priority);
501e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
502d7b241e6Sjeremylt }
503d7b241e6Sjeremylt
504b11c1e72Sjeremylt /**
50560f9e2d6SJeremy L Thompson @brief Return debugging status flag
50660f9e2d6SJeremy L Thompson
507ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to get debugging flag
508ea61e9acSJeremy L Thompson @param[out] is_debug Variable to store debugging flag
50960f9e2d6SJeremy L Thompson
51060f9e2d6SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
51160f9e2d6SJeremy L Thompson
512d1d35e2fSjeremylt @ref Backend
51360f9e2d6SJeremy L Thompson **/
CeedIsDebug(Ceed ceed,bool * is_debug)514d1d35e2fSjeremylt int CeedIsDebug(Ceed ceed, bool *is_debug) {
5153f21f6b1SJeremy L Thompson *is_debug = ceed->is_debug;
516e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
51760f9e2d6SJeremy L Thompson }
51860f9e2d6SJeremy L Thompson
51960f9e2d6SJeremy L Thompson /**
520bf84744cSJeremy L Thompson @brief Get the root of the requested resource.
521bf84744cSJeremy L Thompson
522bf84744cSJeremy L Thompson Note: Caller is responsible for calling @ref CeedFree() on the `resource_root`.
523bc246734SJeremy L Thompson
524ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to get resource name of
525ca94c3ddSJeremy L Thompson @param[in] resource Full user specified resource
526ca94c3ddSJeremy L Thompson @param[in] delineator Delineator to break `resource_root` and `resource_spec`
527bc246734SJeremy L Thompson @param[out] resource_root Variable to store resource root
528bc246734SJeremy L Thompson
529bc246734SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
530bc246734SJeremy L Thompson
531bc246734SJeremy L Thompson @ref Backend
532bc246734SJeremy L Thompson **/
CeedGetResourceRoot(Ceed ceed,const char * resource,const char * delineator,char ** resource_root)533bc246734SJeremy L Thompson int CeedGetResourceRoot(Ceed ceed, const char *resource, const char *delineator, char **resource_root) {
534bc246734SJeremy L Thompson char *device_spec = strstr(resource, delineator);
535bc246734SJeremy L Thompson size_t resource_root_len = device_spec ? (size_t)(device_spec - resource) + 1 : strlen(resource) + 1;
5361c66c397SJeremy L Thompson
537bc246734SJeremy L Thompson CeedCall(CeedCalloc(resource_root_len, resource_root));
538bc246734SJeremy L Thompson memcpy(*resource_root, resource, resource_root_len - 1);
539bc246734SJeremy L Thompson return CEED_ERROR_SUCCESS;
540bc246734SJeremy L Thompson }
541bc246734SJeremy L Thompson
542bc246734SJeremy L Thompson /**
543ca94c3ddSJeremy L Thompson @brief Retrieve a parent `Ceed` context
5447a982d89SJeremy L. Thompson
545ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve parent of
5467a982d89SJeremy L. Thompson @param[out] parent Address to save the parent to
5477a982d89SJeremy L. Thompson
5487a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
5497a982d89SJeremy L. Thompson
5507a982d89SJeremy L. Thompson @ref Backend
5517a982d89SJeremy L. Thompson **/
CeedGetParent(Ceed ceed,Ceed * parent)5527a982d89SJeremy L. Thompson int CeedGetParent(Ceed ceed, Ceed *parent) {
5537a982d89SJeremy L. Thompson if (ceed->parent) {
5542b730f8bSJeremy L Thompson CeedCall(CeedGetParent(ceed->parent, parent));
555e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
5567a982d89SJeremy L. Thompson }
5579bc66399SJeremy L Thompson *parent = NULL;
5589bc66399SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, parent));
559e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
5607a982d89SJeremy L. Thompson }
5617a982d89SJeremy L. Thompson
5627a982d89SJeremy L. Thompson /**
563ca94c3ddSJeremy L Thompson @brief Retrieve a delegate `Ceed` context
5647a982d89SJeremy L. Thompson
565ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve delegate of
5667a982d89SJeremy L. Thompson @param[out] delegate Address to save the delegate to
5677a982d89SJeremy L. Thompson
5687a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
5697a982d89SJeremy L. Thompson
5707a982d89SJeremy L. Thompson @ref Backend
5717a982d89SJeremy L. Thompson **/
CeedGetDelegate(Ceed ceed,Ceed * delegate)5727a982d89SJeremy L. Thompson int CeedGetDelegate(Ceed ceed, Ceed *delegate) {
5739bc66399SJeremy L Thompson *delegate = NULL;
5749bc66399SJeremy L Thompson if (ceed->delegate) CeedCall(CeedReferenceCopy(ceed->delegate, delegate));
575e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
5767a982d89SJeremy L. Thompson }
5777a982d89SJeremy L. Thompson
5787a982d89SJeremy L. Thompson /**
579ca94c3ddSJeremy L Thompson @brief Set a delegate `Ceed` context
5807a982d89SJeremy L. Thompson
581ca94c3ddSJeremy L Thompson This function allows a `Ceed` context to set a delegate `Ceed` context.
582ca94c3ddSJeremy L Thompson All backend implementations default to the delegate `Ceed` context, unless overridden.
5837a982d89SJeremy L. Thompson
584ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to set delegate of
5857a982d89SJeremy L. Thompson @param[out] delegate Address to set the delegate to
5867a982d89SJeremy L. Thompson
5877a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
5887a982d89SJeremy L. Thompson
5897a982d89SJeremy L. Thompson @ref Backend
5907a982d89SJeremy L. Thompson **/
CeedSetDelegate(Ceed ceed,Ceed delegate)5917a982d89SJeremy L. Thompson int CeedSetDelegate(Ceed ceed, Ceed delegate) {
5929bc66399SJeremy L Thompson CeedCall(CeedReferenceCopy(delegate, &ceed->delegate));
5937a982d89SJeremy L. Thompson delegate->parent = ceed;
594e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
5957a982d89SJeremy L. Thompson }
5967a982d89SJeremy L. Thompson
5977a982d89SJeremy L. Thompson /**
598ca94c3ddSJeremy L Thompson @brief Retrieve a delegate `Ceed` context for a specific object type
5997a982d89SJeremy L. Thompson
600ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve delegate of
6017a982d89SJeremy L. Thompson @param[out] delegate Address to save the delegate to
602d1d35e2fSjeremylt @param[in] obj_name Name of the object type to retrieve delegate for
6037a982d89SJeremy L. Thompson
6047a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
6057a982d89SJeremy L. Thompson
6067a982d89SJeremy L. Thompson @ref Backend
6077a982d89SJeremy L. Thompson **/
CeedGetObjectDelegate(Ceed ceed,Ceed * delegate,const char * obj_name)608d1d35e2fSjeremylt int CeedGetObjectDelegate(Ceed ceed, Ceed *delegate, const char *obj_name) {
6097a982d89SJeremy L. Thompson // Check for object delegate
6102b730f8bSJeremy L Thompson for (CeedInt i = 0; i < ceed->obj_delegate_count; i++) {
611d1d35e2fSjeremylt if (!strcmp(obj_name, ceed->obj_delegates->obj_name)) {
6129bc66399SJeremy L Thompson *delegate = NULL;
6139bc66399SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed->obj_delegates->delegate, delegate));
614e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
6157a982d89SJeremy L. Thompson }
6162b730f8bSJeremy L Thompson }
6177a982d89SJeremy L. Thompson
6187a982d89SJeremy L. Thompson // Use default delegate if no object delegate
6192b730f8bSJeremy L Thompson CeedCall(CeedGetDelegate(ceed, delegate));
620e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
6217a982d89SJeremy L. Thompson }
6227a982d89SJeremy L. Thompson
6237a982d89SJeremy L. Thompson /**
624ca94c3ddSJeremy L Thompson @brief Set a delegate `Ceed` context for a specific object type
6257a982d89SJeremy L. Thompson
626ca94c3ddSJeremy L Thompson This function allows a `Ceed` context to set a delegate `Ceed` context for a given type of `Ceed` object.
627ca94c3ddSJeremy L Thompson All backend implementations default to the delegate `Ceed` context for this object.
628ca94c3ddSJeremy L Thompson For example, `CeedSetObjectDelegate(ceed, delegate, "Basis")` uses delegate implementations for all `CeedBasis` backend functions.
6297a982d89SJeremy L. Thompson
630ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context to set delegate of
631ca94c3ddSJeremy L Thompson @param[in] delegate `Ceed` context to use for delegation
632d1d35e2fSjeremylt @param[in] obj_name Name of the object type to set delegate for
6337a982d89SJeremy L. Thompson
6347a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
6357a982d89SJeremy L. Thompson
6367a982d89SJeremy L. Thompson @ref Backend
6377a982d89SJeremy L. Thompson **/
CeedSetObjectDelegate(Ceed ceed,Ceed delegate,const char * obj_name)638d1d35e2fSjeremylt int CeedSetObjectDelegate(Ceed ceed, Ceed delegate, const char *obj_name) {
639d1d35e2fSjeremylt CeedInt count = ceed->obj_delegate_count;
6407a982d89SJeremy L. Thompson
6417a982d89SJeremy L. Thompson // Malloc or Realloc
6427a982d89SJeremy L. Thompson if (count) {
6432b730f8bSJeremy L Thompson CeedCall(CeedRealloc(count + 1, &ceed->obj_delegates));
6447a982d89SJeremy L. Thompson } else {
6452b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &ceed->obj_delegates));
6467a982d89SJeremy L. Thompson }
647d1d35e2fSjeremylt ceed->obj_delegate_count++;
6487a982d89SJeremy L. Thompson
6497a982d89SJeremy L. Thompson // Set object delegate
6509bc66399SJeremy L Thompson CeedCall(CeedReferenceCopy(delegate, &ceed->obj_delegates[count].delegate));
6512b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(obj_name, &ceed->obj_delegates[count].obj_name));
6527a982d89SJeremy L. Thompson
6537a982d89SJeremy L. Thompson // Set delegate parent
6547a982d89SJeremy L. Thompson delegate->parent = ceed;
655e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
6567a982d89SJeremy L. Thompson }
6577a982d89SJeremy L. Thompson
6587a982d89SJeremy L. Thompson /**
659ca94c3ddSJeremy L Thompson @brief Get the fallback `Ceed` for `CeedOperator`
6608687e1d4SJeremy L Thompson
661ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context
662ca94c3ddSJeremy L Thompson @param[out] fallback_ceed Variable to store fallback `Ceed`
6638687e1d4SJeremy L Thompson
6648687e1d4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
6658687e1d4SJeremy L Thompson
6668687e1d4SJeremy L Thompson @ref Backend
6678687e1d4SJeremy L Thompson **/
CeedGetOperatorFallbackCeed(Ceed ceed,Ceed * fallback_ceed)6688687e1d4SJeremy L Thompson int CeedGetOperatorFallbackCeed(Ceed ceed, Ceed *fallback_ceed) {
66946b50f9eSZach Atkins if (ceed->op_fallback_ceed) {
670ca38d01dSJeremy L Thompson CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "---------- Ceed Fallback ----------\n");
67146b50f9eSZach Atkins CeedDebug(ceed, "Falling back from Ceed with backend %s at address %p to Ceed with backend %s at address %p", ceed->resource, ceed,
67246b50f9eSZach Atkins ceed->op_fallback_ceed->resource, ceed->op_fallback_ceed);
673d04bbc78SJeremy L Thompson }
6748687e1d4SJeremy L Thompson
6759bc66399SJeremy L Thompson *fallback_ceed = NULL;
6769bc66399SJeremy L Thompson if (ceed->op_fallback_ceed) CeedCall(CeedReferenceCopy(ceed->op_fallback_ceed, fallback_ceed));
6778687e1d4SJeremy L Thompson return CEED_ERROR_SUCCESS;
6788687e1d4SJeremy L Thompson }
6798687e1d4SJeremy L Thompson
6808687e1d4SJeremy L Thompson /**
681ca94c3ddSJeremy L Thompson @brief Set the fallback resource for `CeedOperator`.
6824385fb7fSSebastian Grimberg
68346b50f9eSZach Atkins The current fallback, if any, is freed by calling this function.
6847a982d89SJeremy L. Thompson
685ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context
68646b50f9eSZach Atkins @param[in] fallback_ceed `Ceed` context to create fallback operators
6877a982d89SJeremy L. Thompson
6887a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
6897a982d89SJeremy L. Thompson
6907a982d89SJeremy L. Thompson @ref Backend
6917a982d89SJeremy L. Thompson **/
CeedSetOperatorFallbackCeed(Ceed ceed,Ceed fallback_ceed)69246b50f9eSZach Atkins int CeedSetOperatorFallbackCeed(Ceed ceed, Ceed fallback_ceed) {
69346b50f9eSZach Atkins CeedCall(CeedReferenceCopy(fallback_ceed, &ceed->op_fallback_ceed));
69446b50f9eSZach Atkins fallback_ceed->parent = ceed;
695e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
6967a982d89SJeremy L. Thompson }
6977a982d89SJeremy L. Thompson
6987a982d89SJeremy L. Thompson /**
699ca94c3ddSJeremy L Thompson @brief Flag `Ceed` context as deterministic
7009525855cSJeremy L Thompson
701ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` to flag as deterministic
70296b902e2Sjeremylt @param[out] is_deterministic Deterministic status to set
7039525855cSJeremy L Thompson
7049525855cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
7059525855cSJeremy L Thompson
7069525855cSJeremy L Thompson @ref Backend
7079525855cSJeremy L Thompson **/
CeedSetDeterministic(Ceed ceed,bool is_deterministic)708d1d35e2fSjeremylt int CeedSetDeterministic(Ceed ceed, bool is_deterministic) {
709d1d35e2fSjeremylt ceed->is_deterministic = is_deterministic;
710e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
7119525855cSJeremy L Thompson }
7129525855cSJeremy L Thompson
7139525855cSJeremy L Thompson /**
714ca94c3ddSJeremy L Thompson @brief Set a backend function.
7157a982d89SJeremy L. Thompson
716ea61e9acSJeremy L Thompson This function is used for a backend to set the function associated with the Ceed objects.
717ca94c3ddSJeremy L Thompson For example, `CeedSetBackendFunction(ceed, "Ceed", ceed, "VectorCreate", BackendVectorCreate)` sets the backend implementation of @ref CeedVectorCreate() and `CeedSetBackendFunction(ceed, "Basis", basis, "Apply", BackendBasisApply)` sets the backend implementation of @ref CeedBasisApply().
7189fd66db6SSebastian Grimberg Note, the prefix 'Ceed' is not required for the object type ("Basis" vs "CeedBasis").
7197a982d89SJeremy L. Thompson
720ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context for error handling
721ea61e9acSJeremy L Thompson @param[in] type Type of Ceed object to set function for
7227a982d89SJeremy L. Thompson @param[out] object Ceed object to set function for
723ea61e9acSJeremy L Thompson @param[in] func_name Name of function to set
724ea61e9acSJeremy L Thompson @param[in] f Function to set
7257a982d89SJeremy L. Thompson
7267a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
7277a982d89SJeremy L. Thompson
7287a982d89SJeremy L. Thompson @ref Backend
7297a982d89SJeremy L. Thompson **/
CeedSetBackendFunctionImpl(Ceed ceed,const char * type,void * object,const char * func_name,void (* f)(void))730897d4737SSebastian Grimberg int CeedSetBackendFunctionImpl(Ceed ceed, const char *type, void *object, const char *func_name, void (*f)(void)) {
731d1d35e2fSjeremylt char lookup_name[CEED_MAX_RESOURCE_LEN + 1] = "";
7327a982d89SJeremy L. Thompson
7337a982d89SJeremy L. Thompson // Build lookup name
7342b730f8bSJeremy L Thompson if (strcmp(type, "Ceed")) strncat(lookup_name, "Ceed", CEED_MAX_RESOURCE_LEN);
735d1d35e2fSjeremylt strncat(lookup_name, type, CEED_MAX_RESOURCE_LEN);
736d1d35e2fSjeremylt strncat(lookup_name, func_name, CEED_MAX_RESOURCE_LEN);
7377a982d89SJeremy L. Thompson
7387a982d89SJeremy L. Thompson // Find and use offset
7392b730f8bSJeremy L Thompson for (CeedInt i = 0; ceed->f_offsets[i].func_name; i++) {
740d1d35e2fSjeremylt if (!strcmp(ceed->f_offsets[i].func_name, lookup_name)) {
741d1d35e2fSjeremylt size_t offset = ceed->f_offsets[i].offset;
7427a982d89SJeremy L. Thompson int (**fpointer)(void) = (int (**)(void))((char *)object + offset); // *NOPAD*
7431c66c397SJeremy L Thompson
744897d4737SSebastian Grimberg *fpointer = (int (*)(void))f;
745e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
7467a982d89SJeremy L. Thompson }
7472b730f8bSJeremy L Thompson }
7487a982d89SJeremy L. Thompson
7497a982d89SJeremy L. Thompson // LCOV_EXCL_START
7502b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Requested function '%s' was not found for CEED object '%s'", func_name, type);
7517a982d89SJeremy L. Thompson // LCOV_EXCL_STOP
7527a982d89SJeremy L. Thompson }
7537a982d89SJeremy L. Thompson
7547a982d89SJeremy L. Thompson /**
755ca94c3ddSJeremy L Thompson @brief Retrieve backend data for a `Ceed` context
7567a982d89SJeremy L. Thompson
757ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve data of
7587a982d89SJeremy L. Thompson @param[out] data Address to save data to
7597a982d89SJeremy L. Thompson
7607a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
7617a982d89SJeremy L. Thompson
7627a982d89SJeremy L. Thompson @ref Backend
7637a982d89SJeremy L. Thompson **/
CeedGetData(Ceed ceed,void * data)764777ff853SJeremy L Thompson int CeedGetData(Ceed ceed, void *data) {
765777ff853SJeremy L Thompson *(void **)data = ceed->data;
766e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
7677a982d89SJeremy L. Thompson }
7687a982d89SJeremy L. Thompson
7697a982d89SJeremy L. Thompson /**
770ca94c3ddSJeremy L Thompson @brief Set backend data for a `Ceed` context
7717a982d89SJeremy L. Thompson
772ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context to set data of
773ea61e9acSJeremy L Thompson @param[in] data Address of data to set
7747a982d89SJeremy L. Thompson
7757a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure
7767a982d89SJeremy L. Thompson
7777a982d89SJeremy L. Thompson @ref Backend
7787a982d89SJeremy L. Thompson **/
CeedSetData(Ceed ceed,void * data)779777ff853SJeremy L Thompson int CeedSetData(Ceed ceed, void *data) {
780777ff853SJeremy L Thompson ceed->data = data;
781e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
7827a982d89SJeremy L. Thompson }
7837a982d89SJeremy L. Thompson
78434359f16Sjeremylt /**
785ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `Ceed` context
78634359f16Sjeremylt
787ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context to increment the reference counter
78834359f16Sjeremylt
78934359f16Sjeremylt @return An error code: 0 - success, otherwise - failure
79034359f16Sjeremylt
79134359f16Sjeremylt @ref Backend
79234359f16Sjeremylt **/
CeedReference(Ceed ceed)7939560d06aSjeremylt int CeedReference(Ceed ceed) {
794b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)ceed));
79534359f16Sjeremylt return CEED_ERROR_SUCCESS;
79634359f16Sjeremylt }
79734359f16Sjeremylt
79873501bfeSJeremy L Thompson /**
7990b37c066SZach Atkins @brief Computes the current memory usage of the work vectors in a `Ceed` context and prints to debug.abort
8000b37c066SZach Atkins
8010b37c066SZach Atkins @param[in] ceed `Ceed` context
802ec4241e6SJeremy L Thompson @param[out] usage_mb Address of the variable where the MB of work vector usage will be stored
8030b37c066SZach Atkins
8040b37c066SZach Atkins @return An error code: 0 - success, otherwise - failure
8050b37c066SZach Atkins
8060b37c066SZach Atkins @ref Developer
8070b37c066SZach Atkins **/
CeedGetWorkVectorMemoryUsage(Ceed ceed,CeedScalar * usage_mb)80855326fe7SZach Atkins int CeedGetWorkVectorMemoryUsage(Ceed ceed, CeedScalar *usage_mb) {
809fd326ce8SZach Atkins if (!ceed->VectorCreate) {
810fd326ce8SZach Atkins Ceed delegate;
811fd326ce8SZach Atkins
812fd326ce8SZach Atkins CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Vector"));
813fd326ce8SZach Atkins CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement VectorCreate");
814fd326ce8SZach Atkins CeedCall(CeedGetWorkVectorMemoryUsage(delegate, usage_mb));
815fd326ce8SZach Atkins CeedCall(CeedDestroy(&delegate));
816fd326ce8SZach Atkins return CEED_ERROR_SUCCESS;
817fd326ce8SZach Atkins }
81855326fe7SZach Atkins *usage_mb = 0.0;
8190b37c066SZach Atkins if (ceed->work_vectors) {
8200b37c066SZach Atkins for (CeedInt i = 0; i < ceed->work_vectors->num_vecs; i++) {
8210b37c066SZach Atkins CeedSize vec_len;
8220b37c066SZach Atkins CeedCall(CeedVectorGetLength(ceed->work_vectors->vecs[i], &vec_len));
82355326fe7SZach Atkins *usage_mb += vec_len;
8240b37c066SZach Atkins }
82555326fe7SZach Atkins *usage_mb *= sizeof(CeedScalar) * 1e-6;
82655326fe7SZach Atkins CeedDebug(ceed, "Resource {%s}: Work vectors memory usage: %" CeedInt_FMT " vectors, %g MB\n", ceed->resource, ceed->work_vectors->num_vecs,
82755326fe7SZach Atkins *usage_mb);
8280b37c066SZach Atkins }
8290b37c066SZach Atkins return CEED_ERROR_SUCCESS;
8300b37c066SZach Atkins }
8310b37c066SZach Atkins
8320b37c066SZach Atkins /**
8330b37c066SZach Atkins @brief Clear inactive work vectors in a `Ceed` context below a minimum length.
8340b37c066SZach Atkins
8350b37c066SZach Atkins @param[in,out] ceed `Ceed` context
8360b37c066SZach Atkins @param[in] min_len Minimum length of work vector to keep
8370b37c066SZach Atkins
8380b37c066SZach Atkins @return An error code: 0 - success, otherwise - failure
8390b37c066SZach Atkins
8400b37c066SZach Atkins @ref Backend
8410b37c066SZach Atkins **/
CeedClearWorkVectors(Ceed ceed,CeedSize min_len)8420b37c066SZach Atkins int CeedClearWorkVectors(Ceed ceed, CeedSize min_len) {
843fd326ce8SZach Atkins if (!ceed->VectorCreate) {
844fd326ce8SZach Atkins Ceed delegate;
845fd326ce8SZach Atkins
846fd326ce8SZach Atkins CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Vector"));
847fd326ce8SZach Atkins CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement VectorCreate");
848fd326ce8SZach Atkins CeedCall(CeedClearWorkVectors(delegate, min_len));
849fd326ce8SZach Atkins CeedCall(CeedDestroy(&delegate));
850fd326ce8SZach Atkins return CEED_ERROR_SUCCESS;
851fd326ce8SZach Atkins }
8520b37c066SZach Atkins if (!ceed->work_vectors) return CEED_ERROR_SUCCESS;
8530b37c066SZach Atkins for (CeedInt i = 0; i < ceed->work_vectors->num_vecs; i++) {
8540b37c066SZach Atkins if (ceed->work_vectors->is_in_use[i]) continue;
8550b37c066SZach Atkins CeedSize vec_len;
8560b37c066SZach Atkins CeedCall(CeedVectorGetLength(ceed->work_vectors->vecs[i], &vec_len));
8570b37c066SZach Atkins if (vec_len < min_len) {
858b0f67a9cSJeremy L Thompson // Note: increase ref_count to prevent Ceed destructor from triggering
859b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)ceed));
860b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)ceed));
8610b37c066SZach Atkins CeedCall(CeedVectorDestroy(&ceed->work_vectors->vecs[i]));
862b0f67a9cSJeremy L Thompson // Note: restore ref_count
863b0f67a9cSJeremy L Thompson CeedObjectDereference((CeedObject)ceed);
8640b37c066SZach Atkins ceed->work_vectors->num_vecs--;
8650b37c066SZach Atkins if (ceed->work_vectors->num_vecs > 0) {
8660b37c066SZach Atkins ceed->work_vectors->vecs[i] = ceed->work_vectors->vecs[ceed->work_vectors->num_vecs];
8670b37c066SZach Atkins ceed->work_vectors->is_in_use[i] = ceed->work_vectors->is_in_use[ceed->work_vectors->num_vecs];
8680b37c066SZach Atkins ceed->work_vectors->is_in_use[ceed->work_vectors->num_vecs] = false;
8690b37c066SZach Atkins i--;
8700b37c066SZach Atkins }
8710b37c066SZach Atkins }
8720b37c066SZach Atkins }
8730b37c066SZach Atkins return CEED_ERROR_SUCCESS;
8740b37c066SZach Atkins }
8750b37c066SZach Atkins
8760b37c066SZach Atkins /**
87773501bfeSJeremy L Thompson @brief Get a `CeedVector` for scratch work from a `Ceed` context.
87873501bfeSJeremy L Thompson
87973501bfeSJeremy L Thompson Note: This vector must be restored with @ref CeedRestoreWorkVector().
88073501bfeSJeremy L Thompson
88173501bfeSJeremy L Thompson @param[in] ceed `Ceed` context
88273501bfeSJeremy L Thompson @param[in] len Minimum length of work vector
88373501bfeSJeremy L Thompson @param[out] vec Address of the variable where `CeedVector` will be stored
88473501bfeSJeremy L Thompson
88573501bfeSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
88673501bfeSJeremy L Thompson
88773501bfeSJeremy L Thompson @ref Backend
88873501bfeSJeremy L Thompson **/
CeedGetWorkVector(Ceed ceed,CeedSize len,CeedVector * vec)88973501bfeSJeremy L Thompson int CeedGetWorkVector(Ceed ceed, CeedSize len, CeedVector *vec) {
89073501bfeSJeremy L Thompson CeedInt i = 0;
89155326fe7SZach Atkins CeedScalar usage_mb;
89273501bfeSJeremy L Thompson
893fd326ce8SZach Atkins if (!ceed->VectorCreate) {
894fd326ce8SZach Atkins Ceed delegate;
895fd326ce8SZach Atkins
896fd326ce8SZach Atkins CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Vector"));
897fd326ce8SZach Atkins CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement VectorCreate");
898fd326ce8SZach Atkins CeedCall(CeedGetWorkVector(delegate, len, vec));
899fd326ce8SZach Atkins CeedCall(CeedDestroy(&delegate));
900fd326ce8SZach Atkins return CEED_ERROR_SUCCESS;
901fd326ce8SZach Atkins }
902fd326ce8SZach Atkins
90373501bfeSJeremy L Thompson if (!ceed->work_vectors) CeedCall(CeedWorkVectorsCreate(ceed));
90473501bfeSJeremy L Thompson
90573501bfeSJeremy L Thompson // Search for big enough work vector
90673501bfeSJeremy L Thompson for (i = 0; i < ceed->work_vectors->num_vecs; i++) {
90773501bfeSJeremy L Thompson if (!ceed->work_vectors->is_in_use[i]) {
90873501bfeSJeremy L Thompson CeedSize work_len;
90973501bfeSJeremy L Thompson
91073501bfeSJeremy L Thompson CeedCall(CeedVectorGetLength(ceed->work_vectors->vecs[i], &work_len));
91173501bfeSJeremy L Thompson if (work_len >= len) break;
91273501bfeSJeremy L Thompson }
91373501bfeSJeremy L Thompson }
91473501bfeSJeremy L Thompson // Long enough vector was not found
91573501bfeSJeremy L Thompson if (i == ceed->work_vectors->num_vecs) {
91673501bfeSJeremy L Thompson if (ceed->work_vectors->max_vecs == 0) {
91773501bfeSJeremy L Thompson ceed->work_vectors->max_vecs = 1;
91873501bfeSJeremy L Thompson CeedCall(CeedCalloc(ceed->work_vectors->max_vecs, &ceed->work_vectors->vecs));
91973501bfeSJeremy L Thompson CeedCall(CeedCalloc(ceed->work_vectors->max_vecs, &ceed->work_vectors->is_in_use));
92073501bfeSJeremy L Thompson } else if (ceed->work_vectors->max_vecs == i) {
92173501bfeSJeremy L Thompson ceed->work_vectors->max_vecs *= 2;
92273501bfeSJeremy L Thompson CeedCall(CeedRealloc(ceed->work_vectors->max_vecs, &ceed->work_vectors->vecs));
92373501bfeSJeremy L Thompson CeedCall(CeedRealloc(ceed->work_vectors->max_vecs, &ceed->work_vectors->is_in_use));
92473501bfeSJeremy L Thompson }
92573501bfeSJeremy L Thompson ceed->work_vectors->num_vecs++;
92673501bfeSJeremy L Thompson CeedCallBackend(CeedVectorCreate(ceed, len, &ceed->work_vectors->vecs[i]));
927b0f67a9cSJeremy L Thompson // Note: ref_count manipulation to prevent a ref-loop
928b0f67a9cSJeremy L Thompson CeedObjectDereference((CeedObject)ceed);
92955326fe7SZach Atkins if (ceed->is_debug) CeedGetWorkVectorMemoryUsage(ceed, &usage_mb);
93073501bfeSJeremy L Thompson }
93173501bfeSJeremy L Thompson // Return pointer to work vector
93273501bfeSJeremy L Thompson ceed->work_vectors->is_in_use[i] = true;
93373501bfeSJeremy L Thompson *vec = NULL;
93473501bfeSJeremy L Thompson CeedCall(CeedVectorReferenceCopy(ceed->work_vectors->vecs[i], vec));
935b0f67a9cSJeremy L Thompson // Note: bump ref_count to account for external access
936b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)ceed));
93773501bfeSJeremy L Thompson return CEED_ERROR_SUCCESS;
93873501bfeSJeremy L Thompson }
93973501bfeSJeremy L Thompson
94073501bfeSJeremy L Thompson /**
94173501bfeSJeremy L Thompson @brief Restore a `CeedVector` for scratch work from a `Ceed` context from @ref CeedGetWorkVector()
94273501bfeSJeremy L Thompson
94373501bfeSJeremy L Thompson @param[in] ceed `Ceed` context
94473501bfeSJeremy L Thompson @param[out] vec `CeedVector` to restore
94573501bfeSJeremy L Thompson
94673501bfeSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
94773501bfeSJeremy L Thompson
94873501bfeSJeremy L Thompson @ref Backend
94973501bfeSJeremy L Thompson **/
CeedRestoreWorkVector(Ceed ceed,CeedVector * vec)95073501bfeSJeremy L Thompson int CeedRestoreWorkVector(Ceed ceed, CeedVector *vec) {
951fd326ce8SZach Atkins if (!ceed->VectorCreate) {
952fd326ce8SZach Atkins Ceed delegate;
953fd326ce8SZach Atkins
954fd326ce8SZach Atkins CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Vector"));
955fd326ce8SZach Atkins CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement VectorCreate");
956fd326ce8SZach Atkins CeedCall(CeedRestoreWorkVector(delegate, vec));
957fd326ce8SZach Atkins CeedCall(CeedDestroy(&delegate));
958fd326ce8SZach Atkins return CEED_ERROR_SUCCESS;
959fd326ce8SZach Atkins }
960fd326ce8SZach Atkins
96173501bfeSJeremy L Thompson for (CeedInt i = 0; i < ceed->work_vectors->num_vecs; i++) {
96273501bfeSJeremy L Thompson if (*vec == ceed->work_vectors->vecs[i]) {
96373501bfeSJeremy L Thompson CeedCheck(ceed->work_vectors->is_in_use[i], ceed, CEED_ERROR_ACCESS, "Work vector %" CeedSize_FMT " was not checked out but is being returned");
96473501bfeSJeremy L Thompson CeedCall(CeedVectorDestroy(vec));
96573501bfeSJeremy L Thompson ceed->work_vectors->is_in_use[i] = false;
966b0f67a9cSJeremy L Thompson // Note: reduce ref_count again to prevent a ref-loop
967b0f67a9cSJeremy L Thompson CeedObjectDereference((CeedObject)ceed);
96873501bfeSJeremy L Thompson return CEED_ERROR_SUCCESS;
96973501bfeSJeremy L Thompson }
97073501bfeSJeremy L Thompson }
97173501bfeSJeremy L Thompson // LCOV_EXCL_START
97273501bfeSJeremy L Thompson return CeedError(ceed, CEED_ERROR_MAJOR, "vec was not checked out via CeedGetWorkVector()");
97373501bfeSJeremy L Thompson // LCOV_EXCL_STOP
97473501bfeSJeremy L Thompson }
97573501bfeSJeremy L Thompson
976b13efd58SJeremy L Thompson /**
977b13efd58SJeremy L Thompson @brief Retrieve list of additional JiT source roots from `Ceed` context.
978b13efd58SJeremy L Thompson
979b13efd58SJeremy L Thompson Note: The caller is responsible for restoring `jit_source_roots` with @ref CeedRestoreJitSourceRoots().
980b13efd58SJeremy L Thompson
981b13efd58SJeremy L Thompson @param[in] ceed `Ceed` context
982b13efd58SJeremy L Thompson @param[out] num_source_roots Number of JiT source directories
983b13efd58SJeremy L Thompson @param[out] jit_source_roots Absolute paths to additional JiT source directories
984b13efd58SJeremy L Thompson
985b13efd58SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
986b13efd58SJeremy L Thompson
987b13efd58SJeremy L Thompson @ref Backend
988b13efd58SJeremy L Thompson **/
CeedGetJitSourceRoots(Ceed ceed,CeedInt * num_source_roots,const char *** jit_source_roots)989b13efd58SJeremy L Thompson int CeedGetJitSourceRoots(Ceed ceed, CeedInt *num_source_roots, const char ***jit_source_roots) {
990b13efd58SJeremy L Thompson Ceed ceed_parent;
991b13efd58SJeremy L Thompson
992b13efd58SJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent));
993b13efd58SJeremy L Thompson *num_source_roots = ceed_parent->num_jit_source_roots;
994b13efd58SJeremy L Thompson *jit_source_roots = (const char **)ceed_parent->jit_source_roots;
995aeb3a72dSJeremy L Thompson ceed_parent->num_jit_source_roots_readers++;
9969bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed_parent));
997b13efd58SJeremy L Thompson return CEED_ERROR_SUCCESS;
998b13efd58SJeremy L Thompson }
999b13efd58SJeremy L Thompson
1000b13efd58SJeremy L Thompson /**
10012027fb9dSSirAlienTheGreat @brief Retrieve list of additional Rust source roots from `Ceed` context.
10022027fb9dSSirAlienTheGreat
10032027fb9dSSirAlienTheGreat Note: The caller is responsible for restoring `rust_source_roots` with @ref CeedRestoreRustSourceRoots().
10042027fb9dSSirAlienTheGreat
10052027fb9dSSirAlienTheGreat @param[in] ceed `Ceed` context
10062027fb9dSSirAlienTheGreat @param[out] num_source_roots Number of JiT source directories
10072027fb9dSSirAlienTheGreat @param[out] rust_source_roots Absolute paths to additional Rust source directories
10082027fb9dSSirAlienTheGreat
10092027fb9dSSirAlienTheGreat @return An error code: 0 - success, otherwise - failure
10102027fb9dSSirAlienTheGreat
10112027fb9dSSirAlienTheGreat @ref Backend
10122027fb9dSSirAlienTheGreat **/
CeedGetRustSourceRoots(Ceed ceed,CeedInt * num_source_roots,const char *** rust_source_roots)10132027fb9dSSirAlienTheGreat int CeedGetRustSourceRoots(Ceed ceed, CeedInt *num_source_roots, const char ***rust_source_roots) {
10142027fb9dSSirAlienTheGreat Ceed ceed_parent;
10152027fb9dSSirAlienTheGreat
10162027fb9dSSirAlienTheGreat CeedCall(CeedGetParent(ceed, &ceed_parent));
10172027fb9dSSirAlienTheGreat *num_source_roots = ceed_parent->num_rust_source_roots;
10182027fb9dSSirAlienTheGreat *rust_source_roots = (const char **)ceed_parent->rust_source_roots;
10192027fb9dSSirAlienTheGreat ceed_parent->num_rust_source_roots_readers++;
10202027fb9dSSirAlienTheGreat CeedCall(CeedDestroy(&ceed_parent));
10212027fb9dSSirAlienTheGreat return CEED_ERROR_SUCCESS;
10222027fb9dSSirAlienTheGreat }
10232027fb9dSSirAlienTheGreat
10242027fb9dSSirAlienTheGreat /**
1025b13efd58SJeremy L Thompson @brief Restore list of additional JiT source roots from with @ref CeedGetJitSourceRoots()
1026b13efd58SJeremy L Thompson
1027b13efd58SJeremy L Thompson @param[in] ceed `Ceed` context
1028b13efd58SJeremy L Thompson @param[out] jit_source_roots Absolute paths to additional JiT source directories
1029b13efd58SJeremy L Thompson
1030b13efd58SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1031b13efd58SJeremy L Thompson
1032b13efd58SJeremy L Thompson @ref Backend
1033b13efd58SJeremy L Thompson **/
CeedRestoreJitSourceRoots(Ceed ceed,const char *** jit_source_roots)1034b13efd58SJeremy L Thompson int CeedRestoreJitSourceRoots(Ceed ceed, const char ***jit_source_roots) {
1035aeb3a72dSJeremy L Thompson Ceed ceed_parent;
1036aeb3a72dSJeremy L Thompson
1037aeb3a72dSJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent));
1038b13efd58SJeremy L Thompson *jit_source_roots = NULL;
1039aeb3a72dSJeremy L Thompson ceed_parent->num_jit_source_roots_readers--;
10409bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed_parent));
1041b13efd58SJeremy L Thompson return CEED_ERROR_SUCCESS;
1042b13efd58SJeremy L Thompson }
1043b13efd58SJeremy L Thompson
10444753b775SJeremy L Thompson /**
10452027fb9dSSirAlienTheGreat @brief Restore list of additional Rust source roots from with @ref CeedGetJitSourceRoots()
10462027fb9dSSirAlienTheGreat
10472027fb9dSSirAlienTheGreat @param[in] ceed `Ceed` context
10482027fb9dSSirAlienTheGreat @param[out] rust_source_roots Absolute paths to additional Rust source directories
10492027fb9dSSirAlienTheGreat
10502027fb9dSSirAlienTheGreat @return An error code: 0 - success, otherwise - failure
10512027fb9dSSirAlienTheGreat
10522027fb9dSSirAlienTheGreat @ref Backend
10532027fb9dSSirAlienTheGreat **/
CeedRestoreRustSourceRoots(Ceed ceed,const char *** rust_source_roots)10542027fb9dSSirAlienTheGreat int CeedRestoreRustSourceRoots(Ceed ceed, const char ***rust_source_roots) {
10552027fb9dSSirAlienTheGreat Ceed ceed_parent;
10562027fb9dSSirAlienTheGreat
10572027fb9dSSirAlienTheGreat CeedCall(CeedGetParent(ceed, &ceed_parent));
10582027fb9dSSirAlienTheGreat *rust_source_roots = NULL;
10592027fb9dSSirAlienTheGreat ceed_parent->num_rust_source_roots_readers--;
10602027fb9dSSirAlienTheGreat CeedCall(CeedDestroy(&ceed_parent));
10612027fb9dSSirAlienTheGreat return CEED_ERROR_SUCCESS;
10622027fb9dSSirAlienTheGreat }
10632027fb9dSSirAlienTheGreat
10642027fb9dSSirAlienTheGreat /**
10654753b775SJeremy L Thompson @brief Retrieve list of additional JiT defines from `Ceed` context.
10664753b775SJeremy L Thompson
10674753b775SJeremy L Thompson Note: The caller is responsible for restoring `jit_defines` with @ref CeedRestoreJitDefines().
10684753b775SJeremy L Thompson
10694753b775SJeremy L Thompson @param[in] ceed `Ceed` context
10704753b775SJeremy L Thompson @param[out] num_jit_defines Number of JiT defines
10714753b775SJeremy L Thompson @param[out] jit_defines Strings such as `foo=bar`, used as `-Dfoo=bar` in JiT
10724753b775SJeremy L Thompson
10734753b775SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
10744753b775SJeremy L Thompson
10754753b775SJeremy L Thompson @ref Backend
10764753b775SJeremy L Thompson **/
CeedGetJitDefines(Ceed ceed,CeedInt * num_jit_defines,const char *** jit_defines)10772686ebe6SJed Brown int CeedGetJitDefines(Ceed ceed, CeedInt *num_jit_defines, const char ***jit_defines) {
10784753b775SJeremy L Thompson Ceed ceed_parent;
10794753b775SJeremy L Thompson
10804753b775SJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent));
10812686ebe6SJed Brown *num_jit_defines = ceed_parent->num_jit_defines;
10824753b775SJeremy L Thompson *jit_defines = (const char **)ceed_parent->jit_defines;
1083aeb3a72dSJeremy L Thompson ceed_parent->num_jit_defines_readers++;
10849bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed_parent));
10854753b775SJeremy L Thompson return CEED_ERROR_SUCCESS;
10864753b775SJeremy L Thompson }
10874753b775SJeremy L Thompson
10884753b775SJeremy L Thompson /**
10894753b775SJeremy L Thompson @brief Restore list of additional JiT defines from with @ref CeedGetJitDefines()
10904753b775SJeremy L Thompson
10914753b775SJeremy L Thompson @param[in] ceed `Ceed` context
10924753b775SJeremy L Thompson @param[out] jit_defines String such as `foo=bar`, used as `-Dfoo=bar` in JiT
10934753b775SJeremy L Thompson
10944753b775SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
10954753b775SJeremy L Thompson
10964753b775SJeremy L Thompson @ref Backend
10974753b775SJeremy L Thompson **/
CeedRestoreJitDefines(Ceed ceed,const char *** jit_defines)10984753b775SJeremy L Thompson int CeedRestoreJitDefines(Ceed ceed, const char ***jit_defines) {
1099aeb3a72dSJeremy L Thompson Ceed ceed_parent;
1100aeb3a72dSJeremy L Thompson
1101aeb3a72dSJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent));
11024753b775SJeremy L Thompson *jit_defines = NULL;
1103aeb3a72dSJeremy L Thompson ceed_parent->num_jit_defines_readers--;
11049bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed_parent));
11054753b775SJeremy L Thompson return CEED_ERROR_SUCCESS;
11064753b775SJeremy L Thompson }
11074753b775SJeremy L Thompson
11087a982d89SJeremy L. Thompson /// @}
11097a982d89SJeremy L. Thompson
11107a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
11117a982d89SJeremy L. Thompson /// Ceed Public API
11127a982d89SJeremy L. Thompson /// ----------------------------------------------------------------------------
11137a982d89SJeremy L. Thompson /// @addtogroup CeedUser
11147a982d89SJeremy L. Thompson /// @{
11157a982d89SJeremy L. Thompson
11167a982d89SJeremy L. Thompson /**
1117ca94c3ddSJeremy L Thompson @brief Get the list of available resource names for `Ceed` contexts
11184385fb7fSSebastian Grimberg
1119ca94c3ddSJeremy L Thompson Note: The caller is responsible for `free()`ing the resources and priorities arrays, but should not `free()` the contents of the resources array.
112022e44211Sjeremylt
112192ee7d1cSjeremylt @param[out] n Number of available resources
112292ee7d1cSjeremylt @param[out] resources List of available resource names
112322e44211Sjeremylt @param[out] priorities Resource name prioritization values, lower is better
112422e44211Sjeremylt
112522e44211Sjeremylt @return An error code: 0 - success, otherwise - failure
112622e44211Sjeremylt
112722e44211Sjeremylt @ref User
112822e44211Sjeremylt **/
112922e44211Sjeremylt // LCOV_EXCL_START
CeedRegistryGetList(size_t * n,char *** const resources,CeedInt ** priorities)11302b730f8bSJeremy L Thompson int CeedRegistryGetList(size_t *n, char ***const resources, CeedInt **priorities) {
1131d0c91ce9Sjeremylt *n = 0;
11329ff86846Sjeremylt *resources = malloc(num_backends * sizeof(**resources));
11336574a04fSJeremy L Thompson CeedCheck(resources, NULL, CEED_ERROR_MAJOR, "malloc() failure");
11349ff86846Sjeremylt if (priorities) {
11359ff86846Sjeremylt *priorities = malloc(num_backends * sizeof(**priorities));
11366574a04fSJeremy L Thompson CeedCheck(priorities, NULL, CEED_ERROR_MAJOR, "malloc() failure");
11379ff86846Sjeremylt }
113822e44211Sjeremylt for (size_t i = 0; i < num_backends; i++) {
1139d0c91ce9Sjeremylt // Only report compiled backends
1140d0c91ce9Sjeremylt if (backends[i].priority < CEED_MAX_BACKEND_PRIORITY) {
114122e44211Sjeremylt *resources[i] = backends[i].prefix;
11429ff86846Sjeremylt if (priorities) *priorities[i] = backends[i].priority;
1143d0c91ce9Sjeremylt *n += 1;
1144d0c91ce9Sjeremylt }
1145d0c91ce9Sjeremylt }
11466574a04fSJeremy L Thompson CeedCheck(*n, NULL, CEED_ERROR_MAJOR, "No backends installed");
1147d0c91ce9Sjeremylt *resources = realloc(*resources, *n * sizeof(**resources));
11486574a04fSJeremy L Thompson CeedCheck(resources, NULL, CEED_ERROR_MAJOR, "realloc() failure");
1149d0c91ce9Sjeremylt if (priorities) {
1150d0c91ce9Sjeremylt *priorities = realloc(*priorities, *n * sizeof(**priorities));
11516574a04fSJeremy L Thompson CeedCheck(priorities, NULL, CEED_ERROR_MAJOR, "realloc() failure");
115222e44211Sjeremylt }
115322e44211Sjeremylt return CEED_ERROR_SUCCESS;
115445f1e315Sjeremylt }
115522e44211Sjeremylt // LCOV_EXCL_STOP
115622e44211Sjeremylt
115722e44211Sjeremylt /**
1158ca94c3ddSJeremy L Thompson @brief Initialize a `Ceed` context to use the specified resource.
11594385fb7fSSebastian Grimberg
1160ca94c3ddSJeremy L Thompson Note: Prefixing the resource with "help:" (e.g. "help:/cpu/self") will result in @ref CeedInt() printing the current libCEED version number and a list of current available backend resources to `stderr`.
1161b11c1e72Sjeremylt
1162ea61e9acSJeremy L Thompson @param[in] resource Resource to use, e.g., "/cpu/self"
1163ea61e9acSJeremy L Thompson @param[out] ceed The library context
1164b11c1e72Sjeremylt
1165b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure
1166dfdf5a53Sjeremylt
11677a982d89SJeremy L. Thompson @ref User
1168ca94c3ddSJeremy L Thompson
1169ca94c3ddSJeremy L Thompson @sa CeedRegister() CeedDestroy()
1170b11c1e72Sjeremylt **/
CeedInit(const char * resource,Ceed * ceed)1171d7b241e6Sjeremylt int CeedInit(const char *resource, Ceed *ceed) {
11722b730f8bSJeremy L Thompson size_t match_len = 0, match_index = UINT_MAX, match_priority = CEED_MAX_BACKEND_PRIORITY, priority;
1173d7b241e6Sjeremylt
1174fe2413ffSjeremylt // Find matching backend
11756574a04fSJeremy L Thompson CeedCheck(resource, NULL, CEED_ERROR_MAJOR, "No resource provided");
11762b730f8bSJeremy L Thompson CeedCall(CeedRegisterAll());
117713873f79Sjeremylt
117822e44211Sjeremylt // Check for help request
117922e44211Sjeremylt const char *help_prefix = "help";
11802b730f8bSJeremy L Thompson size_t match_help = 0;
11812b730f8bSJeremy L Thompson while (match_help < 4 && resource[match_help] == help_prefix[match_help]) match_help++;
118222e44211Sjeremylt if (match_help == 4) {
11832b730f8bSJeremy L Thompson fprintf(stderr, "libCEED version: %d.%d%d%s\n", CEED_VERSION_MAJOR, CEED_VERSION_MINOR, CEED_VERSION_PATCH,
118422e44211Sjeremylt CEED_VERSION_RELEASE ? "" : "+development");
118592ee7d1cSjeremylt fprintf(stderr, "Available backend resources:\n");
118622e44211Sjeremylt for (size_t i = 0; i < num_backends; i++) {
1187d0c91ce9Sjeremylt // Only report compiled backends
11882b730f8bSJeremy L Thompson if (backends[i].priority < CEED_MAX_BACKEND_PRIORITY) fprintf(stderr, " %s\n", backends[i].prefix);
118922e44211Sjeremylt }
119022e44211Sjeremylt fflush(stderr);
119122e44211Sjeremylt match_help = 5; // Delineating character expected
119222e44211Sjeremylt } else {
119322e44211Sjeremylt match_help = 0;
119422e44211Sjeremylt }
119522e44211Sjeremylt
1196ea61e9acSJeremy L Thompson // Find best match, computed as number of matching characters from requested resource stem
11972b730f8bSJeremy L Thompson size_t stem_length = 0;
11982b730f8bSJeremy L Thompson while (resource[stem_length + match_help] && resource[stem_length + match_help] != ':') stem_length++;
1199d7b241e6Sjeremylt for (size_t i = 0; i < num_backends; i++) {
12002b730f8bSJeremy L Thompson size_t n = 0;
1201d7b241e6Sjeremylt const char *prefix = backends[i].prefix;
12022b730f8bSJeremy L Thompson while (prefix[n] && prefix[n] == resource[n + match_help]) n++;
1203d7b241e6Sjeremylt priority = backends[i].priority;
1204d1d35e2fSjeremylt if (n > match_len || (n == match_len && match_priority > priority)) {
1205d1d35e2fSjeremylt match_len = n;
1206d1d35e2fSjeremylt match_priority = priority;
1207f7e22acaSJeremy L Thompson match_index = i;
1208d7b241e6Sjeremylt }
1209d7b241e6Sjeremylt }
12109c9a0587SLeila Ghaffari // Using Levenshtein distance to find closest match
12119c9a0587SLeila Ghaffari if (match_len <= 1 || match_len != stem_length) {
1212203015caSLeila Ghaffari // LCOV_EXCL_START
12139c9a0587SLeila Ghaffari size_t lev_dis = UINT_MAX;
1214f7e22acaSJeremy L Thompson size_t lev_index = UINT_MAX, lev_priority = CEED_MAX_BACKEND_PRIORITY;
12159c9a0587SLeila Ghaffari for (size_t i = 0; i < num_backends; i++) {
12169c9a0587SLeila Ghaffari const char *prefix = backends[i].prefix;
12179c9a0587SLeila Ghaffari size_t prefix_length = strlen(backends[i].prefix);
12189c9a0587SLeila Ghaffari size_t min_len = (prefix_length < stem_length) ? prefix_length : stem_length;
1219092904ddSLeila Ghaffari size_t column[min_len + 1];
1220092904ddSLeila Ghaffari for (size_t j = 0; j <= min_len; j++) column[j] = j;
12219c9a0587SLeila Ghaffari for (size_t j = 1; j <= min_len; j++) {
12229c9a0587SLeila Ghaffari column[0] = j;
12239c9a0587SLeila Ghaffari for (size_t k = 1, last_diag = j - 1; k <= min_len; k++) {
1224092904ddSLeila Ghaffari size_t old_diag = column[k];
12259c9a0587SLeila Ghaffari size_t min_1 = (column[k] < column[k - 1]) ? column[k] + 1 : column[k - 1] + 1;
12269c9a0587SLeila Ghaffari size_t min_2 = last_diag + (resource[k - 1] == prefix[j - 1] ? 0 : 1);
12279c9a0587SLeila Ghaffari column[k] = (min_1 < min_2) ? min_1 : min_2;
12289c9a0587SLeila Ghaffari last_diag = old_diag;
12299c9a0587SLeila Ghaffari }
12309c9a0587SLeila Ghaffari }
12319c9a0587SLeila Ghaffari size_t n = column[min_len];
12329c9a0587SLeila Ghaffari priority = backends[i].priority;
12332b730f8bSJeremy L Thompson if (n < lev_dis || (n == lev_dis && lev_priority > priority)) {
12349c9a0587SLeila Ghaffari lev_dis = n;
12359c9a0587SLeila Ghaffari lev_priority = priority;
1236f7e22acaSJeremy L Thompson lev_index = i;
12379c9a0587SLeila Ghaffari }
12389c9a0587SLeila Ghaffari }
1239f7e22acaSJeremy L Thompson const char *prefix_lev = backends[lev_index].prefix;
12402b730f8bSJeremy L Thompson size_t lev_length = 0;
12412b730f8bSJeremy L Thompson while (prefix_lev[lev_length] && prefix_lev[lev_length] != '\0') lev_length++;
12429c9a0587SLeila Ghaffari size_t m = (lev_length < stem_length) ? lev_length : stem_length;
12436574a04fSJeremy L Thompson if (lev_dis + 1 >= m) return CeedError(NULL, CEED_ERROR_MAJOR, "No suitable backend: %s", resource);
12446574a04fSJeremy L Thompson else return CeedError(NULL, CEED_ERROR_MAJOR, "No suitable backend: %s\nClosest match: %s", resource, backends[lev_index].prefix);
1245203015caSLeila Ghaffari // LCOV_EXCL_STOP
12469c9a0587SLeila Ghaffari }
1247fe2413ffSjeremylt
1248fe2413ffSjeremylt // Setup Ceed
12492b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, ceed));
12506c328a79SJeremy L Thompson CeedCall(CeedObjectCreate(NULL, CeedView_Object, CeedDestroy_Object, &(*ceed)->obj));
12512b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &(*ceed)->jit_source_roots));
12522027fb9dSSirAlienTheGreat CeedCall(CeedCalloc(1, &(*ceed)->rust_source_roots));
1253bc81ce41Sjeremylt const char *ceed_error_handler = getenv("CEED_ERROR_HANDLER");
12542b730f8bSJeremy L Thompson if (!ceed_error_handler) ceed_error_handler = "abort";
12552b730f8bSJeremy L Thompson if (!strcmp(ceed_error_handler, "exit")) (*ceed)->Error = CeedErrorExit;
12562b730f8bSJeremy L Thompson else if (!strcmp(ceed_error_handler, "store")) (*ceed)->Error = CeedErrorStore;
12572b730f8bSJeremy L Thompson else (*ceed)->Error = CeedErrorAbort;
1258d1d35e2fSjeremylt memcpy((*ceed)->err_msg, "No error message stored", 24);
1259d7b241e6Sjeremylt (*ceed)->data = NULL;
1260fe2413ffSjeremylt
1261fe2413ffSjeremylt // Set lookup table
1262d1d35e2fSjeremylt FOffset f_offsets[] = {
12636e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, Error),
12645ae360d4SJeremy L Thompson CEED_FTABLE_ENTRY(Ceed, SetStream),
12656e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, GetPreferredMemType),
12666e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, Destroy),
1267f8902d9eSjeremylt CEED_FTABLE_ENTRY(Ceed, VectorCreate),
12686e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, ElemRestrictionCreate),
12693ac8f562SJeremy L Thompson CEED_FTABLE_ENTRY(Ceed, ElemRestrictionCreateAtPoints),
12706e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, ElemRestrictionCreateBlocked),
12716e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, BasisCreateTensorH1),
12726e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, BasisCreateH1),
127350c301a5SRezgar Shakeri CEED_FTABLE_ENTRY(Ceed, BasisCreateHdiv),
1274c4e3f59bSSebastian Grimberg CEED_FTABLE_ENTRY(Ceed, BasisCreateHcurl),
12756e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, TensorContractCreate),
12766e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, QFunctionCreate),
1277777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(Ceed, QFunctionContextCreate),
12786e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, OperatorCreate),
127948acf710SJeremy L Thompson CEED_FTABLE_ENTRY(Ceed, OperatorCreateAtPoints),
12806e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, CompositeOperatorCreate),
12819c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, HasValidArray),
12829c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, HasBorrowedArrayOfType),
12830b8f3c4eSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, CopyStrided),
12846e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, SetArray),
12856a6c615bSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, TakeArray),
12866e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, SetValue),
12870b8f3c4eSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, SetValueStrided),
1288f48ed27dSnbeams CEED_FTABLE_ENTRY(CeedVector, SyncArray),
12896e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, GetArray),
12906e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, GetArrayRead),
12919c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, GetArrayWrite),
12926e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, RestoreArray),
12936e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, RestoreArrayRead),
1294547d9b97Sjeremylt CEED_FTABLE_ENTRY(CeedVector, Norm),
1295e0dd3b27Sjeremylt CEED_FTABLE_ENTRY(CeedVector, Scale),
12960f7fd0f8Sjeremylt CEED_FTABLE_ENTRY(CeedVector, AXPY),
12975fb68f37SKaren (Ren) Stengel CEED_FTABLE_ENTRY(CeedVector, AXPBY),
12980f7fd0f8Sjeremylt CEED_FTABLE_ENTRY(CeedVector, PointwiseMult),
1299d99fa3c5SJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, Reciprocal),
13006e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, Destroy),
13016e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedElemRestriction, Apply),
1302f30b1135SSebastian Grimberg CEED_FTABLE_ENTRY(CeedElemRestriction, ApplyUnsigned),
13037c1dbaffSSebastian Grimberg CEED_FTABLE_ENTRY(CeedElemRestriction, ApplyUnoriented),
130405fa913cSJeremy L Thompson CEED_FTABLE_ENTRY(CeedElemRestriction, ApplyAtPointsInElement),
13056e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedElemRestriction, ApplyBlock),
1306bd33150aSjeremylt CEED_FTABLE_ENTRY(CeedElemRestriction, GetOffsets),
130777d1c127SSebastian Grimberg CEED_FTABLE_ENTRY(CeedElemRestriction, GetOrientations),
130877d1c127SSebastian Grimberg CEED_FTABLE_ENTRY(CeedElemRestriction, GetCurlOrientations),
130919605835SJeremy L Thompson CEED_FTABLE_ENTRY(CeedElemRestriction, GetAtPointsElementOffset),
13106e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedElemRestriction, Destroy),
13116e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedBasis, Apply),
1312db2becc9SJeremy L Thompson CEED_FTABLE_ENTRY(CeedBasis, ApplyAdd),
1313c8c3fa7dSJeremy L Thompson CEED_FTABLE_ENTRY(CeedBasis, ApplyAtPoints),
1314db2becc9SJeremy L Thompson CEED_FTABLE_ENTRY(CeedBasis, ApplyAddAtPoints),
13156e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedBasis, Destroy),
13166e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedTensorContract, Apply),
13176e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedTensorContract, Destroy),
13186e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedQFunction, Apply),
13198c84ac63Sjeremylt CEED_FTABLE_ENTRY(CeedQFunction, SetCUDAUserFunction),
13208c84ac63Sjeremylt CEED_FTABLE_ENTRY(CeedQFunction, SetHIPUserFunction),
13216e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedQFunction, Destroy),
13229c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, HasValidData),
13239c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, HasBorrowedDataOfType),
1324777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, SetData),
1325891038deSjeremylt CEED_FTABLE_ENTRY(CeedQFunctionContext, TakeData),
1326777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, GetData),
132728bfd0b7SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, GetDataRead),
1328777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, RestoreData),
132928bfd0b7SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, RestoreDataRead),
13302e64a2b9SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, DataDestroy),
1331777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, Destroy),
133280ac2e43SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleQFunction),
133370a7ffb3SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleQFunctionUpdate),
133480ac2e43SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleDiagonal),
13359e9210b8SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleAddDiagonal),
133680ac2e43SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssemblePointBlockDiagonal),
13379e9210b8SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleAddPointBlockDiagonal),
1338e2f04181SAndrew T. Barker CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleSymbolic),
1339e2f04181SAndrew T. Barker CEED_FTABLE_ENTRY(CeedOperator, LinearAssemble),
1340cefa2673SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleSingle),
1341713f43c3Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, CreateFDMElementInverse),
13426e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, Apply),
1343250756a7Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, ApplyComposite),
1344cae8b89aSjeremylt CEED_FTABLE_ENTRY(CeedOperator, ApplyAdd),
1345250756a7Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, ApplyAddComposite),
13466e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, ApplyJacobian),
13476e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, Destroy),
13486e79d475Sjeremylt {NULL, 0} // End of lookup table - used in SetBackendFunction loop
13491dfeef1dSjeremylt };
1350fe2413ffSjeremylt
13512b730f8bSJeremy L Thompson CeedCall(CeedCalloc(sizeof(f_offsets), &(*ceed)->f_offsets));
1352d1d35e2fSjeremylt memcpy((*ceed)->f_offsets, f_offsets, sizeof(f_offsets));
1353fe2413ffSjeremylt
135460f9e2d6SJeremy L Thompson // Record env variables CEED_DEBUG or DBG
13551c66c397SJeremy L Thompson (*ceed)->is_debug = getenv("CEED_DEBUG") || getenv("DEBUG") || getenv("DBG");
135660f9e2d6SJeremy L Thompson
135722e44211Sjeremylt // Copy resource prefix, if backend setup successful
13582b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(backends[match_index].prefix, (char **)&(*ceed)->resource));
1359ee5a26f2SJeremy L Thompson
1360ee5a26f2SJeremy L Thompson // Set default JiT source root
1361ea61e9acSJeremy L Thompson // Note: there will always be the default root for every Ceed but all additional paths are added to the top-most parent
13622b730f8bSJeremy L Thompson CeedCall(CeedAddJitSourceRoot(*ceed, (char *)CeedJitSourceRootDefault));
1363ee5a26f2SJeremy L Thompson
13642027fb9dSSirAlienTheGreat // By default, make cuda compile without clang, use nvrtc instead
13652027fb9dSSirAlienTheGreat // Note that this is overridden if a rust file is included (rust requires clang)
13662027fb9dSSirAlienTheGreat const char *env = getenv("GPU_CLANG");
13672027fb9dSSirAlienTheGreat
13682027fb9dSSirAlienTheGreat if (env && strcmp(env, "1") == 0) {
13692027fb9dSSirAlienTheGreat (*ceed)->cuda_compile_with_clang = true;
13702027fb9dSSirAlienTheGreat } else {
13712027fb9dSSirAlienTheGreat (*ceed)->cuda_compile_with_clang = false;
13722027fb9dSSirAlienTheGreat }
13732027fb9dSSirAlienTheGreat
1374d04bbc78SJeremy L Thompson // Backend specific setup
13752b730f8bSJeremy L Thompson CeedCall(backends[match_index].init(&resource[match_help], *ceed));
1376e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1377d7b241e6Sjeremylt }
1378d7b241e6Sjeremylt
1379d7b241e6Sjeremylt /**
1380ca94c3ddSJeremy L Thompson @brief Set the GPU stream for a `Ceed` context
13815ae360d4SJeremy L Thompson
1382ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context to set the stream
13835ae360d4SJeremy L Thompson @param[in] handle Handle to GPU stream
13845ae360d4SJeremy L Thompson
13855ae360d4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
13865ae360d4SJeremy L Thompson
13875ae360d4SJeremy L Thompson @ref User
13885ae360d4SJeremy L Thompson **/
CeedSetStream(Ceed ceed,void * handle)13895ae360d4SJeremy L Thompson int CeedSetStream(Ceed ceed, void *handle) {
1390ca94c3ddSJeremy L Thompson CeedCheck(handle, ceed, CEED_ERROR_INCOMPATIBLE, "Stream handle must be non-NULL");
13919ffb25e0SJames Wright if (ceed->SetStream) {
13925ae360d4SJeremy L Thompson CeedCall(ceed->SetStream(ceed, handle));
13939ffb25e0SJames Wright } else {
13949ffb25e0SJames Wright Ceed delegate;
13959ffb25e0SJames Wright CeedCall(CeedGetDelegate(ceed, &delegate));
13965ae360d4SJeremy L Thompson
139728ce3d2aSJeremy L Thompson if (delegate) CeedCall(CeedSetStream(delegate, handle));
139828ce3d2aSJeremy L Thompson else return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support setting stream");
13999bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate));
14009ffb25e0SJames Wright }
14015ae360d4SJeremy L Thompson return CEED_ERROR_SUCCESS;
14025ae360d4SJeremy L Thompson }
14035ae360d4SJeremy L Thompson
14045ae360d4SJeremy L Thompson /**
1405ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `Ceed` context.
14064385fb7fSSebastian Grimberg
1407ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedDestroy().
1408512bb800SJeremy L Thompson
1409ca94c3ddSJeremy L Thompson Note: If the value of `*ceed_copy` passed to this function is non-`NULL`, then it is assumed that `*ceed_copy` is a pointer to a `Ceed` context.
1410ca94c3ddSJeremy L Thompson This `Ceed` context will be destroyed if `*ceed_copy` is the only reference to this `Ceed` context.
14119560d06aSjeremylt
1412ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to copy reference to
1413ea61e9acSJeremy L Thompson @param[in,out] ceed_copy Variable to store copied reference
14149560d06aSjeremylt
14159560d06aSjeremylt @return An error code: 0 - success, otherwise - failure
14169560d06aSjeremylt
14179560d06aSjeremylt @ref User
14189560d06aSjeremylt **/
CeedReferenceCopy(Ceed ceed,Ceed * ceed_copy)14199560d06aSjeremylt int CeedReferenceCopy(Ceed ceed, Ceed *ceed_copy) {
14202b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed));
14212b730f8bSJeremy L Thompson CeedCall(CeedDestroy(ceed_copy));
14229560d06aSjeremylt *ceed_copy = ceed;
14239560d06aSjeremylt return CEED_ERROR_SUCCESS;
14249560d06aSjeremylt }
14259560d06aSjeremylt
14269560d06aSjeremylt /**
1427ca94c3ddSJeremy L Thompson @brief Get the full resource name for a `Ceed` context
14282f86a920SJeremy L Thompson
1429ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to get resource name of
14307a982d89SJeremy L. Thompson @param[out] resource Variable to store resource name
14312f86a920SJeremy L Thompson
14322f86a920SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
14332f86a920SJeremy L Thompson
14347a982d89SJeremy L. Thompson @ref User
14355107b09fSJeremy L Thompson **/
CeedGetResource(Ceed ceed,const char ** resource)14367a982d89SJeremy L. Thompson int CeedGetResource(Ceed ceed, const char **resource) {
14377a982d89SJeremy L. Thompson *resource = (const char *)ceed->resource;
1438e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
14395107b09fSJeremy L Thompson }
14405107b09fSJeremy L Thompson
14415107b09fSJeremy L Thompson /**
1442ca94c3ddSJeremy L Thompson @brief Return `Ceed` context preferred memory type
1443c907536fSjeremylt
1444ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to get preferred memory type of
1445d1d35e2fSjeremylt @param[out] mem_type Address to save preferred memory type to
1446c907536fSjeremylt
1447c907536fSjeremylt @return An error code: 0 - success, otherwise - failure
1448c907536fSjeremylt
14497a982d89SJeremy L. Thompson @ref User
1450c907536fSjeremylt **/
CeedGetPreferredMemType(Ceed ceed,CeedMemType * mem_type)1451d1d35e2fSjeremylt int CeedGetPreferredMemType(Ceed ceed, CeedMemType *mem_type) {
1452c907536fSjeremylt if (ceed->GetPreferredMemType) {
14532b730f8bSJeremy L Thompson CeedCall(ceed->GetPreferredMemType(mem_type));
1454c907536fSjeremylt } else {
1455c263cd57Sjeremylt Ceed delegate;
14562b730f8bSJeremy L Thompson CeedCall(CeedGetDelegate(ceed, &delegate));
1457c263cd57Sjeremylt
1458c263cd57Sjeremylt if (delegate) {
14592b730f8bSJeremy L Thompson CeedCall(CeedGetPreferredMemType(delegate, mem_type));
1460c263cd57Sjeremylt } else {
1461d1d35e2fSjeremylt *mem_type = CEED_MEM_HOST;
1462c907536fSjeremylt }
14639bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate));
1464c263cd57Sjeremylt }
1465e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1466c907536fSjeremylt }
1467c907536fSjeremylt
1468c907536fSjeremylt /**
1469ca94c3ddSJeremy L Thompson @brief Get deterministic status of `Ceed` context
14709525855cSJeremy L Thompson
1471ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context
1472d1d35e2fSjeremylt @param[out] is_deterministic Variable to store deterministic status
14739525855cSJeremy L Thompson
14749525855cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
14759525855cSJeremy L Thompson
14769525855cSJeremy L Thompson @ref User
14779525855cSJeremy L Thompson **/
CeedIsDeterministic(Ceed ceed,bool * is_deterministic)1478d1d35e2fSjeremylt int CeedIsDeterministic(Ceed ceed, bool *is_deterministic) {
1479d1d35e2fSjeremylt *is_deterministic = ceed->is_deterministic;
1480e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
14819525855cSJeremy L Thompson }
14829525855cSJeremy L Thompson
14839525855cSJeremy L Thompson /**
1484ca94c3ddSJeremy L Thompson @brief Set additional JiT source root for `Ceed` context
1485ee5a26f2SJeremy L Thompson
1486ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context
1487ee5a26f2SJeremy L Thompson @param[in] jit_source_root Absolute path to additional JiT source directory
1488ee5a26f2SJeremy L Thompson
1489ee5a26f2SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1490ee5a26f2SJeremy L Thompson
1491ee5a26f2SJeremy L Thompson @ref User
1492ee5a26f2SJeremy L Thompson **/
CeedAddJitSourceRoot(Ceed ceed,const char * jit_source_root)1493ee5a26f2SJeremy L Thompson int CeedAddJitSourceRoot(Ceed ceed, const char *jit_source_root) {
14946155f12fSJeremy L Thompson Ceed ceed_parent;
1495ee5a26f2SJeremy L Thompson
14962b730f8bSJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent));
1497830fc37bSJeremy L Thompson CeedCheck(!ceed_parent->num_jit_source_roots_readers, ceed, CEED_ERROR_ACCESS, "Cannot add JiT source root, read access has not been restored");
14986155f12fSJeremy L Thompson
14996155f12fSJeremy L Thompson CeedInt index = ceed_parent->num_jit_source_roots;
1500ee5a26f2SJeremy L Thompson size_t path_length = strlen(jit_source_root);
15011c66c397SJeremy L Thompson
15024753b775SJeremy L Thompson if (ceed_parent->num_jit_source_roots == ceed_parent->max_jit_source_roots) {
15034753b775SJeremy L Thompson if (ceed_parent->max_jit_source_roots == 0) ceed_parent->max_jit_source_roots = 1;
15044753b775SJeremy L Thompson ceed_parent->max_jit_source_roots *= 2;
15054753b775SJeremy L Thompson CeedCall(CeedRealloc(ceed_parent->max_jit_source_roots, &ceed_parent->jit_source_roots));
15064753b775SJeremy L Thompson }
15072b730f8bSJeremy L Thompson CeedCall(CeedCalloc(path_length + 1, &ceed_parent->jit_source_roots[index]));
1508d602d780SJeremy L Thompson memcpy(ceed_parent->jit_source_roots[index], jit_source_root, path_length);
15096155f12fSJeremy L Thompson ceed_parent->num_jit_source_roots++;
15109bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed_parent));
1511ee5a26f2SJeremy L Thompson return CEED_ERROR_SUCCESS;
1512ee5a26f2SJeremy L Thompson }
1513ee5a26f2SJeremy L Thompson
1514ee5a26f2SJeremy L Thompson /**
15152027fb9dSSirAlienTheGreat @brief Set additional Rust source root for `Ceed` context for use in QFunction
15162027fb9dSSirAlienTheGreat
15172027fb9dSSirAlienTheGreat @param[in,out] ceed `Ceed` context
15182027fb9dSSirAlienTheGreat @param[in] rust_source_root Absolute path to additional Rust source directory
15192027fb9dSSirAlienTheGreat
15202027fb9dSSirAlienTheGreat @return An error code: 0 - success, otherwise - failure
15212027fb9dSSirAlienTheGreat
15222027fb9dSSirAlienTheGreat @ref User
15232027fb9dSSirAlienTheGreat **/
CeedAddRustSourceRoot(Ceed ceed,const char * rust_source_root)15242027fb9dSSirAlienTheGreat int CeedAddRustSourceRoot(Ceed ceed, const char *rust_source_root) {
15252027fb9dSSirAlienTheGreat Ceed ceed_parent;
15262027fb9dSSirAlienTheGreat
15272027fb9dSSirAlienTheGreat CeedCall(CeedGetParent(ceed, &ceed_parent));
15282027fb9dSSirAlienTheGreat CeedCheck(!ceed_parent->num_rust_source_roots_readers, ceed, CEED_ERROR_ACCESS, "Cannot add Rust source root, read access has not been restored");
15292027fb9dSSirAlienTheGreat
15302027fb9dSSirAlienTheGreat CeedInt index = ceed_parent->num_rust_source_roots;
15312027fb9dSSirAlienTheGreat size_t path_length = strlen(rust_source_root);
15322027fb9dSSirAlienTheGreat
15332027fb9dSSirAlienTheGreat if (ceed_parent->num_rust_source_roots == ceed_parent->max_rust_source_roots) {
15342027fb9dSSirAlienTheGreat if (ceed_parent->max_rust_source_roots == 0) ceed_parent->max_rust_source_roots = 1;
15352027fb9dSSirAlienTheGreat ceed_parent->max_rust_source_roots *= 2;
15362027fb9dSSirAlienTheGreat CeedCall(CeedRealloc(ceed_parent->max_rust_source_roots, &ceed_parent->rust_source_roots));
15372027fb9dSSirAlienTheGreat }
15382027fb9dSSirAlienTheGreat CeedCall(CeedCalloc(path_length + 1, &ceed_parent->rust_source_roots[index]));
15392027fb9dSSirAlienTheGreat memcpy(ceed_parent->rust_source_roots[index], rust_source_root, path_length);
15402027fb9dSSirAlienTheGreat ceed_parent->num_rust_source_roots++;
15412027fb9dSSirAlienTheGreat ceed_parent->cuda_compile_with_clang = true;
15422027fb9dSSirAlienTheGreat ceed->cuda_compile_with_clang = true;
15432027fb9dSSirAlienTheGreat CeedCall(CeedDestroy(&ceed_parent));
15442027fb9dSSirAlienTheGreat return CEED_ERROR_SUCCESS;
15452027fb9dSSirAlienTheGreat }
15462027fb9dSSirAlienTheGreat
15472027fb9dSSirAlienTheGreat /**
15484753b775SJeremy L Thompson @brief Set additional JiT compiler define for `Ceed` context
15494753b775SJeremy L Thompson
15504753b775SJeremy L Thompson @param[in,out] ceed `Ceed` context
15514753b775SJeremy L Thompson @param[in] jit_define String such as `foo=bar`, used as `-Dfoo=bar` in JiT
15524753b775SJeremy L Thompson
15534753b775SJeremy L Thompson @return An error code: 0 - success, otherwise - failure
15544753b775SJeremy L Thompson
15554753b775SJeremy L Thompson @ref User
15564753b775SJeremy L Thompson **/
CeedAddJitDefine(Ceed ceed,const char * jit_define)15574753b775SJeremy L Thompson int CeedAddJitDefine(Ceed ceed, const char *jit_define) {
15584753b775SJeremy L Thompson Ceed ceed_parent;
15594753b775SJeremy L Thompson
15604753b775SJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent));
1561830fc37bSJeremy L Thompson CeedCheck(!ceed_parent->num_jit_defines_readers, ceed, CEED_ERROR_ACCESS, "Cannot add JiT define, read access has not been restored");
15624753b775SJeremy L Thompson
15634753b775SJeremy L Thompson CeedInt index = ceed_parent->num_jit_defines;
15644753b775SJeremy L Thompson size_t define_length = strlen(jit_define);
15654753b775SJeremy L Thompson
15664753b775SJeremy L Thompson if (ceed_parent->num_jit_defines == ceed_parent->max_jit_defines) {
15674753b775SJeremy L Thompson if (ceed_parent->max_jit_defines == 0) ceed_parent->max_jit_defines = 1;
15684753b775SJeremy L Thompson ceed_parent->max_jit_defines *= 2;
15694753b775SJeremy L Thompson CeedCall(CeedRealloc(ceed_parent->max_jit_defines, &ceed_parent->jit_defines));
15704753b775SJeremy L Thompson }
15714753b775SJeremy L Thompson CeedCall(CeedCalloc(define_length + 1, &ceed_parent->jit_defines[index]));
15724753b775SJeremy L Thompson memcpy(ceed_parent->jit_defines[index], jit_define, define_length);
15734753b775SJeremy L Thompson ceed_parent->num_jit_defines++;
15749bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed_parent));
15754753b775SJeremy L Thompson return CEED_ERROR_SUCCESS;
15764753b775SJeremy L Thompson }
15774753b775SJeremy L Thompson
15784753b775SJeremy L Thompson /**
15794c789ea2SJeremy L Thompson @brief Set the number of tabs to indent for @ref CeedView() output
15804c789ea2SJeremy L Thompson
15814c789ea2SJeremy L Thompson @param[in] ceed `Ceed` to set the number of view tabs
15824c789ea2SJeremy L Thompson @param[in] num_tabs Number of view tabs to set
15834c789ea2SJeremy L Thompson
15844c789ea2SJeremy L Thompson @return Error code: 0 - success, otherwise - failure
15854c789ea2SJeremy L Thompson
15864c789ea2SJeremy L Thompson @ref User
15874c789ea2SJeremy L Thompson **/
CeedSetNumViewTabs(Ceed ceed,CeedInt num_tabs)15884c789ea2SJeremy L Thompson int CeedSetNumViewTabs(Ceed ceed, CeedInt num_tabs) {
1589a299a25bSJeremy L Thompson CeedCall(CeedObjectSetNumViewTabs((CeedObject)ceed, num_tabs));
15904c789ea2SJeremy L Thompson return CEED_ERROR_SUCCESS;
15914c789ea2SJeremy L Thompson }
15924c789ea2SJeremy L Thompson
15934c789ea2SJeremy L Thompson /**
1594690992b2SZach Atkins @brief Get the number of tabs to indent for @ref CeedView() output
1595690992b2SZach Atkins
1596690992b2SZach Atkins @param[in] ceed `Ceed` to get the number of view tabs
1597690992b2SZach Atkins @param[out] num_tabs Number of view tabs
1598690992b2SZach Atkins
1599690992b2SZach Atkins @return Error code: 0 - success, otherwise - failure
1600690992b2SZach Atkins
1601690992b2SZach Atkins @ref User
1602690992b2SZach Atkins **/
CeedGetNumViewTabs(Ceed ceed,CeedInt * num_tabs)1603690992b2SZach Atkins int CeedGetNumViewTabs(Ceed ceed, CeedInt *num_tabs) {
1604a299a25bSJeremy L Thompson CeedCall(CeedObjectGetNumViewTabs((CeedObject)ceed, num_tabs));
1605690992b2SZach Atkins return CEED_ERROR_SUCCESS;
1606690992b2SZach Atkins }
1607690992b2SZach Atkins
1608690992b2SZach Atkins /**
1609ca94c3ddSJeremy L Thompson @brief View a `Ceed`
16100a0da059Sjeremylt
1611ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` to view
16120a0da059Sjeremylt @param[in] stream Filestream to write to
16130a0da059Sjeremylt
16140a0da059Sjeremylt @return An error code: 0 - success, otherwise - failure
16150a0da059Sjeremylt
16160a0da059Sjeremylt @ref User
16170a0da059Sjeremylt **/
CeedView(Ceed ceed,FILE * stream)16180a0da059Sjeremylt int CeedView(Ceed ceed, FILE *stream) {
16194c789ea2SJeremy L Thompson char *tabs = NULL;
1620d1d35e2fSjeremylt CeedMemType mem_type;
16210a0da059Sjeremylt
1622*73c5a4d2SJeremy L Thompson CeedCall(CeedGetPreferredMemType(ceed, &mem_type));
1623*73c5a4d2SJeremy L Thompson
16244c789ea2SJeremy L Thompson {
16254c789ea2SJeremy L Thompson CeedInt num_tabs = 0;
16264c789ea2SJeremy L Thompson
16274c789ea2SJeremy L Thompson CeedCall(CeedGetNumViewTabs(ceed, &num_tabs));
16284c789ea2SJeremy L Thompson CeedCall(CeedCalloc(CEED_TAB_WIDTH * num_tabs + 1, &tabs));
16294c789ea2SJeremy L Thompson for (CeedInt i = 0; i < CEED_TAB_WIDTH * num_tabs; i++) tabs[i] = ' ';
16304c789ea2SJeremy L Thompson }
16312b730f8bSJeremy L Thompson fprintf(stream,
16324c789ea2SJeremy L Thompson "%sCeed\n"
16334c789ea2SJeremy L Thompson "%s Ceed Resource: %s\n"
16344c789ea2SJeremy L Thompson "%s Preferred MemType: %s\n",
16354c789ea2SJeremy L Thompson tabs, tabs, ceed->resource, tabs, CeedMemTypes[mem_type]);
16364c789ea2SJeremy L Thompson CeedCall(CeedFree(&tabs));
1637e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
16380a0da059Sjeremylt }
16390a0da059Sjeremylt
16400a0da059Sjeremylt /**
1641ca94c3ddSJeremy L Thompson @brief Destroy a `Ceed`
1642d7b241e6Sjeremylt
1643ca94c3ddSJeremy L Thompson @param[in,out] ceed Address of `Ceed` context to destroy
1644b11c1e72Sjeremylt
1645b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure
1646dfdf5a53Sjeremylt
16477a982d89SJeremy L. Thompson @ref User
1648b11c1e72Sjeremylt **/
CeedDestroy(Ceed * ceed)1649d7b241e6Sjeremylt int CeedDestroy(Ceed *ceed) {
1650b0f67a9cSJeremy L Thompson if (!*ceed || CeedObjectDereference((CeedObject)*ceed) > 0) {
1651ad6481ceSJeremy L Thompson *ceed = NULL;
1652ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS;
1653ad6481ceSJeremy L Thompson }
1654aeb3a72dSJeremy L Thompson
1655aeb3a72dSJeremy L Thompson CeedCheck(!(*ceed)->num_jit_source_roots_readers, *ceed, CEED_ERROR_ACCESS,
1656aeb3a72dSJeremy L Thompson "Cannot destroy ceed context, read access for JiT source roots has been granted");
1657aeb3a72dSJeremy L Thompson CeedCheck(!(*ceed)->num_jit_defines_readers, *ceed, CEED_ERROR_ACCESS, "Cannot add JiT source root, read access for JiT defines has been granted");
1658aeb3a72dSJeremy L Thompson
16592b730f8bSJeremy L Thompson if ((*ceed)->delegate) CeedCall(CeedDestroy(&(*ceed)->delegate));
16600ace9bf2Sjeremylt
1661d1d35e2fSjeremylt if ((*ceed)->obj_delegate_count > 0) {
166292ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*ceed)->obj_delegate_count; i++) {
16632b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&((*ceed)->obj_delegates[i].delegate)));
16642b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->obj_delegates[i].obj_name));
1665aefd8378Sjeremylt }
16662b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->obj_delegates));
1667aefd8378Sjeremylt }
16680ace9bf2Sjeremylt
16692b730f8bSJeremy L Thompson if ((*ceed)->Destroy) CeedCall((*ceed)->Destroy(*ceed));
16700ace9bf2Sjeremylt
167192ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*ceed)->num_jit_source_roots; i++) {
16722b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->jit_source_roots[i]));
1673032e71eaSJeremy L Thompson }
16742b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->jit_source_roots));
1675032e71eaSJeremy L Thompson
16764753b775SJeremy L Thompson for (CeedInt i = 0; i < (*ceed)->num_jit_defines; i++) {
16774753b775SJeremy L Thompson CeedCall(CeedFree(&(*ceed)->jit_defines[i]));
16784753b775SJeremy L Thompson }
16794753b775SJeremy L Thompson CeedCall(CeedFree(&(*ceed)->jit_defines));
16804753b775SJeremy L Thompson
1681898eb931SJeremy L Thompson for (CeedInt i = 0; i < (*ceed)->num_rust_source_roots; i++) {
1682898eb931SJeremy L Thompson CeedCall(CeedFree(&(*ceed)->rust_source_roots[i]));
1683898eb931SJeremy L Thompson }
1684898eb931SJeremy L Thompson CeedCall(CeedFree(&(*ceed)->rust_source_roots));
1685898eb931SJeremy L Thompson
16862b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->f_offsets));
16872b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->resource));
16882b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*ceed)->op_fallback_ceed));
168973501bfeSJeremy L Thompson CeedCall(CeedWorkVectorsDestroy(*ceed));
16906c328a79SJeremy L Thompson CeedCall(CeedObjectDestroy_Private(&(*ceed)->obj));
16912b730f8bSJeremy L Thompson CeedCall(CeedFree(ceed));
1692e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1693d7b241e6Sjeremylt }
1694d7b241e6Sjeremylt
1695f9982c62SWill Pazner // LCOV_EXCL_START
CeedErrorFormat(Ceed ceed,const char * format,va_list * args)1696f9982c62SWill Pazner const char *CeedErrorFormat(Ceed ceed, const char *format, va_list *args) {
16972b730f8bSJeremy L Thompson if (ceed->parent) return CeedErrorFormat(ceed->parent, format, args);
169878464608Sjeremylt // Using pointer to va_list for better FFI, but clang-tidy can't verify va_list is initalized
169978464608Sjeremylt vsnprintf(ceed->err_msg, CEED_MAX_RESOURCE_LEN, format, *args); // NOLINT
1700d1d35e2fSjeremylt return ceed->err_msg;
1701f9982c62SWill Pazner }
1702f9982c62SWill Pazner // LCOV_EXCL_STOP
1703f9982c62SWill Pazner
17047a982d89SJeremy L. Thompson /**
1705ca94c3ddSJeremy L Thompson @brief Error handling implementation; use @ref CeedError() instead.
1706ca94c3ddSJeremy L Thompson
1707ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
17087a982d89SJeremy L. Thompson
17097a982d89SJeremy L. Thompson @ref Developer
17107a982d89SJeremy L. Thompson **/
CeedErrorImpl(Ceed ceed,const char * filename,int lineno,const char * func,int ecode,const char * format,...)17112b730f8bSJeremy L Thompson int CeedErrorImpl(Ceed ceed, const char *filename, int lineno, const char *func, int ecode, const char *format, ...) {
17127a982d89SJeremy L. Thompson va_list args;
1713d1d35e2fSjeremylt int ret_val;
17141c66c397SJeremy L Thompson
17157a982d89SJeremy L. Thompson va_start(args, format);
17167a982d89SJeremy L. Thompson if (ceed) {
1717d1d35e2fSjeremylt ret_val = ceed->Error(ceed, filename, lineno, func, ecode, format, &args);
17187a982d89SJeremy L. Thompson } else {
1719b0d62198Sjeremylt // LCOV_EXCL_START
1720477729cfSJeremy L Thompson const char *ceed_error_handler = getenv("CEED_ERROR_HANDLER");
17212b730f8bSJeremy L Thompson if (!ceed_error_handler) ceed_error_handler = "abort";
1722bcbe1c99SJeremy L Thompson if (!strcmp(ceed_error_handler, "return")) {
1723bcbe1c99SJeremy L Thompson ret_val = CeedErrorReturn(ceed, filename, lineno, func, ecode, format, &args);
1724bcbe1c99SJeremy L Thompson } else {
1725477729cfSJeremy L Thompson // This function will not return
1726d1d35e2fSjeremylt ret_val = CeedErrorAbort(ceed, filename, lineno, func, ecode, format, &args);
17277a982d89SJeremy L. Thompson }
1728bcbe1c99SJeremy L Thompson }
17297a982d89SJeremy L. Thompson va_end(args);
1730d1d35e2fSjeremylt return ret_val;
1731b0d62198Sjeremylt // LCOV_EXCL_STOP
17327a982d89SJeremy L. Thompson }
17337a982d89SJeremy L. Thompson
1734477729cfSJeremy L Thompson /**
1735477729cfSJeremy L Thompson @brief Error handler that returns without printing anything.
1736477729cfSJeremy L Thompson
1737ca94c3ddSJeremy L Thompson Pass this to @ref CeedSetErrorHandler() to obtain this error handling behavior.
1738ca94c3ddSJeremy L Thompson
1739ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1740477729cfSJeremy L Thompson
1741477729cfSJeremy L Thompson @ref Developer
1742477729cfSJeremy L Thompson **/
1743477729cfSJeremy L Thompson // LCOV_EXCL_START
CeedErrorReturn(Ceed ceed,const char * filename,int line_no,const char * func,int err_code,const char * format,va_list * args)17442b730f8bSJeremy L Thompson int CeedErrorReturn(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) {
1745d1d35e2fSjeremylt return err_code;
1746477729cfSJeremy L Thompson }
1747477729cfSJeremy L Thompson // LCOV_EXCL_STOP
1748477729cfSJeremy L Thompson
1749477729cfSJeremy L Thompson /**
1750ea61e9acSJeremy L Thompson @brief Error handler that stores the error message for future use and returns the error.
1751477729cfSJeremy L Thompson
1752ca94c3ddSJeremy L Thompson Pass this to @ref CeedSetErrorHandler() to obtain this error handling behavior.
1753ca94c3ddSJeremy L Thompson
1754ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1755477729cfSJeremy L Thompson
1756477729cfSJeremy L Thompson @ref Developer
1757477729cfSJeremy L Thompson **/
1758477729cfSJeremy L Thompson // LCOV_EXCL_START
CeedErrorStore(Ceed ceed,const char * filename,int line_no,const char * func,int err_code,const char * format,va_list * args)17592b730f8bSJeremy L Thompson int CeedErrorStore(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) {
17602b730f8bSJeremy L Thompson if (ceed->parent) return CeedErrorStore(ceed->parent, filename, line_no, func, err_code, format, args);
1761477729cfSJeremy L Thompson
1762477729cfSJeremy L Thompson // Build message
17631c66c397SJeremy L Thompson int len = snprintf(ceed->err_msg, CEED_MAX_RESOURCE_LEN, "%s:%d in %s(): ", filename, line_no, func);
176478464608Sjeremylt // Using pointer to va_list for better FFI, but clang-tidy can't verify va_list is initalized
176578464608Sjeremylt vsnprintf(ceed->err_msg + len, CEED_MAX_RESOURCE_LEN - len, format, *args); // NOLINT
1766d1d35e2fSjeremylt return err_code;
1767477729cfSJeremy L Thompson }
1768477729cfSJeremy L Thompson // LCOV_EXCL_STOP
1769477729cfSJeremy L Thompson
1770477729cfSJeremy L Thompson /**
1771ca94c3ddSJeremy L Thompson @brief Error handler that prints to `stderr` and aborts
1772477729cfSJeremy L Thompson
1773ca94c3ddSJeremy L Thompson Pass this to @ref CeedSetErrorHandler() to obtain this error handling behavior.
1774ca94c3ddSJeremy L Thompson
1775ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1776477729cfSJeremy L Thompson
1777477729cfSJeremy L Thompson @ref Developer
1778477729cfSJeremy L Thompson **/
1779477729cfSJeremy L Thompson // LCOV_EXCL_START
CeedErrorAbort(Ceed ceed,const char * filename,int line_no,const char * func,int err_code,const char * format,va_list * args)17802b730f8bSJeremy L Thompson int CeedErrorAbort(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) {
1781d1d35e2fSjeremylt fprintf(stderr, "%s:%d in %s(): ", filename, line_no, func);
1782f9982c62SWill Pazner vfprintf(stderr, format, *args);
1783477729cfSJeremy L Thompson fprintf(stderr, "\n");
1784477729cfSJeremy L Thompson abort();
1785d1d35e2fSjeremylt return err_code;
1786477729cfSJeremy L Thompson }
1787477729cfSJeremy L Thompson // LCOV_EXCL_STOP
1788477729cfSJeremy L Thompson
1789477729cfSJeremy L Thompson /**
1790ca94c3ddSJeremy L Thompson @brief Error handler that prints to `stderr` and exits.
1791477729cfSJeremy L Thompson
1792ca94c3ddSJeremy L Thompson Pass this to @ref CeedSetErrorHandler() to obtain this error handling behavior.
1793477729cfSJeremy L Thompson
1794ca94c3ddSJeremy L Thompson In contrast to @ref CeedErrorAbort(), this exits without a signal, so `atexit()` handlers (e.g., as used by gcov) are run.
1795ca94c3ddSJeremy L Thompson
1796ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1797477729cfSJeremy L Thompson
1798477729cfSJeremy L Thompson @ref Developer
1799477729cfSJeremy L Thompson **/
CeedErrorExit(Ceed ceed,const char * filename,int line_no,const char * func,int err_code,const char * format,va_list * args)18002b730f8bSJeremy L Thompson int CeedErrorExit(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) {
1801d1d35e2fSjeremylt fprintf(stderr, "%s:%d in %s(): ", filename, line_no, func);
180278464608Sjeremylt // Using pointer to va_list for better FFI, but clang-tidy can't verify va_list is initalized
180378464608Sjeremylt vfprintf(stderr, format, *args); // NOLINT
1804477729cfSJeremy L Thompson fprintf(stderr, "\n");
1805d1d35e2fSjeremylt exit(err_code);
1806d1d35e2fSjeremylt return err_code;
1807477729cfSJeremy L Thompson }
1808477729cfSJeremy L Thompson
1809477729cfSJeremy L Thompson /**
1810477729cfSJeremy L Thompson @brief Set error handler
1811477729cfSJeremy L Thompson
1812ca94c3ddSJeremy L Thompson A default error handler is set in @ref CeedInit().
1813ca94c3ddSJeremy L Thompson Use this function to change the error handler to @ref CeedErrorReturn(), @ref CeedErrorAbort(), or a user-defined error handler.
1814ca94c3ddSJeremy L Thompson
1815ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1816477729cfSJeremy L Thompson
1817477729cfSJeremy L Thompson @ref Developer
1818477729cfSJeremy L Thompson **/
CeedSetErrorHandler(Ceed ceed,CeedErrorHandler handler)1819d1d35e2fSjeremylt int CeedSetErrorHandler(Ceed ceed, CeedErrorHandler handler) {
1820d1d35e2fSjeremylt ceed->Error = handler;
1821d1d35e2fSjeremylt if (ceed->delegate) CeedSetErrorHandler(ceed->delegate, handler);
18222b730f8bSJeremy L Thompson for (CeedInt i = 0; i < ceed->obj_delegate_count; i++) CeedSetErrorHandler(ceed->obj_delegates[i].delegate, handler);
1823e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1824477729cfSJeremy L Thompson }
1825477729cfSJeremy L Thompson
1826477729cfSJeremy L Thompson /**
1827477729cfSJeremy L Thompson @brief Get error message
1828477729cfSJeremy L Thompson
1829ca94c3ddSJeremy L Thompson The error message is only stored when using the error handler @ref CeedErrorStore()
1830477729cfSJeremy L Thompson
1831ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve error message
1832d1d35e2fSjeremylt @param[out] err_msg Char pointer to hold error message
1833477729cfSJeremy L Thompson
1834ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1835ca94c3ddSJeremy L Thompson
1836477729cfSJeremy L Thompson @ref Developer
1837477729cfSJeremy L Thompson **/
CeedGetErrorMessage(Ceed ceed,const char ** err_msg)1838d1d35e2fSjeremylt int CeedGetErrorMessage(Ceed ceed, const char **err_msg) {
18392b730f8bSJeremy L Thompson if (ceed->parent) return CeedGetErrorMessage(ceed->parent, err_msg);
1840d1d35e2fSjeremylt *err_msg = ceed->err_msg;
1841e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1842477729cfSJeremy L Thompson }
1843477729cfSJeremy L Thompson
1844477729cfSJeremy L Thompson /**
1845ca94c3ddSJeremy L Thompson @brief Restore error message.
1846477729cfSJeremy L Thompson
1847ca94c3ddSJeremy L Thompson The error message is only stored when using the error handler @ref CeedErrorStore().
1848477729cfSJeremy L Thompson
1849ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to restore error message
1850d1d35e2fSjeremylt @param[out] err_msg Char pointer that holds error message
1851477729cfSJeremy L Thompson
1852ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1853ca94c3ddSJeremy L Thompson
1854477729cfSJeremy L Thompson @ref Developer
1855477729cfSJeremy L Thompson **/
CeedResetErrorMessage(Ceed ceed,const char ** err_msg)1856d1d35e2fSjeremylt int CeedResetErrorMessage(Ceed ceed, const char **err_msg) {
18572b730f8bSJeremy L Thompson if (ceed->parent) return CeedResetErrorMessage(ceed->parent, err_msg);
1858d1d35e2fSjeremylt *err_msg = NULL;
1859d1d35e2fSjeremylt memcpy(ceed->err_msg, "No error message stored", 24);
1860e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS;
1861477729cfSJeremy L Thompson }
1862477729cfSJeremy L Thompson
18631070991dSJed Brown /**
1864ca94c3ddSJeremy L Thompson @brief Get libCEED library version information.
18651070991dSJed Brown
1866ea61e9acSJeremy L Thompson libCEED version numbers have the form major.minor.patch.
1867ea61e9acSJeremy L Thompson Non-release versions may contain unstable interfaces.
18681070991dSJed Brown
18691070991dSJed Brown @param[out] major Major version of the library
18701070991dSJed Brown @param[out] minor Minor version of the library
18711070991dSJed Brown @param[out] patch Patch (subminor) version of the library
187253cbfc38SJeremy L Thompson @param[out] release True for releases; false for development branches
18731070991dSJed Brown
1874ca94c3ddSJeremy L Thompson The caller may pass `NULL` for any arguments that are not needed.
18751070991dSJed Brown
1876ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
18771070991dSJed Brown
18781070991dSJed Brown @ref Developer
1879ca94c3ddSJeremy L Thompson
18804f69910bSJed Brown @sa CEED_VERSION_GE() CeedGetGitVersion() CeedGetBuildConfiguration()
18811070991dSJed Brown */
CeedGetVersion(int * major,int * minor,int * patch,bool * release)18821070991dSJed Brown int CeedGetVersion(int *major, int *minor, int *patch, bool *release) {
18831070991dSJed Brown if (major) *major = CEED_VERSION_MAJOR;
18841070991dSJed Brown if (minor) *minor = CEED_VERSION_MINOR;
18851070991dSJed Brown if (patch) *patch = CEED_VERSION_PATCH;
18861070991dSJed Brown if (release) *release = CEED_VERSION_RELEASE;
1887ca94c3ddSJeremy L Thompson return CEED_ERROR_SUCCESS;
18881070991dSJed Brown }
18891070991dSJed Brown
189053cbfc38SJeremy L Thompson /**
189153cbfc38SJeremy L Thompson @brief Get libCEED scalar type, such as F64 or F32
189253cbfc38SJeremy L Thompson
189353cbfc38SJeremy L Thompson @param[out] scalar_type Type of libCEED scalars
189453cbfc38SJeremy L Thompson
1895ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure
1896ca94c3ddSJeremy L Thompson
189753cbfc38SJeremy L Thompson @ref Developer
189853cbfc38SJeremy L Thompson */
CeedGetScalarType(CeedScalarType * scalar_type)189980a9ef05SNatalie Beams int CeedGetScalarType(CeedScalarType *scalar_type) {
190080a9ef05SNatalie Beams *scalar_type = CEED_SCALAR_TYPE;
1901ca94c3ddSJeremy L Thompson return CEED_ERROR_SUCCESS;
190280a9ef05SNatalie Beams }
190380a9ef05SNatalie Beams
1904d7b241e6Sjeremylt /// @}
1905