15aed82e4SJeremy L Thompson // Copyright (c) 2017-2024, 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 **/ 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 **/ 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 1417a982d89SJeremy L. Thompson /// @} 142d7b241e6Sjeremylt 1437a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1447a982d89SJeremy L. Thompson /// Ceed Backend API 1457a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1467a982d89SJeremy L. Thompson /// @addtogroup CeedBackend 1477a982d89SJeremy L. Thompson /// @{ 148d7b241e6Sjeremylt 149b11c1e72Sjeremylt /** 150ca94c3ddSJeremy L Thompson @brief Return value of `CEED_DEBUG` environment variable 15160f9e2d6SJeremy L Thompson 152ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context 15360f9e2d6SJeremy L Thompson 154ca94c3ddSJeremy L Thompson @return Boolean value: true - debugging mode enabled 1553f21f6b1SJeremy L Thompson false - debugging mode disabled 15660f9e2d6SJeremy L Thompson 15760f9e2d6SJeremy L Thompson @ref Backend 15860f9e2d6SJeremy L Thompson **/ 159fc6bbcedSJeremy L Thompson // LCOV_EXCL_START 1602b730f8bSJeremy L Thompson bool CeedDebugFlag(const Ceed ceed) { return ceed->is_debug; } 161fc6bbcedSJeremy L Thompson // LCOV_EXCL_STOP 16260f9e2d6SJeremy L Thompson 16360f9e2d6SJeremy L Thompson /** 164ca94c3ddSJeremy L Thompson @brief Return value of `CEED_DEBUG` environment variable 16560f9e2d6SJeremy L Thompson 166ca94c3ddSJeremy L Thompson @return Boolean value: true - debugging mode enabled 1673f21f6b1SJeremy L Thompson false - debugging mode disabled 1683f21f6b1SJeremy L Thompson 1693f21f6b1SJeremy L Thompson @ref Backend 1703f21f6b1SJeremy L Thompson **/ 1713f21f6b1SJeremy L Thompson // LCOV_EXCL_START 1721c66c397SJeremy L Thompson bool CeedDebugFlagEnv(void) { return getenv("CEED_DEBUG") || getenv("DEBUG") || getenv("DBG"); } 1733f21f6b1SJeremy L Thompson // LCOV_EXCL_STOP 1743f21f6b1SJeremy L Thompson 1753f21f6b1SJeremy L Thompson /** 1763f21f6b1SJeremy L Thompson @brief Print debugging information in color 1773f21f6b1SJeremy L Thompson 178ca94c3ddSJeremy L Thompson @param[in] color Color to print 179ca94c3ddSJeremy L Thompson @param[in] format Printing format 18060f9e2d6SJeremy L Thompson 18160f9e2d6SJeremy L Thompson @ref Backend 18260f9e2d6SJeremy L Thompson **/ 183fc6bbcedSJeremy L Thompson // LCOV_EXCL_START 1843f21f6b1SJeremy L Thompson void CeedDebugImpl256(const unsigned char color, const char *format, ...) { 18560f9e2d6SJeremy L Thompson va_list args; 18660f9e2d6SJeremy L Thompson va_start(args, format); 18760f9e2d6SJeremy L Thompson fflush(stdout); 1882b730f8bSJeremy L Thompson if (color != CEED_DEBUG_COLOR_NONE) fprintf(stdout, "\033[38;5;%dm", color); 18960f9e2d6SJeremy L Thompson vfprintf(stdout, format, args); 1902b730f8bSJeremy L Thompson if (color != CEED_DEBUG_COLOR_NONE) fprintf(stdout, "\033[m"); 19160f9e2d6SJeremy L Thompson fprintf(stdout, "\n"); 19260f9e2d6SJeremy L Thompson fflush(stdout); 19360f9e2d6SJeremy L Thompson va_end(args); 19460f9e2d6SJeremy L Thompson } 195fc6bbcedSJeremy L Thompson // LCOV_EXCL_STOP 19660f9e2d6SJeremy L Thompson 19760f9e2d6SJeremy L Thompson /** 198ca94c3ddSJeremy L Thompson @brief Allocate an array on the host; use @ref CeedMalloc(). 199b11c1e72Sjeremylt 200ea61e9acSJeremy L Thompson Memory usage can be tracked by the library. 201ea61e9acSJeremy L Thompson This ensures sufficient alignment for vectorization and should be used for large allocations. 202b11c1e72Sjeremylt 203ea61e9acSJeremy L Thompson @param[in] n Number of units to allocate 204ea61e9acSJeremy L Thompson @param[in] unit Size of each unit 205ca94c3ddSJeremy L Thompson @param[out] p Address of pointer to hold the result 206b11c1e72Sjeremylt 207b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 208b11c1e72Sjeremylt 2097a982d89SJeremy L. Thompson @ref Backend 210ca94c3ddSJeremy L Thompson 211ca94c3ddSJeremy L Thompson @sa CeedFree() 212b11c1e72Sjeremylt **/ 213d7b241e6Sjeremylt int CeedMallocArray(size_t n, size_t unit, void *p) { 214d7b241e6Sjeremylt int ierr = posix_memalign((void **)p, CEED_ALIGN, n * unit); 2156574a04fSJeremy L Thompson CeedCheck(ierr == 0, NULL, CEED_ERROR_MAJOR, "posix_memalign failed to allocate %zd members of size %zd\n", n, unit); 216e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 217d7b241e6Sjeremylt } 218d7b241e6Sjeremylt 219b11c1e72Sjeremylt /** 220ca94c3ddSJeremy L Thompson @brief Allocate a cleared (zeroed) array on the host; use @ref CeedCalloc(). 221b11c1e72Sjeremylt 222b11c1e72Sjeremylt Memory usage can be tracked by the library. 223b11c1e72Sjeremylt 224ea61e9acSJeremy L Thompson @param[in] n Number of units to allocate 225ea61e9acSJeremy L Thompson @param[in] unit Size of each unit 226ca94c3ddSJeremy L Thompson @param[out] p Address of pointer to hold the result 227b11c1e72Sjeremylt 228b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 229b11c1e72Sjeremylt 2307a982d89SJeremy L. Thompson @ref Backend 231ca94c3ddSJeremy L Thompson 232ca94c3ddSJeremy L Thompson @sa CeedFree() 233b11c1e72Sjeremylt **/ 234d7b241e6Sjeremylt int CeedCallocArray(size_t n, size_t unit, void *p) { 235d7b241e6Sjeremylt *(void **)p = calloc(n, unit); 2366574a04fSJeremy L Thompson CeedCheck(!n || !unit || *(void **)p, NULL, CEED_ERROR_MAJOR, "calloc failed to allocate %zd members of size %zd\n", n, unit); 237e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 238d7b241e6Sjeremylt } 239d7b241e6Sjeremylt 240b11c1e72Sjeremylt /** 241ca94c3ddSJeremy L Thompson @brief Reallocate an array on the host; use @ref CeedRealloc(). 242b11c1e72Sjeremylt 243b11c1e72Sjeremylt Memory usage can be tracked by the library. 244b11c1e72Sjeremylt 245ea61e9acSJeremy L Thompson @param[in] n Number of units to allocate 246ea61e9acSJeremy L Thompson @param[in] unit Size of each unit 247ca94c3ddSJeremy L Thompson @param[out] p Address of pointer to hold the result 248b11c1e72Sjeremylt 249b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 250b11c1e72Sjeremylt 2517a982d89SJeremy L. Thompson @ref Backend 252ca94c3ddSJeremy L Thompson 253ca94c3ddSJeremy L Thompson @sa CeedFree() 254b11c1e72Sjeremylt **/ 255d7b241e6Sjeremylt int CeedReallocArray(size_t n, size_t unit, void *p) { 256d7b241e6Sjeremylt *(void **)p = realloc(*(void **)p, n * unit); 2576574a04fSJeremy L Thompson CeedCheck(!n || !unit || *(void **)p, NULL, CEED_ERROR_MAJOR, "realloc failed to allocate %zd members of size %zd\n", n, unit); 258e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 259d7b241e6Sjeremylt } 260d7b241e6Sjeremylt 261f7e22acaSJeremy L Thompson /** 262ca94c3ddSJeremy L Thompson @brief Allocate a cleared string buffer on the host. 263f7e22acaSJeremy L Thompson 264f7e22acaSJeremy L Thompson Memory usage can be tracked by the library. 265f7e22acaSJeremy L Thompson 266ea61e9acSJeremy L Thompson @param[in] source Pointer to string to be copied 267ea61e9acSJeremy L Thompson @param[out] copy Pointer to variable to hold newly allocated string copy 268f7e22acaSJeremy L Thompson 269f7e22acaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 270f7e22acaSJeremy L Thompson 271f7e22acaSJeremy L Thompson @ref Backend 272ca94c3ddSJeremy L Thompson 273ca94c3ddSJeremy L Thompson @sa CeedFree() 274f7e22acaSJeremy L Thompson **/ 275f7e22acaSJeremy L Thompson int CeedStringAllocCopy(const char *source, char **copy) { 276f7e22acaSJeremy L Thompson size_t len = strlen(source); 2772b730f8bSJeremy L Thompson CeedCall(CeedCalloc(len + 1, copy)); 278d602d780SJeremy L Thompson memcpy(*copy, source, len); 279f7e22acaSJeremy L Thompson return CEED_ERROR_SUCCESS; 280f7e22acaSJeremy L Thompson } 281f7e22acaSJeremy L Thompson 282ca94c3ddSJeremy L Thompson /** Free memory allocated using @ref CeedMalloc() or @ref CeedCalloc() 28334138859Sjeremylt 284ca94c3ddSJeremy L Thompson @param[in,out] p Address of pointer to memory. 285ca94c3ddSJeremy 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. 286ca94c3ddSJeremy L Thompson 287ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 288ca94c3ddSJeremy L Thompson 289ca94c3ddSJeremy L Thompson @ref Backend 29034138859Sjeremylt **/ 291d7b241e6Sjeremylt int CeedFree(void *p) { 292d7b241e6Sjeremylt free(*(void **)p); 293d7b241e6Sjeremylt *(void **)p = NULL; 294e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 295d7b241e6Sjeremylt } 296d7b241e6Sjeremylt 297f5d1e504SJeremy L Thompson /** Internal helper to manage handoff of user `source_array` to backend with proper @ref CeedCopyMode behavior. 298f5d1e504SJeremy L Thompson 299f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user 300f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data 301f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle 30217afdf5cSJames Wright @param[in] size_unit Size of array element in bytes 303f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated 304f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data 305f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data 306f5d1e504SJeremy L Thompson 307f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 308f5d1e504SJeremy L Thompson 309f5d1e504SJeremy L Thompson @ref Backend 310f5d1e504SJeremy L Thompson **/ 311f5d1e504SJeremy L Thompson static inline int CeedSetHostGenericArray(const void *source_array, CeedCopyMode copy_mode, size_t size_unit, CeedSize num_values, 312f5d1e504SJeremy L Thompson void *target_array_owned, void *target_array_borrowed, void *target_array) { 313f5d1e504SJeremy L Thompson switch (copy_mode) { 314f5d1e504SJeremy L Thompson case CEED_COPY_VALUES: 315f5d1e504SJeremy L Thompson if (!*(void **)target_array_owned) CeedCall(CeedCallocArray(num_values, size_unit, target_array_owned)); 316f5d1e504SJeremy L Thompson if (source_array) memcpy(*(void **)target_array_owned, source_array, size_unit * num_values); 317f5d1e504SJeremy L Thompson *(void **)target_array_borrowed = NULL; 318f5d1e504SJeremy L Thompson *(void **)target_array = *(void **)target_array_owned; 319f5d1e504SJeremy L Thompson break; 320f5d1e504SJeremy L Thompson case CEED_OWN_POINTER: 321f5d1e504SJeremy L Thompson CeedCall(CeedFree(target_array_owned)); 322f5d1e504SJeremy L Thompson *(void **)target_array_owned = (void *)source_array; 323f5d1e504SJeremy L Thompson *(void **)target_array_borrowed = NULL; 324f5d1e504SJeremy L Thompson *(void **)target_array = *(void **)target_array_owned; 325f5d1e504SJeremy L Thompson break; 326f5d1e504SJeremy L Thompson case CEED_USE_POINTER: 327f5d1e504SJeremy L Thompson CeedCall(CeedFree(target_array_owned)); 328f5d1e504SJeremy L Thompson *(void **)target_array_owned = NULL; 329f5d1e504SJeremy L Thompson *(void **)target_array_borrowed = (void *)source_array; 330f5d1e504SJeremy L Thompson *(void **)target_array = *(void **)target_array_borrowed; 331f5d1e504SJeremy L Thompson } 332f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS; 333f5d1e504SJeremy L Thompson } 334f5d1e504SJeremy L Thompson 335f5d1e504SJeremy L Thompson /** Manage handoff of user `bool` `source_array` to backend with proper @ref CeedCopyMode behavior. 336f5d1e504SJeremy L Thompson 337f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user 338f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data 339f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle 340f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated 341f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data 342f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data 343f5d1e504SJeremy L Thompson 344f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 345f5d1e504SJeremy L Thompson 346f5d1e504SJeremy L Thompson @ref Backend 347f5d1e504SJeremy L Thompson **/ 348f5d1e504SJeremy L Thompson int CeedSetHostBoolArray(const bool *source_array, CeedCopyMode copy_mode, CeedSize num_values, const bool **target_array_owned, 349f5d1e504SJeremy L Thompson const bool **target_array_borrowed, const bool **target_array) { 350f5d1e504SJeremy L Thompson CeedCall(CeedSetHostGenericArray(source_array, copy_mode, sizeof(bool), num_values, target_array_owned, target_array_borrowed, target_array)); 351f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS; 352f5d1e504SJeremy L Thompson } 353f5d1e504SJeremy L Thompson 354f5d1e504SJeremy L Thompson /** Manage handoff of user `CeedInt8` `source_array` to backend with proper @ref CeedCopyMode behavior. 355f5d1e504SJeremy L Thompson 356f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user 357f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data 358f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle 359f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated 360f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data 361f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data 362f5d1e504SJeremy L Thompson 363f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 364f5d1e504SJeremy L Thompson 365f5d1e504SJeremy L Thompson @ref Backend 366f5d1e504SJeremy L Thompson **/ 367f5d1e504SJeremy L Thompson int CeedSetHostCeedInt8Array(const CeedInt8 *source_array, CeedCopyMode copy_mode, CeedSize num_values, const CeedInt8 **target_array_owned, 368f5d1e504SJeremy L Thompson const CeedInt8 **target_array_borrowed, const CeedInt8 **target_array) { 369f5d1e504SJeremy L Thompson CeedCall(CeedSetHostGenericArray(source_array, copy_mode, sizeof(CeedInt8), num_values, target_array_owned, target_array_borrowed, target_array)); 370f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS; 371f5d1e504SJeremy L Thompson } 372f5d1e504SJeremy L Thompson 373f5d1e504SJeremy L Thompson /** Manage handoff of user `CeedInt` `source_array` to backend with proper @ref CeedCopyMode behavior. 374f5d1e504SJeremy L Thompson 375f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user 376f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data 377f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle 378f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated 379f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data 380f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data 381f5d1e504SJeremy L Thompson 382f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 383f5d1e504SJeremy L Thompson 384f5d1e504SJeremy L Thompson @ref Backend 385f5d1e504SJeremy L Thompson **/ 386f5d1e504SJeremy L Thompson int CeedSetHostCeedIntArray(const CeedInt *source_array, CeedCopyMode copy_mode, CeedSize num_values, const CeedInt **target_array_owned, 387f5d1e504SJeremy L Thompson const CeedInt **target_array_borrowed, const CeedInt **target_array) { 388f5d1e504SJeremy L Thompson CeedCall(CeedSetHostGenericArray(source_array, copy_mode, sizeof(CeedInt), num_values, target_array_owned, target_array_borrowed, target_array)); 389f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS; 390f5d1e504SJeremy L Thompson } 391f5d1e504SJeremy L Thompson 392f5d1e504SJeremy L Thompson /** Manage handoff of user `CeedScalar` `source_array` to backend with proper @ref CeedCopyMode behavior. 393f5d1e504SJeremy L Thompson 394f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user 395f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data 396f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle 397f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated 398f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data 399f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data 400f5d1e504SJeremy L Thompson 401f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 402f5d1e504SJeremy L Thompson 403f5d1e504SJeremy L Thompson @ref Backend 404f5d1e504SJeremy L Thompson **/ 405f5d1e504SJeremy L Thompson int CeedSetHostCeedScalarArray(const CeedScalar *source_array, CeedCopyMode copy_mode, CeedSize num_values, const CeedScalar **target_array_owned, 406f5d1e504SJeremy L Thompson const CeedScalar **target_array_borrowed, const CeedScalar **target_array) { 407f5d1e504SJeremy L Thompson CeedCall(CeedSetHostGenericArray(source_array, copy_mode, sizeof(CeedScalar), num_values, target_array_owned, target_array_borrowed, target_array)); 408f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS; 409f5d1e504SJeremy L Thompson } 410f5d1e504SJeremy L Thompson 411d7b241e6Sjeremylt /** 412ca94c3ddSJeremy L Thompson @brief Register a `Ceed` backend 413d7b241e6Sjeremylt 414ea61e9acSJeremy L Thompson @param[in] prefix Prefix of resources for this backend to respond to. 415ea61e9acSJeremy L Thompson For example, the reference backend responds to "/cpu/self". 416ca94c3ddSJeremy L Thompson @param[in] init Initialization function called by @ref CeedInit() when the backend is selected to drive the requested resource 417ea61e9acSJeremy L Thompson @param[in] priority Integer priority. 418ca94c3ddSJeremy L Thompson Lower values are preferred in case the resource requested by @ref CeedInit() has non-unique best prefix match. 419b11c1e72Sjeremylt 420b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 421dfdf5a53Sjeremylt 4227a982d89SJeremy L. Thompson @ref Backend 423b11c1e72Sjeremylt **/ 4242b730f8bSJeremy L Thompson int CeedRegister(const char *prefix, int (*init)(const char *, Ceed), unsigned int priority) { 42510243053SJeremy L Thompson CeedDebugEnv("Backend Register: %s", prefix); 4266a406739SJeremy L Thompson CeedRegisterImpl(prefix, init, priority); 427e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 428d7b241e6Sjeremylt } 429d7b241e6Sjeremylt 430b11c1e72Sjeremylt /** 43160f9e2d6SJeremy L Thompson @brief Return debugging status flag 43260f9e2d6SJeremy L Thompson 433ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to get debugging flag 434ea61e9acSJeremy L Thompson @param[out] is_debug Variable to store debugging flag 43560f9e2d6SJeremy L Thompson 43660f9e2d6SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 43760f9e2d6SJeremy L Thompson 438d1d35e2fSjeremylt @ref Backend 43960f9e2d6SJeremy L Thompson **/ 440d1d35e2fSjeremylt int CeedIsDebug(Ceed ceed, bool *is_debug) { 4413f21f6b1SJeremy L Thompson *is_debug = ceed->is_debug; 442e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 44360f9e2d6SJeremy L Thompson } 44460f9e2d6SJeremy L Thompson 44560f9e2d6SJeremy L Thompson /** 446*bf84744cSJeremy L Thompson @brief Get the root of the requested resource. 447*bf84744cSJeremy L Thompson 448*bf84744cSJeremy L Thompson Note: Caller is responsible for calling @ref CeedFree() on the `resource_root`. 449bc246734SJeremy L Thompson 450ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to get resource name of 451ca94c3ddSJeremy L Thompson @param[in] resource Full user specified resource 452ca94c3ddSJeremy L Thompson @param[in] delineator Delineator to break `resource_root` and `resource_spec` 453bc246734SJeremy L Thompson @param[out] resource_root Variable to store resource root 454bc246734SJeremy L Thompson 455bc246734SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 456bc246734SJeremy L Thompson 457bc246734SJeremy L Thompson @ref Backend 458bc246734SJeremy L Thompson **/ 459bc246734SJeremy L Thompson int CeedGetResourceRoot(Ceed ceed, const char *resource, const char *delineator, char **resource_root) { 460bc246734SJeremy L Thompson char *device_spec = strstr(resource, delineator); 461bc246734SJeremy L Thompson size_t resource_root_len = device_spec ? (size_t)(device_spec - resource) + 1 : strlen(resource) + 1; 4621c66c397SJeremy L Thompson 463bc246734SJeremy L Thompson CeedCall(CeedCalloc(resource_root_len, resource_root)); 464bc246734SJeremy L Thompson memcpy(*resource_root, resource, resource_root_len - 1); 465bc246734SJeremy L Thompson return CEED_ERROR_SUCCESS; 466bc246734SJeremy L Thompson } 467bc246734SJeremy L Thompson 468bc246734SJeremy L Thompson /** 469ca94c3ddSJeremy L Thompson @brief Retrieve a parent `Ceed` context 4707a982d89SJeremy L. Thompson 471ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve parent of 4727a982d89SJeremy L. Thompson @param[out] parent Address to save the parent to 4737a982d89SJeremy L. Thompson 4747a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4757a982d89SJeremy L. Thompson 4767a982d89SJeremy L. Thompson @ref Backend 4777a982d89SJeremy L. Thompson **/ 4787a982d89SJeremy L. Thompson int CeedGetParent(Ceed ceed, Ceed *parent) { 4797a982d89SJeremy L. Thompson if (ceed->parent) { 4802b730f8bSJeremy L Thompson CeedCall(CeedGetParent(ceed->parent, parent)); 481e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4827a982d89SJeremy L. Thompson } 4837a982d89SJeremy L. Thompson *parent = ceed; 484e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 4857a982d89SJeremy L. Thompson } 4867a982d89SJeremy L. Thompson 4877a982d89SJeremy L. Thompson /** 488ca94c3ddSJeremy L Thompson @brief Retrieve a delegate `Ceed` context 4897a982d89SJeremy L. Thompson 490ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve delegate of 4917a982d89SJeremy L. Thompson @param[out] delegate Address to save the delegate to 4927a982d89SJeremy L. Thompson 4937a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 4947a982d89SJeremy L. Thompson 4957a982d89SJeremy L. Thompson @ref Backend 4967a982d89SJeremy L. Thompson **/ 4977a982d89SJeremy L. Thompson int CeedGetDelegate(Ceed ceed, Ceed *delegate) { 4987a982d89SJeremy L. Thompson *delegate = ceed->delegate; 499e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5007a982d89SJeremy L. Thompson } 5017a982d89SJeremy L. Thompson 5027a982d89SJeremy L. Thompson /** 503ca94c3ddSJeremy L Thompson @brief Set a delegate `Ceed` context 5047a982d89SJeremy L. Thompson 505ca94c3ddSJeremy L Thompson This function allows a `Ceed` context to set a delegate `Ceed` context. 506ca94c3ddSJeremy L Thompson All backend implementations default to the delegate `Ceed` context, unless overridden. 5077a982d89SJeremy L. Thompson 508ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to set delegate of 5097a982d89SJeremy L. Thompson @param[out] delegate Address to set the delegate to 5107a982d89SJeremy L. Thompson 5117a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5127a982d89SJeremy L. Thompson 5137a982d89SJeremy L. Thompson @ref Backend 5147a982d89SJeremy L. Thompson **/ 5157a982d89SJeremy L. Thompson int CeedSetDelegate(Ceed ceed, Ceed delegate) { 5167a982d89SJeremy L. Thompson ceed->delegate = delegate; 5177a982d89SJeremy L. Thompson delegate->parent = ceed; 518e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5197a982d89SJeremy L. Thompson } 5207a982d89SJeremy L. Thompson 5217a982d89SJeremy L. Thompson /** 522ca94c3ddSJeremy L Thompson @brief Retrieve a delegate `Ceed` context for a specific object type 5237a982d89SJeremy L. Thompson 524ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve delegate of 5257a982d89SJeremy L. Thompson @param[out] delegate Address to save the delegate to 526d1d35e2fSjeremylt @param[in] obj_name Name of the object type to retrieve delegate for 5277a982d89SJeremy L. Thompson 5287a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5297a982d89SJeremy L. Thompson 5307a982d89SJeremy L. Thompson @ref Backend 5317a982d89SJeremy L. Thompson **/ 532d1d35e2fSjeremylt int CeedGetObjectDelegate(Ceed ceed, Ceed *delegate, const char *obj_name) { 5337a982d89SJeremy L. Thompson // Check for object delegate 5342b730f8bSJeremy L Thompson for (CeedInt i = 0; i < ceed->obj_delegate_count; i++) { 535d1d35e2fSjeremylt if (!strcmp(obj_name, ceed->obj_delegates->obj_name)) { 536d1d35e2fSjeremylt *delegate = ceed->obj_delegates->delegate; 537e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5387a982d89SJeremy L. Thompson } 5392b730f8bSJeremy L Thompson } 5407a982d89SJeremy L. Thompson 5417a982d89SJeremy L. Thompson // Use default delegate if no object delegate 5422b730f8bSJeremy L Thompson CeedCall(CeedGetDelegate(ceed, delegate)); 543e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5447a982d89SJeremy L. Thompson } 5457a982d89SJeremy L. Thompson 5467a982d89SJeremy L. Thompson /** 547ca94c3ddSJeremy L Thompson @brief Set a delegate `Ceed` context for a specific object type 5487a982d89SJeremy L. Thompson 549ca94c3ddSJeremy L Thompson This function allows a `Ceed` context to set a delegate `Ceed` context for a given type of `Ceed` object. 550ca94c3ddSJeremy L Thompson All backend implementations default to the delegate `Ceed` context for this object. 551ca94c3ddSJeremy L Thompson For example, `CeedSetObjectDelegate(ceed, delegate, "Basis")` uses delegate implementations for all `CeedBasis` backend functions. 5527a982d89SJeremy L. Thompson 553ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context to set delegate of 554ca94c3ddSJeremy L Thompson @param[in] delegate `Ceed` context to use for delegation 555d1d35e2fSjeremylt @param[in] obj_name Name of the object type to set delegate for 5567a982d89SJeremy L. Thompson 5577a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5587a982d89SJeremy L. Thompson 5597a982d89SJeremy L. Thompson @ref Backend 5607a982d89SJeremy L. Thompson **/ 561d1d35e2fSjeremylt int CeedSetObjectDelegate(Ceed ceed, Ceed delegate, const char *obj_name) { 562d1d35e2fSjeremylt CeedInt count = ceed->obj_delegate_count; 5637a982d89SJeremy L. Thompson 5647a982d89SJeremy L. Thompson // Malloc or Realloc 5657a982d89SJeremy L. Thompson if (count) { 5662b730f8bSJeremy L Thompson CeedCall(CeedRealloc(count + 1, &ceed->obj_delegates)); 5677a982d89SJeremy L. Thompson } else { 5682b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &ceed->obj_delegates)); 5697a982d89SJeremy L. Thompson } 570d1d35e2fSjeremylt ceed->obj_delegate_count++; 5717a982d89SJeremy L. Thompson 5727a982d89SJeremy L. Thompson // Set object delegate 573d1d35e2fSjeremylt ceed->obj_delegates[count].delegate = delegate; 5742b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(obj_name, &ceed->obj_delegates[count].obj_name)); 5757a982d89SJeremy L. Thompson 5767a982d89SJeremy L. Thompson // Set delegate parent 5777a982d89SJeremy L. Thompson delegate->parent = ceed; 578e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5797a982d89SJeremy L. Thompson } 5807a982d89SJeremy L. Thompson 5817a982d89SJeremy L. Thompson /** 582ca94c3ddSJeremy L Thompson @brief Get the fallback resource for `CeedOperator` 5837a982d89SJeremy L. Thompson 584ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context 5857a982d89SJeremy L. Thompson @param[out] resource Variable to store fallback resource 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 **/ 591363aefefSSebastian Grimberg int CeedGetOperatorFallbackResource(Ceed ceed, const char **resource) { 592d1d35e2fSjeremylt *resource = (const char *)ceed->op_fallback_resource; 593e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5947a982d89SJeremy L. Thompson } 5957a982d89SJeremy L. Thompson 5967a982d89SJeremy L. Thompson /** 597ca94c3ddSJeremy L Thompson @brief Get the fallback `Ceed` for `CeedOperator` 5988687e1d4SJeremy L Thompson 599ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context 600ca94c3ddSJeremy L Thompson @param[out] fallback_ceed Variable to store fallback `Ceed` 6018687e1d4SJeremy L Thompson 6028687e1d4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 6038687e1d4SJeremy L Thompson 6048687e1d4SJeremy L Thompson @ref Backend 6058687e1d4SJeremy L Thompson **/ 6068687e1d4SJeremy L Thompson int CeedGetOperatorFallbackCeed(Ceed ceed, Ceed *fallback_ceed) { 607d04bbc78SJeremy L Thompson if (ceed->has_valid_op_fallback_resource) { 60823d4529eSJeremy L Thompson CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "---------- CeedOperator Fallback ----------\n"); 6092b730f8bSJeremy L Thompson CeedDebug(ceed, "Getting fallback from %s to %s\n", ceed->resource, ceed->op_fallback_resource); 610d04bbc78SJeremy L Thompson } 6118687e1d4SJeremy L Thompson 612d04bbc78SJeremy L Thompson // Create fallback Ceed if uninitalized 613d04bbc78SJeremy L Thompson if (!ceed->op_fallback_ceed && ceed->has_valid_op_fallback_resource) { 61413f886e9SJeremy L Thompson CeedDebug(ceed, "Creating fallback Ceed"); 615d04bbc78SJeremy L Thompson 6168687e1d4SJeremy L Thompson Ceed fallback_ceed; 617d04bbc78SJeremy L Thompson const char *fallback_resource; 618d04bbc78SJeremy L Thompson 619363aefefSSebastian Grimberg CeedCall(CeedGetOperatorFallbackResource(ceed, &fallback_resource)); 6202b730f8bSJeremy L Thompson CeedCall(CeedInit(fallback_resource, &fallback_ceed)); 6218687e1d4SJeremy L Thompson fallback_ceed->op_fallback_parent = ceed; 6228687e1d4SJeremy L Thompson fallback_ceed->Error = ceed->Error; 6238687e1d4SJeremy L Thompson ceed->op_fallback_ceed = fallback_ceed; 6248687e1d4SJeremy L Thompson } 6258687e1d4SJeremy L Thompson *fallback_ceed = ceed->op_fallback_ceed; 6268687e1d4SJeremy L Thompson return CEED_ERROR_SUCCESS; 6278687e1d4SJeremy L Thompson } 6288687e1d4SJeremy L Thompson 6298687e1d4SJeremy L Thompson /** 630ca94c3ddSJeremy L Thompson @brief Set the fallback resource for `CeedOperator`. 6314385fb7fSSebastian Grimberg 632ea61e9acSJeremy L Thompson The current resource, if any, is freed by calling this function. 633ca94c3ddSJeremy L Thompson This string is freed upon the destruction of the `Ceed` context. 6347a982d89SJeremy L. Thompson 635ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context 636ea61e9acSJeremy L Thompson @param[in] resource Fallback resource to set 6377a982d89SJeremy L. Thompson 6387a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6397a982d89SJeremy L. Thompson 6407a982d89SJeremy L. Thompson @ref Backend 6417a982d89SJeremy L. Thompson **/ 6427a982d89SJeremy L. Thompson int CeedSetOperatorFallbackResource(Ceed ceed, const char *resource) { 6437a982d89SJeremy L. Thompson // Free old 6442b730f8bSJeremy L Thompson CeedCall(CeedFree(&ceed->op_fallback_resource)); 6457a982d89SJeremy L. Thompson 6467a982d89SJeremy L. Thompson // Set new 6472b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(resource, (char **)&ceed->op_fallback_resource)); 648d04bbc78SJeremy L Thompson 649d04bbc78SJeremy L Thompson // Check validity 6502b730f8bSJeremy L Thompson ceed->has_valid_op_fallback_resource = ceed->op_fallback_resource && ceed->resource && strcmp(ceed->op_fallback_resource, ceed->resource); 651e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6527a982d89SJeremy L. Thompson } 6537a982d89SJeremy L. Thompson 6547a982d89SJeremy L. Thompson /** 655ca94c3ddSJeremy L Thompson @brief Flag `Ceed` context as deterministic 6569525855cSJeremy L Thompson 657ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` to flag as deterministic 65896b902e2Sjeremylt @param[out] is_deterministic Deterministic status to set 6599525855cSJeremy L Thompson 6609525855cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 6619525855cSJeremy L Thompson 6629525855cSJeremy L Thompson @ref Backend 6639525855cSJeremy L Thompson **/ 664d1d35e2fSjeremylt int CeedSetDeterministic(Ceed ceed, bool is_deterministic) { 665d1d35e2fSjeremylt ceed->is_deterministic = is_deterministic; 666e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6679525855cSJeremy L Thompson } 6689525855cSJeremy L Thompson 6699525855cSJeremy L Thompson /** 670ca94c3ddSJeremy L Thompson @brief Set a backend function. 6717a982d89SJeremy L. Thompson 672ea61e9acSJeremy L Thompson This function is used for a backend to set the function associated with the Ceed objects. 673ca94c3ddSJeremy 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(). 6749fd66db6SSebastian Grimberg Note, the prefix 'Ceed' is not required for the object type ("Basis" vs "CeedBasis"). 6757a982d89SJeremy L. Thompson 676ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context for error handling 677ea61e9acSJeremy L Thompson @param[in] type Type of Ceed object to set function for 6787a982d89SJeremy L. Thompson @param[out] object Ceed object to set function for 679ea61e9acSJeremy L Thompson @param[in] func_name Name of function to set 680ea61e9acSJeremy L Thompson @param[in] f Function to set 6817a982d89SJeremy L. Thompson 6827a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6837a982d89SJeremy L. Thompson 6847a982d89SJeremy L. Thompson @ref Backend 6857a982d89SJeremy L. Thompson **/ 686897d4737SSebastian Grimberg int CeedSetBackendFunctionImpl(Ceed ceed, const char *type, void *object, const char *func_name, void (*f)(void)) { 687d1d35e2fSjeremylt char lookup_name[CEED_MAX_RESOURCE_LEN + 1] = ""; 6887a982d89SJeremy L. Thompson 6897a982d89SJeremy L. Thompson // Build lookup name 6902b730f8bSJeremy L Thompson if (strcmp(type, "Ceed")) strncat(lookup_name, "Ceed", CEED_MAX_RESOURCE_LEN); 691d1d35e2fSjeremylt strncat(lookup_name, type, CEED_MAX_RESOURCE_LEN); 692d1d35e2fSjeremylt strncat(lookup_name, func_name, CEED_MAX_RESOURCE_LEN); 6937a982d89SJeremy L. Thompson 6947a982d89SJeremy L. Thompson // Find and use offset 6952b730f8bSJeremy L Thompson for (CeedInt i = 0; ceed->f_offsets[i].func_name; i++) { 696d1d35e2fSjeremylt if (!strcmp(ceed->f_offsets[i].func_name, lookup_name)) { 697d1d35e2fSjeremylt size_t offset = ceed->f_offsets[i].offset; 6987a982d89SJeremy L. Thompson int (**fpointer)(void) = (int (**)(void))((char *)object + offset); // *NOPAD* 6991c66c397SJeremy L Thompson 700897d4737SSebastian Grimberg *fpointer = (int (*)(void))f; 701e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7027a982d89SJeremy L. Thompson } 7032b730f8bSJeremy L Thompson } 7047a982d89SJeremy L. Thompson 7057a982d89SJeremy L. Thompson // LCOV_EXCL_START 7062b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Requested function '%s' was not found for CEED object '%s'", func_name, type); 7077a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 7087a982d89SJeremy L. Thompson } 7097a982d89SJeremy L. Thompson 7107a982d89SJeremy L. Thompson /** 711ca94c3ddSJeremy L Thompson @brief Retrieve backend data for a `Ceed` context 7127a982d89SJeremy L. Thompson 713ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve data of 7147a982d89SJeremy L. Thompson @param[out] data Address to save data to 7157a982d89SJeremy L. Thompson 7167a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 7177a982d89SJeremy L. Thompson 7187a982d89SJeremy L. Thompson @ref Backend 7197a982d89SJeremy L. Thompson **/ 720777ff853SJeremy L Thompson int CeedGetData(Ceed ceed, void *data) { 721777ff853SJeremy L Thompson *(void **)data = ceed->data; 722e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7237a982d89SJeremy L. Thompson } 7247a982d89SJeremy L. Thompson 7257a982d89SJeremy L. Thompson /** 726ca94c3ddSJeremy L Thompson @brief Set backend data for a `Ceed` context 7277a982d89SJeremy L. Thompson 728ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context to set data of 729ea61e9acSJeremy L Thompson @param[in] data Address of data to set 7307a982d89SJeremy L. Thompson 7317a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 7327a982d89SJeremy L. Thompson 7337a982d89SJeremy L. Thompson @ref Backend 7347a982d89SJeremy L. Thompson **/ 735777ff853SJeremy L Thompson int CeedSetData(Ceed ceed, void *data) { 736777ff853SJeremy L Thompson ceed->data = data; 737e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7387a982d89SJeremy L. Thompson } 7397a982d89SJeremy L. Thompson 74034359f16Sjeremylt /** 741ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `Ceed` context 74234359f16Sjeremylt 743ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context to increment the reference counter 74434359f16Sjeremylt 74534359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 74634359f16Sjeremylt 74734359f16Sjeremylt @ref Backend 74834359f16Sjeremylt **/ 7499560d06aSjeremylt int CeedReference(Ceed ceed) { 75034359f16Sjeremylt ceed->ref_count++; 75134359f16Sjeremylt return CEED_ERROR_SUCCESS; 75234359f16Sjeremylt } 75334359f16Sjeremylt 7547a982d89SJeremy L. Thompson /// @} 7557a982d89SJeremy L. Thompson 7567a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 7577a982d89SJeremy L. Thompson /// Ceed Public API 7587a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 7597a982d89SJeremy L. Thompson /// @addtogroup CeedUser 7607a982d89SJeremy L. Thompson /// @{ 7617a982d89SJeremy L. Thompson 7627a982d89SJeremy L. Thompson /** 763ca94c3ddSJeremy L Thompson @brief Get the list of available resource names for `Ceed` contexts 7644385fb7fSSebastian Grimberg 765ca94c3ddSJeremy 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. 76622e44211Sjeremylt 76792ee7d1cSjeremylt @param[out] n Number of available resources 76892ee7d1cSjeremylt @param[out] resources List of available resource names 76922e44211Sjeremylt @param[out] priorities Resource name prioritization values, lower is better 77022e44211Sjeremylt 77122e44211Sjeremylt @return An error code: 0 - success, otherwise - failure 77222e44211Sjeremylt 77322e44211Sjeremylt @ref User 77422e44211Sjeremylt **/ 77522e44211Sjeremylt // LCOV_EXCL_START 7762b730f8bSJeremy L Thompson int CeedRegistryGetList(size_t *n, char ***const resources, CeedInt **priorities) { 777d0c91ce9Sjeremylt *n = 0; 7789ff86846Sjeremylt *resources = malloc(num_backends * sizeof(**resources)); 7796574a04fSJeremy L Thompson CeedCheck(resources, NULL, CEED_ERROR_MAJOR, "malloc() failure"); 7809ff86846Sjeremylt if (priorities) { 7819ff86846Sjeremylt *priorities = malloc(num_backends * sizeof(**priorities)); 7826574a04fSJeremy L Thompson CeedCheck(priorities, NULL, CEED_ERROR_MAJOR, "malloc() failure"); 7839ff86846Sjeremylt } 78422e44211Sjeremylt for (size_t i = 0; i < num_backends; i++) { 785d0c91ce9Sjeremylt // Only report compiled backends 786d0c91ce9Sjeremylt if (backends[i].priority < CEED_MAX_BACKEND_PRIORITY) { 78722e44211Sjeremylt *resources[i] = backends[i].prefix; 7889ff86846Sjeremylt if (priorities) *priorities[i] = backends[i].priority; 789d0c91ce9Sjeremylt *n += 1; 790d0c91ce9Sjeremylt } 791d0c91ce9Sjeremylt } 7926574a04fSJeremy L Thompson CeedCheck(*n, NULL, CEED_ERROR_MAJOR, "No backends installed"); 793d0c91ce9Sjeremylt *resources = realloc(*resources, *n * sizeof(**resources)); 7946574a04fSJeremy L Thompson CeedCheck(resources, NULL, CEED_ERROR_MAJOR, "realloc() failure"); 795d0c91ce9Sjeremylt if (priorities) { 796d0c91ce9Sjeremylt *priorities = realloc(*priorities, *n * sizeof(**priorities)); 7976574a04fSJeremy L Thompson CeedCheck(priorities, NULL, CEED_ERROR_MAJOR, "realloc() failure"); 79822e44211Sjeremylt } 79922e44211Sjeremylt return CEED_ERROR_SUCCESS; 80045f1e315Sjeremylt } 80122e44211Sjeremylt // LCOV_EXCL_STOP 80222e44211Sjeremylt 80322e44211Sjeremylt /** 804ca94c3ddSJeremy L Thompson @brief Initialize a `Ceed` context to use the specified resource. 8054385fb7fSSebastian Grimberg 806ca94c3ddSJeremy 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`. 807b11c1e72Sjeremylt 808ea61e9acSJeremy L Thompson @param[in] resource Resource to use, e.g., "/cpu/self" 809ea61e9acSJeremy L Thompson @param[out] ceed The library context 810b11c1e72Sjeremylt 811b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 812dfdf5a53Sjeremylt 8137a982d89SJeremy L. Thompson @ref User 814ca94c3ddSJeremy L Thompson 815ca94c3ddSJeremy L Thompson @sa CeedRegister() CeedDestroy() 816b11c1e72Sjeremylt **/ 817d7b241e6Sjeremylt int CeedInit(const char *resource, Ceed *ceed) { 8182b730f8bSJeremy L Thompson size_t match_len = 0, match_index = UINT_MAX, match_priority = CEED_MAX_BACKEND_PRIORITY, priority; 819d7b241e6Sjeremylt 820fe2413ffSjeremylt // Find matching backend 8216574a04fSJeremy L Thompson CeedCheck(resource, NULL, CEED_ERROR_MAJOR, "No resource provided"); 8222b730f8bSJeremy L Thompson CeedCall(CeedRegisterAll()); 82313873f79Sjeremylt 82422e44211Sjeremylt // Check for help request 82522e44211Sjeremylt const char *help_prefix = "help"; 8262b730f8bSJeremy L Thompson size_t match_help = 0; 8272b730f8bSJeremy L Thompson while (match_help < 4 && resource[match_help] == help_prefix[match_help]) match_help++; 82822e44211Sjeremylt if (match_help == 4) { 8292b730f8bSJeremy L Thompson fprintf(stderr, "libCEED version: %d.%d%d%s\n", CEED_VERSION_MAJOR, CEED_VERSION_MINOR, CEED_VERSION_PATCH, 83022e44211Sjeremylt CEED_VERSION_RELEASE ? "" : "+development"); 83192ee7d1cSjeremylt fprintf(stderr, "Available backend resources:\n"); 83222e44211Sjeremylt for (size_t i = 0; i < num_backends; i++) { 833d0c91ce9Sjeremylt // Only report compiled backends 8342b730f8bSJeremy L Thompson if (backends[i].priority < CEED_MAX_BACKEND_PRIORITY) fprintf(stderr, " %s\n", backends[i].prefix); 83522e44211Sjeremylt } 83622e44211Sjeremylt fflush(stderr); 83722e44211Sjeremylt match_help = 5; // Delineating character expected 83822e44211Sjeremylt } else { 83922e44211Sjeremylt match_help = 0; 84022e44211Sjeremylt } 84122e44211Sjeremylt 842ea61e9acSJeremy L Thompson // Find best match, computed as number of matching characters from requested resource stem 8432b730f8bSJeremy L Thompson size_t stem_length = 0; 8442b730f8bSJeremy L Thompson while (resource[stem_length + match_help] && resource[stem_length + match_help] != ':') stem_length++; 845d7b241e6Sjeremylt for (size_t i = 0; i < num_backends; i++) { 8462b730f8bSJeremy L Thompson size_t n = 0; 847d7b241e6Sjeremylt const char *prefix = backends[i].prefix; 8482b730f8bSJeremy L Thompson while (prefix[n] && prefix[n] == resource[n + match_help]) n++; 849d7b241e6Sjeremylt priority = backends[i].priority; 850d1d35e2fSjeremylt if (n > match_len || (n == match_len && match_priority > priority)) { 851d1d35e2fSjeremylt match_len = n; 852d1d35e2fSjeremylt match_priority = priority; 853f7e22acaSJeremy L Thompson match_index = i; 854d7b241e6Sjeremylt } 855d7b241e6Sjeremylt } 8569c9a0587SLeila Ghaffari // Using Levenshtein distance to find closest match 8579c9a0587SLeila Ghaffari if (match_len <= 1 || match_len != stem_length) { 858203015caSLeila Ghaffari // LCOV_EXCL_START 8599c9a0587SLeila Ghaffari size_t lev_dis = UINT_MAX; 860f7e22acaSJeremy L Thompson size_t lev_index = UINT_MAX, lev_priority = CEED_MAX_BACKEND_PRIORITY; 8619c9a0587SLeila Ghaffari for (size_t i = 0; i < num_backends; i++) { 8629c9a0587SLeila Ghaffari const char *prefix = backends[i].prefix; 8639c9a0587SLeila Ghaffari size_t prefix_length = strlen(backends[i].prefix); 8649c9a0587SLeila Ghaffari size_t min_len = (prefix_length < stem_length) ? prefix_length : stem_length; 865092904ddSLeila Ghaffari size_t column[min_len + 1]; 866092904ddSLeila Ghaffari for (size_t j = 0; j <= min_len; j++) column[j] = j; 8679c9a0587SLeila Ghaffari for (size_t j = 1; j <= min_len; j++) { 8689c9a0587SLeila Ghaffari column[0] = j; 8699c9a0587SLeila Ghaffari for (size_t k = 1, last_diag = j - 1; k <= min_len; k++) { 870092904ddSLeila Ghaffari size_t old_diag = column[k]; 8719c9a0587SLeila Ghaffari size_t min_1 = (column[k] < column[k - 1]) ? column[k] + 1 : column[k - 1] + 1; 8729c9a0587SLeila Ghaffari size_t min_2 = last_diag + (resource[k - 1] == prefix[j - 1] ? 0 : 1); 8739c9a0587SLeila Ghaffari column[k] = (min_1 < min_2) ? min_1 : min_2; 8749c9a0587SLeila Ghaffari last_diag = old_diag; 8759c9a0587SLeila Ghaffari } 8769c9a0587SLeila Ghaffari } 8779c9a0587SLeila Ghaffari size_t n = column[min_len]; 8789c9a0587SLeila Ghaffari priority = backends[i].priority; 8792b730f8bSJeremy L Thompson if (n < lev_dis || (n == lev_dis && lev_priority > priority)) { 8809c9a0587SLeila Ghaffari lev_dis = n; 8819c9a0587SLeila Ghaffari lev_priority = priority; 882f7e22acaSJeremy L Thompson lev_index = i; 8839c9a0587SLeila Ghaffari } 8849c9a0587SLeila Ghaffari } 885f7e22acaSJeremy L Thompson const char *prefix_lev = backends[lev_index].prefix; 8862b730f8bSJeremy L Thompson size_t lev_length = 0; 8872b730f8bSJeremy L Thompson while (prefix_lev[lev_length] && prefix_lev[lev_length] != '\0') lev_length++; 8889c9a0587SLeila Ghaffari size_t m = (lev_length < stem_length) ? lev_length : stem_length; 8896574a04fSJeremy L Thompson if (lev_dis + 1 >= m) return CeedError(NULL, CEED_ERROR_MAJOR, "No suitable backend: %s", resource); 8906574a04fSJeremy L Thompson else return CeedError(NULL, CEED_ERROR_MAJOR, "No suitable backend: %s\nClosest match: %s", resource, backends[lev_index].prefix); 891203015caSLeila Ghaffari // LCOV_EXCL_STOP 8929c9a0587SLeila Ghaffari } 893fe2413ffSjeremylt 894fe2413ffSjeremylt // Setup Ceed 8952b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, ceed)); 8962b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &(*ceed)->jit_source_roots)); 897bc81ce41Sjeremylt const char *ceed_error_handler = getenv("CEED_ERROR_HANDLER"); 8982b730f8bSJeremy L Thompson if (!ceed_error_handler) ceed_error_handler = "abort"; 8992b730f8bSJeremy L Thompson if (!strcmp(ceed_error_handler, "exit")) (*ceed)->Error = CeedErrorExit; 9002b730f8bSJeremy L Thompson else if (!strcmp(ceed_error_handler, "store")) (*ceed)->Error = CeedErrorStore; 9012b730f8bSJeremy L Thompson else (*ceed)->Error = CeedErrorAbort; 902d1d35e2fSjeremylt memcpy((*ceed)->err_msg, "No error message stored", 24); 903d1d35e2fSjeremylt (*ceed)->ref_count = 1; 904d7b241e6Sjeremylt (*ceed)->data = NULL; 905fe2413ffSjeremylt 906fe2413ffSjeremylt // Set lookup table 907d1d35e2fSjeremylt FOffset f_offsets[] = { 9086e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, Error), 9095ae360d4SJeremy L Thompson CEED_FTABLE_ENTRY(Ceed, SetStream), 9106e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, GetPreferredMemType), 9116e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, Destroy), 912f8902d9eSjeremylt CEED_FTABLE_ENTRY(Ceed, VectorCreate), 9136e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, ElemRestrictionCreate), 9143ac8f562SJeremy L Thompson CEED_FTABLE_ENTRY(Ceed, ElemRestrictionCreateAtPoints), 9156e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, ElemRestrictionCreateBlocked), 9166e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, BasisCreateTensorH1), 9176e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, BasisCreateH1), 91850c301a5SRezgar Shakeri CEED_FTABLE_ENTRY(Ceed, BasisCreateHdiv), 919c4e3f59bSSebastian Grimberg CEED_FTABLE_ENTRY(Ceed, BasisCreateHcurl), 9206e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, TensorContractCreate), 9216e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, QFunctionCreate), 922777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(Ceed, QFunctionContextCreate), 9236e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, OperatorCreate), 92448acf710SJeremy L Thompson CEED_FTABLE_ENTRY(Ceed, OperatorCreateAtPoints), 9256e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, CompositeOperatorCreate), 9269c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, HasValidArray), 9279c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, HasBorrowedArrayOfType), 9280b8f3c4eSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, CopyStrided), 9296e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, SetArray), 9306a6c615bSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, TakeArray), 9316e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, SetValue), 9320b8f3c4eSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, SetValueStrided), 933f48ed27dSnbeams CEED_FTABLE_ENTRY(CeedVector, SyncArray), 9346e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, GetArray), 9356e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, GetArrayRead), 9369c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, GetArrayWrite), 9376e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, RestoreArray), 9386e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, RestoreArrayRead), 939547d9b97Sjeremylt CEED_FTABLE_ENTRY(CeedVector, Norm), 940e0dd3b27Sjeremylt CEED_FTABLE_ENTRY(CeedVector, Scale), 9410f7fd0f8Sjeremylt CEED_FTABLE_ENTRY(CeedVector, AXPY), 9425fb68f37SKaren (Ren) Stengel CEED_FTABLE_ENTRY(CeedVector, AXPBY), 9430f7fd0f8Sjeremylt CEED_FTABLE_ENTRY(CeedVector, PointwiseMult), 944d99fa3c5SJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, Reciprocal), 9456e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, Destroy), 9466e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedElemRestriction, Apply), 947f30b1135SSebastian Grimberg CEED_FTABLE_ENTRY(CeedElemRestriction, ApplyUnsigned), 9487c1dbaffSSebastian Grimberg CEED_FTABLE_ENTRY(CeedElemRestriction, ApplyUnoriented), 94905fa913cSJeremy L Thompson CEED_FTABLE_ENTRY(CeedElemRestriction, ApplyAtPointsInElement), 9506e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedElemRestriction, ApplyBlock), 951bd33150aSjeremylt CEED_FTABLE_ENTRY(CeedElemRestriction, GetOffsets), 95277d1c127SSebastian Grimberg CEED_FTABLE_ENTRY(CeedElemRestriction, GetOrientations), 95377d1c127SSebastian Grimberg CEED_FTABLE_ENTRY(CeedElemRestriction, GetCurlOrientations), 95419605835SJeremy L Thompson CEED_FTABLE_ENTRY(CeedElemRestriction, GetAtPointsElementOffset), 9556e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedElemRestriction, Destroy), 9566e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedBasis, Apply), 957db2becc9SJeremy L Thompson CEED_FTABLE_ENTRY(CeedBasis, ApplyAdd), 958c8c3fa7dSJeremy L Thompson CEED_FTABLE_ENTRY(CeedBasis, ApplyAtPoints), 959db2becc9SJeremy L Thompson CEED_FTABLE_ENTRY(CeedBasis, ApplyAddAtPoints), 9606e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedBasis, Destroy), 9616e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedTensorContract, Apply), 9626e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedTensorContract, Destroy), 9636e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedQFunction, Apply), 9648c84ac63Sjeremylt CEED_FTABLE_ENTRY(CeedQFunction, SetCUDAUserFunction), 9658c84ac63Sjeremylt CEED_FTABLE_ENTRY(CeedQFunction, SetHIPUserFunction), 9666e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedQFunction, Destroy), 9679c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, HasValidData), 9689c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, HasBorrowedDataOfType), 969777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, SetData), 970891038deSjeremylt CEED_FTABLE_ENTRY(CeedQFunctionContext, TakeData), 971777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, GetData), 97228bfd0b7SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, GetDataRead), 973777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, RestoreData), 97428bfd0b7SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, RestoreDataRead), 9752e64a2b9SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, DataDestroy), 976777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, Destroy), 97780ac2e43SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleQFunction), 97870a7ffb3SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleQFunctionUpdate), 97980ac2e43SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleDiagonal), 9809e9210b8SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleAddDiagonal), 98180ac2e43SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssemblePointBlockDiagonal), 9829e9210b8SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleAddPointBlockDiagonal), 983e2f04181SAndrew T. Barker CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleSymbolic), 984e2f04181SAndrew T. Barker CEED_FTABLE_ENTRY(CeedOperator, LinearAssemble), 985cefa2673SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleSingle), 986713f43c3Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, CreateFDMElementInverse), 9876e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, Apply), 988250756a7Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, ApplyComposite), 989cae8b89aSjeremylt CEED_FTABLE_ENTRY(CeedOperator, ApplyAdd), 990250756a7Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, ApplyAddComposite), 9916e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, ApplyJacobian), 9926e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, Destroy), 9936e79d475Sjeremylt {NULL, 0} // End of lookup table - used in SetBackendFunction loop 9941dfeef1dSjeremylt }; 995fe2413ffSjeremylt 9962b730f8bSJeremy L Thompson CeedCall(CeedCalloc(sizeof(f_offsets), &(*ceed)->f_offsets)); 997d1d35e2fSjeremylt memcpy((*ceed)->f_offsets, f_offsets, sizeof(f_offsets)); 998fe2413ffSjeremylt 9995107b09fSJeremy L Thompson // Set fallback for advanced CeedOperator functions 1000ca735530SJeremy L Thompson const char fallback_resource[] = ""; 1001ca735530SJeremy L Thompson CeedCall(CeedSetOperatorFallbackResource(*ceed, fallback_resource)); 10025107b09fSJeremy L Thompson 100360f9e2d6SJeremy L Thompson // Record env variables CEED_DEBUG or DBG 10041c66c397SJeremy L Thompson (*ceed)->is_debug = getenv("CEED_DEBUG") || getenv("DEBUG") || getenv("DBG"); 100560f9e2d6SJeremy L Thompson 100622e44211Sjeremylt // Copy resource prefix, if backend setup successful 10072b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(backends[match_index].prefix, (char **)&(*ceed)->resource)); 1008ee5a26f2SJeremy L Thompson 1009ee5a26f2SJeremy L Thompson // Set default JiT source root 1010ea61e9acSJeremy L Thompson // Note: there will always be the default root for every Ceed but all additional paths are added to the top-most parent 10112b730f8bSJeremy L Thompson CeedCall(CeedAddJitSourceRoot(*ceed, (char *)CeedJitSourceRootDefault)); 1012ee5a26f2SJeremy L Thompson 1013d04bbc78SJeremy L Thompson // Backend specific setup 10142b730f8bSJeremy L Thompson CeedCall(backends[match_index].init(&resource[match_help], *ceed)); 1015e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1016d7b241e6Sjeremylt } 1017d7b241e6Sjeremylt 1018d7b241e6Sjeremylt /** 1019ca94c3ddSJeremy L Thompson @brief Set the GPU stream for a `Ceed` context 10205ae360d4SJeremy L Thompson 1021ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context to set the stream 10225ae360d4SJeremy L Thompson @param[in] handle Handle to GPU stream 10235ae360d4SJeremy L Thompson 10245ae360d4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 10255ae360d4SJeremy L Thompson 10265ae360d4SJeremy L Thompson @ref User 10275ae360d4SJeremy L Thompson **/ 10285ae360d4SJeremy L Thompson int CeedSetStream(Ceed ceed, void *handle) { 1029ca94c3ddSJeremy L Thompson CeedCheck(handle, ceed, CEED_ERROR_INCOMPATIBLE, "Stream handle must be non-NULL"); 10309ffb25e0SJames Wright if (ceed->SetStream) { 10315ae360d4SJeremy L Thompson CeedCall(ceed->SetStream(ceed, handle)); 10329ffb25e0SJames Wright } else { 10339ffb25e0SJames Wright Ceed delegate; 10349ffb25e0SJames Wright CeedCall(CeedGetDelegate(ceed, &delegate)); 10355ae360d4SJeremy L Thompson 103628ce3d2aSJeremy L Thompson if (delegate) CeedCall(CeedSetStream(delegate, handle)); 103728ce3d2aSJeremy L Thompson else return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support setting stream"); 10389ffb25e0SJames Wright } 10395ae360d4SJeremy L Thompson return CEED_ERROR_SUCCESS; 10405ae360d4SJeremy L Thompson } 10415ae360d4SJeremy L Thompson 10425ae360d4SJeremy L Thompson /** 1043ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `Ceed` context. 10444385fb7fSSebastian Grimberg 1045ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedDestroy(). 1046512bb800SJeremy L Thompson 1047ca94c3ddSJeremy 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. 1048ca94c3ddSJeremy L Thompson This `Ceed` context will be destroyed if `*ceed_copy` is the only reference to this `Ceed` context. 10499560d06aSjeremylt 1050ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to copy reference to 1051ea61e9acSJeremy L Thompson @param[in,out] ceed_copy Variable to store copied reference 10529560d06aSjeremylt 10539560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 10549560d06aSjeremylt 10559560d06aSjeremylt @ref User 10569560d06aSjeremylt **/ 10579560d06aSjeremylt int CeedReferenceCopy(Ceed ceed, Ceed *ceed_copy) { 10582b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 10592b730f8bSJeremy L Thompson CeedCall(CeedDestroy(ceed_copy)); 10609560d06aSjeremylt *ceed_copy = ceed; 10619560d06aSjeremylt return CEED_ERROR_SUCCESS; 10629560d06aSjeremylt } 10639560d06aSjeremylt 10649560d06aSjeremylt /** 1065ca94c3ddSJeremy L Thompson @brief Get the full resource name for a `Ceed` context 10662f86a920SJeremy L Thompson 1067ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to get resource name of 10687a982d89SJeremy L. Thompson @param[out] resource Variable to store resource name 10692f86a920SJeremy L Thompson 10702f86a920SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 10712f86a920SJeremy L Thompson 10727a982d89SJeremy L. Thompson @ref User 10735107b09fSJeremy L Thompson **/ 10747a982d89SJeremy L. Thompson int CeedGetResource(Ceed ceed, const char **resource) { 10757a982d89SJeremy L. Thompson *resource = (const char *)ceed->resource; 1076e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 10775107b09fSJeremy L Thompson } 10785107b09fSJeremy L Thompson 10795107b09fSJeremy L Thompson /** 1080ca94c3ddSJeremy L Thompson @brief Return `Ceed` context preferred memory type 1081c907536fSjeremylt 1082ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to get preferred memory type of 1083d1d35e2fSjeremylt @param[out] mem_type Address to save preferred memory type to 1084c907536fSjeremylt 1085c907536fSjeremylt @return An error code: 0 - success, otherwise - failure 1086c907536fSjeremylt 10877a982d89SJeremy L. Thompson @ref User 1088c907536fSjeremylt **/ 1089d1d35e2fSjeremylt int CeedGetPreferredMemType(Ceed ceed, CeedMemType *mem_type) { 1090c907536fSjeremylt if (ceed->GetPreferredMemType) { 10912b730f8bSJeremy L Thompson CeedCall(ceed->GetPreferredMemType(mem_type)); 1092c907536fSjeremylt } else { 1093c263cd57Sjeremylt Ceed delegate; 10942b730f8bSJeremy L Thompson CeedCall(CeedGetDelegate(ceed, &delegate)); 1095c263cd57Sjeremylt 1096c263cd57Sjeremylt if (delegate) { 10972b730f8bSJeremy L Thompson CeedCall(CeedGetPreferredMemType(delegate, mem_type)); 1098c263cd57Sjeremylt } else { 1099d1d35e2fSjeremylt *mem_type = CEED_MEM_HOST; 1100c907536fSjeremylt } 1101c263cd57Sjeremylt } 1102e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1103c907536fSjeremylt } 1104c907536fSjeremylt 1105c907536fSjeremylt /** 1106ca94c3ddSJeremy L Thompson @brief Get deterministic status of `Ceed` context 11079525855cSJeremy L Thompson 1108ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context 1109d1d35e2fSjeremylt @param[out] is_deterministic Variable to store deterministic status 11109525855cSJeremy L Thompson 11119525855cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 11129525855cSJeremy L Thompson 11139525855cSJeremy L Thompson @ref User 11149525855cSJeremy L Thompson **/ 1115d1d35e2fSjeremylt int CeedIsDeterministic(Ceed ceed, bool *is_deterministic) { 1116d1d35e2fSjeremylt *is_deterministic = ceed->is_deterministic; 1117e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 11189525855cSJeremy L Thompson } 11199525855cSJeremy L Thompson 11209525855cSJeremy L Thompson /** 1121ca94c3ddSJeremy L Thompson @brief Set additional JiT source root for `Ceed` context 1122ee5a26f2SJeremy L Thompson 1123ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context 1124ee5a26f2SJeremy L Thompson @param[in] jit_source_root Absolute path to additional JiT source directory 1125ee5a26f2SJeremy L Thompson 1126ee5a26f2SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1127ee5a26f2SJeremy L Thompson 1128ee5a26f2SJeremy L Thompson @ref User 1129ee5a26f2SJeremy L Thompson **/ 1130ee5a26f2SJeremy L Thompson int CeedAddJitSourceRoot(Ceed ceed, const char *jit_source_root) { 11316155f12fSJeremy L Thompson Ceed ceed_parent; 1132ee5a26f2SJeremy L Thompson 11332b730f8bSJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent)); 11346155f12fSJeremy L Thompson 11356155f12fSJeremy L Thompson CeedInt index = ceed_parent->num_jit_source_roots; 1136ee5a26f2SJeremy L Thompson size_t path_length = strlen(jit_source_root); 11371c66c397SJeremy L Thompson 11382b730f8bSJeremy L Thompson CeedCall(CeedRealloc(index + 1, &ceed_parent->jit_source_roots)); 11392b730f8bSJeremy L Thompson CeedCall(CeedCalloc(path_length + 1, &ceed_parent->jit_source_roots[index])); 1140d602d780SJeremy L Thompson memcpy(ceed_parent->jit_source_roots[index], jit_source_root, path_length); 11416155f12fSJeremy L Thompson ceed_parent->num_jit_source_roots++; 1142ee5a26f2SJeremy L Thompson return CEED_ERROR_SUCCESS; 1143ee5a26f2SJeremy L Thompson } 1144ee5a26f2SJeremy L Thompson 1145ee5a26f2SJeremy L Thompson /** 1146ca94c3ddSJeremy L Thompson @brief View a `Ceed` 11470a0da059Sjeremylt 1148ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` to view 11490a0da059Sjeremylt @param[in] stream Filestream to write to 11500a0da059Sjeremylt 11510a0da059Sjeremylt @return An error code: 0 - success, otherwise - failure 11520a0da059Sjeremylt 11530a0da059Sjeremylt @ref User 11540a0da059Sjeremylt **/ 11550a0da059Sjeremylt int CeedView(Ceed ceed, FILE *stream) { 1156d1d35e2fSjeremylt CeedMemType mem_type; 11570a0da059Sjeremylt 11582b730f8bSJeremy L Thompson CeedCall(CeedGetPreferredMemType(ceed, &mem_type)); 11590a0da059Sjeremylt 11602b730f8bSJeremy L Thompson fprintf(stream, 11612b730f8bSJeremy L Thompson "Ceed\n" 11620a0da059Sjeremylt " Ceed Resource: %s\n" 11630a0da059Sjeremylt " Preferred MemType: %s\n", 1164d1d35e2fSjeremylt ceed->resource, CeedMemTypes[mem_type]); 1165e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 11660a0da059Sjeremylt } 11670a0da059Sjeremylt 11680a0da059Sjeremylt /** 1169ca94c3ddSJeremy L Thompson @brief Destroy a `Ceed` 1170d7b241e6Sjeremylt 1171ca94c3ddSJeremy L Thompson @param[in,out] ceed Address of `Ceed` context to destroy 1172b11c1e72Sjeremylt 1173b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1174dfdf5a53Sjeremylt 11757a982d89SJeremy L. Thompson @ref User 1176b11c1e72Sjeremylt **/ 1177d7b241e6Sjeremylt int CeedDestroy(Ceed *ceed) { 1178ad6481ceSJeremy L Thompson if (!*ceed || --(*ceed)->ref_count > 0) { 1179ad6481ceSJeremy L Thompson *ceed = NULL; 1180ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1181ad6481ceSJeremy L Thompson } 11822b730f8bSJeremy L Thompson if ((*ceed)->delegate) CeedCall(CeedDestroy(&(*ceed)->delegate)); 11830ace9bf2Sjeremylt 1184d1d35e2fSjeremylt if ((*ceed)->obj_delegate_count > 0) { 118592ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*ceed)->obj_delegate_count; i++) { 11862b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&((*ceed)->obj_delegates[i].delegate))); 11872b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->obj_delegates[i].obj_name)); 1188aefd8378Sjeremylt } 11892b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->obj_delegates)); 1190aefd8378Sjeremylt } 11910ace9bf2Sjeremylt 11922b730f8bSJeremy L Thompson if ((*ceed)->Destroy) CeedCall((*ceed)->Destroy(*ceed)); 11930ace9bf2Sjeremylt 119492ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*ceed)->num_jit_source_roots; i++) { 11952b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->jit_source_roots[i])); 1196032e71eaSJeremy L Thompson } 11972b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->jit_source_roots)); 1198032e71eaSJeremy L Thompson 11992b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->f_offsets)); 12002b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->resource)); 12012b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*ceed)->op_fallback_ceed)); 12022b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->op_fallback_resource)); 12032b730f8bSJeremy L Thompson CeedCall(CeedFree(ceed)); 1204e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1205d7b241e6Sjeremylt } 1206d7b241e6Sjeremylt 1207f9982c62SWill Pazner // LCOV_EXCL_START 1208f9982c62SWill Pazner const char *CeedErrorFormat(Ceed ceed, const char *format, va_list *args) { 12092b730f8bSJeremy L Thompson if (ceed->parent) return CeedErrorFormat(ceed->parent, format, args); 12102b730f8bSJeremy L Thompson if (ceed->op_fallback_parent) return CeedErrorFormat(ceed->op_fallback_parent, format, args); 121178464608Sjeremylt // Using pointer to va_list for better FFI, but clang-tidy can't verify va_list is initalized 121278464608Sjeremylt vsnprintf(ceed->err_msg, CEED_MAX_RESOURCE_LEN, format, *args); // NOLINT 1213d1d35e2fSjeremylt return ceed->err_msg; 1214f9982c62SWill Pazner } 1215f9982c62SWill Pazner // LCOV_EXCL_STOP 1216f9982c62SWill Pazner 12177a982d89SJeremy L. Thompson /** 1218ca94c3ddSJeremy L Thompson @brief Error handling implementation; use @ref CeedError() instead. 1219ca94c3ddSJeremy L Thompson 1220ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 12217a982d89SJeremy L. Thompson 12227a982d89SJeremy L. Thompson @ref Developer 12237a982d89SJeremy L. Thompson **/ 12242b730f8bSJeremy L Thompson int CeedErrorImpl(Ceed ceed, const char *filename, int lineno, const char *func, int ecode, const char *format, ...) { 12257a982d89SJeremy L. Thompson va_list args; 1226d1d35e2fSjeremylt int ret_val; 12271c66c397SJeremy L Thompson 12287a982d89SJeremy L. Thompson va_start(args, format); 12297a982d89SJeremy L. Thompson if (ceed) { 1230d1d35e2fSjeremylt ret_val = ceed->Error(ceed, filename, lineno, func, ecode, format, &args); 12317a982d89SJeremy L. Thompson } else { 1232b0d62198Sjeremylt // LCOV_EXCL_START 1233477729cfSJeremy L Thompson const char *ceed_error_handler = getenv("CEED_ERROR_HANDLER"); 12342b730f8bSJeremy L Thompson if (!ceed_error_handler) ceed_error_handler = "abort"; 1235bcbe1c99SJeremy L Thompson if (!strcmp(ceed_error_handler, "return")) { 1236bcbe1c99SJeremy L Thompson ret_val = CeedErrorReturn(ceed, filename, lineno, func, ecode, format, &args); 1237bcbe1c99SJeremy L Thompson } else { 1238477729cfSJeremy L Thompson // This function will not return 1239d1d35e2fSjeremylt ret_val = CeedErrorAbort(ceed, filename, lineno, func, ecode, format, &args); 12407a982d89SJeremy L. Thompson } 1241bcbe1c99SJeremy L Thompson } 12427a982d89SJeremy L. Thompson va_end(args); 1243d1d35e2fSjeremylt return ret_val; 1244b0d62198Sjeremylt // LCOV_EXCL_STOP 12457a982d89SJeremy L. Thompson } 12467a982d89SJeremy L. Thompson 1247477729cfSJeremy L Thompson /** 1248477729cfSJeremy L Thompson @brief Error handler that returns without printing anything. 1249477729cfSJeremy L Thompson 1250ca94c3ddSJeremy L Thompson Pass this to @ref CeedSetErrorHandler() to obtain this error handling behavior. 1251ca94c3ddSJeremy L Thompson 1252ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1253477729cfSJeremy L Thompson 1254477729cfSJeremy L Thompson @ref Developer 1255477729cfSJeremy L Thompson **/ 1256477729cfSJeremy L Thompson // LCOV_EXCL_START 12572b730f8bSJeremy L Thompson int CeedErrorReturn(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) { 1258d1d35e2fSjeremylt return err_code; 1259477729cfSJeremy L Thompson } 1260477729cfSJeremy L Thompson // LCOV_EXCL_STOP 1261477729cfSJeremy L Thompson 1262477729cfSJeremy L Thompson /** 1263ea61e9acSJeremy L Thompson @brief Error handler that stores the error message for future use and returns the error. 1264477729cfSJeremy L Thompson 1265ca94c3ddSJeremy L Thompson Pass this to @ref CeedSetErrorHandler() to obtain this error handling behavior. 1266ca94c3ddSJeremy L Thompson 1267ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1268477729cfSJeremy L Thompson 1269477729cfSJeremy L Thompson @ref Developer 1270477729cfSJeremy L Thompson **/ 1271477729cfSJeremy L Thompson // LCOV_EXCL_START 12722b730f8bSJeremy L Thompson int CeedErrorStore(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) { 12732b730f8bSJeremy L Thompson if (ceed->parent) return CeedErrorStore(ceed->parent, filename, line_no, func, err_code, format, args); 12742b730f8bSJeremy L Thompson if (ceed->op_fallback_parent) return CeedErrorStore(ceed->op_fallback_parent, filename, line_no, func, err_code, format, args); 1275477729cfSJeremy L Thompson 1276477729cfSJeremy L Thompson // Build message 12771c66c397SJeremy L Thompson int len = snprintf(ceed->err_msg, CEED_MAX_RESOURCE_LEN, "%s:%d in %s(): ", filename, line_no, func); 127878464608Sjeremylt // Using pointer to va_list for better FFI, but clang-tidy can't verify va_list is initalized 127978464608Sjeremylt vsnprintf(ceed->err_msg + len, CEED_MAX_RESOURCE_LEN - len, format, *args); // NOLINT 1280d1d35e2fSjeremylt return err_code; 1281477729cfSJeremy L Thompson } 1282477729cfSJeremy L Thompson // LCOV_EXCL_STOP 1283477729cfSJeremy L Thompson 1284477729cfSJeremy L Thompson /** 1285ca94c3ddSJeremy L Thompson @brief Error handler that prints to `stderr` and aborts 1286477729cfSJeremy L Thompson 1287ca94c3ddSJeremy L Thompson Pass this to @ref CeedSetErrorHandler() to obtain this error handling behavior. 1288ca94c3ddSJeremy L Thompson 1289ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1290477729cfSJeremy L Thompson 1291477729cfSJeremy L Thompson @ref Developer 1292477729cfSJeremy L Thompson **/ 1293477729cfSJeremy L Thompson // LCOV_EXCL_START 12942b730f8bSJeremy L Thompson int CeedErrorAbort(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) { 1295d1d35e2fSjeremylt fprintf(stderr, "%s:%d in %s(): ", filename, line_no, func); 1296f9982c62SWill Pazner vfprintf(stderr, format, *args); 1297477729cfSJeremy L Thompson fprintf(stderr, "\n"); 1298477729cfSJeremy L Thompson abort(); 1299d1d35e2fSjeremylt return err_code; 1300477729cfSJeremy L Thompson } 1301477729cfSJeremy L Thompson // LCOV_EXCL_STOP 1302477729cfSJeremy L Thompson 1303477729cfSJeremy L Thompson /** 1304ca94c3ddSJeremy L Thompson @brief Error handler that prints to `stderr` and exits. 1305477729cfSJeremy L Thompson 1306ca94c3ddSJeremy L Thompson Pass this to @ref CeedSetErrorHandler() to obtain this error handling behavior. 1307477729cfSJeremy L Thompson 1308ca94c3ddSJeremy L Thompson In contrast to @ref CeedErrorAbort(), this exits without a signal, so `atexit()` handlers (e.g., as used by gcov) are run. 1309ca94c3ddSJeremy L Thompson 1310ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1311477729cfSJeremy L Thompson 1312477729cfSJeremy L Thompson @ref Developer 1313477729cfSJeremy L Thompson **/ 13142b730f8bSJeremy L Thompson int CeedErrorExit(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) { 1315d1d35e2fSjeremylt fprintf(stderr, "%s:%d in %s(): ", filename, line_no, func); 131678464608Sjeremylt // Using pointer to va_list for better FFI, but clang-tidy can't verify va_list is initalized 131778464608Sjeremylt vfprintf(stderr, format, *args); // NOLINT 1318477729cfSJeremy L Thompson fprintf(stderr, "\n"); 1319d1d35e2fSjeremylt exit(err_code); 1320d1d35e2fSjeremylt return err_code; 1321477729cfSJeremy L Thompson } 1322477729cfSJeremy L Thompson 1323477729cfSJeremy L Thompson /** 1324477729cfSJeremy L Thompson @brief Set error handler 1325477729cfSJeremy L Thompson 1326ca94c3ddSJeremy L Thompson A default error handler is set in @ref CeedInit(). 1327ca94c3ddSJeremy L Thompson Use this function to change the error handler to @ref CeedErrorReturn(), @ref CeedErrorAbort(), or a user-defined error handler. 1328ca94c3ddSJeremy L Thompson 1329ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1330477729cfSJeremy L Thompson 1331477729cfSJeremy L Thompson @ref Developer 1332477729cfSJeremy L Thompson **/ 1333d1d35e2fSjeremylt int CeedSetErrorHandler(Ceed ceed, CeedErrorHandler handler) { 1334d1d35e2fSjeremylt ceed->Error = handler; 1335d1d35e2fSjeremylt if (ceed->delegate) CeedSetErrorHandler(ceed->delegate, handler); 13362b730f8bSJeremy L Thompson for (CeedInt i = 0; i < ceed->obj_delegate_count; i++) CeedSetErrorHandler(ceed->obj_delegates[i].delegate, handler); 1337e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1338477729cfSJeremy L Thompson } 1339477729cfSJeremy L Thompson 1340477729cfSJeremy L Thompson /** 1341477729cfSJeremy L Thompson @brief Get error message 1342477729cfSJeremy L Thompson 1343ca94c3ddSJeremy L Thompson The error message is only stored when using the error handler @ref CeedErrorStore() 1344477729cfSJeremy L Thompson 1345ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve error message 1346d1d35e2fSjeremylt @param[out] err_msg Char pointer to hold error message 1347477729cfSJeremy L Thompson 1348ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1349ca94c3ddSJeremy L Thompson 1350477729cfSJeremy L Thompson @ref Developer 1351477729cfSJeremy L Thompson **/ 1352d1d35e2fSjeremylt int CeedGetErrorMessage(Ceed ceed, const char **err_msg) { 13532b730f8bSJeremy L Thompson if (ceed->parent) return CeedGetErrorMessage(ceed->parent, err_msg); 13542b730f8bSJeremy L Thompson if (ceed->op_fallback_parent) return CeedGetErrorMessage(ceed->op_fallback_parent, err_msg); 1355d1d35e2fSjeremylt *err_msg = ceed->err_msg; 1356e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1357477729cfSJeremy L Thompson } 1358477729cfSJeremy L Thompson 1359477729cfSJeremy L Thompson /** 1360ca94c3ddSJeremy L Thompson @brief Restore error message. 1361477729cfSJeremy L Thompson 1362ca94c3ddSJeremy L Thompson The error message is only stored when using the error handler @ref CeedErrorStore(). 1363477729cfSJeremy L Thompson 1364ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to restore error message 1365d1d35e2fSjeremylt @param[out] err_msg Char pointer that holds error message 1366477729cfSJeremy L Thompson 1367ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1368ca94c3ddSJeremy L Thompson 1369477729cfSJeremy L Thompson @ref Developer 1370477729cfSJeremy L Thompson **/ 1371d1d35e2fSjeremylt int CeedResetErrorMessage(Ceed ceed, const char **err_msg) { 13722b730f8bSJeremy L Thompson if (ceed->parent) return CeedResetErrorMessage(ceed->parent, err_msg); 13732b730f8bSJeremy L Thompson if (ceed->op_fallback_parent) return CeedResetErrorMessage(ceed->op_fallback_parent, err_msg); 1374d1d35e2fSjeremylt *err_msg = NULL; 1375d1d35e2fSjeremylt memcpy(ceed->err_msg, "No error message stored", 24); 1376e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1377477729cfSJeremy L Thompson } 1378477729cfSJeremy L Thompson 13791070991dSJed Brown /** 1380ca94c3ddSJeremy L Thompson @brief Get libCEED library version information. 13811070991dSJed Brown 1382ea61e9acSJeremy L Thompson libCEED version numbers have the form major.minor.patch. 1383ea61e9acSJeremy L Thompson Non-release versions may contain unstable interfaces. 13841070991dSJed Brown 13851070991dSJed Brown @param[out] major Major version of the library 13861070991dSJed Brown @param[out] minor Minor version of the library 13871070991dSJed Brown @param[out] patch Patch (subminor) version of the library 138853cbfc38SJeremy L Thompson @param[out] release True for releases; false for development branches 13891070991dSJed Brown 1390ca94c3ddSJeremy L Thompson The caller may pass `NULL` for any arguments that are not needed. 13911070991dSJed Brown 1392ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13931070991dSJed Brown 13941070991dSJed Brown @ref Developer 1395ca94c3ddSJeremy L Thompson 1396ca94c3ddSJeremy L Thompson @sa CEED_VERSION_GE() 13971070991dSJed Brown */ 13981070991dSJed Brown int CeedGetVersion(int *major, int *minor, int *patch, bool *release) { 13991070991dSJed Brown if (major) *major = CEED_VERSION_MAJOR; 14001070991dSJed Brown if (minor) *minor = CEED_VERSION_MINOR; 14011070991dSJed Brown if (patch) *patch = CEED_VERSION_PATCH; 14021070991dSJed Brown if (release) *release = CEED_VERSION_RELEASE; 1403ca94c3ddSJeremy L Thompson return CEED_ERROR_SUCCESS; 14041070991dSJed Brown } 14051070991dSJed Brown 140653cbfc38SJeremy L Thompson /** 140753cbfc38SJeremy L Thompson @brief Get libCEED scalar type, such as F64 or F32 140853cbfc38SJeremy L Thompson 140953cbfc38SJeremy L Thompson @param[out] scalar_type Type of libCEED scalars 141053cbfc38SJeremy L Thompson 1411ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1412ca94c3ddSJeremy L Thompson 141353cbfc38SJeremy L Thompson @ref Developer 141453cbfc38SJeremy L Thompson */ 141580a9ef05SNatalie Beams int CeedGetScalarType(CeedScalarType *scalar_type) { 141680a9ef05SNatalie Beams *scalar_type = CEED_SCALAR_TYPE; 1417ca94c3ddSJeremy L Thompson return CEED_ERROR_SUCCESS; 141880a9ef05SNatalie Beams } 141980a9ef05SNatalie Beams 1420d7b241e6Sjeremylt /// @} 1421