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 **/ 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 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 **/ 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 **/ 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 **/ 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 1967a982d89SJeremy L. Thompson /// @} 197d7b241e6Sjeremylt 1987a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 1997a982d89SJeremy L. Thompson /// Ceed Backend API 2007a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 2017a982d89SJeremy L. Thompson /// @addtogroup CeedBackend 2027a982d89SJeremy L. Thompson /// @{ 203d7b241e6Sjeremylt 204b11c1e72Sjeremylt /** 205ca94c3ddSJeremy L Thompson @brief Return value of `CEED_DEBUG` environment variable 20660f9e2d6SJeremy L Thompson 207ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context 20860f9e2d6SJeremy L Thompson 209ca94c3ddSJeremy L Thompson @return Boolean value: true - debugging mode enabled 2103f21f6b1SJeremy L Thompson false - debugging mode disabled 21160f9e2d6SJeremy L Thompson 21260f9e2d6SJeremy L Thompson @ref Backend 21360f9e2d6SJeremy L Thompson **/ 214fc6bbcedSJeremy L Thompson // LCOV_EXCL_START 2152b730f8bSJeremy L Thompson bool CeedDebugFlag(const Ceed ceed) { return ceed->is_debug; } 216fc6bbcedSJeremy L Thompson // LCOV_EXCL_STOP 21760f9e2d6SJeremy L Thompson 21860f9e2d6SJeremy L Thompson /** 219ca94c3ddSJeremy L Thompson @brief Return value of `CEED_DEBUG` environment variable 22060f9e2d6SJeremy L Thompson 221ca94c3ddSJeremy L Thompson @return Boolean value: true - debugging mode enabled 2223f21f6b1SJeremy L Thompson false - debugging mode disabled 2233f21f6b1SJeremy L Thompson 2243f21f6b1SJeremy L Thompson @ref Backend 2253f21f6b1SJeremy L Thompson **/ 2263f21f6b1SJeremy L Thompson // LCOV_EXCL_START 2271c66c397SJeremy L Thompson bool CeedDebugFlagEnv(void) { return getenv("CEED_DEBUG") || getenv("DEBUG") || getenv("DBG"); } 2283f21f6b1SJeremy L Thompson // LCOV_EXCL_STOP 2293f21f6b1SJeremy L Thompson 2303f21f6b1SJeremy L Thompson /** 2313f21f6b1SJeremy L Thompson @brief Print debugging information in color 2323f21f6b1SJeremy L Thompson 233ca94c3ddSJeremy L Thompson @param[in] color Color to print 234ca94c3ddSJeremy L Thompson @param[in] format Printing format 23560f9e2d6SJeremy L Thompson 23660f9e2d6SJeremy L Thompson @ref Backend 23760f9e2d6SJeremy L Thompson **/ 238fc6bbcedSJeremy L Thompson // LCOV_EXCL_START 2393f21f6b1SJeremy L Thompson void CeedDebugImpl256(const unsigned char color, const char *format, ...) { 24060f9e2d6SJeremy L Thompson va_list args; 24160f9e2d6SJeremy L Thompson va_start(args, format); 24260f9e2d6SJeremy L Thompson fflush(stdout); 2432b730f8bSJeremy L Thompson if (color != CEED_DEBUG_COLOR_NONE) fprintf(stdout, "\033[38;5;%dm", color); 24460f9e2d6SJeremy L Thompson vfprintf(stdout, format, args); 2452b730f8bSJeremy L Thompson if (color != CEED_DEBUG_COLOR_NONE) fprintf(stdout, "\033[m"); 24660f9e2d6SJeremy L Thompson fprintf(stdout, "\n"); 24760f9e2d6SJeremy L Thompson fflush(stdout); 24860f9e2d6SJeremy L Thompson va_end(args); 24960f9e2d6SJeremy L Thompson } 250fc6bbcedSJeremy L Thompson // LCOV_EXCL_STOP 25160f9e2d6SJeremy L Thompson 25260f9e2d6SJeremy L Thompson /** 253ca94c3ddSJeremy L Thompson @brief Allocate an array on the host; use @ref CeedMalloc(). 254b11c1e72Sjeremylt 255ea61e9acSJeremy L Thompson Memory usage can be tracked by the library. 256ea61e9acSJeremy L Thompson This ensures sufficient alignment for vectorization and should be used for large allocations. 257b11c1e72Sjeremylt 258ea61e9acSJeremy L Thompson @param[in] n Number of units to allocate 259ea61e9acSJeremy L Thompson @param[in] unit Size of each unit 260ca94c3ddSJeremy L Thompson @param[out] p Address of pointer to hold the result 261b11c1e72Sjeremylt 262b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 263b11c1e72Sjeremylt 2647a982d89SJeremy L. Thompson @ref Backend 265ca94c3ddSJeremy L Thompson 266ca94c3ddSJeremy L Thompson @sa CeedFree() 267b11c1e72Sjeremylt **/ 268d7b241e6Sjeremylt int CeedMallocArray(size_t n, size_t unit, void *p) { 269d7b241e6Sjeremylt int ierr = posix_memalign((void **)p, CEED_ALIGN, n * unit); 2706574a04fSJeremy L Thompson CeedCheck(ierr == 0, NULL, CEED_ERROR_MAJOR, "posix_memalign failed to allocate %zd members of size %zd\n", n, unit); 271e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 272d7b241e6Sjeremylt } 273d7b241e6Sjeremylt 274b11c1e72Sjeremylt /** 275ca94c3ddSJeremy L Thompson @brief Allocate a cleared (zeroed) array on the host; use @ref CeedCalloc(). 276b11c1e72Sjeremylt 277b11c1e72Sjeremylt Memory usage can be tracked by the library. 278b11c1e72Sjeremylt 279ea61e9acSJeremy L Thompson @param[in] n Number of units to allocate 280ea61e9acSJeremy L Thompson @param[in] unit Size of each unit 281ca94c3ddSJeremy L Thompson @param[out] p Address of pointer to hold the result 282b11c1e72Sjeremylt 283b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 284b11c1e72Sjeremylt 2857a982d89SJeremy L. Thompson @ref Backend 286ca94c3ddSJeremy L Thompson 287ca94c3ddSJeremy L Thompson @sa CeedFree() 288b11c1e72Sjeremylt **/ 289d7b241e6Sjeremylt int CeedCallocArray(size_t n, size_t unit, void *p) { 290d7b241e6Sjeremylt *(void **)p = calloc(n, unit); 2916574a04fSJeremy L Thompson CeedCheck(!n || !unit || *(void **)p, NULL, CEED_ERROR_MAJOR, "calloc failed to allocate %zd members of size %zd\n", n, unit); 292e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 293d7b241e6Sjeremylt } 294d7b241e6Sjeremylt 295b11c1e72Sjeremylt /** 296ca94c3ddSJeremy L Thompson @brief Reallocate an array on the host; use @ref CeedRealloc(). 297b11c1e72Sjeremylt 298b11c1e72Sjeremylt Memory usage can be tracked by the library. 299b11c1e72Sjeremylt 300ea61e9acSJeremy L Thompson @param[in] n Number of units to allocate 301ea61e9acSJeremy L Thompson @param[in] unit Size of each unit 302ca94c3ddSJeremy L Thompson @param[out] p Address of pointer to hold the result 303b11c1e72Sjeremylt 304b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 305b11c1e72Sjeremylt 3067a982d89SJeremy L. Thompson @ref Backend 307ca94c3ddSJeremy L Thompson 308ca94c3ddSJeremy L Thompson @sa CeedFree() 309b11c1e72Sjeremylt **/ 310d7b241e6Sjeremylt int CeedReallocArray(size_t n, size_t unit, void *p) { 311d7b241e6Sjeremylt *(void **)p = realloc(*(void **)p, n * unit); 3126574a04fSJeremy L Thompson CeedCheck(!n || !unit || *(void **)p, NULL, CEED_ERROR_MAJOR, "realloc failed to allocate %zd members of size %zd\n", n, unit); 313e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 314d7b241e6Sjeremylt } 315d7b241e6Sjeremylt 316f7e22acaSJeremy L Thompson /** 317ca94c3ddSJeremy L Thompson @brief Allocate a cleared string buffer on the host. 318f7e22acaSJeremy L Thompson 319f7e22acaSJeremy L Thompson Memory usage can be tracked by the library. 320f7e22acaSJeremy L Thompson 321ea61e9acSJeremy L Thompson @param[in] source Pointer to string to be copied 322ea61e9acSJeremy L Thompson @param[out] copy Pointer to variable to hold newly allocated string copy 323f7e22acaSJeremy L Thompson 324f7e22acaSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 325f7e22acaSJeremy L Thompson 326f7e22acaSJeremy L Thompson @ref Backend 327ca94c3ddSJeremy L Thompson 328ca94c3ddSJeremy L Thompson @sa CeedFree() 329f7e22acaSJeremy L Thompson **/ 330f7e22acaSJeremy L Thompson int CeedStringAllocCopy(const char *source, char **copy) { 331f7e22acaSJeremy L Thompson size_t len = strlen(source); 3322b730f8bSJeremy L Thompson CeedCall(CeedCalloc(len + 1, copy)); 333d602d780SJeremy L Thompson memcpy(*copy, source, len); 334f7e22acaSJeremy L Thompson return CEED_ERROR_SUCCESS; 335f7e22acaSJeremy L Thompson } 336f7e22acaSJeremy L Thompson 337ca94c3ddSJeremy L Thompson /** Free memory allocated using @ref CeedMalloc() or @ref CeedCalloc() 33834138859Sjeremylt 339ca94c3ddSJeremy L Thompson @param[in,out] p Address of pointer to memory. 340ca94c3ddSJeremy 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. 341ca94c3ddSJeremy L Thompson 342ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 343ca94c3ddSJeremy L Thompson 344ca94c3ddSJeremy L Thompson @ref Backend 34534138859Sjeremylt **/ 346d7b241e6Sjeremylt int CeedFree(void *p) { 347d7b241e6Sjeremylt free(*(void **)p); 348d7b241e6Sjeremylt *(void **)p = NULL; 349e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 350d7b241e6Sjeremylt } 351d7b241e6Sjeremylt 352f5d1e504SJeremy L Thompson /** Internal helper to manage handoff of user `source_array` to backend with proper @ref CeedCopyMode behavior. 353f5d1e504SJeremy L Thompson 354f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user 355f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data 356f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle 35717afdf5cSJames Wright @param[in] size_unit Size of array element in bytes 358f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated 359f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data 360f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data 361f5d1e504SJeremy L Thompson 362f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 363f5d1e504SJeremy L Thompson 364f5d1e504SJeremy L Thompson @ref Backend 365f5d1e504SJeremy L Thompson **/ 366f5d1e504SJeremy L Thompson static inline int CeedSetHostGenericArray(const void *source_array, CeedCopyMode copy_mode, size_t size_unit, CeedSize num_values, 367f5d1e504SJeremy L Thompson void *target_array_owned, void *target_array_borrowed, void *target_array) { 368f5d1e504SJeremy L Thompson switch (copy_mode) { 369f5d1e504SJeremy L Thompson case CEED_COPY_VALUES: 370cc3bdf8cSJeremy L Thompson if (!*(void **)target_array) { 371cc3bdf8cSJeremy L Thompson if (*(void **)target_array_borrowed) { 372cc3bdf8cSJeremy L Thompson *(void **)target_array = *(void **)target_array_borrowed; 373cc3bdf8cSJeremy L Thompson } else { 374f5d1e504SJeremy L Thompson if (!*(void **)target_array_owned) CeedCall(CeedCallocArray(num_values, size_unit, target_array_owned)); 375f5d1e504SJeremy L Thompson *(void **)target_array = *(void **)target_array_owned; 376cc3bdf8cSJeremy L Thompson } 377cc3bdf8cSJeremy L Thompson } 378cc3bdf8cSJeremy L Thompson if (source_array) memcpy(*(void **)target_array, source_array, size_unit * num_values); 379f5d1e504SJeremy L Thompson break; 380f5d1e504SJeremy L Thompson case CEED_OWN_POINTER: 381f5d1e504SJeremy L Thompson CeedCall(CeedFree(target_array_owned)); 382f5d1e504SJeremy L Thompson *(void **)target_array_owned = (void *)source_array; 383f5d1e504SJeremy L Thompson *(void **)target_array_borrowed = NULL; 384f5d1e504SJeremy L Thompson *(void **)target_array = *(void **)target_array_owned; 385f5d1e504SJeremy L Thompson break; 386f5d1e504SJeremy L Thompson case CEED_USE_POINTER: 387f5d1e504SJeremy L Thompson CeedCall(CeedFree(target_array_owned)); 388f5d1e504SJeremy L Thompson *(void **)target_array_owned = NULL; 389f5d1e504SJeremy L Thompson *(void **)target_array_borrowed = (void *)source_array; 390f5d1e504SJeremy L Thompson *(void **)target_array = *(void **)target_array_borrowed; 391f5d1e504SJeremy L Thompson } 392f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS; 393f5d1e504SJeremy L Thompson } 394f5d1e504SJeremy L Thompson 395f5d1e504SJeremy L Thompson /** Manage handoff of user `bool` `source_array` to backend with proper @ref CeedCopyMode behavior. 396f5d1e504SJeremy L Thompson 397f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user 398f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data 399f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle 400f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated 401f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data 402f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data 403f5d1e504SJeremy L Thompson 404f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 405f5d1e504SJeremy L Thompson 406f5d1e504SJeremy L Thompson @ref Backend 407f5d1e504SJeremy L Thompson **/ 408f5d1e504SJeremy L Thompson int CeedSetHostBoolArray(const bool *source_array, CeedCopyMode copy_mode, CeedSize num_values, const bool **target_array_owned, 409f5d1e504SJeremy L Thompson const bool **target_array_borrowed, const bool **target_array) { 410f5d1e504SJeremy L Thompson CeedCall(CeedSetHostGenericArray(source_array, copy_mode, sizeof(bool), num_values, target_array_owned, target_array_borrowed, target_array)); 411f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS; 412f5d1e504SJeremy L Thompson } 413f5d1e504SJeremy L Thompson 414f5d1e504SJeremy L Thompson /** Manage handoff of user `CeedInt8` `source_array` to backend with proper @ref CeedCopyMode behavior. 415f5d1e504SJeremy L Thompson 416f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user 417f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data 418f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle 419f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated 420f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data 421f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data 422f5d1e504SJeremy L Thompson 423f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 424f5d1e504SJeremy L Thompson 425f5d1e504SJeremy L Thompson @ref Backend 426f5d1e504SJeremy L Thompson **/ 427f5d1e504SJeremy L Thompson int CeedSetHostCeedInt8Array(const CeedInt8 *source_array, CeedCopyMode copy_mode, CeedSize num_values, const CeedInt8 **target_array_owned, 428f5d1e504SJeremy L Thompson const CeedInt8 **target_array_borrowed, const CeedInt8 **target_array) { 429f5d1e504SJeremy L Thompson CeedCall(CeedSetHostGenericArray(source_array, copy_mode, sizeof(CeedInt8), num_values, target_array_owned, target_array_borrowed, target_array)); 430f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS; 431f5d1e504SJeremy L Thompson } 432f5d1e504SJeremy L Thompson 433f5d1e504SJeremy L Thompson /** Manage handoff of user `CeedInt` `source_array` to backend with proper @ref CeedCopyMode behavior. 434f5d1e504SJeremy L Thompson 435f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user 436f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data 437f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle 438f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated 439f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data 440f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data 441f5d1e504SJeremy L Thompson 442f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 443f5d1e504SJeremy L Thompson 444f5d1e504SJeremy L Thompson @ref Backend 445f5d1e504SJeremy L Thompson **/ 446f5d1e504SJeremy L Thompson int CeedSetHostCeedIntArray(const CeedInt *source_array, CeedCopyMode copy_mode, CeedSize num_values, const CeedInt **target_array_owned, 447f5d1e504SJeremy L Thompson const CeedInt **target_array_borrowed, const CeedInt **target_array) { 448f5d1e504SJeremy L Thompson CeedCall(CeedSetHostGenericArray(source_array, copy_mode, sizeof(CeedInt), num_values, target_array_owned, target_array_borrowed, target_array)); 449f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS; 450f5d1e504SJeremy L Thompson } 451f5d1e504SJeremy L Thompson 452f5d1e504SJeremy L Thompson /** Manage handoff of user `CeedScalar` `source_array` to backend with proper @ref CeedCopyMode behavior. 453f5d1e504SJeremy L Thompson 454f5d1e504SJeremy L Thompson @param[in] source_array Source data provided by user 455f5d1e504SJeremy L Thompson @param[in] copy_mode Copy mode for the data 456f5d1e504SJeremy L Thompson @param[in] num_values Number of values to handle 457f5d1e504SJeremy L Thompson @param[in,out] target_array_owned Pointer to location to allocated or hold owned data, may be freed if already allocated 458f5d1e504SJeremy L Thompson @param[out] target_array_borrowed Pointer to location to hold borrowed data 459f5d1e504SJeremy L Thompson @param[out] target_array Pointer to location for data 460f5d1e504SJeremy L Thompson 461f5d1e504SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 462f5d1e504SJeremy L Thompson 463f5d1e504SJeremy L Thompson @ref Backend 464f5d1e504SJeremy L Thompson **/ 465f5d1e504SJeremy L Thompson int CeedSetHostCeedScalarArray(const CeedScalar *source_array, CeedCopyMode copy_mode, CeedSize num_values, const CeedScalar **target_array_owned, 466f5d1e504SJeremy L Thompson const CeedScalar **target_array_borrowed, const CeedScalar **target_array) { 467f5d1e504SJeremy L Thompson CeedCall(CeedSetHostGenericArray(source_array, copy_mode, sizeof(CeedScalar), num_values, target_array_owned, target_array_borrowed, target_array)); 468f5d1e504SJeremy L Thompson return CEED_ERROR_SUCCESS; 469f5d1e504SJeremy L Thompson } 470f5d1e504SJeremy L Thompson 471d7b241e6Sjeremylt /** 472ca94c3ddSJeremy L Thompson @brief Register a `Ceed` backend 473d7b241e6Sjeremylt 474ea61e9acSJeremy L Thompson @param[in] prefix Prefix of resources for this backend to respond to. 475ea61e9acSJeremy L Thompson For example, the reference backend responds to "/cpu/self". 476ca94c3ddSJeremy L Thompson @param[in] init Initialization function called by @ref CeedInit() when the backend is selected to drive the requested resource 477ea61e9acSJeremy L Thompson @param[in] priority Integer priority. 478ca94c3ddSJeremy L Thompson Lower values are preferred in case the resource requested by @ref CeedInit() has non-unique best prefix match. 479b11c1e72Sjeremylt 480b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 481dfdf5a53Sjeremylt 4827a982d89SJeremy L. Thompson @ref Backend 483b11c1e72Sjeremylt **/ 4842b730f8bSJeremy L Thompson int CeedRegister(const char *prefix, int (*init)(const char *, Ceed), unsigned int priority) { 48510243053SJeremy L Thompson CeedDebugEnv("Backend Register: %s", prefix); 4866a406739SJeremy L Thompson CeedRegisterImpl(prefix, init, priority); 487e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 488d7b241e6Sjeremylt } 489d7b241e6Sjeremylt 490b11c1e72Sjeremylt /** 49160f9e2d6SJeremy L Thompson @brief Return debugging status flag 49260f9e2d6SJeremy L Thompson 493ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to get debugging flag 494ea61e9acSJeremy L Thompson @param[out] is_debug Variable to store debugging flag 49560f9e2d6SJeremy L Thompson 49660f9e2d6SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 49760f9e2d6SJeremy L Thompson 498d1d35e2fSjeremylt @ref Backend 49960f9e2d6SJeremy L Thompson **/ 500d1d35e2fSjeremylt int CeedIsDebug(Ceed ceed, bool *is_debug) { 5013f21f6b1SJeremy L Thompson *is_debug = ceed->is_debug; 502e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 50360f9e2d6SJeremy L Thompson } 50460f9e2d6SJeremy L Thompson 50560f9e2d6SJeremy L Thompson /** 506bf84744cSJeremy L Thompson @brief Get the root of the requested resource. 507bf84744cSJeremy L Thompson 508bf84744cSJeremy L Thompson Note: Caller is responsible for calling @ref CeedFree() on the `resource_root`. 509bc246734SJeremy L Thompson 510ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to get resource name of 511ca94c3ddSJeremy L Thompson @param[in] resource Full user specified resource 512ca94c3ddSJeremy L Thompson @param[in] delineator Delineator to break `resource_root` and `resource_spec` 513bc246734SJeremy L Thompson @param[out] resource_root Variable to store resource root 514bc246734SJeremy L Thompson 515bc246734SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 516bc246734SJeremy L Thompson 517bc246734SJeremy L Thompson @ref Backend 518bc246734SJeremy L Thompson **/ 519bc246734SJeremy L Thompson int CeedGetResourceRoot(Ceed ceed, const char *resource, const char *delineator, char **resource_root) { 520bc246734SJeremy L Thompson char *device_spec = strstr(resource, delineator); 521bc246734SJeremy L Thompson size_t resource_root_len = device_spec ? (size_t)(device_spec - resource) + 1 : strlen(resource) + 1; 5221c66c397SJeremy L Thompson 523bc246734SJeremy L Thompson CeedCall(CeedCalloc(resource_root_len, resource_root)); 524bc246734SJeremy L Thompson memcpy(*resource_root, resource, resource_root_len - 1); 525bc246734SJeremy L Thompson return CEED_ERROR_SUCCESS; 526bc246734SJeremy L Thompson } 527bc246734SJeremy L Thompson 528bc246734SJeremy L Thompson /** 529ca94c3ddSJeremy L Thompson @brief Retrieve a parent `Ceed` context 5307a982d89SJeremy L. Thompson 531ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve parent of 5327a982d89SJeremy L. Thompson @param[out] parent Address to save the parent to 5337a982d89SJeremy L. Thompson 5347a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5357a982d89SJeremy L. Thompson 5367a982d89SJeremy L. Thompson @ref Backend 5377a982d89SJeremy L. Thompson **/ 5387a982d89SJeremy L. Thompson int CeedGetParent(Ceed ceed, Ceed *parent) { 5397a982d89SJeremy L. Thompson if (ceed->parent) { 5402b730f8bSJeremy L Thompson CeedCall(CeedGetParent(ceed->parent, parent)); 541e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5427a982d89SJeremy L. Thompson } 5439bc66399SJeremy L Thompson *parent = NULL; 5449bc66399SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed, parent)); 545e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5467a982d89SJeremy L. Thompson } 5477a982d89SJeremy L. Thompson 5487a982d89SJeremy L. Thompson /** 549ca94c3ddSJeremy L Thompson @brief Retrieve a delegate `Ceed` context 5507a982d89SJeremy L. Thompson 551ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve delegate of 5527a982d89SJeremy L. Thompson @param[out] delegate Address to save the delegate to 5537a982d89SJeremy L. Thompson 5547a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5557a982d89SJeremy L. Thompson 5567a982d89SJeremy L. Thompson @ref Backend 5577a982d89SJeremy L. Thompson **/ 5587a982d89SJeremy L. Thompson int CeedGetDelegate(Ceed ceed, Ceed *delegate) { 5599bc66399SJeremy L Thompson *delegate = NULL; 5609bc66399SJeremy L Thompson if (ceed->delegate) CeedCall(CeedReferenceCopy(ceed->delegate, delegate)); 561e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5627a982d89SJeremy L. Thompson } 5637a982d89SJeremy L. Thompson 5647a982d89SJeremy L. Thompson /** 565ca94c3ddSJeremy L Thompson @brief Set a delegate `Ceed` context 5667a982d89SJeremy L. Thompson 567ca94c3ddSJeremy L Thompson This function allows a `Ceed` context to set a delegate `Ceed` context. 568ca94c3ddSJeremy L Thompson All backend implementations default to the delegate `Ceed` context, unless overridden. 5697a982d89SJeremy L. Thompson 570ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to set delegate of 5717a982d89SJeremy L. Thompson @param[out] delegate Address to set the delegate to 5727a982d89SJeremy L. Thompson 5737a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5747a982d89SJeremy L. Thompson 5757a982d89SJeremy L. Thompson @ref Backend 5767a982d89SJeremy L. Thompson **/ 5777a982d89SJeremy L. Thompson int CeedSetDelegate(Ceed ceed, Ceed delegate) { 5789bc66399SJeremy L Thompson CeedCall(CeedReferenceCopy(delegate, &ceed->delegate)); 5797a982d89SJeremy L. Thompson delegate->parent = ceed; 580e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 5817a982d89SJeremy L. Thompson } 5827a982d89SJeremy L. Thompson 5837a982d89SJeremy L. Thompson /** 584ca94c3ddSJeremy L Thompson @brief Retrieve a delegate `Ceed` context for a specific object type 5857a982d89SJeremy L. Thompson 586ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve delegate of 5877a982d89SJeremy L. Thompson @param[out] delegate Address to save the delegate to 588d1d35e2fSjeremylt @param[in] obj_name Name of the object type to retrieve delegate for 5897a982d89SJeremy L. Thompson 5907a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 5917a982d89SJeremy L. Thompson 5927a982d89SJeremy L. Thompson @ref Backend 5937a982d89SJeremy L. Thompson **/ 594d1d35e2fSjeremylt int CeedGetObjectDelegate(Ceed ceed, Ceed *delegate, const char *obj_name) { 5957a982d89SJeremy L. Thompson // Check for object delegate 5962b730f8bSJeremy L Thompson for (CeedInt i = 0; i < ceed->obj_delegate_count; i++) { 597d1d35e2fSjeremylt if (!strcmp(obj_name, ceed->obj_delegates->obj_name)) { 5989bc66399SJeremy L Thompson *delegate = NULL; 5999bc66399SJeremy L Thompson CeedCall(CeedReferenceCopy(ceed->obj_delegates->delegate, delegate)); 600e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6017a982d89SJeremy L. Thompson } 6022b730f8bSJeremy L Thompson } 6037a982d89SJeremy L. Thompson 6047a982d89SJeremy L. Thompson // Use default delegate if no object delegate 6052b730f8bSJeremy L Thompson CeedCall(CeedGetDelegate(ceed, delegate)); 606e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6077a982d89SJeremy L. Thompson } 6087a982d89SJeremy L. Thompson 6097a982d89SJeremy L. Thompson /** 610ca94c3ddSJeremy L Thompson @brief Set a delegate `Ceed` context for a specific object type 6117a982d89SJeremy L. Thompson 612ca94c3ddSJeremy L Thompson This function allows a `Ceed` context to set a delegate `Ceed` context for a given type of `Ceed` object. 613ca94c3ddSJeremy L Thompson All backend implementations default to the delegate `Ceed` context for this object. 614ca94c3ddSJeremy L Thompson For example, `CeedSetObjectDelegate(ceed, delegate, "Basis")` uses delegate implementations for all `CeedBasis` backend functions. 6157a982d89SJeremy L. Thompson 616ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context to set delegate of 617ca94c3ddSJeremy L Thompson @param[in] delegate `Ceed` context to use for delegation 618d1d35e2fSjeremylt @param[in] obj_name Name of the object type to set delegate for 6197a982d89SJeremy L. Thompson 6207a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6217a982d89SJeremy L. Thompson 6227a982d89SJeremy L. Thompson @ref Backend 6237a982d89SJeremy L. Thompson **/ 624d1d35e2fSjeremylt int CeedSetObjectDelegate(Ceed ceed, Ceed delegate, const char *obj_name) { 625d1d35e2fSjeremylt CeedInt count = ceed->obj_delegate_count; 6267a982d89SJeremy L. Thompson 6277a982d89SJeremy L. Thompson // Malloc or Realloc 6287a982d89SJeremy L. Thompson if (count) { 6292b730f8bSJeremy L Thompson CeedCall(CeedRealloc(count + 1, &ceed->obj_delegates)); 6307a982d89SJeremy L. Thompson } else { 6312b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &ceed->obj_delegates)); 6327a982d89SJeremy L. Thompson } 633d1d35e2fSjeremylt ceed->obj_delegate_count++; 6347a982d89SJeremy L. Thompson 6357a982d89SJeremy L. Thompson // Set object delegate 6369bc66399SJeremy L Thompson CeedCall(CeedReferenceCopy(delegate, &ceed->obj_delegates[count].delegate)); 6372b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(obj_name, &ceed->obj_delegates[count].obj_name)); 6387a982d89SJeremy L. Thompson 6397a982d89SJeremy L. Thompson // Set delegate parent 6407a982d89SJeremy L. Thompson delegate->parent = ceed; 641e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6427a982d89SJeremy L. Thompson } 6437a982d89SJeremy L. Thompson 6447a982d89SJeremy L. Thompson /** 645ca94c3ddSJeremy L Thompson @brief Get the fallback `Ceed` for `CeedOperator` 6468687e1d4SJeremy L Thompson 647ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context 648ca94c3ddSJeremy L Thompson @param[out] fallback_ceed Variable to store fallback `Ceed` 6498687e1d4SJeremy L Thompson 6508687e1d4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 6518687e1d4SJeremy L Thompson 6528687e1d4SJeremy L Thompson @ref Backend 6538687e1d4SJeremy L Thompson **/ 6548687e1d4SJeremy L Thompson int CeedGetOperatorFallbackCeed(Ceed ceed, Ceed *fallback_ceed) { 65546b50f9eSZach Atkins if (ceed->op_fallback_ceed) { 656ca38d01dSJeremy L Thompson CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "---------- Ceed Fallback ----------\n"); 65746b50f9eSZach Atkins CeedDebug(ceed, "Falling back from Ceed with backend %s at address %p to Ceed with backend %s at address %p", ceed->resource, ceed, 65846b50f9eSZach Atkins ceed->op_fallback_ceed->resource, ceed->op_fallback_ceed); 659d04bbc78SJeremy L Thompson } 6608687e1d4SJeremy L Thompson 6619bc66399SJeremy L Thompson *fallback_ceed = NULL; 6629bc66399SJeremy L Thompson if (ceed->op_fallback_ceed) CeedCall(CeedReferenceCopy(ceed->op_fallback_ceed, fallback_ceed)); 6638687e1d4SJeremy L Thompson return CEED_ERROR_SUCCESS; 6648687e1d4SJeremy L Thompson } 6658687e1d4SJeremy L Thompson 6668687e1d4SJeremy L Thompson /** 667ca94c3ddSJeremy L Thompson @brief Set the fallback resource for `CeedOperator`. 6684385fb7fSSebastian Grimberg 66946b50f9eSZach Atkins The current fallback, if any, is freed by calling this function. 6707a982d89SJeremy L. Thompson 671ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context 67246b50f9eSZach Atkins @param[in] fallback_ceed `Ceed` context to create fallback operators 6737a982d89SJeremy L. Thompson 6747a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 6757a982d89SJeremy L. Thompson 6767a982d89SJeremy L. Thompson @ref Backend 6777a982d89SJeremy L. Thompson **/ 67846b50f9eSZach Atkins int CeedSetOperatorFallbackCeed(Ceed ceed, Ceed fallback_ceed) { 67946b50f9eSZach Atkins CeedCall(CeedReferenceCopy(fallback_ceed, &ceed->op_fallback_ceed)); 68046b50f9eSZach Atkins fallback_ceed->parent = ceed; 681e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6827a982d89SJeremy L. Thompson } 6837a982d89SJeremy L. Thompson 6847a982d89SJeremy L. Thompson /** 685ca94c3ddSJeremy L Thompson @brief Flag `Ceed` context as deterministic 6869525855cSJeremy L Thompson 687ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` to flag as deterministic 68896b902e2Sjeremylt @param[out] is_deterministic Deterministic status to set 6899525855cSJeremy L Thompson 6909525855cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 6919525855cSJeremy L Thompson 6929525855cSJeremy L Thompson @ref Backend 6939525855cSJeremy L Thompson **/ 694d1d35e2fSjeremylt int CeedSetDeterministic(Ceed ceed, bool is_deterministic) { 695d1d35e2fSjeremylt ceed->is_deterministic = is_deterministic; 696e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 6979525855cSJeremy L Thompson } 6989525855cSJeremy L Thompson 6999525855cSJeremy L Thompson /** 700ca94c3ddSJeremy L Thompson @brief Set a backend function. 7017a982d89SJeremy L. Thompson 702ea61e9acSJeremy L Thompson This function is used for a backend to set the function associated with the Ceed objects. 703ca94c3ddSJeremy 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(). 7049fd66db6SSebastian Grimberg Note, the prefix 'Ceed' is not required for the object type ("Basis" vs "CeedBasis"). 7057a982d89SJeremy L. Thompson 706ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context for error handling 707ea61e9acSJeremy L Thompson @param[in] type Type of Ceed object to set function for 7087a982d89SJeremy L. Thompson @param[out] object Ceed object to set function for 709ea61e9acSJeremy L Thompson @param[in] func_name Name of function to set 710ea61e9acSJeremy L Thompson @param[in] f Function to set 7117a982d89SJeremy L. Thompson 7127a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 7137a982d89SJeremy L. Thompson 7147a982d89SJeremy L. Thompson @ref Backend 7157a982d89SJeremy L. Thompson **/ 716897d4737SSebastian Grimberg int CeedSetBackendFunctionImpl(Ceed ceed, const char *type, void *object, const char *func_name, void (*f)(void)) { 717d1d35e2fSjeremylt char lookup_name[CEED_MAX_RESOURCE_LEN + 1] = ""; 7187a982d89SJeremy L. Thompson 7197a982d89SJeremy L. Thompson // Build lookup name 7202b730f8bSJeremy L Thompson if (strcmp(type, "Ceed")) strncat(lookup_name, "Ceed", CEED_MAX_RESOURCE_LEN); 721d1d35e2fSjeremylt strncat(lookup_name, type, CEED_MAX_RESOURCE_LEN); 722d1d35e2fSjeremylt strncat(lookup_name, func_name, CEED_MAX_RESOURCE_LEN); 7237a982d89SJeremy L. Thompson 7247a982d89SJeremy L. Thompson // Find and use offset 7252b730f8bSJeremy L Thompson for (CeedInt i = 0; ceed->f_offsets[i].func_name; i++) { 726d1d35e2fSjeremylt if (!strcmp(ceed->f_offsets[i].func_name, lookup_name)) { 727d1d35e2fSjeremylt size_t offset = ceed->f_offsets[i].offset; 7287a982d89SJeremy L. Thompson int (**fpointer)(void) = (int (**)(void))((char *)object + offset); // *NOPAD* 7291c66c397SJeremy L Thompson 730897d4737SSebastian Grimberg *fpointer = (int (*)(void))f; 731e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7327a982d89SJeremy L. Thompson } 7332b730f8bSJeremy L Thompson } 7347a982d89SJeremy L. Thompson 7357a982d89SJeremy L. Thompson // LCOV_EXCL_START 7362b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Requested function '%s' was not found for CEED object '%s'", func_name, type); 7377a982d89SJeremy L. Thompson // LCOV_EXCL_STOP 7387a982d89SJeremy L. Thompson } 7397a982d89SJeremy L. Thompson 7407a982d89SJeremy L. Thompson /** 741ca94c3ddSJeremy L Thompson @brief Retrieve backend data for a `Ceed` context 7427a982d89SJeremy L. Thompson 743ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve data of 7447a982d89SJeremy L. Thompson @param[out] data Address to save data to 7457a982d89SJeremy L. Thompson 7467a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 7477a982d89SJeremy L. Thompson 7487a982d89SJeremy L. Thompson @ref Backend 7497a982d89SJeremy L. Thompson **/ 750777ff853SJeremy L Thompson int CeedGetData(Ceed ceed, void *data) { 751777ff853SJeremy L Thompson *(void **)data = ceed->data; 752e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7537a982d89SJeremy L. Thompson } 7547a982d89SJeremy L. Thompson 7557a982d89SJeremy L. Thompson /** 756ca94c3ddSJeremy L Thompson @brief Set backend data for a `Ceed` context 7577a982d89SJeremy L. Thompson 758ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context to set data of 759ea61e9acSJeremy L Thompson @param[in] data Address of data to set 7607a982d89SJeremy L. Thompson 7617a982d89SJeremy L. Thompson @return An error code: 0 - success, otherwise - failure 7627a982d89SJeremy L. Thompson 7637a982d89SJeremy L. Thompson @ref Backend 7647a982d89SJeremy L. Thompson **/ 765777ff853SJeremy L Thompson int CeedSetData(Ceed ceed, void *data) { 766777ff853SJeremy L Thompson ceed->data = data; 767e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 7687a982d89SJeremy L. Thompson } 7697a982d89SJeremy L. Thompson 77034359f16Sjeremylt /** 771ca94c3ddSJeremy L Thompson @brief Increment the reference counter for a `Ceed` context 77234359f16Sjeremylt 773ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context to increment the reference counter 77434359f16Sjeremylt 77534359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 77634359f16Sjeremylt 77734359f16Sjeremylt @ref Backend 77834359f16Sjeremylt **/ 7799560d06aSjeremylt int CeedReference(Ceed ceed) { 780b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)ceed)); 78134359f16Sjeremylt return CEED_ERROR_SUCCESS; 78234359f16Sjeremylt } 78334359f16Sjeremylt 78473501bfeSJeremy L Thompson /** 7850b37c066SZach Atkins @brief Computes the current memory usage of the work vectors in a `Ceed` context and prints to debug.abort 7860b37c066SZach Atkins 7870b37c066SZach Atkins @param[in] ceed `Ceed` context 788ec4241e6SJeremy L Thompson @param[out] usage_mb Address of the variable where the MB of work vector usage will be stored 7890b37c066SZach Atkins 7900b37c066SZach Atkins @return An error code: 0 - success, otherwise - failure 7910b37c066SZach Atkins 7920b37c066SZach Atkins @ref Developer 7930b37c066SZach Atkins **/ 79455326fe7SZach Atkins int CeedGetWorkVectorMemoryUsage(Ceed ceed, CeedScalar *usage_mb) { 795fd326ce8SZach Atkins if (!ceed->VectorCreate) { 796fd326ce8SZach Atkins Ceed delegate; 797fd326ce8SZach Atkins 798fd326ce8SZach Atkins CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Vector")); 799fd326ce8SZach Atkins CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement VectorCreate"); 800fd326ce8SZach Atkins CeedCall(CeedGetWorkVectorMemoryUsage(delegate, usage_mb)); 801fd326ce8SZach Atkins CeedCall(CeedDestroy(&delegate)); 802fd326ce8SZach Atkins return CEED_ERROR_SUCCESS; 803fd326ce8SZach Atkins } 80455326fe7SZach Atkins *usage_mb = 0.0; 8050b37c066SZach Atkins if (ceed->work_vectors) { 8060b37c066SZach Atkins for (CeedInt i = 0; i < ceed->work_vectors->num_vecs; i++) { 8070b37c066SZach Atkins CeedSize vec_len; 8080b37c066SZach Atkins CeedCall(CeedVectorGetLength(ceed->work_vectors->vecs[i], &vec_len)); 80955326fe7SZach Atkins *usage_mb += vec_len; 8100b37c066SZach Atkins } 81155326fe7SZach Atkins *usage_mb *= sizeof(CeedScalar) * 1e-6; 81255326fe7SZach Atkins CeedDebug(ceed, "Resource {%s}: Work vectors memory usage: %" CeedInt_FMT " vectors, %g MB\n", ceed->resource, ceed->work_vectors->num_vecs, 81355326fe7SZach Atkins *usage_mb); 8140b37c066SZach Atkins } 8150b37c066SZach Atkins return CEED_ERROR_SUCCESS; 8160b37c066SZach Atkins } 8170b37c066SZach Atkins 8180b37c066SZach Atkins /** 8190b37c066SZach Atkins @brief Clear inactive work vectors in a `Ceed` context below a minimum length. 8200b37c066SZach Atkins 8210b37c066SZach Atkins @param[in,out] ceed `Ceed` context 8220b37c066SZach Atkins @param[in] min_len Minimum length of work vector to keep 8230b37c066SZach Atkins 8240b37c066SZach Atkins @return An error code: 0 - success, otherwise - failure 8250b37c066SZach Atkins 8260b37c066SZach Atkins @ref Backend 8270b37c066SZach Atkins **/ 8280b37c066SZach Atkins int CeedClearWorkVectors(Ceed ceed, CeedSize min_len) { 829fd326ce8SZach Atkins if (!ceed->VectorCreate) { 830fd326ce8SZach Atkins Ceed delegate; 831fd326ce8SZach Atkins 832fd326ce8SZach Atkins CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Vector")); 833fd326ce8SZach Atkins CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement VectorCreate"); 834fd326ce8SZach Atkins CeedCall(CeedClearWorkVectors(delegate, min_len)); 835fd326ce8SZach Atkins CeedCall(CeedDestroy(&delegate)); 836fd326ce8SZach Atkins return CEED_ERROR_SUCCESS; 837fd326ce8SZach Atkins } 8380b37c066SZach Atkins if (!ceed->work_vectors) return CEED_ERROR_SUCCESS; 8390b37c066SZach Atkins for (CeedInt i = 0; i < ceed->work_vectors->num_vecs; i++) { 8400b37c066SZach Atkins if (ceed->work_vectors->is_in_use[i]) continue; 8410b37c066SZach Atkins CeedSize vec_len; 8420b37c066SZach Atkins CeedCall(CeedVectorGetLength(ceed->work_vectors->vecs[i], &vec_len)); 8430b37c066SZach Atkins if (vec_len < min_len) { 844b0f67a9cSJeremy L Thompson // Note: increase ref_count to prevent Ceed destructor from triggering 845b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)ceed)); 846b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)ceed)); 8470b37c066SZach Atkins CeedCall(CeedVectorDestroy(&ceed->work_vectors->vecs[i])); 848b0f67a9cSJeremy L Thompson // Note: restore ref_count 849b0f67a9cSJeremy L Thompson CeedObjectDereference((CeedObject)ceed); 8500b37c066SZach Atkins ceed->work_vectors->num_vecs--; 8510b37c066SZach Atkins if (ceed->work_vectors->num_vecs > 0) { 8520b37c066SZach Atkins ceed->work_vectors->vecs[i] = ceed->work_vectors->vecs[ceed->work_vectors->num_vecs]; 8530b37c066SZach Atkins ceed->work_vectors->is_in_use[i] = ceed->work_vectors->is_in_use[ceed->work_vectors->num_vecs]; 8540b37c066SZach Atkins ceed->work_vectors->is_in_use[ceed->work_vectors->num_vecs] = false; 8550b37c066SZach Atkins i--; 8560b37c066SZach Atkins } 8570b37c066SZach Atkins } 8580b37c066SZach Atkins } 8590b37c066SZach Atkins return CEED_ERROR_SUCCESS; 8600b37c066SZach Atkins } 8610b37c066SZach Atkins 8620b37c066SZach Atkins /** 86373501bfeSJeremy L Thompson @brief Get a `CeedVector` for scratch work from a `Ceed` context. 86473501bfeSJeremy L Thompson 86573501bfeSJeremy L Thompson Note: This vector must be restored with @ref CeedRestoreWorkVector(). 86673501bfeSJeremy L Thompson 86773501bfeSJeremy L Thompson @param[in] ceed `Ceed` context 86873501bfeSJeremy L Thompson @param[in] len Minimum length of work vector 86973501bfeSJeremy L Thompson @param[out] vec Address of the variable where `CeedVector` will be stored 87073501bfeSJeremy L Thompson 87173501bfeSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 87273501bfeSJeremy L Thompson 87373501bfeSJeremy L Thompson @ref Backend 87473501bfeSJeremy L Thompson **/ 87573501bfeSJeremy L Thompson int CeedGetWorkVector(Ceed ceed, CeedSize len, CeedVector *vec) { 87673501bfeSJeremy L Thompson CeedInt i = 0; 87755326fe7SZach Atkins CeedScalar usage_mb; 87873501bfeSJeremy L Thompson 879fd326ce8SZach Atkins if (!ceed->VectorCreate) { 880fd326ce8SZach Atkins Ceed delegate; 881fd326ce8SZach Atkins 882fd326ce8SZach Atkins CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Vector")); 883fd326ce8SZach Atkins CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement VectorCreate"); 884fd326ce8SZach Atkins CeedCall(CeedGetWorkVector(delegate, len, vec)); 885fd326ce8SZach Atkins CeedCall(CeedDestroy(&delegate)); 886fd326ce8SZach Atkins return CEED_ERROR_SUCCESS; 887fd326ce8SZach Atkins } 888fd326ce8SZach Atkins 88973501bfeSJeremy L Thompson if (!ceed->work_vectors) CeedCall(CeedWorkVectorsCreate(ceed)); 89073501bfeSJeremy L Thompson 89173501bfeSJeremy L Thompson // Search for big enough work vector 89273501bfeSJeremy L Thompson for (i = 0; i < ceed->work_vectors->num_vecs; i++) { 89373501bfeSJeremy L Thompson if (!ceed->work_vectors->is_in_use[i]) { 89473501bfeSJeremy L Thompson CeedSize work_len; 89573501bfeSJeremy L Thompson 89673501bfeSJeremy L Thompson CeedCall(CeedVectorGetLength(ceed->work_vectors->vecs[i], &work_len)); 89773501bfeSJeremy L Thompson if (work_len >= len) break; 89873501bfeSJeremy L Thompson } 89973501bfeSJeremy L Thompson } 90073501bfeSJeremy L Thompson // Long enough vector was not found 90173501bfeSJeremy L Thompson if (i == ceed->work_vectors->num_vecs) { 90273501bfeSJeremy L Thompson if (ceed->work_vectors->max_vecs == 0) { 90373501bfeSJeremy L Thompson ceed->work_vectors->max_vecs = 1; 90473501bfeSJeremy L Thompson CeedCall(CeedCalloc(ceed->work_vectors->max_vecs, &ceed->work_vectors->vecs)); 90573501bfeSJeremy L Thompson CeedCall(CeedCalloc(ceed->work_vectors->max_vecs, &ceed->work_vectors->is_in_use)); 90673501bfeSJeremy L Thompson } else if (ceed->work_vectors->max_vecs == i) { 90773501bfeSJeremy L Thompson ceed->work_vectors->max_vecs *= 2; 90873501bfeSJeremy L Thompson CeedCall(CeedRealloc(ceed->work_vectors->max_vecs, &ceed->work_vectors->vecs)); 90973501bfeSJeremy L Thompson CeedCall(CeedRealloc(ceed->work_vectors->max_vecs, &ceed->work_vectors->is_in_use)); 91073501bfeSJeremy L Thompson } 91173501bfeSJeremy L Thompson ceed->work_vectors->num_vecs++; 91273501bfeSJeremy L Thompson CeedCallBackend(CeedVectorCreate(ceed, len, &ceed->work_vectors->vecs[i])); 913b0f67a9cSJeremy L Thompson // Note: ref_count manipulation to prevent a ref-loop 914b0f67a9cSJeremy L Thompson CeedObjectDereference((CeedObject)ceed); 91555326fe7SZach Atkins if (ceed->is_debug) CeedGetWorkVectorMemoryUsage(ceed, &usage_mb); 91673501bfeSJeremy L Thompson } 91773501bfeSJeremy L Thompson // Return pointer to work vector 91873501bfeSJeremy L Thompson ceed->work_vectors->is_in_use[i] = true; 91973501bfeSJeremy L Thompson *vec = NULL; 92073501bfeSJeremy L Thompson CeedCall(CeedVectorReferenceCopy(ceed->work_vectors->vecs[i], vec)); 921b0f67a9cSJeremy L Thompson // Note: bump ref_count to account for external access 922b0f67a9cSJeremy L Thompson CeedCall(CeedObjectReference((CeedObject)ceed)); 92373501bfeSJeremy L Thompson return CEED_ERROR_SUCCESS; 92473501bfeSJeremy L Thompson } 92573501bfeSJeremy L Thompson 92673501bfeSJeremy L Thompson /** 92773501bfeSJeremy L Thompson @brief Restore a `CeedVector` for scratch work from a `Ceed` context from @ref CeedGetWorkVector() 92873501bfeSJeremy L Thompson 92973501bfeSJeremy L Thompson @param[in] ceed `Ceed` context 93073501bfeSJeremy L Thompson @param[out] vec `CeedVector` to restore 93173501bfeSJeremy L Thompson 93273501bfeSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 93373501bfeSJeremy L Thompson 93473501bfeSJeremy L Thompson @ref Backend 93573501bfeSJeremy L Thompson **/ 93673501bfeSJeremy L Thompson int CeedRestoreWorkVector(Ceed ceed, CeedVector *vec) { 937fd326ce8SZach Atkins if (!ceed->VectorCreate) { 938fd326ce8SZach Atkins Ceed delegate; 939fd326ce8SZach Atkins 940fd326ce8SZach Atkins CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Vector")); 941fd326ce8SZach Atkins CeedCheck(delegate, ceed, CEED_ERROR_UNSUPPORTED, "Backend does not implement VectorCreate"); 942fd326ce8SZach Atkins CeedCall(CeedRestoreWorkVector(delegate, vec)); 943fd326ce8SZach Atkins CeedCall(CeedDestroy(&delegate)); 944fd326ce8SZach Atkins return CEED_ERROR_SUCCESS; 945fd326ce8SZach Atkins } 946fd326ce8SZach Atkins 94773501bfeSJeremy L Thompson for (CeedInt i = 0; i < ceed->work_vectors->num_vecs; i++) { 94873501bfeSJeremy L Thompson if (*vec == ceed->work_vectors->vecs[i]) { 94973501bfeSJeremy 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"); 95073501bfeSJeremy L Thompson CeedCall(CeedVectorDestroy(vec)); 95173501bfeSJeremy L Thompson ceed->work_vectors->is_in_use[i] = false; 952b0f67a9cSJeremy L Thompson // Note: reduce ref_count again to prevent a ref-loop 953b0f67a9cSJeremy L Thompson CeedObjectDereference((CeedObject)ceed); 95473501bfeSJeremy L Thompson return CEED_ERROR_SUCCESS; 95573501bfeSJeremy L Thompson } 95673501bfeSJeremy L Thompson } 95773501bfeSJeremy L Thompson // LCOV_EXCL_START 95873501bfeSJeremy L Thompson return CeedError(ceed, CEED_ERROR_MAJOR, "vec was not checked out via CeedGetWorkVector()"); 95973501bfeSJeremy L Thompson // LCOV_EXCL_STOP 96073501bfeSJeremy L Thompson } 96173501bfeSJeremy L Thompson 962b13efd58SJeremy L Thompson /** 963b13efd58SJeremy L Thompson @brief Retrieve list of additional JiT source roots from `Ceed` context. 964b13efd58SJeremy L Thompson 965b13efd58SJeremy L Thompson Note: The caller is responsible for restoring `jit_source_roots` with @ref CeedRestoreJitSourceRoots(). 966b13efd58SJeremy L Thompson 967b13efd58SJeremy L Thompson @param[in] ceed `Ceed` context 968b13efd58SJeremy L Thompson @param[out] num_source_roots Number of JiT source directories 969b13efd58SJeremy L Thompson @param[out] jit_source_roots Absolute paths to additional JiT source directories 970b13efd58SJeremy L Thompson 971b13efd58SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 972b13efd58SJeremy L Thompson 973b13efd58SJeremy L Thompson @ref Backend 974b13efd58SJeremy L Thompson **/ 975b13efd58SJeremy L Thompson int CeedGetJitSourceRoots(Ceed ceed, CeedInt *num_source_roots, const char ***jit_source_roots) { 976b13efd58SJeremy L Thompson Ceed ceed_parent; 977b13efd58SJeremy L Thompson 978b13efd58SJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent)); 979b13efd58SJeremy L Thompson *num_source_roots = ceed_parent->num_jit_source_roots; 980b13efd58SJeremy L Thompson *jit_source_roots = (const char **)ceed_parent->jit_source_roots; 981aeb3a72dSJeremy L Thompson ceed_parent->num_jit_source_roots_readers++; 9829bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed_parent)); 983b13efd58SJeremy L Thompson return CEED_ERROR_SUCCESS; 984b13efd58SJeremy L Thompson } 985b13efd58SJeremy L Thompson 986b13efd58SJeremy L Thompson /** 9872027fb9dSSirAlienTheGreat @brief Retrieve list of additional Rust source roots from `Ceed` context. 9882027fb9dSSirAlienTheGreat 9892027fb9dSSirAlienTheGreat Note: The caller is responsible for restoring `rust_source_roots` with @ref CeedRestoreRustSourceRoots(). 9902027fb9dSSirAlienTheGreat 9912027fb9dSSirAlienTheGreat @param[in] ceed `Ceed` context 9922027fb9dSSirAlienTheGreat @param[out] num_source_roots Number of JiT source directories 9932027fb9dSSirAlienTheGreat @param[out] rust_source_roots Absolute paths to additional Rust source directories 9942027fb9dSSirAlienTheGreat 9952027fb9dSSirAlienTheGreat @return An error code: 0 - success, otherwise - failure 9962027fb9dSSirAlienTheGreat 9972027fb9dSSirAlienTheGreat @ref Backend 9982027fb9dSSirAlienTheGreat **/ 9992027fb9dSSirAlienTheGreat int CeedGetRustSourceRoots(Ceed ceed, CeedInt *num_source_roots, const char ***rust_source_roots) { 10002027fb9dSSirAlienTheGreat Ceed ceed_parent; 10012027fb9dSSirAlienTheGreat 10022027fb9dSSirAlienTheGreat CeedCall(CeedGetParent(ceed, &ceed_parent)); 10032027fb9dSSirAlienTheGreat *num_source_roots = ceed_parent->num_rust_source_roots; 10042027fb9dSSirAlienTheGreat *rust_source_roots = (const char **)ceed_parent->rust_source_roots; 10052027fb9dSSirAlienTheGreat ceed_parent->num_rust_source_roots_readers++; 10062027fb9dSSirAlienTheGreat CeedCall(CeedDestroy(&ceed_parent)); 10072027fb9dSSirAlienTheGreat return CEED_ERROR_SUCCESS; 10082027fb9dSSirAlienTheGreat } 10092027fb9dSSirAlienTheGreat 10102027fb9dSSirAlienTheGreat /** 1011b13efd58SJeremy L Thompson @brief Restore list of additional JiT source roots from with @ref CeedGetJitSourceRoots() 1012b13efd58SJeremy L Thompson 1013b13efd58SJeremy L Thompson @param[in] ceed `Ceed` context 1014b13efd58SJeremy L Thompson @param[out] jit_source_roots Absolute paths to additional JiT source directories 1015b13efd58SJeremy L Thompson 1016b13efd58SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1017b13efd58SJeremy L Thompson 1018b13efd58SJeremy L Thompson @ref Backend 1019b13efd58SJeremy L Thompson **/ 1020b13efd58SJeremy L Thompson int CeedRestoreJitSourceRoots(Ceed ceed, const char ***jit_source_roots) { 1021aeb3a72dSJeremy L Thompson Ceed ceed_parent; 1022aeb3a72dSJeremy L Thompson 1023aeb3a72dSJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent)); 1024b13efd58SJeremy L Thompson *jit_source_roots = NULL; 1025aeb3a72dSJeremy L Thompson ceed_parent->num_jit_source_roots_readers--; 10269bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed_parent)); 1027b13efd58SJeremy L Thompson return CEED_ERROR_SUCCESS; 1028b13efd58SJeremy L Thompson } 1029b13efd58SJeremy L Thompson 10304753b775SJeremy L Thompson /** 10312027fb9dSSirAlienTheGreat @brief Restore list of additional Rust source roots from with @ref CeedGetJitSourceRoots() 10322027fb9dSSirAlienTheGreat 10332027fb9dSSirAlienTheGreat @param[in] ceed `Ceed` context 10342027fb9dSSirAlienTheGreat @param[out] rust_source_roots Absolute paths to additional Rust source directories 10352027fb9dSSirAlienTheGreat 10362027fb9dSSirAlienTheGreat @return An error code: 0 - success, otherwise - failure 10372027fb9dSSirAlienTheGreat 10382027fb9dSSirAlienTheGreat @ref Backend 10392027fb9dSSirAlienTheGreat **/ 10402027fb9dSSirAlienTheGreat int CeedRestoreRustSourceRoots(Ceed ceed, const char ***rust_source_roots) { 10412027fb9dSSirAlienTheGreat Ceed ceed_parent; 10422027fb9dSSirAlienTheGreat 10432027fb9dSSirAlienTheGreat CeedCall(CeedGetParent(ceed, &ceed_parent)); 10442027fb9dSSirAlienTheGreat *rust_source_roots = NULL; 10452027fb9dSSirAlienTheGreat ceed_parent->num_rust_source_roots_readers--; 10462027fb9dSSirAlienTheGreat CeedCall(CeedDestroy(&ceed_parent)); 10472027fb9dSSirAlienTheGreat return CEED_ERROR_SUCCESS; 10482027fb9dSSirAlienTheGreat } 10492027fb9dSSirAlienTheGreat 10502027fb9dSSirAlienTheGreat /** 10514753b775SJeremy L Thompson @brief Retrieve list of additional JiT defines from `Ceed` context. 10524753b775SJeremy L Thompson 10534753b775SJeremy L Thompson Note: The caller is responsible for restoring `jit_defines` with @ref CeedRestoreJitDefines(). 10544753b775SJeremy L Thompson 10554753b775SJeremy L Thompson @param[in] ceed `Ceed` context 10564753b775SJeremy L Thompson @param[out] num_jit_defines Number of JiT defines 10574753b775SJeremy L Thompson @param[out] jit_defines Strings such as `foo=bar`, used as `-Dfoo=bar` in JiT 10584753b775SJeremy L Thompson 10594753b775SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 10604753b775SJeremy L Thompson 10614753b775SJeremy L Thompson @ref Backend 10624753b775SJeremy L Thompson **/ 10632686ebe6SJed Brown int CeedGetJitDefines(Ceed ceed, CeedInt *num_jit_defines, const char ***jit_defines) { 10644753b775SJeremy L Thompson Ceed ceed_parent; 10654753b775SJeremy L Thompson 10664753b775SJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent)); 10672686ebe6SJed Brown *num_jit_defines = ceed_parent->num_jit_defines; 10684753b775SJeremy L Thompson *jit_defines = (const char **)ceed_parent->jit_defines; 1069aeb3a72dSJeremy L Thompson ceed_parent->num_jit_defines_readers++; 10709bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed_parent)); 10714753b775SJeremy L Thompson return CEED_ERROR_SUCCESS; 10724753b775SJeremy L Thompson } 10734753b775SJeremy L Thompson 10744753b775SJeremy L Thompson /** 10754753b775SJeremy L Thompson @brief Restore list of additional JiT defines from with @ref CeedGetJitDefines() 10764753b775SJeremy L Thompson 10774753b775SJeremy L Thompson @param[in] ceed `Ceed` context 10784753b775SJeremy L Thompson @param[out] jit_defines String such as `foo=bar`, used as `-Dfoo=bar` in JiT 10794753b775SJeremy L Thompson 10804753b775SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 10814753b775SJeremy L Thompson 10824753b775SJeremy L Thompson @ref Backend 10834753b775SJeremy L Thompson **/ 10844753b775SJeremy L Thompson int CeedRestoreJitDefines(Ceed ceed, const char ***jit_defines) { 1085aeb3a72dSJeremy L Thompson Ceed ceed_parent; 1086aeb3a72dSJeremy L Thompson 1087aeb3a72dSJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent)); 10884753b775SJeremy L Thompson *jit_defines = NULL; 1089aeb3a72dSJeremy L Thompson ceed_parent->num_jit_defines_readers--; 10909bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed_parent)); 10914753b775SJeremy L Thompson return CEED_ERROR_SUCCESS; 10924753b775SJeremy L Thompson } 10934753b775SJeremy L Thompson 10947a982d89SJeremy L. Thompson /// @} 10957a982d89SJeremy L. Thompson 10967a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 10977a982d89SJeremy L. Thompson /// Ceed Public API 10987a982d89SJeremy L. Thompson /// ---------------------------------------------------------------------------- 10997a982d89SJeremy L. Thompson /// @addtogroup CeedUser 11007a982d89SJeremy L. Thompson /// @{ 11017a982d89SJeremy L. Thompson 11027a982d89SJeremy L. Thompson /** 1103ca94c3ddSJeremy L Thompson @brief Get the list of available resource names for `Ceed` contexts 11044385fb7fSSebastian Grimberg 1105ca94c3ddSJeremy 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. 110622e44211Sjeremylt 110792ee7d1cSjeremylt @param[out] n Number of available resources 110892ee7d1cSjeremylt @param[out] resources List of available resource names 110922e44211Sjeremylt @param[out] priorities Resource name prioritization values, lower is better 111022e44211Sjeremylt 111122e44211Sjeremylt @return An error code: 0 - success, otherwise - failure 111222e44211Sjeremylt 111322e44211Sjeremylt @ref User 111422e44211Sjeremylt **/ 111522e44211Sjeremylt // LCOV_EXCL_START 11162b730f8bSJeremy L Thompson int CeedRegistryGetList(size_t *n, char ***const resources, CeedInt **priorities) { 1117d0c91ce9Sjeremylt *n = 0; 11189ff86846Sjeremylt *resources = malloc(num_backends * sizeof(**resources)); 11196574a04fSJeremy L Thompson CeedCheck(resources, NULL, CEED_ERROR_MAJOR, "malloc() failure"); 11209ff86846Sjeremylt if (priorities) { 11219ff86846Sjeremylt *priorities = malloc(num_backends * sizeof(**priorities)); 11226574a04fSJeremy L Thompson CeedCheck(priorities, NULL, CEED_ERROR_MAJOR, "malloc() failure"); 11239ff86846Sjeremylt } 112422e44211Sjeremylt for (size_t i = 0; i < num_backends; i++) { 1125d0c91ce9Sjeremylt // Only report compiled backends 1126d0c91ce9Sjeremylt if (backends[i].priority < CEED_MAX_BACKEND_PRIORITY) { 112722e44211Sjeremylt *resources[i] = backends[i].prefix; 11289ff86846Sjeremylt if (priorities) *priorities[i] = backends[i].priority; 1129d0c91ce9Sjeremylt *n += 1; 1130d0c91ce9Sjeremylt } 1131d0c91ce9Sjeremylt } 11326574a04fSJeremy L Thompson CeedCheck(*n, NULL, CEED_ERROR_MAJOR, "No backends installed"); 1133d0c91ce9Sjeremylt *resources = realloc(*resources, *n * sizeof(**resources)); 11346574a04fSJeremy L Thompson CeedCheck(resources, NULL, CEED_ERROR_MAJOR, "realloc() failure"); 1135d0c91ce9Sjeremylt if (priorities) { 1136d0c91ce9Sjeremylt *priorities = realloc(*priorities, *n * sizeof(**priorities)); 11376574a04fSJeremy L Thompson CeedCheck(priorities, NULL, CEED_ERROR_MAJOR, "realloc() failure"); 113822e44211Sjeremylt } 113922e44211Sjeremylt return CEED_ERROR_SUCCESS; 114045f1e315Sjeremylt } 114122e44211Sjeremylt // LCOV_EXCL_STOP 114222e44211Sjeremylt 114322e44211Sjeremylt /** 1144ca94c3ddSJeremy L Thompson @brief Initialize a `Ceed` context to use the specified resource. 11454385fb7fSSebastian Grimberg 1146ca94c3ddSJeremy 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`. 1147b11c1e72Sjeremylt 1148ea61e9acSJeremy L Thompson @param[in] resource Resource to use, e.g., "/cpu/self" 1149ea61e9acSJeremy L Thompson @param[out] ceed The library context 1150b11c1e72Sjeremylt 1151b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1152dfdf5a53Sjeremylt 11537a982d89SJeremy L. Thompson @ref User 1154ca94c3ddSJeremy L Thompson 1155ca94c3ddSJeremy L Thompson @sa CeedRegister() CeedDestroy() 1156b11c1e72Sjeremylt **/ 1157d7b241e6Sjeremylt int CeedInit(const char *resource, Ceed *ceed) { 11582b730f8bSJeremy L Thompson size_t match_len = 0, match_index = UINT_MAX, match_priority = CEED_MAX_BACKEND_PRIORITY, priority; 1159d7b241e6Sjeremylt 1160fe2413ffSjeremylt // Find matching backend 11616574a04fSJeremy L Thompson CeedCheck(resource, NULL, CEED_ERROR_MAJOR, "No resource provided"); 11622b730f8bSJeremy L Thompson CeedCall(CeedRegisterAll()); 116313873f79Sjeremylt 116422e44211Sjeremylt // Check for help request 116522e44211Sjeremylt const char *help_prefix = "help"; 11662b730f8bSJeremy L Thompson size_t match_help = 0; 11672b730f8bSJeremy L Thompson while (match_help < 4 && resource[match_help] == help_prefix[match_help]) match_help++; 116822e44211Sjeremylt if (match_help == 4) { 11692b730f8bSJeremy L Thompson fprintf(stderr, "libCEED version: %d.%d%d%s\n", CEED_VERSION_MAJOR, CEED_VERSION_MINOR, CEED_VERSION_PATCH, 117022e44211Sjeremylt CEED_VERSION_RELEASE ? "" : "+development"); 117192ee7d1cSjeremylt fprintf(stderr, "Available backend resources:\n"); 117222e44211Sjeremylt for (size_t i = 0; i < num_backends; i++) { 1173d0c91ce9Sjeremylt // Only report compiled backends 11742b730f8bSJeremy L Thompson if (backends[i].priority < CEED_MAX_BACKEND_PRIORITY) fprintf(stderr, " %s\n", backends[i].prefix); 117522e44211Sjeremylt } 117622e44211Sjeremylt fflush(stderr); 117722e44211Sjeremylt match_help = 5; // Delineating character expected 117822e44211Sjeremylt } else { 117922e44211Sjeremylt match_help = 0; 118022e44211Sjeremylt } 118122e44211Sjeremylt 1182ea61e9acSJeremy L Thompson // Find best match, computed as number of matching characters from requested resource stem 11832b730f8bSJeremy L Thompson size_t stem_length = 0; 11842b730f8bSJeremy L Thompson while (resource[stem_length + match_help] && resource[stem_length + match_help] != ':') stem_length++; 1185d7b241e6Sjeremylt for (size_t i = 0; i < num_backends; i++) { 11862b730f8bSJeremy L Thompson size_t n = 0; 1187d7b241e6Sjeremylt const char *prefix = backends[i].prefix; 11882b730f8bSJeremy L Thompson while (prefix[n] && prefix[n] == resource[n + match_help]) n++; 1189d7b241e6Sjeremylt priority = backends[i].priority; 1190d1d35e2fSjeremylt if (n > match_len || (n == match_len && match_priority > priority)) { 1191d1d35e2fSjeremylt match_len = n; 1192d1d35e2fSjeremylt match_priority = priority; 1193f7e22acaSJeremy L Thompson match_index = i; 1194d7b241e6Sjeremylt } 1195d7b241e6Sjeremylt } 11969c9a0587SLeila Ghaffari // Using Levenshtein distance to find closest match 11979c9a0587SLeila Ghaffari if (match_len <= 1 || match_len != stem_length) { 1198203015caSLeila Ghaffari // LCOV_EXCL_START 11999c9a0587SLeila Ghaffari size_t lev_dis = UINT_MAX; 1200f7e22acaSJeremy L Thompson size_t lev_index = UINT_MAX, lev_priority = CEED_MAX_BACKEND_PRIORITY; 12019c9a0587SLeila Ghaffari for (size_t i = 0; i < num_backends; i++) { 12029c9a0587SLeila Ghaffari const char *prefix = backends[i].prefix; 12039c9a0587SLeila Ghaffari size_t prefix_length = strlen(backends[i].prefix); 12049c9a0587SLeila Ghaffari size_t min_len = (prefix_length < stem_length) ? prefix_length : stem_length; 1205092904ddSLeila Ghaffari size_t column[min_len + 1]; 1206092904ddSLeila Ghaffari for (size_t j = 0; j <= min_len; j++) column[j] = j; 12079c9a0587SLeila Ghaffari for (size_t j = 1; j <= min_len; j++) { 12089c9a0587SLeila Ghaffari column[0] = j; 12099c9a0587SLeila Ghaffari for (size_t k = 1, last_diag = j - 1; k <= min_len; k++) { 1210092904ddSLeila Ghaffari size_t old_diag = column[k]; 12119c9a0587SLeila Ghaffari size_t min_1 = (column[k] < column[k - 1]) ? column[k] + 1 : column[k - 1] + 1; 12129c9a0587SLeila Ghaffari size_t min_2 = last_diag + (resource[k - 1] == prefix[j - 1] ? 0 : 1); 12139c9a0587SLeila Ghaffari column[k] = (min_1 < min_2) ? min_1 : min_2; 12149c9a0587SLeila Ghaffari last_diag = old_diag; 12159c9a0587SLeila Ghaffari } 12169c9a0587SLeila Ghaffari } 12179c9a0587SLeila Ghaffari size_t n = column[min_len]; 12189c9a0587SLeila Ghaffari priority = backends[i].priority; 12192b730f8bSJeremy L Thompson if (n < lev_dis || (n == lev_dis && lev_priority > priority)) { 12209c9a0587SLeila Ghaffari lev_dis = n; 12219c9a0587SLeila Ghaffari lev_priority = priority; 1222f7e22acaSJeremy L Thompson lev_index = i; 12239c9a0587SLeila Ghaffari } 12249c9a0587SLeila Ghaffari } 1225f7e22acaSJeremy L Thompson const char *prefix_lev = backends[lev_index].prefix; 12262b730f8bSJeremy L Thompson size_t lev_length = 0; 12272b730f8bSJeremy L Thompson while (prefix_lev[lev_length] && prefix_lev[lev_length] != '\0') lev_length++; 12289c9a0587SLeila Ghaffari size_t m = (lev_length < stem_length) ? lev_length : stem_length; 12296574a04fSJeremy L Thompson if (lev_dis + 1 >= m) return CeedError(NULL, CEED_ERROR_MAJOR, "No suitable backend: %s", resource); 12306574a04fSJeremy L Thompson else return CeedError(NULL, CEED_ERROR_MAJOR, "No suitable backend: %s\nClosest match: %s", resource, backends[lev_index].prefix); 1231203015caSLeila Ghaffari // LCOV_EXCL_STOP 12329c9a0587SLeila Ghaffari } 1233fe2413ffSjeremylt 1234fe2413ffSjeremylt // Setup Ceed 12352b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, ceed)); 1236b0f67a9cSJeremy L Thompson CeedCall(CeedObjectCreate(NULL, CeedView_Object, &(*ceed)->obj)); 12372b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &(*ceed)->jit_source_roots)); 12382027fb9dSSirAlienTheGreat CeedCall(CeedCalloc(1, &(*ceed)->rust_source_roots)); 1239bc81ce41Sjeremylt const char *ceed_error_handler = getenv("CEED_ERROR_HANDLER"); 12402b730f8bSJeremy L Thompson if (!ceed_error_handler) ceed_error_handler = "abort"; 12412b730f8bSJeremy L Thompson if (!strcmp(ceed_error_handler, "exit")) (*ceed)->Error = CeedErrorExit; 12422b730f8bSJeremy L Thompson else if (!strcmp(ceed_error_handler, "store")) (*ceed)->Error = CeedErrorStore; 12432b730f8bSJeremy L Thompson else (*ceed)->Error = CeedErrorAbort; 1244d1d35e2fSjeremylt memcpy((*ceed)->err_msg, "No error message stored", 24); 1245d7b241e6Sjeremylt (*ceed)->data = NULL; 1246fe2413ffSjeremylt 1247fe2413ffSjeremylt // Set lookup table 1248d1d35e2fSjeremylt FOffset f_offsets[] = { 12496e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, Error), 12505ae360d4SJeremy L Thompson CEED_FTABLE_ENTRY(Ceed, SetStream), 12516e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, GetPreferredMemType), 12526e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, Destroy), 1253f8902d9eSjeremylt CEED_FTABLE_ENTRY(Ceed, VectorCreate), 12546e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, ElemRestrictionCreate), 12553ac8f562SJeremy L Thompson CEED_FTABLE_ENTRY(Ceed, ElemRestrictionCreateAtPoints), 12566e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, ElemRestrictionCreateBlocked), 12576e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, BasisCreateTensorH1), 12586e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, BasisCreateH1), 125950c301a5SRezgar Shakeri CEED_FTABLE_ENTRY(Ceed, BasisCreateHdiv), 1260c4e3f59bSSebastian Grimberg CEED_FTABLE_ENTRY(Ceed, BasisCreateHcurl), 12616e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, TensorContractCreate), 12626e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, QFunctionCreate), 1263777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(Ceed, QFunctionContextCreate), 12646e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, OperatorCreate), 126548acf710SJeremy L Thompson CEED_FTABLE_ENTRY(Ceed, OperatorCreateAtPoints), 12666e79d475Sjeremylt CEED_FTABLE_ENTRY(Ceed, CompositeOperatorCreate), 12679c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, HasValidArray), 12689c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, HasBorrowedArrayOfType), 12690b8f3c4eSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, CopyStrided), 12706e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, SetArray), 12716a6c615bSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, TakeArray), 12726e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, SetValue), 12730b8f3c4eSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, SetValueStrided), 1274f48ed27dSnbeams CEED_FTABLE_ENTRY(CeedVector, SyncArray), 12756e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, GetArray), 12766e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, GetArrayRead), 12779c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, GetArrayWrite), 12786e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, RestoreArray), 12796e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, RestoreArrayRead), 1280547d9b97Sjeremylt CEED_FTABLE_ENTRY(CeedVector, Norm), 1281e0dd3b27Sjeremylt CEED_FTABLE_ENTRY(CeedVector, Scale), 12820f7fd0f8Sjeremylt CEED_FTABLE_ENTRY(CeedVector, AXPY), 12835fb68f37SKaren (Ren) Stengel CEED_FTABLE_ENTRY(CeedVector, AXPBY), 12840f7fd0f8Sjeremylt CEED_FTABLE_ENTRY(CeedVector, PointwiseMult), 1285d99fa3c5SJeremy L Thompson CEED_FTABLE_ENTRY(CeedVector, Reciprocal), 12866e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedVector, Destroy), 12876e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedElemRestriction, Apply), 1288f30b1135SSebastian Grimberg CEED_FTABLE_ENTRY(CeedElemRestriction, ApplyUnsigned), 12897c1dbaffSSebastian Grimberg CEED_FTABLE_ENTRY(CeedElemRestriction, ApplyUnoriented), 129005fa913cSJeremy L Thompson CEED_FTABLE_ENTRY(CeedElemRestriction, ApplyAtPointsInElement), 12916e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedElemRestriction, ApplyBlock), 1292bd33150aSjeremylt CEED_FTABLE_ENTRY(CeedElemRestriction, GetOffsets), 129377d1c127SSebastian Grimberg CEED_FTABLE_ENTRY(CeedElemRestriction, GetOrientations), 129477d1c127SSebastian Grimberg CEED_FTABLE_ENTRY(CeedElemRestriction, GetCurlOrientations), 129519605835SJeremy L Thompson CEED_FTABLE_ENTRY(CeedElemRestriction, GetAtPointsElementOffset), 12966e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedElemRestriction, Destroy), 12976e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedBasis, Apply), 1298db2becc9SJeremy L Thompson CEED_FTABLE_ENTRY(CeedBasis, ApplyAdd), 1299c8c3fa7dSJeremy L Thompson CEED_FTABLE_ENTRY(CeedBasis, ApplyAtPoints), 1300db2becc9SJeremy L Thompson CEED_FTABLE_ENTRY(CeedBasis, ApplyAddAtPoints), 13016e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedBasis, Destroy), 13026e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedTensorContract, Apply), 13036e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedTensorContract, Destroy), 13046e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedQFunction, Apply), 13058c84ac63Sjeremylt CEED_FTABLE_ENTRY(CeedQFunction, SetCUDAUserFunction), 13068c84ac63Sjeremylt CEED_FTABLE_ENTRY(CeedQFunction, SetHIPUserFunction), 13076e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedQFunction, Destroy), 13089c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, HasValidData), 13099c774eddSJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, HasBorrowedDataOfType), 1310777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, SetData), 1311891038deSjeremylt CEED_FTABLE_ENTRY(CeedQFunctionContext, TakeData), 1312777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, GetData), 131328bfd0b7SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, GetDataRead), 1314777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, RestoreData), 131528bfd0b7SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, RestoreDataRead), 13162e64a2b9SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, DataDestroy), 1317777ff853SJeremy L Thompson CEED_FTABLE_ENTRY(CeedQFunctionContext, Destroy), 131880ac2e43SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleQFunction), 131970a7ffb3SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleQFunctionUpdate), 132080ac2e43SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleDiagonal), 13219e9210b8SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleAddDiagonal), 132280ac2e43SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssemblePointBlockDiagonal), 13239e9210b8SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleAddPointBlockDiagonal), 1324e2f04181SAndrew T. Barker CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleSymbolic), 1325e2f04181SAndrew T. Barker CEED_FTABLE_ENTRY(CeedOperator, LinearAssemble), 1326cefa2673SJeremy L Thompson CEED_FTABLE_ENTRY(CeedOperator, LinearAssembleSingle), 1327713f43c3Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, CreateFDMElementInverse), 13286e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, Apply), 1329250756a7Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, ApplyComposite), 1330cae8b89aSjeremylt CEED_FTABLE_ENTRY(CeedOperator, ApplyAdd), 1331250756a7Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, ApplyAddComposite), 13326e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, ApplyJacobian), 13336e79d475Sjeremylt CEED_FTABLE_ENTRY(CeedOperator, Destroy), 13346e79d475Sjeremylt {NULL, 0} // End of lookup table - used in SetBackendFunction loop 13351dfeef1dSjeremylt }; 1336fe2413ffSjeremylt 13372b730f8bSJeremy L Thompson CeedCall(CeedCalloc(sizeof(f_offsets), &(*ceed)->f_offsets)); 1338d1d35e2fSjeremylt memcpy((*ceed)->f_offsets, f_offsets, sizeof(f_offsets)); 1339fe2413ffSjeremylt 134060f9e2d6SJeremy L Thompson // Record env variables CEED_DEBUG or DBG 13411c66c397SJeremy L Thompson (*ceed)->is_debug = getenv("CEED_DEBUG") || getenv("DEBUG") || getenv("DBG"); 134260f9e2d6SJeremy L Thompson 134322e44211Sjeremylt // Copy resource prefix, if backend setup successful 13442b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(backends[match_index].prefix, (char **)&(*ceed)->resource)); 1345ee5a26f2SJeremy L Thompson 1346ee5a26f2SJeremy L Thompson // Set default JiT source root 1347ea61e9acSJeremy L Thompson // Note: there will always be the default root for every Ceed but all additional paths are added to the top-most parent 13482b730f8bSJeremy L Thompson CeedCall(CeedAddJitSourceRoot(*ceed, (char *)CeedJitSourceRootDefault)); 1349ee5a26f2SJeremy L Thompson 13502027fb9dSSirAlienTheGreat // By default, make cuda compile without clang, use nvrtc instead 13512027fb9dSSirAlienTheGreat // Note that this is overridden if a rust file is included (rust requires clang) 13522027fb9dSSirAlienTheGreat const char *env = getenv("GPU_CLANG"); 13532027fb9dSSirAlienTheGreat 13542027fb9dSSirAlienTheGreat if (env && strcmp(env, "1") == 0) { 13552027fb9dSSirAlienTheGreat (*ceed)->cuda_compile_with_clang = true; 13562027fb9dSSirAlienTheGreat } else { 13572027fb9dSSirAlienTheGreat (*ceed)->cuda_compile_with_clang = false; 13582027fb9dSSirAlienTheGreat } 13592027fb9dSSirAlienTheGreat 1360d04bbc78SJeremy L Thompson // Backend specific setup 13612b730f8bSJeremy L Thompson CeedCall(backends[match_index].init(&resource[match_help], *ceed)); 1362e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1363d7b241e6Sjeremylt } 1364d7b241e6Sjeremylt 1365d7b241e6Sjeremylt /** 1366ca94c3ddSJeremy L Thompson @brief Set the GPU stream for a `Ceed` context 13675ae360d4SJeremy L Thompson 1368ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context to set the stream 13695ae360d4SJeremy L Thompson @param[in] handle Handle to GPU stream 13705ae360d4SJeremy L Thompson 13715ae360d4SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 13725ae360d4SJeremy L Thompson 13735ae360d4SJeremy L Thompson @ref User 13745ae360d4SJeremy L Thompson **/ 13755ae360d4SJeremy L Thompson int CeedSetStream(Ceed ceed, void *handle) { 1376ca94c3ddSJeremy L Thompson CeedCheck(handle, ceed, CEED_ERROR_INCOMPATIBLE, "Stream handle must be non-NULL"); 13779ffb25e0SJames Wright if (ceed->SetStream) { 13785ae360d4SJeremy L Thompson CeedCall(ceed->SetStream(ceed, handle)); 13799ffb25e0SJames Wright } else { 13809ffb25e0SJames Wright Ceed delegate; 13819ffb25e0SJames Wright CeedCall(CeedGetDelegate(ceed, &delegate)); 13825ae360d4SJeremy L Thompson 138328ce3d2aSJeremy L Thompson if (delegate) CeedCall(CeedSetStream(delegate, handle)); 138428ce3d2aSJeremy L Thompson else return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support setting stream"); 13859bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 13869ffb25e0SJames Wright } 13875ae360d4SJeremy L Thompson return CEED_ERROR_SUCCESS; 13885ae360d4SJeremy L Thompson } 13895ae360d4SJeremy L Thompson 13905ae360d4SJeremy L Thompson /** 1391ca94c3ddSJeremy L Thompson @brief Copy the pointer to a `Ceed` context. 13924385fb7fSSebastian Grimberg 1393ca94c3ddSJeremy L Thompson Both pointers should be destroyed with @ref CeedDestroy(). 1394512bb800SJeremy L Thompson 1395ca94c3ddSJeremy 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. 1396ca94c3ddSJeremy L Thompson This `Ceed` context will be destroyed if `*ceed_copy` is the only reference to this `Ceed` context. 13979560d06aSjeremylt 1398ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to copy reference to 1399ea61e9acSJeremy L Thompson @param[in,out] ceed_copy Variable to store copied reference 14009560d06aSjeremylt 14019560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 14029560d06aSjeremylt 14039560d06aSjeremylt @ref User 14049560d06aSjeremylt **/ 14059560d06aSjeremylt int CeedReferenceCopy(Ceed ceed, Ceed *ceed_copy) { 14062b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 14072b730f8bSJeremy L Thompson CeedCall(CeedDestroy(ceed_copy)); 14089560d06aSjeremylt *ceed_copy = ceed; 14099560d06aSjeremylt return CEED_ERROR_SUCCESS; 14109560d06aSjeremylt } 14119560d06aSjeremylt 14129560d06aSjeremylt /** 1413ca94c3ddSJeremy L Thompson @brief Get the full resource name for a `Ceed` context 14142f86a920SJeremy L Thompson 1415ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to get resource name of 14167a982d89SJeremy L. Thompson @param[out] resource Variable to store resource name 14172f86a920SJeremy L Thompson 14182f86a920SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 14192f86a920SJeremy L Thompson 14207a982d89SJeremy L. Thompson @ref User 14215107b09fSJeremy L Thompson **/ 14227a982d89SJeremy L. Thompson int CeedGetResource(Ceed ceed, const char **resource) { 14237a982d89SJeremy L. Thompson *resource = (const char *)ceed->resource; 1424e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 14255107b09fSJeremy L Thompson } 14265107b09fSJeremy L Thompson 14275107b09fSJeremy L Thompson /** 1428ca94c3ddSJeremy L Thompson @brief Return `Ceed` context preferred memory type 1429c907536fSjeremylt 1430ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to get preferred memory type of 1431d1d35e2fSjeremylt @param[out] mem_type Address to save preferred memory type to 1432c907536fSjeremylt 1433c907536fSjeremylt @return An error code: 0 - success, otherwise - failure 1434c907536fSjeremylt 14357a982d89SJeremy L. Thompson @ref User 1436c907536fSjeremylt **/ 1437d1d35e2fSjeremylt int CeedGetPreferredMemType(Ceed ceed, CeedMemType *mem_type) { 1438c907536fSjeremylt if (ceed->GetPreferredMemType) { 14392b730f8bSJeremy L Thompson CeedCall(ceed->GetPreferredMemType(mem_type)); 1440c907536fSjeremylt } else { 1441c263cd57Sjeremylt Ceed delegate; 14422b730f8bSJeremy L Thompson CeedCall(CeedGetDelegate(ceed, &delegate)); 1443c263cd57Sjeremylt 1444c263cd57Sjeremylt if (delegate) { 14452b730f8bSJeremy L Thompson CeedCall(CeedGetPreferredMemType(delegate, mem_type)); 1446c263cd57Sjeremylt } else { 1447d1d35e2fSjeremylt *mem_type = CEED_MEM_HOST; 1448c907536fSjeremylt } 14499bc66399SJeremy L Thompson CeedCall(CeedDestroy(&delegate)); 1450c263cd57Sjeremylt } 1451e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1452c907536fSjeremylt } 1453c907536fSjeremylt 1454c907536fSjeremylt /** 1455ca94c3ddSJeremy L Thompson @brief Get deterministic status of `Ceed` context 14569525855cSJeremy L Thompson 1457ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context 1458d1d35e2fSjeremylt @param[out] is_deterministic Variable to store deterministic status 14599525855cSJeremy L Thompson 14609525855cSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 14619525855cSJeremy L Thompson 14629525855cSJeremy L Thompson @ref User 14639525855cSJeremy L Thompson **/ 1464d1d35e2fSjeremylt int CeedIsDeterministic(Ceed ceed, bool *is_deterministic) { 1465d1d35e2fSjeremylt *is_deterministic = ceed->is_deterministic; 1466e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 14679525855cSJeremy L Thompson } 14689525855cSJeremy L Thompson 14699525855cSJeremy L Thompson /** 1470ca94c3ddSJeremy L Thompson @brief Set additional JiT source root for `Ceed` context 1471ee5a26f2SJeremy L Thompson 1472ca94c3ddSJeremy L Thompson @param[in,out] ceed `Ceed` context 1473ee5a26f2SJeremy L Thompson @param[in] jit_source_root Absolute path to additional JiT source directory 1474ee5a26f2SJeremy L Thompson 1475ee5a26f2SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1476ee5a26f2SJeremy L Thompson 1477ee5a26f2SJeremy L Thompson @ref User 1478ee5a26f2SJeremy L Thompson **/ 1479ee5a26f2SJeremy L Thompson int CeedAddJitSourceRoot(Ceed ceed, const char *jit_source_root) { 14806155f12fSJeremy L Thompson Ceed ceed_parent; 1481ee5a26f2SJeremy L Thompson 14822b730f8bSJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent)); 1483830fc37bSJeremy 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"); 14846155f12fSJeremy L Thompson 14856155f12fSJeremy L Thompson CeedInt index = ceed_parent->num_jit_source_roots; 1486ee5a26f2SJeremy L Thompson size_t path_length = strlen(jit_source_root); 14871c66c397SJeremy L Thompson 14884753b775SJeremy L Thompson if (ceed_parent->num_jit_source_roots == ceed_parent->max_jit_source_roots) { 14894753b775SJeremy L Thompson if (ceed_parent->max_jit_source_roots == 0) ceed_parent->max_jit_source_roots = 1; 14904753b775SJeremy L Thompson ceed_parent->max_jit_source_roots *= 2; 14914753b775SJeremy L Thompson CeedCall(CeedRealloc(ceed_parent->max_jit_source_roots, &ceed_parent->jit_source_roots)); 14924753b775SJeremy L Thompson } 14932b730f8bSJeremy L Thompson CeedCall(CeedCalloc(path_length + 1, &ceed_parent->jit_source_roots[index])); 1494d602d780SJeremy L Thompson memcpy(ceed_parent->jit_source_roots[index], jit_source_root, path_length); 14956155f12fSJeremy L Thompson ceed_parent->num_jit_source_roots++; 14969bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed_parent)); 1497ee5a26f2SJeremy L Thompson return CEED_ERROR_SUCCESS; 1498ee5a26f2SJeremy L Thompson } 1499ee5a26f2SJeremy L Thompson 1500ee5a26f2SJeremy L Thompson /** 15012027fb9dSSirAlienTheGreat @brief Set additional Rust source root for `Ceed` context for use in QFunction 15022027fb9dSSirAlienTheGreat 15032027fb9dSSirAlienTheGreat @param[in,out] ceed `Ceed` context 15042027fb9dSSirAlienTheGreat @param[in] rust_source_root Absolute path to additional Rust source directory 15052027fb9dSSirAlienTheGreat 15062027fb9dSSirAlienTheGreat @return An error code: 0 - success, otherwise - failure 15072027fb9dSSirAlienTheGreat 15082027fb9dSSirAlienTheGreat @ref User 15092027fb9dSSirAlienTheGreat **/ 15102027fb9dSSirAlienTheGreat int CeedAddRustSourceRoot(Ceed ceed, const char *rust_source_root) { 15112027fb9dSSirAlienTheGreat Ceed ceed_parent; 15122027fb9dSSirAlienTheGreat 15132027fb9dSSirAlienTheGreat CeedCall(CeedGetParent(ceed, &ceed_parent)); 15142027fb9dSSirAlienTheGreat CeedCheck(!ceed_parent->num_rust_source_roots_readers, ceed, CEED_ERROR_ACCESS, "Cannot add Rust source root, read access has not been restored"); 15152027fb9dSSirAlienTheGreat 15162027fb9dSSirAlienTheGreat CeedInt index = ceed_parent->num_rust_source_roots; 15172027fb9dSSirAlienTheGreat size_t path_length = strlen(rust_source_root); 15182027fb9dSSirAlienTheGreat 15192027fb9dSSirAlienTheGreat if (ceed_parent->num_rust_source_roots == ceed_parent->max_rust_source_roots) { 15202027fb9dSSirAlienTheGreat if (ceed_parent->max_rust_source_roots == 0) ceed_parent->max_rust_source_roots = 1; 15212027fb9dSSirAlienTheGreat ceed_parent->max_rust_source_roots *= 2; 15222027fb9dSSirAlienTheGreat CeedCall(CeedRealloc(ceed_parent->max_rust_source_roots, &ceed_parent->rust_source_roots)); 15232027fb9dSSirAlienTheGreat } 15242027fb9dSSirAlienTheGreat CeedCall(CeedCalloc(path_length + 1, &ceed_parent->rust_source_roots[index])); 15252027fb9dSSirAlienTheGreat memcpy(ceed_parent->rust_source_roots[index], rust_source_root, path_length); 15262027fb9dSSirAlienTheGreat ceed_parent->num_rust_source_roots++; 15272027fb9dSSirAlienTheGreat ceed_parent->cuda_compile_with_clang = true; 15282027fb9dSSirAlienTheGreat ceed->cuda_compile_with_clang = true; 15292027fb9dSSirAlienTheGreat CeedCall(CeedDestroy(&ceed_parent)); 15302027fb9dSSirAlienTheGreat return CEED_ERROR_SUCCESS; 15312027fb9dSSirAlienTheGreat } 15322027fb9dSSirAlienTheGreat 15332027fb9dSSirAlienTheGreat /** 15344753b775SJeremy L Thompson @brief Set additional JiT compiler define for `Ceed` context 15354753b775SJeremy L Thompson 15364753b775SJeremy L Thompson @param[in,out] ceed `Ceed` context 15374753b775SJeremy L Thompson @param[in] jit_define String such as `foo=bar`, used as `-Dfoo=bar` in JiT 15384753b775SJeremy L Thompson 15394753b775SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 15404753b775SJeremy L Thompson 15414753b775SJeremy L Thompson @ref User 15424753b775SJeremy L Thompson **/ 15434753b775SJeremy L Thompson int CeedAddJitDefine(Ceed ceed, const char *jit_define) { 15444753b775SJeremy L Thompson Ceed ceed_parent; 15454753b775SJeremy L Thompson 15464753b775SJeremy L Thompson CeedCall(CeedGetParent(ceed, &ceed_parent)); 1547830fc37bSJeremy L Thompson CeedCheck(!ceed_parent->num_jit_defines_readers, ceed, CEED_ERROR_ACCESS, "Cannot add JiT define, read access has not been restored"); 15484753b775SJeremy L Thompson 15494753b775SJeremy L Thompson CeedInt index = ceed_parent->num_jit_defines; 15504753b775SJeremy L Thompson size_t define_length = strlen(jit_define); 15514753b775SJeremy L Thompson 15524753b775SJeremy L Thompson if (ceed_parent->num_jit_defines == ceed_parent->max_jit_defines) { 15534753b775SJeremy L Thompson if (ceed_parent->max_jit_defines == 0) ceed_parent->max_jit_defines = 1; 15544753b775SJeremy L Thompson ceed_parent->max_jit_defines *= 2; 15554753b775SJeremy L Thompson CeedCall(CeedRealloc(ceed_parent->max_jit_defines, &ceed_parent->jit_defines)); 15564753b775SJeremy L Thompson } 15574753b775SJeremy L Thompson CeedCall(CeedCalloc(define_length + 1, &ceed_parent->jit_defines[index])); 15584753b775SJeremy L Thompson memcpy(ceed_parent->jit_defines[index], jit_define, define_length); 15594753b775SJeremy L Thompson ceed_parent->num_jit_defines++; 15609bc66399SJeremy L Thompson CeedCall(CeedDestroy(&ceed_parent)); 15614753b775SJeremy L Thompson return CEED_ERROR_SUCCESS; 15624753b775SJeremy L Thompson } 15634753b775SJeremy L Thompson 15644753b775SJeremy L Thompson /** 15654c789ea2SJeremy L Thompson @brief Set the number of tabs to indent for @ref CeedView() output 15664c789ea2SJeremy L Thompson 15674c789ea2SJeremy L Thompson @param[in] ceed `Ceed` to set the number of view tabs 15684c789ea2SJeremy L Thompson @param[in] num_tabs Number of view tabs to set 15694c789ea2SJeremy L Thompson 15704c789ea2SJeremy L Thompson @return Error code: 0 - success, otherwise - failure 15714c789ea2SJeremy L Thompson 15724c789ea2SJeremy L Thompson @ref User 15734c789ea2SJeremy L Thompson **/ 15744c789ea2SJeremy L Thompson int CeedSetNumViewTabs(Ceed ceed, CeedInt num_tabs) { 1575*a299a25bSJeremy L Thompson CeedCall(CeedObjectSetNumViewTabs((CeedObject)ceed, num_tabs)); 15764c789ea2SJeremy L Thompson return CEED_ERROR_SUCCESS; 15774c789ea2SJeremy L Thompson } 15784c789ea2SJeremy L Thompson 15794c789ea2SJeremy L Thompson /** 1580690992b2SZach Atkins @brief Get the number of tabs to indent for @ref CeedView() output 1581690992b2SZach Atkins 1582690992b2SZach Atkins @param[in] ceed `Ceed` to get the number of view tabs 1583690992b2SZach Atkins @param[out] num_tabs Number of view tabs 1584690992b2SZach Atkins 1585690992b2SZach Atkins @return Error code: 0 - success, otherwise - failure 1586690992b2SZach Atkins 1587690992b2SZach Atkins @ref User 1588690992b2SZach Atkins **/ 1589690992b2SZach Atkins int CeedGetNumViewTabs(Ceed ceed, CeedInt *num_tabs) { 1590*a299a25bSJeremy L Thompson CeedCall(CeedObjectGetNumViewTabs((CeedObject)ceed, num_tabs)); 1591690992b2SZach Atkins return CEED_ERROR_SUCCESS; 1592690992b2SZach Atkins } 1593690992b2SZach Atkins 1594690992b2SZach Atkins /** 1595ca94c3ddSJeremy L Thompson @brief View a `Ceed` 15960a0da059Sjeremylt 1597ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` to view 15980a0da059Sjeremylt @param[in] stream Filestream to write to 15990a0da059Sjeremylt 16000a0da059Sjeremylt @return An error code: 0 - success, otherwise - failure 16010a0da059Sjeremylt 16020a0da059Sjeremylt @ref User 16030a0da059Sjeremylt **/ 16040a0da059Sjeremylt int CeedView(Ceed ceed, FILE *stream) { 16054c789ea2SJeremy L Thompson char *tabs = NULL; 1606d1d35e2fSjeremylt CeedMemType mem_type; 16070a0da059Sjeremylt 16084c789ea2SJeremy L Thompson { 16094c789ea2SJeremy L Thompson CeedInt num_tabs = 0; 16104c789ea2SJeremy L Thompson 16114c789ea2SJeremy L Thompson CeedCall(CeedGetNumViewTabs(ceed, &num_tabs)); 16124c789ea2SJeremy L Thompson CeedCall(CeedCalloc(CEED_TAB_WIDTH * num_tabs + 1, &tabs)); 16134c789ea2SJeremy L Thompson for (CeedInt i = 0; i < CEED_TAB_WIDTH * num_tabs; i++) tabs[i] = ' '; 16144c789ea2SJeremy L Thompson } 16154c789ea2SJeremy L Thompson 16162b730f8bSJeremy L Thompson CeedCall(CeedGetPreferredMemType(ceed, &mem_type)); 16170a0da059Sjeremylt 16182b730f8bSJeremy L Thompson fprintf(stream, 16194c789ea2SJeremy L Thompson "%sCeed\n" 16204c789ea2SJeremy L Thompson "%s Ceed Resource: %s\n" 16214c789ea2SJeremy L Thompson "%s Preferred MemType: %s\n", 16224c789ea2SJeremy L Thompson tabs, tabs, ceed->resource, tabs, CeedMemTypes[mem_type]); 16234c789ea2SJeremy L Thompson CeedCall(CeedFree(&tabs)); 1624e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 16250a0da059Sjeremylt } 16260a0da059Sjeremylt 16270a0da059Sjeremylt /** 1628ca94c3ddSJeremy L Thompson @brief Destroy a `Ceed` 1629d7b241e6Sjeremylt 1630ca94c3ddSJeremy L Thompson @param[in,out] ceed Address of `Ceed` context to destroy 1631b11c1e72Sjeremylt 1632b11c1e72Sjeremylt @return An error code: 0 - success, otherwise - failure 1633dfdf5a53Sjeremylt 16347a982d89SJeremy L. Thompson @ref User 1635b11c1e72Sjeremylt **/ 1636d7b241e6Sjeremylt int CeedDestroy(Ceed *ceed) { 1637b0f67a9cSJeremy L Thompson if (!*ceed || CeedObjectDereference((CeedObject)*ceed) > 0) { 1638ad6481ceSJeremy L Thompson *ceed = NULL; 1639ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 1640ad6481ceSJeremy L Thompson } 1641aeb3a72dSJeremy L Thompson 1642aeb3a72dSJeremy L Thompson CeedCheck(!(*ceed)->num_jit_source_roots_readers, *ceed, CEED_ERROR_ACCESS, 1643aeb3a72dSJeremy L Thompson "Cannot destroy ceed context, read access for JiT source roots has been granted"); 1644aeb3a72dSJeremy 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"); 1645aeb3a72dSJeremy L Thompson 16462b730f8bSJeremy L Thompson if ((*ceed)->delegate) CeedCall(CeedDestroy(&(*ceed)->delegate)); 16470ace9bf2Sjeremylt 1648d1d35e2fSjeremylt if ((*ceed)->obj_delegate_count > 0) { 164992ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*ceed)->obj_delegate_count; i++) { 16502b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&((*ceed)->obj_delegates[i].delegate))); 16512b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->obj_delegates[i].obj_name)); 1652aefd8378Sjeremylt } 16532b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->obj_delegates)); 1654aefd8378Sjeremylt } 16550ace9bf2Sjeremylt 16562b730f8bSJeremy L Thompson if ((*ceed)->Destroy) CeedCall((*ceed)->Destroy(*ceed)); 16570ace9bf2Sjeremylt 165892ae7e47SJeremy L Thompson for (CeedInt i = 0; i < (*ceed)->num_jit_source_roots; i++) { 16592b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->jit_source_roots[i])); 1660032e71eaSJeremy L Thompson } 16612b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->jit_source_roots)); 1662032e71eaSJeremy L Thompson 16634753b775SJeremy L Thompson for (CeedInt i = 0; i < (*ceed)->num_jit_defines; i++) { 16644753b775SJeremy L Thompson CeedCall(CeedFree(&(*ceed)->jit_defines[i])); 16654753b775SJeremy L Thompson } 16664753b775SJeremy L Thompson CeedCall(CeedFree(&(*ceed)->jit_defines)); 16674753b775SJeremy L Thompson 1668898eb931SJeremy L Thompson for (CeedInt i = 0; i < (*ceed)->num_rust_source_roots; i++) { 1669898eb931SJeremy L Thompson CeedCall(CeedFree(&(*ceed)->rust_source_roots[i])); 1670898eb931SJeremy L Thompson } 1671898eb931SJeremy L Thompson CeedCall(CeedFree(&(*ceed)->rust_source_roots)); 1672898eb931SJeremy L Thompson 16732b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->f_offsets)); 16742b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ceed)->resource)); 16752b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*ceed)->op_fallback_ceed)); 167673501bfeSJeremy L Thompson CeedCall(CeedWorkVectorsDestroy(*ceed)); 1677b0f67a9cSJeremy L Thompson CeedCall(CeedObjectDestroy(&(*ceed)->obj)); 16782b730f8bSJeremy L Thompson CeedCall(CeedFree(ceed)); 1679e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1680d7b241e6Sjeremylt } 1681d7b241e6Sjeremylt 1682f9982c62SWill Pazner // LCOV_EXCL_START 1683f9982c62SWill Pazner const char *CeedErrorFormat(Ceed ceed, const char *format, va_list *args) { 16842b730f8bSJeremy L Thompson if (ceed->parent) return CeedErrorFormat(ceed->parent, format, args); 168578464608Sjeremylt // Using pointer to va_list for better FFI, but clang-tidy can't verify va_list is initalized 168678464608Sjeremylt vsnprintf(ceed->err_msg, CEED_MAX_RESOURCE_LEN, format, *args); // NOLINT 1687d1d35e2fSjeremylt return ceed->err_msg; 1688f9982c62SWill Pazner } 1689f9982c62SWill Pazner // LCOV_EXCL_STOP 1690f9982c62SWill Pazner 16917a982d89SJeremy L. Thompson /** 1692ca94c3ddSJeremy L Thompson @brief Error handling implementation; use @ref CeedError() instead. 1693ca94c3ddSJeremy L Thompson 1694ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 16957a982d89SJeremy L. Thompson 16967a982d89SJeremy L. Thompson @ref Developer 16977a982d89SJeremy L. Thompson **/ 16982b730f8bSJeremy L Thompson int CeedErrorImpl(Ceed ceed, const char *filename, int lineno, const char *func, int ecode, const char *format, ...) { 16997a982d89SJeremy L. Thompson va_list args; 1700d1d35e2fSjeremylt int ret_val; 17011c66c397SJeremy L Thompson 17027a982d89SJeremy L. Thompson va_start(args, format); 17037a982d89SJeremy L. Thompson if (ceed) { 1704d1d35e2fSjeremylt ret_val = ceed->Error(ceed, filename, lineno, func, ecode, format, &args); 17057a982d89SJeremy L. Thompson } else { 1706b0d62198Sjeremylt // LCOV_EXCL_START 1707477729cfSJeremy L Thompson const char *ceed_error_handler = getenv("CEED_ERROR_HANDLER"); 17082b730f8bSJeremy L Thompson if (!ceed_error_handler) ceed_error_handler = "abort"; 1709bcbe1c99SJeremy L Thompson if (!strcmp(ceed_error_handler, "return")) { 1710bcbe1c99SJeremy L Thompson ret_val = CeedErrorReturn(ceed, filename, lineno, func, ecode, format, &args); 1711bcbe1c99SJeremy L Thompson } else { 1712477729cfSJeremy L Thompson // This function will not return 1713d1d35e2fSjeremylt ret_val = CeedErrorAbort(ceed, filename, lineno, func, ecode, format, &args); 17147a982d89SJeremy L. Thompson } 1715bcbe1c99SJeremy L Thompson } 17167a982d89SJeremy L. Thompson va_end(args); 1717d1d35e2fSjeremylt return ret_val; 1718b0d62198Sjeremylt // LCOV_EXCL_STOP 17197a982d89SJeremy L. Thompson } 17207a982d89SJeremy L. Thompson 1721477729cfSJeremy L Thompson /** 1722477729cfSJeremy L Thompson @brief Error handler that returns without printing anything. 1723477729cfSJeremy L Thompson 1724ca94c3ddSJeremy L Thompson Pass this to @ref CeedSetErrorHandler() to obtain this error handling behavior. 1725ca94c3ddSJeremy L Thompson 1726ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1727477729cfSJeremy L Thompson 1728477729cfSJeremy L Thompson @ref Developer 1729477729cfSJeremy L Thompson **/ 1730477729cfSJeremy L Thompson // LCOV_EXCL_START 17312b730f8bSJeremy L Thompson int CeedErrorReturn(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) { 1732d1d35e2fSjeremylt return err_code; 1733477729cfSJeremy L Thompson } 1734477729cfSJeremy L Thompson // LCOV_EXCL_STOP 1735477729cfSJeremy L Thompson 1736477729cfSJeremy L Thompson /** 1737ea61e9acSJeremy L Thompson @brief Error handler that stores the error message for future use and returns the error. 1738477729cfSJeremy L Thompson 1739ca94c3ddSJeremy L Thompson Pass this to @ref CeedSetErrorHandler() to obtain this error handling behavior. 1740ca94c3ddSJeremy L Thompson 1741ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1742477729cfSJeremy L Thompson 1743477729cfSJeremy L Thompson @ref Developer 1744477729cfSJeremy L Thompson **/ 1745477729cfSJeremy L Thompson // LCOV_EXCL_START 17462b730f8bSJeremy L Thompson int CeedErrorStore(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) { 17472b730f8bSJeremy L Thompson if (ceed->parent) return CeedErrorStore(ceed->parent, filename, line_no, func, err_code, format, args); 1748477729cfSJeremy L Thompson 1749477729cfSJeremy L Thompson // Build message 17501c66c397SJeremy L Thompson int len = snprintf(ceed->err_msg, CEED_MAX_RESOURCE_LEN, "%s:%d in %s(): ", filename, line_no, func); 175178464608Sjeremylt // Using pointer to va_list for better FFI, but clang-tidy can't verify va_list is initalized 175278464608Sjeremylt vsnprintf(ceed->err_msg + len, CEED_MAX_RESOURCE_LEN - len, format, *args); // NOLINT 1753d1d35e2fSjeremylt return err_code; 1754477729cfSJeremy L Thompson } 1755477729cfSJeremy L Thompson // LCOV_EXCL_STOP 1756477729cfSJeremy L Thompson 1757477729cfSJeremy L Thompson /** 1758ca94c3ddSJeremy L Thompson @brief Error handler that prints to `stderr` and aborts 1759477729cfSJeremy L Thompson 1760ca94c3ddSJeremy L Thompson Pass this to @ref CeedSetErrorHandler() to obtain this error handling behavior. 1761ca94c3ddSJeremy L Thompson 1762ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1763477729cfSJeremy L Thompson 1764477729cfSJeremy L Thompson @ref Developer 1765477729cfSJeremy L Thompson **/ 1766477729cfSJeremy L Thompson // LCOV_EXCL_START 17672b730f8bSJeremy L Thompson int CeedErrorAbort(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) { 1768d1d35e2fSjeremylt fprintf(stderr, "%s:%d in %s(): ", filename, line_no, func); 1769f9982c62SWill Pazner vfprintf(stderr, format, *args); 1770477729cfSJeremy L Thompson fprintf(stderr, "\n"); 1771477729cfSJeremy L Thompson abort(); 1772d1d35e2fSjeremylt return err_code; 1773477729cfSJeremy L Thompson } 1774477729cfSJeremy L Thompson // LCOV_EXCL_STOP 1775477729cfSJeremy L Thompson 1776477729cfSJeremy L Thompson /** 1777ca94c3ddSJeremy L Thompson @brief Error handler that prints to `stderr` and exits. 1778477729cfSJeremy L Thompson 1779ca94c3ddSJeremy L Thompson Pass this to @ref CeedSetErrorHandler() to obtain this error handling behavior. 1780477729cfSJeremy L Thompson 1781ca94c3ddSJeremy L Thompson In contrast to @ref CeedErrorAbort(), this exits without a signal, so `atexit()` handlers (e.g., as used by gcov) are run. 1782ca94c3ddSJeremy L Thompson 1783ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1784477729cfSJeremy L Thompson 1785477729cfSJeremy L Thompson @ref Developer 1786477729cfSJeremy L Thompson **/ 17872b730f8bSJeremy L Thompson int CeedErrorExit(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) { 1788d1d35e2fSjeremylt fprintf(stderr, "%s:%d in %s(): ", filename, line_no, func); 178978464608Sjeremylt // Using pointer to va_list for better FFI, but clang-tidy can't verify va_list is initalized 179078464608Sjeremylt vfprintf(stderr, format, *args); // NOLINT 1791477729cfSJeremy L Thompson fprintf(stderr, "\n"); 1792d1d35e2fSjeremylt exit(err_code); 1793d1d35e2fSjeremylt return err_code; 1794477729cfSJeremy L Thompson } 1795477729cfSJeremy L Thompson 1796477729cfSJeremy L Thompson /** 1797477729cfSJeremy L Thompson @brief Set error handler 1798477729cfSJeremy L Thompson 1799ca94c3ddSJeremy L Thompson A default error handler is set in @ref CeedInit(). 1800ca94c3ddSJeremy L Thompson Use this function to change the error handler to @ref CeedErrorReturn(), @ref CeedErrorAbort(), or a user-defined error handler. 1801ca94c3ddSJeremy L Thompson 1802ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1803477729cfSJeremy L Thompson 1804477729cfSJeremy L Thompson @ref Developer 1805477729cfSJeremy L Thompson **/ 1806d1d35e2fSjeremylt int CeedSetErrorHandler(Ceed ceed, CeedErrorHandler handler) { 1807d1d35e2fSjeremylt ceed->Error = handler; 1808d1d35e2fSjeremylt if (ceed->delegate) CeedSetErrorHandler(ceed->delegate, handler); 18092b730f8bSJeremy L Thompson for (CeedInt i = 0; i < ceed->obj_delegate_count; i++) CeedSetErrorHandler(ceed->obj_delegates[i].delegate, handler); 1810e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1811477729cfSJeremy L Thompson } 1812477729cfSJeremy L Thompson 1813477729cfSJeremy L Thompson /** 1814477729cfSJeremy L Thompson @brief Get error message 1815477729cfSJeremy L Thompson 1816ca94c3ddSJeremy L Thompson The error message is only stored when using the error handler @ref CeedErrorStore() 1817477729cfSJeremy L Thompson 1818ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to retrieve error message 1819d1d35e2fSjeremylt @param[out] err_msg Char pointer to hold error message 1820477729cfSJeremy L Thompson 1821ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1822ca94c3ddSJeremy L Thompson 1823477729cfSJeremy L Thompson @ref Developer 1824477729cfSJeremy L Thompson **/ 1825d1d35e2fSjeremylt int CeedGetErrorMessage(Ceed ceed, const char **err_msg) { 18262b730f8bSJeremy L Thompson if (ceed->parent) return CeedGetErrorMessage(ceed->parent, err_msg); 1827d1d35e2fSjeremylt *err_msg = ceed->err_msg; 1828e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1829477729cfSJeremy L Thompson } 1830477729cfSJeremy L Thompson 1831477729cfSJeremy L Thompson /** 1832ca94c3ddSJeremy L Thompson @brief Restore error message. 1833477729cfSJeremy L Thompson 1834ca94c3ddSJeremy L Thompson The error message is only stored when using the error handler @ref CeedErrorStore(). 1835477729cfSJeremy L Thompson 1836ca94c3ddSJeremy L Thompson @param[in] ceed `Ceed` context to restore error message 1837d1d35e2fSjeremylt @param[out] err_msg Char pointer that holds error message 1838477729cfSJeremy L Thompson 1839ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1840ca94c3ddSJeremy L Thompson 1841477729cfSJeremy L Thompson @ref Developer 1842477729cfSJeremy L Thompson **/ 1843d1d35e2fSjeremylt int CeedResetErrorMessage(Ceed ceed, const char **err_msg) { 18442b730f8bSJeremy L Thompson if (ceed->parent) return CeedResetErrorMessage(ceed->parent, err_msg); 1845d1d35e2fSjeremylt *err_msg = NULL; 1846d1d35e2fSjeremylt memcpy(ceed->err_msg, "No error message stored", 24); 1847e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 1848477729cfSJeremy L Thompson } 1849477729cfSJeremy L Thompson 18501070991dSJed Brown /** 1851ca94c3ddSJeremy L Thompson @brief Get libCEED library version information. 18521070991dSJed Brown 1853ea61e9acSJeremy L Thompson libCEED version numbers have the form major.minor.patch. 1854ea61e9acSJeremy L Thompson Non-release versions may contain unstable interfaces. 18551070991dSJed Brown 18561070991dSJed Brown @param[out] major Major version of the library 18571070991dSJed Brown @param[out] minor Minor version of the library 18581070991dSJed Brown @param[out] patch Patch (subminor) version of the library 185953cbfc38SJeremy L Thompson @param[out] release True for releases; false for development branches 18601070991dSJed Brown 1861ca94c3ddSJeremy L Thompson The caller may pass `NULL` for any arguments that are not needed. 18621070991dSJed Brown 1863ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 18641070991dSJed Brown 18651070991dSJed Brown @ref Developer 1866ca94c3ddSJeremy L Thompson 18674f69910bSJed Brown @sa CEED_VERSION_GE() CeedGetGitVersion() CeedGetBuildConfiguration() 18681070991dSJed Brown */ 18691070991dSJed Brown int CeedGetVersion(int *major, int *minor, int *patch, bool *release) { 18701070991dSJed Brown if (major) *major = CEED_VERSION_MAJOR; 18711070991dSJed Brown if (minor) *minor = CEED_VERSION_MINOR; 18721070991dSJed Brown if (patch) *patch = CEED_VERSION_PATCH; 18731070991dSJed Brown if (release) *release = CEED_VERSION_RELEASE; 1874ca94c3ddSJeremy L Thompson return CEED_ERROR_SUCCESS; 18751070991dSJed Brown } 18761070991dSJed Brown 187753cbfc38SJeremy L Thompson /** 187853cbfc38SJeremy L Thompson @brief Get libCEED scalar type, such as F64 or F32 187953cbfc38SJeremy L Thompson 188053cbfc38SJeremy L Thompson @param[out] scalar_type Type of libCEED scalars 188153cbfc38SJeremy L Thompson 1882ca94c3ddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1883ca94c3ddSJeremy L Thompson 188453cbfc38SJeremy L Thompson @ref Developer 188553cbfc38SJeremy L Thompson */ 188680a9ef05SNatalie Beams int CeedGetScalarType(CeedScalarType *scalar_type) { 188780a9ef05SNatalie Beams *scalar_type = CEED_SCALAR_TYPE; 1888ca94c3ddSJeremy L Thompson return CEED_ERROR_SUCCESS; 188980a9ef05SNatalie Beams } 189080a9ef05SNatalie Beams 1891d7b241e6Sjeremylt /// @} 1892