Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions backends/cuda-gen/ceed-cuda-gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//------------------------------------------------------------------------------
static int CeedInit_Cuda_gen(const char *resource, Ceed ceed) {
char *resource_root;
Ceed ceed_shared;
Ceed ceed_shared, ceed_ref;
Ceed_Cuda *data;

CeedCallBackend(CeedGetResourceRoot(ceed, resource, ":", &resource_root));
Expand All @@ -34,7 +34,9 @@ static int CeedInit_Cuda_gen(const char *resource, Ceed ceed) {
CeedCallBackend(CeedSetDelegate(ceed, ceed_shared));
CeedCallBackend(CeedDestroy(&ceed_shared));

CeedCallBackend(CeedSetOperatorFallbackResource(ceed, "/gpu/cuda/ref"));
CeedCallBackend(CeedInit("/gpu/cuda/ref", &ceed_ref));
CeedCallBackend(CeedSetOperatorFallbackCeed(ceed, ceed_ref));
CeedCallBackend(CeedDestroy(&ceed_ref));

CeedCallBackend(CeedSetBackendFunction(ceed, "Ceed", ceed, "QFunctionCreate", CeedQFunctionCreate_Cuda_gen));
CeedCallBackend(CeedSetBackendFunction(ceed, "Ceed", ceed, "OperatorCreate", CeedOperatorCreate_Cuda_gen));
Expand Down
6 changes: 4 additions & 2 deletions backends/hip-gen/ceed-hip-gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//------------------------------------------------------------------------------
static int CeedInit_Hip_gen(const char *resource, Ceed ceed) {
char *resource_root;
Ceed ceed_shared;
Ceed ceed_shared, ceed_ref;
Ceed_Hip *data;

CeedCallBackend(CeedGetResourceRoot(ceed, resource, ":", &resource_root));
Expand All @@ -34,7 +34,9 @@ static int CeedInit_Hip_gen(const char *resource, Ceed ceed) {
CeedCallBackend(CeedSetDelegate(ceed, ceed_shared));
CeedCallBackend(CeedDestroy(&ceed_shared));

CeedCallBackend(CeedSetOperatorFallbackResource(ceed, "/gpu/hip/ref"));
CeedCallBackend(CeedInit("/gpu/hip/ref", &ceed_ref));
CeedCallBackend(CeedSetOperatorFallbackCeed(ceed, ceed_ref));
CeedCallBackend(CeedDestroy(&ceed_ref));

CeedCallBackend(CeedSetBackendFunction(ceed, "Ceed", ceed, "QFunctionCreate", CeedQFunctionCreate_Hip_gen));
CeedCallBackend(CeedSetBackendFunction(ceed, "Ceed", ceed, "OperatorCreate", CeedOperatorCreate_Hip_gen));
Expand Down
12 changes: 5 additions & 7 deletions backends/sycl-gen/ceed-sycl-gen.sycl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// Backend init
//------------------------------------------------------------------------------
static int CeedInit_Sycl_gen(const char *resource, Ceed ceed) {
Ceed ceed_shared;
Ceed ceed_shared, ceed_ref;
Ceed_Sycl *data;
char *resource_root;

Expand All @@ -36,12 +36,10 @@ static int CeedInit_Sycl_gen(const char *resource, Ceed ceed) {
CeedCallBackend(CeedSetStream_Sycl(ceed_shared, &(data->sycl_queue)));
CeedCallBackend(CeedDestroy(&ceed_shared));

CeedCallBackend(CeedSetOperatorFallbackResource(ceed, "/gpu/sycl/ref"));

Ceed ceed_fallback = NULL;
CeedCallBackend(CeedGetOperatorFallbackCeed(ceed, &ceed_fallback));
CeedCallBackend(CeedSetStream_Sycl(ceed_fallback, &(data->sycl_queue)));
CeedCallBackend(CeedDestroy(&ceed_fallback));
CeedCallBackend(CeedInit("/gpu/sycl/ref", &ceed_ref));
CeedCallBackend(CeedSetOperatorFallbackCeed(ceed, ceed_ref));
CeedCallBackend(CeedSetStream_Sycl(ceed_ref, &(data->sycl_queue)));
CeedCallBackend(CeedDestroy(&ceed_ref));

CeedCallBackend(CeedSetBackendFunctionCpp(ceed, "Ceed", ceed, "QFunctionCreate", CeedQFunctionCreate_Sycl_gen));
CeedCallBackend(CeedSetBackendFunctionCpp(ceed, "Ceed", ceed, "OperatorCreate", CeedOperatorCreate_Sycl_gen));
Expand Down
6 changes: 3 additions & 3 deletions doc/sphinx/source/libCEEDdev.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ There are three mechanisms by which a Ceed backend can inherit implementations f
This delegate {ref}`Ceed` will only provide the implementation of that specific libCeed object for the parent backend.
Object delegation has higher precedence than delegation.

3. Operator fallback - Developers may use {c:func}`CeedSetOperatorFallbackResource` to set a string identifying which {ref}`Ceed` backend will be instantiated to provide any unimplemented {ref}`CeedOperator` methods that support preconditioning, such as {c:func}`CeedOperatorLinearAssemble`.
3. Operator fallback - Developers may use {c:func}`CeedSetOperatorFallbackCeed` to set a {ref}`Ceed` object to provide any unimplemented {ref}`CeedOperator` methods that support preconditioning, such as {c:func}`CeedOperatorLinearAssemble`.
The parent backend must implement the basic {ref}`CeedOperator` functionality.
This fallback {ref}`Ceed` object will only be created if a method is called that is not implemented by the parent backend.
Like the delegates above, this fallback {ref}`Ceed` object should be created and set in the backend `CeedInit` function.
In order to use operator fallback, the parent backend and fallback backend must use compatible E-vector and Q-vector layouts.
For example, `/gpu/cuda/gen` falls back to `/gpu/cuda/ref` for missing {ref}`CeedOperator` preconditioning support methods.
If an unimplemented method is called, then the parent `/gpu/cuda/gen` {ref}`Ceed` object creates a fallback `/gpu/cuda/ref` {ref}`Ceed` object and creates a clone of the {ref}`CeedOperator` with this fallback {ref}`Ceed` object.
If an unimplemented method is called, then the parent `/gpu/cuda/gen` {ref}`Ceed` object uses its fallback `/gpu/cuda/ref` {ref}`Ceed` object to create a clone of the {ref}`CeedOperator`.
This clone {ref}`CeedOperator` is then used for the unimplemented preconditioning support methods.

## Backend Families
Expand Down
4 changes: 1 addition & 3 deletions include/ceed-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ struct Ceed_private {
Ceed parent;
ObjDelegate *obj_delegates;
int obj_delegate_count;
Ceed op_fallback_ceed, op_fallback_parent;
const char *op_fallback_resource;
Ceed op_fallback_ceed;
char **jit_source_roots;
CeedInt num_jit_source_roots, max_jit_source_roots, num_jit_source_roots_readers;
char **jit_defines;
Expand Down Expand Up @@ -126,7 +125,6 @@ struct Ceed_private {
int ref_count;
void *data;
bool is_debug;
bool has_valid_op_fallback_resource;
bool is_deterministic;
char err_msg[CEED_MAX_RESOURCE_LEN];
FOffset *f_offsets;
Expand Down
3 changes: 1 addition & 2 deletions include/ceed/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,9 +246,8 @@ CEED_EXTERN int CeedGetDelegate(Ceed ceed, Ceed *delegate);
CEED_EXTERN int CeedSetDelegate(Ceed ceed, Ceed delegate);
CEED_EXTERN int CeedGetObjectDelegate(Ceed ceed, Ceed *delegate, const char *obj_name);
CEED_EXTERN int CeedSetObjectDelegate(Ceed ceed, Ceed delegate, const char *obj_name);
CEED_EXTERN int CeedGetOperatorFallbackResource(Ceed ceed, const char **resource);
CEED_EXTERN int CeedGetOperatorFallbackCeed(Ceed ceed, Ceed *fallback_ceed);
CEED_EXTERN int CeedSetOperatorFallbackResource(Ceed ceed, const char *resource);
CEED_EXTERN int CeedSetOperatorFallbackCeed(Ceed ceed, Ceed fallback_ceed);
CEED_EXTERN int CeedSetDeterministic(Ceed ceed, bool is_deterministic);
CEED_EXTERN int CeedSetBackendFunctionImpl(Ceed ceed, const char *type, void *object, const char *func_name, void (*f)(void));
CEED_EXTERN int CeedGetData(Ceed ceed, void *data);
Expand Down
82 changes: 9 additions & 73 deletions interface/ceed.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,21 +623,6 @@ int CeedSetObjectDelegate(Ceed ceed, Ceed delegate, const char *obj_name) {
return CEED_ERROR_SUCCESS;
}

/**
@brief Get the fallback resource for `CeedOperator`

@param[in] ceed `Ceed` context
@param[out] resource Variable to store fallback resource

@return An error code: 0 - success, otherwise - failure

@ref Backend
**/
int CeedGetOperatorFallbackResource(Ceed ceed, const char **resource) {
*resource = (const char *)ceed->op_fallback_resource;
return CEED_ERROR_SUCCESS;
}

/**
@brief Get the fallback `Ceed` for `CeedOperator`

Expand All @@ -649,72 +634,32 @@ int CeedGetOperatorFallbackResource(Ceed ceed, const char **resource) {
@ref Backend
**/
int CeedGetOperatorFallbackCeed(Ceed ceed, Ceed *fallback_ceed) {
if (ceed->has_valid_op_fallback_resource) {
if (ceed->op_fallback_ceed) {
CeedDebug256(ceed, CEED_DEBUG_COLOR_SUCCESS, "---------- Ceed Fallback ----------\n");
CeedDebug(ceed, "Falling back from Ceed with backend %s at address %p to Ceed with backend %s", ceed->resource, ceed, ceed->op_fallback_resource);
CeedDebug(ceed, "Falling back from Ceed with backend %s at address %p to Ceed with backend %s at address %p", ceed->resource, ceed,
ceed->op_fallback_ceed->resource, ceed->op_fallback_ceed);
}

// Create fallback Ceed if uninitialized
if (!ceed->op_fallback_ceed && ceed->has_valid_op_fallback_resource) {
CeedDebug(ceed, "Creating fallback Ceed");

Ceed fallback_ceed;
const char *fallback_resource;

CeedCall(CeedGetOperatorFallbackResource(ceed, &fallback_resource));
CeedCall(CeedInit(fallback_resource, &fallback_ceed));
fallback_ceed->op_fallback_parent = ceed;
fallback_ceed->Error = ceed->Error;
ceed->op_fallback_ceed = fallback_ceed;
{
const char **jit_source_roots;
CeedInt num_jit_source_roots = 0;

CeedCall(CeedGetJitSourceRoots(ceed, &num_jit_source_roots, &jit_source_roots));
for (CeedInt i = 0; i < num_jit_source_roots; i++) {
CeedCall(CeedAddJitSourceRoot(fallback_ceed, jit_source_roots[i]));
}
CeedCall(CeedRestoreJitSourceRoots(ceed, &jit_source_roots));
}
{
const char **jit_defines;
CeedInt num_jit_defines = 0;

CeedCall(CeedGetJitDefines(ceed, &num_jit_defines, &jit_defines));
for (CeedInt i = 0; i < num_jit_defines; i++) {
CeedCall(CeedAddJitSourceRoot(fallback_ceed, jit_defines[i]));
}
CeedCall(CeedRestoreJitDefines(ceed, &jit_defines));
}
}
*fallback_ceed = NULL;
CeedDebug(ceed, "Fallback Ceed with backend %s at address %p\n", ceed->op_fallback_resource, ceed->op_fallback_ceed);
if (ceed->op_fallback_ceed) CeedCall(CeedReferenceCopy(ceed->op_fallback_ceed, fallback_ceed));
return CEED_ERROR_SUCCESS;
}

/**
@brief Set the fallback resource for `CeedOperator`.

The current resource, if any, is freed by calling this function.
This string is freed upon the destruction of the `Ceed` context.
The current fallback, if any, is freed by calling this function.

@param[in,out] ceed `Ceed` context
@param[in] resource Fallback resource to set
@param[in,out] ceed `Ceed` context
@param[in] fallback_ceed `Ceed` context to create fallback operators

@return An error code: 0 - success, otherwise - failure

@ref Backend
**/
int CeedSetOperatorFallbackResource(Ceed ceed, const char *resource) {
// Free old
CeedCall(CeedFree(&ceed->op_fallback_resource));

// Set new
CeedCall(CeedStringAllocCopy(resource, (char **)&ceed->op_fallback_resource));

// Check validity
ceed->has_valid_op_fallback_resource = ceed->op_fallback_resource && ceed->resource && strcmp(ceed->op_fallback_resource, ceed->resource);
int CeedSetOperatorFallbackCeed(Ceed ceed, Ceed fallback_ceed) {
CeedCall(CeedReferenceCopy(fallback_ceed, &ceed->op_fallback_ceed));
fallback_ceed->parent = ceed;
return CEED_ERROR_SUCCESS;
}

Expand Down Expand Up @@ -1323,10 +1268,6 @@ int CeedInit(const char *resource, Ceed *ceed) {
CeedCall(CeedCalloc(sizeof(f_offsets), &(*ceed)->f_offsets));
memcpy((*ceed)->f_offsets, f_offsets, sizeof(f_offsets));

// Set fallback for advanced CeedOperator functions
const char fallback_resource[] = "";
CeedCall(CeedSetOperatorFallbackResource(*ceed, fallback_resource));

// Record env variables CEED_DEBUG or DBG
(*ceed)->is_debug = getenv("CEED_DEBUG") || getenv("DEBUG") || getenv("DBG");

Expand Down Expand Up @@ -1575,7 +1516,6 @@ int CeedDestroy(Ceed *ceed) {
CeedCall(CeedFree(&(*ceed)->f_offsets));
CeedCall(CeedFree(&(*ceed)->resource));
CeedCall(CeedDestroy(&(*ceed)->op_fallback_ceed));
CeedCall(CeedFree(&(*ceed)->op_fallback_resource));
CeedCall(CeedWorkVectorsDestroy(*ceed));
CeedCall(CeedFree(ceed));
return CEED_ERROR_SUCCESS;
Expand All @@ -1584,7 +1524,6 @@ int CeedDestroy(Ceed *ceed) {
// LCOV_EXCL_START
const char *CeedErrorFormat(Ceed ceed, const char *format, va_list *args) {
if (ceed->parent) return CeedErrorFormat(ceed->parent, format, args);
if (ceed->op_fallback_parent) return CeedErrorFormat(ceed->op_fallback_parent, format, args);
// Using pointer to va_list for better FFI, but clang-tidy can't verify va_list is initalized
vsnprintf(ceed->err_msg, CEED_MAX_RESOURCE_LEN, format, *args); // NOLINT
return ceed->err_msg;
Expand Down Expand Up @@ -1648,7 +1587,6 @@ int CeedErrorReturn(Ceed ceed, const char *filename, int line_no, const char *fu
// LCOV_EXCL_START
int CeedErrorStore(Ceed ceed, const char *filename, int line_no, const char *func, int err_code, const char *format, va_list *args) {
if (ceed->parent) return CeedErrorStore(ceed->parent, filename, line_no, func, err_code, format, args);
if (ceed->op_fallback_parent) return CeedErrorStore(ceed->op_fallback_parent, filename, line_no, func, err_code, format, args);

// Build message
int len = snprintf(ceed->err_msg, CEED_MAX_RESOURCE_LEN, "%s:%d in %s(): ", filename, line_no, func);
Expand Down Expand Up @@ -1728,7 +1666,6 @@ int CeedSetErrorHandler(Ceed ceed, CeedErrorHandler handler) {
**/
int CeedGetErrorMessage(Ceed ceed, const char **err_msg) {
if (ceed->parent) return CeedGetErrorMessage(ceed->parent, err_msg);
if (ceed->op_fallback_parent) return CeedGetErrorMessage(ceed->op_fallback_parent, err_msg);
*err_msg = ceed->err_msg;
return CEED_ERROR_SUCCESS;
}
Expand All @@ -1747,7 +1684,6 @@ int CeedGetErrorMessage(Ceed ceed, const char **err_msg) {
**/
int CeedResetErrorMessage(Ceed ceed, const char **err_msg) {
if (ceed->parent) return CeedResetErrorMessage(ceed->parent, err_msg);
if (ceed->op_fallback_parent) return CeedResetErrorMessage(ceed->op_fallback_parent, err_msg);
*err_msg = NULL;
memcpy(ceed->err_msg, "No error message stored", 24);
return CEED_ERROR_SUCCESS;
Expand Down