13d8e8822SJeremy L Thompson // Copyright (c) 2017-2022, 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. 3777ff853SJeremy L Thompson // 43d8e8822SJeremy L Thompson // SPDX-License-Identifier: BSD-2-Clause 5777ff853SJeremy L Thompson // 63d8e8822SJeremy L Thompson // This file is part of CEED: http://github.com/ceed 7777ff853SJeremy L Thompson 83d576824SJeremy L Thompson #include <ceed-impl.h> 949aac155SJeremy L Thompson #include <ceed.h> 102b730f8bSJeremy L Thompson #include <ceed/backend.h> 1149aac155SJeremy L Thompson #include <stdbool.h> 123d576824SJeremy L Thompson #include <stdint.h> 133d576824SJeremy L Thompson #include <stdio.h> 14cdf32b93SJeremy L Thompson #include <string.h> 15777ff853SJeremy L Thompson 16777ff853SJeremy L Thompson /// @file 17777ff853SJeremy L Thompson /// Implementation of public CeedQFunctionContext interfaces 18777ff853SJeremy L Thompson 19777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 20cdf32b93SJeremy L Thompson /// CeedQFunctionContext Library Internal Functions 21cdf32b93SJeremy L Thompson /// ---------------------------------------------------------------------------- 22cdf32b93SJeremy L Thompson /// @addtogroup CeedQFunctionDeveloper 23cdf32b93SJeremy L Thompson /// @{ 24cdf32b93SJeremy L Thompson 25cdf32b93SJeremy L Thompson /** 26cdf32b93SJeremy L Thompson @brief Get index for QFunctionContext field 27cdf32b93SJeremy L Thompson 28ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 29ea61e9acSJeremy L Thompson @param[in] field_name Name of field 30ea61e9acSJeremy L Thompson @param[out] field_index Index of field, or -1 if field is not registered 31cdf32b93SJeremy L Thompson 32cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 33cdf32b93SJeremy L Thompson 34cdf32b93SJeremy L Thompson @ref Developer 35cdf32b93SJeremy L Thompson **/ 362b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldIndex(CeedQFunctionContext ctx, const char *field_name, CeedInt *field_index) { 37cdf32b93SJeremy L Thompson *field_index = -1; 382b730f8bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 392b730f8bSJeremy L Thompson if (!strcmp(ctx->field_labels[i]->name, field_name)) *field_index = i; 402b730f8bSJeremy L Thompson } 41cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 42cdf32b93SJeremy L Thompson } 43cdf32b93SJeremy L Thompson 44cdf32b93SJeremy L Thompson /** 45cdf32b93SJeremy L Thompson @brief Common function for registering QFunctionContext fields 46cdf32b93SJeremy L Thompson 47ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 48ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 49ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 50ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 51ea61e9acSJeremy L Thompson @param[in] field_type Field data type, such as double or int32 52ea61e9acSJeremy L Thompson @param[in] field_size Size of field, in bytes 53ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 54cdf32b93SJeremy L Thompson 55cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 56cdf32b93SJeremy L Thompson 57cdf32b93SJeremy L Thompson @ref Developer 58cdf32b93SJeremy L Thompson **/ 592b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterGeneric(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, const char *field_description, 602b730f8bSJeremy L Thompson CeedContextFieldType field_type, size_t field_size, size_t num_values) { 61cdf32b93SJeremy L Thompson // Check for duplicate 62cdf32b93SJeremy L Thompson CeedInt field_index = -1; 632b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index)); 642b730f8bSJeremy L Thompson if (field_index != -1) { 65cdf32b93SJeremy L Thompson // LCOV_EXCL_START 662b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" already registered", field_name); 67cdf32b93SJeremy L Thompson // LCOV_EXCL_STOP 682b730f8bSJeremy L Thompson } 69cdf32b93SJeremy L Thompson 70cdf32b93SJeremy L Thompson // Allocate space for field data 71cdf32b93SJeremy L Thompson if (ctx->num_fields == 0) { 722b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &ctx->field_labels)); 73cdf32b93SJeremy L Thompson ctx->max_fields = 1; 74cdf32b93SJeremy L Thompson } else if (ctx->num_fields == ctx->max_fields) { 752b730f8bSJeremy L Thompson CeedCall(CeedRealloc(2 * ctx->max_fields, &ctx->field_labels)); 76cdf32b93SJeremy L Thompson ctx->max_fields *= 2; 77cdf32b93SJeremy L Thompson } 782b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, &ctx->field_labels[ctx->num_fields])); 79cdf32b93SJeremy L Thompson 80cdf32b93SJeremy L Thompson // Copy field data 812b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_name, (char **)&ctx->field_labels[ctx->num_fields]->name)); 822b730f8bSJeremy L Thompson CeedCall(CeedStringAllocCopy(field_description, (char **)&ctx->field_labels[ctx->num_fields]->description)); 833668ca4bSJeremy L Thompson ctx->field_labels[ctx->num_fields]->type = field_type; 843668ca4bSJeremy L Thompson ctx->field_labels[ctx->num_fields]->offset = field_offset; 857bfe0f0eSJeremy L Thompson ctx->field_labels[ctx->num_fields]->size = field_size * num_values; 867bfe0f0eSJeremy L Thompson ctx->field_labels[ctx->num_fields]->num_values = num_values; 87cdf32b93SJeremy L Thompson ctx->num_fields++; 88cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 89cdf32b93SJeremy L Thompson } 90cdf32b93SJeremy L Thompson 913b190ab8SJeremy L Thompson /** 92ea61e9acSJeremy L Thompson @brief Destroy user data held by CeedQFunctionContext, using function set by CeedQFunctionContextSetDataDestroy, if applicable 933b190ab8SJeremy L Thompson 943b190ab8SJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to destroy user data 953b190ab8SJeremy L Thompson 963b190ab8SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 973b190ab8SJeremy L Thompson 983b190ab8SJeremy L Thompson @ref Developer 993b190ab8SJeremy L Thompson **/ 1003b190ab8SJeremy L Thompson static int CeedQFunctionContextDestroyData(CeedQFunctionContext ctx) { 1013b190ab8SJeremy L Thompson if (ctx->DataDestroy) { 1022b730f8bSJeremy L Thompson CeedCall(ctx->DataDestroy(ctx)); 1033b190ab8SJeremy L Thompson } else { 1043b190ab8SJeremy L Thompson CeedQFunctionContextDataDestroyUser data_destroy_function; 1053b190ab8SJeremy L Thompson CeedMemType data_destroy_mem_type; 1063b190ab8SJeremy L Thompson 1072b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetDataDestroy(ctx, &data_destroy_mem_type, &data_destroy_function)); 1083b190ab8SJeremy L Thompson if (data_destroy_function) { 1093b190ab8SJeremy L Thompson void *data; 1103b190ab8SJeremy L Thompson 1112b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, data_destroy_mem_type, &data)); 1122b730f8bSJeremy L Thompson CeedCall(data_destroy_function(data)); 1132b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 1143b190ab8SJeremy L Thompson } 1153b190ab8SJeremy L Thompson } 1163b190ab8SJeremy L Thompson 1173b190ab8SJeremy L Thompson return CEED_ERROR_SUCCESS; 1183b190ab8SJeremy L Thompson } 1193b190ab8SJeremy L Thompson 120cdf32b93SJeremy L Thompson /// @} 121cdf32b93SJeremy L Thompson 122cdf32b93SJeremy L Thompson /// ---------------------------------------------------------------------------- 123777ff853SJeremy L Thompson /// CeedQFunctionContext Backend API 124777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 125777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionBackend 126777ff853SJeremy L Thompson /// @{ 127777ff853SJeremy L Thompson 128777ff853SJeremy L Thompson /** 129777ff853SJeremy L Thompson @brief Get the Ceed associated with a CeedQFunctionContext 130777ff853SJeremy L Thompson 131ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 132777ff853SJeremy L Thompson @param[out] ceed Variable to store Ceed 133777ff853SJeremy L Thompson 134777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 135777ff853SJeremy L Thompson 136777ff853SJeremy L Thompson @ref Backend 137777ff853SJeremy L Thompson **/ 138777ff853SJeremy L Thompson int CeedQFunctionContextGetCeed(CeedQFunctionContext ctx, Ceed *ceed) { 139777ff853SJeremy L Thompson *ceed = ctx->ceed; 140e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 141777ff853SJeremy L Thompson } 142777ff853SJeremy L Thompson 143777ff853SJeremy L Thompson /** 1449c774eddSJeremy L Thompson @brief Check for valid data in a CeedQFunctionContext 1459c774eddSJeremy L Thompson 146ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to check validity 1479c774eddSJeremy L Thompson @param[out] has_valid_data Variable to store validity 1489c774eddSJeremy L Thompson 1499c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1509c774eddSJeremy L Thompson 1519c774eddSJeremy L Thompson @ref Backend 1529c774eddSJeremy L Thompson **/ 1532b730f8bSJeremy L Thompson int CeedQFunctionContextHasValidData(CeedQFunctionContext ctx, bool *has_valid_data) { 1542b730f8bSJeremy L Thompson if (!ctx->HasValidData) { 1559c774eddSJeremy L Thompson // LCOV_EXCL_START 1562b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support HasValidData"); 1579c774eddSJeremy L Thompson // LCOV_EXCL_STOP 1582b730f8bSJeremy L Thompson } 1599c774eddSJeremy L Thompson 1602b730f8bSJeremy L Thompson CeedCall(ctx->HasValidData(ctx, has_valid_data)); 1619c774eddSJeremy L Thompson 1629c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1639c774eddSJeremy L Thompson } 1649c774eddSJeremy L Thompson 1659c774eddSJeremy L Thompson /** 166ea61e9acSJeremy L Thompson @brief Check for borrowed data of a specific CeedMemType in a CeedQFunctionContext 1679c774eddSJeremy L Thompson 168ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to check 169ea61e9acSJeremy L Thompson @param[in] mem_type Memory type to check 1709c774eddSJeremy L Thompson @param[out] has_borrowed_data_of_type Variable to store result 1719c774eddSJeremy L Thompson 1729c774eddSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 1739c774eddSJeremy L Thompson 1749c774eddSJeremy L Thompson @ref Backend 1759c774eddSJeremy L Thompson **/ 1762b730f8bSJeremy L Thompson int CeedQFunctionContextHasBorrowedDataOfType(CeedQFunctionContext ctx, CeedMemType mem_type, bool *has_borrowed_data_of_type) { 1772b730f8bSJeremy L Thompson if (!ctx->HasBorrowedDataOfType) { 1789c774eddSJeremy L Thompson // LCOV_EXCL_START 1792b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support HasBorrowedDataOfType"); 1809c774eddSJeremy L Thompson // LCOV_EXCL_STOP 1812b730f8bSJeremy L Thompson } 1829c774eddSJeremy L Thompson 1832b730f8bSJeremy L Thompson CeedCall(ctx->HasBorrowedDataOfType(ctx, mem_type, has_borrowed_data_of_type)); 1849c774eddSJeremy L Thompson 1859c774eddSJeremy L Thompson return CEED_ERROR_SUCCESS; 1869c774eddSJeremy L Thompson } 1879c774eddSJeremy L Thompson 1889c774eddSJeremy L Thompson /** 189777ff853SJeremy L Thompson @brief Get the state of a CeedQFunctionContext 190777ff853SJeremy L Thompson 191ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to retrieve state 192777ff853SJeremy L Thompson @param[out] state Variable to store state 193777ff853SJeremy L Thompson 194777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 195777ff853SJeremy L Thompson 196777ff853SJeremy L Thompson @ref Backend 197777ff853SJeremy L Thompson **/ 198777ff853SJeremy L Thompson int CeedQFunctionContextGetState(CeedQFunctionContext ctx, uint64_t *state) { 199777ff853SJeremy L Thompson *state = ctx->state; 200e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 201777ff853SJeremy L Thompson } 202777ff853SJeremy L Thompson 203777ff853SJeremy L Thompson /** 204777ff853SJeremy L Thompson @brief Get backend data of a CeedQFunctionContext 205777ff853SJeremy L Thompson 206ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 207777ff853SJeremy L Thompson @param[out] data Variable to store data 208777ff853SJeremy L Thompson 209777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 210777ff853SJeremy L Thompson 211777ff853SJeremy L Thompson @ref Backend 212777ff853SJeremy L Thompson **/ 213777ff853SJeremy L Thompson int CeedQFunctionContextGetBackendData(CeedQFunctionContext ctx, void *data) { 214777ff853SJeremy L Thompson *(void **)data = ctx->data; 215e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 216777ff853SJeremy L Thompson } 217777ff853SJeremy L Thompson 218777ff853SJeremy L Thompson /** 219777ff853SJeremy L Thompson @brief Set backend data of a CeedQFunctionContext 220777ff853SJeremy L Thompson 221ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 222ea61e9acSJeremy L Thompson @param[in] data Data to set 223777ff853SJeremy L Thompson 224777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 225777ff853SJeremy L Thompson 226777ff853SJeremy L Thompson @ref Backend 227777ff853SJeremy L Thompson **/ 228777ff853SJeremy L Thompson int CeedQFunctionContextSetBackendData(CeedQFunctionContext ctx, void *data) { 229777ff853SJeremy L Thompson ctx->data = data; 230e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 231777ff853SJeremy L Thompson } 232777ff853SJeremy L Thompson 23334359f16Sjeremylt /** 234ea61e9acSJeremy L Thompson @brief Get label for a registered QFunctionContext field, or `NULL` if no field has been registered with this `field_name` 235e6a0ab89SJeremy L Thompson 236e6a0ab89SJeremy L Thompson @param[in] ctx CeedQFunctionContext 237e6a0ab89SJeremy L Thompson @param[in] field_name Name of field to retrieve label 238e6a0ab89SJeremy L Thompson @param[out] field_label Variable to field label 239e6a0ab89SJeremy L Thompson 240e6a0ab89SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 241e6a0ab89SJeremy L Thompson 2423e1e85abSJeremy L Thompson @ref Backend 243e6a0ab89SJeremy L Thompson **/ 2442b730f8bSJeremy L Thompson int CeedQFunctionContextGetFieldLabel(CeedQFunctionContext ctx, const char *field_name, CeedContextFieldLabel *field_label) { 245e6a0ab89SJeremy L Thompson CeedInt field_index; 2462b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetFieldIndex(ctx, field_name, &field_index)); 247e6a0ab89SJeremy L Thompson 248e6a0ab89SJeremy L Thompson if (field_index != -1) { 249e6a0ab89SJeremy L Thompson *field_label = ctx->field_labels[field_index]; 250e6a0ab89SJeremy L Thompson } else { 251e6a0ab89SJeremy L Thompson *field_label = NULL; 252e6a0ab89SJeremy L Thompson } 253e6a0ab89SJeremy L Thompson 254e6a0ab89SJeremy L Thompson return CEED_ERROR_SUCCESS; 255e6a0ab89SJeremy L Thompson } 256e6a0ab89SJeremy L Thompson 257e6a0ab89SJeremy L Thompson /** 258d8dd9a91SJeremy L Thompson @brief Set QFunctionContext field 259d8dd9a91SJeremy L Thompson 260ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 261ea61e9acSJeremy L Thompson @param[in] field_label Label of field to set 262ea61e9acSJeremy L Thompson @param[in] field_type Type of field to set 2632788fa27SJeremy L Thompson @param[in] values Value to set 264d8dd9a91SJeremy L Thompson 265d8dd9a91SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 266d8dd9a91SJeremy L Thompson 2673e1e85abSJeremy L Thompson @ref Backend 268d8dd9a91SJeremy L Thompson **/ 2692788fa27SJeremy L Thompson int CeedQFunctionContextSetGeneric(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, void *values) { 2703668ca4bSJeremy L Thompson // Check field type 2712b730f8bSJeremy L Thompson if (field_label->type != field_type) { 272d8dd9a91SJeremy L Thompson // LCOV_EXCL_START 2732b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", 2742b730f8bSJeremy L Thompson field_label->name, CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 275d8dd9a91SJeremy L Thompson // LCOV_EXCL_STOP 2762b730f8bSJeremy L Thompson } 277d8dd9a91SJeremy L Thompson 278d8dd9a91SJeremy L Thompson char *data; 2792b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextGetData(ctx, CEED_MEM_HOST, &data)); 2802788fa27SJeremy L Thompson memcpy(&data[field_label->offset], values, field_label->size); 2812b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextRestoreData(ctx, &data)); 282d8dd9a91SJeremy L Thompson 283d8dd9a91SJeremy L Thompson return CEED_ERROR_SUCCESS; 284d8dd9a91SJeremy L Thompson } 285d8dd9a91SJeremy L Thompson 286d8dd9a91SJeremy L Thompson /** 2872788fa27SJeremy L Thompson @brief Get QFunctionContext field data, read-only 2882788fa27SJeremy L Thompson 2892788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 2902788fa27SJeremy L Thompson @param[in] field_label Label of field to read 2912788fa27SJeremy L Thompson @param[in] field_type Type of field to read 2922788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 2932788fa27SJeremy L Thompson @param[out] values Pointer to context values 2942788fa27SJeremy L Thompson 2952788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 2962788fa27SJeremy L Thompson 2972788fa27SJeremy L Thompson @ref Backend 2982788fa27SJeremy L Thompson **/ 2992788fa27SJeremy L Thompson int CeedQFunctionContextGetGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, 3002788fa27SJeremy L Thompson size_t *num_values, void *values) { 3012788fa27SJeremy L Thompson // Check field type 3022788fa27SJeremy L Thompson if (field_label->type != field_type) { 3032788fa27SJeremy L Thompson // LCOV_EXCL_START 3042788fa27SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", 3052788fa27SJeremy L Thompson field_label->name, CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 3062788fa27SJeremy L Thompson // LCOV_EXCL_STOP 3072788fa27SJeremy L Thompson } 3082788fa27SJeremy L Thompson 3092788fa27SJeremy L Thompson char *data; 3102788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetDataRead(ctx, CEED_MEM_HOST, &data)); 3112788fa27SJeremy L Thompson *(void **)values = &data[field_label->offset]; 3122788fa27SJeremy L Thompson switch (field_type) { 3132788fa27SJeremy L Thompson case CEED_CONTEXT_FIELD_INT32: 3142788fa27SJeremy L Thompson *num_values = field_label->size / sizeof(int); 3152788fa27SJeremy L Thompson break; 3162788fa27SJeremy L Thompson case CEED_CONTEXT_FIELD_DOUBLE: 3172788fa27SJeremy L Thompson *num_values = field_label->size / sizeof(double); 3182788fa27SJeremy L Thompson break; 3192788fa27SJeremy L Thompson } 3202788fa27SJeremy L Thompson 3212788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3222788fa27SJeremy L Thompson } 3232788fa27SJeremy L Thompson 3242788fa27SJeremy L Thompson /** 3252788fa27SJeremy L Thompson @brief Restore QFunctionContext field data, read-only 3262788fa27SJeremy L Thompson 3272788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 3282788fa27SJeremy L Thompson @param[in] field_label Label of field to restore 3292788fa27SJeremy L Thompson @param[in] field_type Type of field to restore 3302788fa27SJeremy L Thompson @param[out] values Pointer to context values 3312788fa27SJeremy L Thompson 3322788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3332788fa27SJeremy L Thompson 3342788fa27SJeremy L Thompson @ref Backend 3352788fa27SJeremy L Thompson **/ 3362788fa27SJeremy L Thompson int CeedQFunctionContextRestoreGenericRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, CeedContextFieldType field_type, 3372788fa27SJeremy L Thompson void *values) { 3382788fa27SJeremy L Thompson // Check field type 3392788fa27SJeremy L Thompson if (field_label->type != field_type) { 3402788fa27SJeremy L Thompson // LCOV_EXCL_START 3412788fa27SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "QFunctionContext field with name \"%s\" registered as %s, not registered as %s", 3422788fa27SJeremy L Thompson field_label->name, CeedContextFieldTypes[field_label->type], CeedContextFieldTypes[field_type]); 3432788fa27SJeremy L Thompson // LCOV_EXCL_STOP 3442788fa27SJeremy L Thompson } 3452788fa27SJeremy L Thompson 3462788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreDataRead(ctx, values)); 3472788fa27SJeremy L Thompson 3482788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3492788fa27SJeremy L Thompson } 3502788fa27SJeremy L Thompson 3512788fa27SJeremy L Thompson /** 352bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding a double precision value 353bfacc300SJeremy L Thompson 354ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 3552788fa27SJeremy L Thompson @param[in] field_label Label for field to set 356ea61e9acSJeremy L Thompson @param[in] values Values to set 357bfacc300SJeremy L Thompson 358bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 359bfacc300SJeremy L Thompson 3603e1e85abSJeremy L Thompson @ref Backend 361bfacc300SJeremy L Thompson **/ 3622b730f8bSJeremy L Thompson int CeedQFunctionContextSetDouble(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, double *values) { 3632b730f8bSJeremy L Thompson if (!field_label) { 364bfacc300SJeremy L Thompson // LCOV_EXCL_START 3652b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 366bfacc300SJeremy L Thompson // LCOV_EXCL_STOP 3672b730f8bSJeremy L Thompson } 368bfacc300SJeremy L Thompson 3692b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values)); 370bfacc300SJeremy L Thompson 371bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 372bfacc300SJeremy L Thompson } 373bfacc300SJeremy L Thompson 374bfacc300SJeremy L Thompson /** 3752788fa27SJeremy L Thompson @brief Get QFunctionContext field holding a double precision value, read-only 3762788fa27SJeremy L Thompson 3772788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 3782788fa27SJeremy L Thompson @param[in] field_label Label for field to get 3792788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 3802788fa27SJeremy L Thompson @param[out] values Pointer to context values 3812788fa27SJeremy L Thompson 3822788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 3832788fa27SJeremy L Thompson 3842788fa27SJeremy L Thompson @ref Backend 3852788fa27SJeremy L Thompson **/ 3862788fa27SJeremy L Thompson int CeedQFunctionContextGetDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const double **values) { 3872788fa27SJeremy L Thompson if (!field_label) { 3882788fa27SJeremy L Thompson // LCOV_EXCL_START 3892788fa27SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 3902788fa27SJeremy L Thompson // LCOV_EXCL_STOP 3912788fa27SJeremy L Thompson } 3922788fa27SJeremy L Thompson 3932788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, num_values, values)); 3942788fa27SJeremy L Thompson 3952788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 3962788fa27SJeremy L Thompson } 3972788fa27SJeremy L Thompson 3982788fa27SJeremy L Thompson /** 3992788fa27SJeremy L Thompson @brief Restore QFunctionContext field holding a double precision value, read-only 4002788fa27SJeremy L Thompson 4012788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 4022788fa27SJeremy L Thompson @param[in] field_label Label for field to restore 4032788fa27SJeremy L Thompson @param[out] values Pointer to context values 4042788fa27SJeremy L Thompson 4052788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4062788fa27SJeremy L Thompson 4072788fa27SJeremy L Thompson @ref Backend 4082788fa27SJeremy L Thompson **/ 4092788fa27SJeremy L Thompson int CeedQFunctionContextRestoreDoubleRead(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const double **values) { 4102788fa27SJeremy L Thompson if (!field_label) { 4112788fa27SJeremy L Thompson // LCOV_EXCL_START 4122788fa27SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4132788fa27SJeremy L Thompson // LCOV_EXCL_STOP 4142788fa27SJeremy L Thompson } 4152788fa27SJeremy L Thompson 4162788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_DOUBLE, values)); 4172788fa27SJeremy L Thompson 4182788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4192788fa27SJeremy L Thompson } 4202788fa27SJeremy L Thompson 4212788fa27SJeremy L Thompson /** 422bfacc300SJeremy L Thompson @brief Set QFunctionContext field holding an int32 value 423bfacc300SJeremy L Thompson 424ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 4252788fa27SJeremy L Thompson @param[in] field_label Label for field to set 426ea61e9acSJeremy L Thompson @param[in] values Values to set 427bfacc300SJeremy L Thompson 428bfacc300SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 429bfacc300SJeremy L Thompson 4303e1e85abSJeremy L Thompson @ref Backend 431bfacc300SJeremy L Thompson **/ 4322b730f8bSJeremy L Thompson int CeedQFunctionContextSetInt32(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, int *values) { 4332b730f8bSJeremy L Thompson if (!field_label) { 434bfacc300SJeremy L Thompson // LCOV_EXCL_START 4352b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 436bfacc300SJeremy L Thompson // LCOV_EXCL_STOP 4372b730f8bSJeremy L Thompson } 438bfacc300SJeremy L Thompson 4392b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextSetGeneric(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values)); 440bfacc300SJeremy L Thompson 441bfacc300SJeremy L Thompson return CEED_ERROR_SUCCESS; 442bfacc300SJeremy L Thompson } 443bfacc300SJeremy L Thompson 444bfacc300SJeremy L Thompson /** 4452788fa27SJeremy L Thompson @brief Get QFunctionContext field holding a int32 value, read-only 4462788fa27SJeremy L Thompson 4472788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 4482788fa27SJeremy L Thompson @param[in] field_label Label for field to get 4492788fa27SJeremy L Thompson @param[out] num_values Number of values in the field label 4502788fa27SJeremy L Thompson @param[out] values Pointer to context values 4512788fa27SJeremy L Thompson 4522788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4532788fa27SJeremy L Thompson 4542788fa27SJeremy L Thompson @ref Backend 4552788fa27SJeremy L Thompson **/ 4562788fa27SJeremy L Thompson int CeedQFunctionContextGetInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, size_t *num_values, const int **values) { 4572788fa27SJeremy L Thompson if (!field_label) { 4582788fa27SJeremy L Thompson // LCOV_EXCL_START 4592788fa27SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4602788fa27SJeremy L Thompson // LCOV_EXCL_STOP 4612788fa27SJeremy L Thompson } 4622788fa27SJeremy L Thompson 4632788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextGetGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, num_values, values)); 4642788fa27SJeremy L Thompson 4652788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4662788fa27SJeremy L Thompson } 4672788fa27SJeremy L Thompson 4682788fa27SJeremy L Thompson /** 4692788fa27SJeremy L Thompson @brief Restore QFunctionContext field holding a int32 value, read-only 4702788fa27SJeremy L Thompson 4712788fa27SJeremy L Thompson @param[in] ctx CeedQFunctionContext 4722788fa27SJeremy L Thompson @param[in] field_label Label for field to restore 4732788fa27SJeremy L Thompson @param[out] values Pointer to context values 4742788fa27SJeremy L Thompson 4752788fa27SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4762788fa27SJeremy L Thompson 4772788fa27SJeremy L Thompson @ref Backend 4782788fa27SJeremy L Thompson **/ 4792788fa27SJeremy L Thompson int CeedQFunctionContextRestoreInt32Read(CeedQFunctionContext ctx, CeedContextFieldLabel field_label, const int **values) { 4802788fa27SJeremy L Thompson if (!field_label) { 4812788fa27SJeremy L Thompson // LCOV_EXCL_START 4822788fa27SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Invalid field label"); 4832788fa27SJeremy L Thompson // LCOV_EXCL_STOP 4842788fa27SJeremy L Thompson } 4852788fa27SJeremy L Thompson 4862788fa27SJeremy L Thompson CeedCall(CeedQFunctionContextRestoreGenericRead(ctx, field_label, CEED_CONTEXT_FIELD_INT32, values)); 4872788fa27SJeremy L Thompson 4882788fa27SJeremy L Thompson return CEED_ERROR_SUCCESS; 4892788fa27SJeremy L Thompson } 4902788fa27SJeremy L Thompson 4912788fa27SJeremy L Thompson /** 4922e64a2b9SJeremy L Thompson @brief Get additional destroy routine for CeedQFunctionContext user data 4932e64a2b9SJeremy L Thompson 4942e64a2b9SJeremy L Thompson @param[in] ctx CeedQFunctionContext to get user destroy function 4952e64a2b9SJeremy L Thompson @param[out] f_mem_type Memory type to use when passing data into `f` 4962e64a2b9SJeremy L Thompson @param[out] f Additional routine to use to destroy user data 4972e64a2b9SJeremy L Thompson 4982e64a2b9SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 4992e64a2b9SJeremy L Thompson 5002e64a2b9SJeremy L Thompson @ref Backend 5012e64a2b9SJeremy L Thompson **/ 5022b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataDestroy(CeedQFunctionContext ctx, CeedMemType *f_mem_type, CeedQFunctionContextDataDestroyUser *f) { 5032e64a2b9SJeremy L Thompson if (f_mem_type) *f_mem_type = ctx->data_destroy_mem_type; 5042e64a2b9SJeremy L Thompson if (f) *f = ctx->data_destroy_function; 5052e64a2b9SJeremy L Thompson return CEED_ERROR_SUCCESS; 5062e64a2b9SJeremy L Thompson } 5072e64a2b9SJeremy L Thompson 5082e64a2b9SJeremy L Thompson /** 50934359f16Sjeremylt @brief Increment the reference counter for a CeedQFunctionContext 51034359f16Sjeremylt 511ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to increment the reference counter 51234359f16Sjeremylt 51334359f16Sjeremylt @return An error code: 0 - success, otherwise - failure 51434359f16Sjeremylt 51534359f16Sjeremylt @ref Backend 51634359f16Sjeremylt **/ 5179560d06aSjeremylt int CeedQFunctionContextReference(CeedQFunctionContext ctx) { 51834359f16Sjeremylt ctx->ref_count++; 51934359f16Sjeremylt return CEED_ERROR_SUCCESS; 52034359f16Sjeremylt } 52134359f16Sjeremylt 522777ff853SJeremy L Thompson /// @} 523777ff853SJeremy L Thompson 524777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 525777ff853SJeremy L Thompson /// CeedQFunctionContext Public API 526777ff853SJeremy L Thompson /// ---------------------------------------------------------------------------- 527777ff853SJeremy L Thompson /// @addtogroup CeedQFunctionUser 528777ff853SJeremy L Thompson /// @{ 529777ff853SJeremy L Thompson 530777ff853SJeremy L Thompson /** 531777ff853SJeremy L Thompson @brief Create a CeedQFunctionContext for storing CeedQFunction user context data 532777ff853SJeremy L Thompson 533ea61e9acSJeremy L Thompson @param[in] ceed Ceed object where the CeedQFunctionContext will be created 534ea61e9acSJeremy L Thompson @param[out] ctx Address of the variable where the newly created CeedQFunctionContext will be stored 535777ff853SJeremy L Thompson 536777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 537777ff853SJeremy L Thompson 538777ff853SJeremy L Thompson @ref User 539777ff853SJeremy L Thompson **/ 540777ff853SJeremy L Thompson int CeedQFunctionContextCreate(Ceed ceed, CeedQFunctionContext *ctx) { 541777ff853SJeremy L Thompson if (!ceed->QFunctionContextCreate) { 542777ff853SJeremy L Thompson Ceed delegate; 5432b730f8bSJeremy L Thompson CeedCall(CeedGetObjectDelegate(ceed, &delegate, "Context")); 544777ff853SJeremy L Thompson 5452b730f8bSJeremy L Thompson if (!delegate) { 546777ff853SJeremy L Thompson // LCOV_EXCL_START 5472b730f8bSJeremy L Thompson return CeedError(ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextCreate"); 548777ff853SJeremy L Thompson // LCOV_EXCL_STOP 5492b730f8bSJeremy L Thompson } 550777ff853SJeremy L Thompson 5512b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextCreate(delegate, ctx)); 552e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 553777ff853SJeremy L Thompson } 554777ff853SJeremy L Thompson 5552b730f8bSJeremy L Thompson CeedCall(CeedCalloc(1, ctx)); 556777ff853SJeremy L Thompson (*ctx)->ceed = ceed; 5572b730f8bSJeremy L Thompson CeedCall(CeedReference(ceed)); 558d1d35e2fSjeremylt (*ctx)->ref_count = 1; 5592b730f8bSJeremy L Thompson CeedCall(ceed->QFunctionContextCreate(*ctx)); 560e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 561777ff853SJeremy L Thompson } 562777ff853SJeremy L Thompson 563777ff853SJeremy L Thompson /** 564ea61e9acSJeremy L Thompson @brief Copy the pointer to a CeedQFunctionContext. 5654385fb7fSSebastian Grimberg 566ea61e9acSJeremy L Thompson Both pointers should be destroyed with `CeedQFunctionContextDestroy()`. 567512bb800SJeremy L Thompson 568512bb800SJeremy L Thompson Note: If the value of `ctx_copy` passed to this function is non-NULL, then it is assumed that `ctx_copy` is a pointer to a 569512bb800SJeremy L Thompson CeedQFunctionContext. This CeedQFunctionContext will be destroyed if `ctx_copy` is the only reference to this CeedQFunctionContext. 5709560d06aSjeremylt 571ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to copy reference to 572ea61e9acSJeremy L Thompson @param[in,out] ctx_copy Variable to store copied reference 5739560d06aSjeremylt 5749560d06aSjeremylt @return An error code: 0 - success, otherwise - failure 5759560d06aSjeremylt 5769560d06aSjeremylt @ref User 5779560d06aSjeremylt **/ 5782b730f8bSJeremy L Thompson int CeedQFunctionContextReferenceCopy(CeedQFunctionContext ctx, CeedQFunctionContext *ctx_copy) { 5792b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextReference(ctx)); 5802b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroy(ctx_copy)); 5819560d06aSjeremylt *ctx_copy = ctx; 5829560d06aSjeremylt return CEED_ERROR_SUCCESS; 5839560d06aSjeremylt } 5849560d06aSjeremylt 5859560d06aSjeremylt /** 586ea61e9acSJeremy L Thompson @brief Set the data used by a CeedQFunctionContext, freeing any previously allocated data if applicable. 5874385fb7fSSebastian Grimberg 588ea61e9acSJeremy L Thompson The backend may copy values to a different memtype, such as during @ref CeedQFunctionApply(). 589777ff853SJeremy L Thompson See also @ref CeedQFunctionContextTakeData(). 590777ff853SJeremy L Thompson 591ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 592ea61e9acSJeremy L Thompson @param[in] mem_type Memory type of the data being passed 593ea61e9acSJeremy L Thompson @param[in] copy_mode Copy mode for the data 594ea61e9acSJeremy L Thompson @param[in] size Size of data, in bytes 595ea61e9acSJeremy L Thompson @param[in] data Data to be used 596777ff853SJeremy L Thompson 597777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 598777ff853SJeremy L Thompson 599777ff853SJeremy L Thompson @ref User 600777ff853SJeremy L Thompson **/ 6012b730f8bSJeremy L Thompson int CeedQFunctionContextSetData(CeedQFunctionContext ctx, CeedMemType mem_type, CeedCopyMode copy_mode, size_t size, void *data) { 6022b730f8bSJeremy L Thompson if (!ctx->SetData) { 603777ff853SJeremy L Thompson // LCOV_EXCL_START 6042b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support ContextSetData"); 605777ff853SJeremy L Thompson // LCOV_EXCL_STOP 6062b730f8bSJeremy L Thompson } 6072b730f8bSJeremy L Thompson if (ctx->state % 2 == 1) { 608777ff853SJeremy L Thompson // LCOV_EXCL_START 6092b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 610777ff853SJeremy L Thompson // LCOV_EXCL_STOP 6112b730f8bSJeremy L Thompson } 612777ff853SJeremy L Thompson 6132b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(ctx)); 614d1d35e2fSjeremylt ctx->ctx_size = size; 6152b730f8bSJeremy L Thompson CeedCall(ctx->SetData(ctx, mem_type, copy_mode, data)); 616777ff853SJeremy L Thompson ctx->state += 2; 617e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 618777ff853SJeremy L Thompson } 619777ff853SJeremy L Thompson 620777ff853SJeremy L Thompson /** 621891038deSjeremylt @brief Take ownership of the data in a CeedQFunctionContext via the specified memory type. 6224385fb7fSSebastian Grimberg 623891038deSjeremylt The caller is responsible for managing and freeing the memory. 624891038deSjeremylt 625ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 626ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 627ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 628891038deSjeremylt @param[out] data Data on memory type mem_type 629891038deSjeremylt 630891038deSjeremylt @return An error code: 0 - success, otherwise - failure 631891038deSjeremylt 632891038deSjeremylt @ref User 633891038deSjeremylt **/ 6342b730f8bSJeremy L Thompson int CeedQFunctionContextTakeData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 6359c774eddSJeremy L Thompson bool has_valid_data = true; 6362b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 6372b730f8bSJeremy L Thompson if (!has_valid_data) { 6389c774eddSJeremy L Thompson // LCOV_EXCL_START 6392b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to take, must set data"); 6409c774eddSJeremy L Thompson // LCOV_EXCL_STOP 6412b730f8bSJeremy L Thompson } 6429c774eddSJeremy L Thompson 6432b730f8bSJeremy L Thompson if (!ctx->TakeData) { 644891038deSjeremylt // LCOV_EXCL_START 6452b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support TakeData"); 646891038deSjeremylt // LCOV_EXCL_STOP 6472b730f8bSJeremy L Thompson } 6482b730f8bSJeremy L Thompson if (ctx->state % 2 == 1) { 649891038deSjeremylt // LCOV_EXCL_START 6502b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 651891038deSjeremylt // LCOV_EXCL_STOP 6522b730f8bSJeremy L Thompson } 653891038deSjeremylt 6549c774eddSJeremy L Thompson bool has_borrowed_data_of_type = true; 6552b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasBorrowedDataOfType(ctx, mem_type, &has_borrowed_data_of_type)); 6562b730f8bSJeremy L Thompson if (!has_borrowed_data_of_type) { 6579c774eddSJeremy L Thompson // LCOV_EXCL_START 6586ed4cbd1SJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no borrowed %s data, must set data with CeedQFunctionContextSetData", 6599c774eddSJeremy L Thompson CeedMemTypes[mem_type]); 6609c774eddSJeremy L Thompson // LCOV_EXCL_STOP 6612b730f8bSJeremy L Thompson } 6629c774eddSJeremy L Thompson 663891038deSjeremylt void *temp_data = NULL; 6642b730f8bSJeremy L Thompson CeedCall(ctx->TakeData(ctx, mem_type, &temp_data)); 665891038deSjeremylt if (data) (*(void **)data) = temp_data; 666891038deSjeremylt return CEED_ERROR_SUCCESS; 667891038deSjeremylt } 668891038deSjeremylt 669891038deSjeremylt /** 670777ff853SJeremy L Thompson @brief Get read/write access to a CeedQFunctionContext via the specified memory type. 6714385fb7fSSebastian Grimberg 672777ff853SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 673777ff853SJeremy L Thompson 674ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 675ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 676ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 677d1d35e2fSjeremylt @param[out] data Data on memory type mem_type 678777ff853SJeremy L Thompson 679ea61e9acSJeremy L Thompson @note The CeedQFunctionContextGetData() and @ref CeedQFunctionContextRestoreData() functions provide access to array pointers in the desired memory 680*9fd66db6SSebastian Grimberg space. 681*9fd66db6SSebastian Grimberg Pairing get/restore allows the Context to track access. 682777ff853SJeremy L Thompson 683777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 684777ff853SJeremy L Thompson 685777ff853SJeremy L Thompson @ref User 686777ff853SJeremy L Thompson **/ 6872b730f8bSJeremy L Thompson int CeedQFunctionContextGetData(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 6882b730f8bSJeremy L Thompson if (!ctx->GetData) { 689777ff853SJeremy L Thompson // LCOV_EXCL_START 6902b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetData"); 691777ff853SJeremy L Thompson // LCOV_EXCL_STOP 6922b730f8bSJeremy L Thompson } 6932b730f8bSJeremy L Thompson if (ctx->state % 2 == 1) { 694777ff853SJeremy L Thompson // LCOV_EXCL_START 6952b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 696777ff853SJeremy L Thompson // LCOV_EXCL_STOP 6972b730f8bSJeremy L Thompson } 6982b730f8bSJeremy L Thompson if (ctx->num_readers > 0) { 69928bfd0b7SJeremy L Thompson // LCOV_EXCL_START 7002b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, a process has read access"); 70128bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 7022b730f8bSJeremy L Thompson } 70328bfd0b7SJeremy L Thompson 7049c774eddSJeremy L Thompson bool has_valid_data = true; 7052b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 7062b730f8bSJeremy L Thompson if (!has_valid_data) { 7079c774eddSJeremy L Thompson // LCOV_EXCL_START 7082b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 7099c774eddSJeremy L Thompson // LCOV_EXCL_STOP 7102b730f8bSJeremy L Thompson } 7119c774eddSJeremy L Thompson 7122b730f8bSJeremy L Thompson CeedCall(ctx->GetData(ctx, mem_type, data)); 71328bfd0b7SJeremy L Thompson ctx->state++; 71428bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 71528bfd0b7SJeremy L Thompson } 71628bfd0b7SJeremy L Thompson 71728bfd0b7SJeremy L Thompson /** 71828bfd0b7SJeremy L Thompson @brief Get read only access to a CeedQFunctionContext via the specified memory type. 7194385fb7fSSebastian Grimberg 72028bfd0b7SJeremy L Thompson Restore access with @ref CeedQFunctionContextRestoreData(). 72128bfd0b7SJeremy L Thompson 722ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to access 723ea61e9acSJeremy L Thompson @param[in] mem_type Memory type on which to access the data. 724ea61e9acSJeremy L Thompson If the backend uses a different memory type, this will perform a copy. 72528bfd0b7SJeremy L Thompson @param[out] data Data on memory type mem_type 72628bfd0b7SJeremy L Thompson 727ea61e9acSJeremy L Thompson @note The CeedQFunctionContextGetDataRead() and @ref CeedQFunctionContextRestoreDataRead() functions provide access to array pointers in the desired 728*9fd66db6SSebastian Grimberg memory space. 729*9fd66db6SSebastian Grimberg Pairing get/restore allows the Context to track access. 73028bfd0b7SJeremy L Thompson 73128bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 73228bfd0b7SJeremy L Thompson 73328bfd0b7SJeremy L Thompson @ref User 73428bfd0b7SJeremy L Thompson **/ 7352b730f8bSJeremy L Thompson int CeedQFunctionContextGetDataRead(CeedQFunctionContext ctx, CeedMemType mem_type, void *data) { 7362b730f8bSJeremy L Thompson if (!ctx->GetDataRead) { 73728bfd0b7SJeremy L Thompson // LCOV_EXCL_START 7382b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_UNSUPPORTED, "Backend does not support GetDataRead"); 73928bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 7402b730f8bSJeremy L Thompson } 7412b730f8bSJeremy L Thompson if (ctx->state % 2 == 1) { 74228bfd0b7SJeremy L Thompson // LCOV_EXCL_START 7432b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot grant CeedQFunctionContext data access, the access lock is already in use"); 74428bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 7452b730f8bSJeremy L Thompson } 74628bfd0b7SJeremy L Thompson 74728bfd0b7SJeremy L Thompson bool has_valid_data = true; 7482b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextHasValidData(ctx, &has_valid_data)); 7492b730f8bSJeremy L Thompson if (!has_valid_data) { 75028bfd0b7SJeremy L Thompson // LCOV_EXCL_START 7512b730f8bSJeremy L Thompson return CeedError(ctx->ceed, CEED_ERROR_BACKEND, "CeedQFunctionContext has no valid data to get, must set data"); 75228bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 7532b730f8bSJeremy L Thompson } 75428bfd0b7SJeremy L Thompson 7552b730f8bSJeremy L Thompson CeedCall(ctx->GetDataRead(ctx, mem_type, data)); 75628bfd0b7SJeremy L Thompson ctx->num_readers++; 757e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 758777ff853SJeremy L Thompson } 759777ff853SJeremy L Thompson 760777ff853SJeremy L Thompson /** 761777ff853SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetData() 762777ff853SJeremy L Thompson 763ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to restore 764ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 765777ff853SJeremy L Thompson 766777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 767777ff853SJeremy L Thompson 768777ff853SJeremy L Thompson @ref User 769777ff853SJeremy L Thompson **/ 770777ff853SJeremy L Thompson int CeedQFunctionContextRestoreData(CeedQFunctionContext ctx, void *data) { 7712b730f8bSJeremy L Thompson if (ctx->state % 2 != 1) { 772777ff853SJeremy L Thompson // LCOV_EXCL_START 7732b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 774777ff853SJeremy L Thompson // LCOV_EXCL_STOP 7752b730f8bSJeremy L Thompson } 776777ff853SJeremy L Thompson 777706efda3SJeremy L Thompson if (ctx->RestoreData) { 7782b730f8bSJeremy L Thompson CeedCall(ctx->RestoreData(ctx)); 779706efda3SJeremy L Thompson } 780777ff853SJeremy L Thompson *(void **)data = NULL; 78128bfd0b7SJeremy L Thompson ctx->state++; 78228bfd0b7SJeremy L Thompson return CEED_ERROR_SUCCESS; 78328bfd0b7SJeremy L Thompson } 78428bfd0b7SJeremy L Thompson 78528bfd0b7SJeremy L Thompson /** 78628bfd0b7SJeremy L Thompson @brief Restore data obtained using @ref CeedQFunctionContextGetDataRead() 78728bfd0b7SJeremy L Thompson 788ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext to restore 789ea61e9acSJeremy L Thompson @param[in,out] data Data to restore 79028bfd0b7SJeremy L Thompson 79128bfd0b7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 79228bfd0b7SJeremy L Thompson 79328bfd0b7SJeremy L Thompson @ref User 79428bfd0b7SJeremy L Thompson **/ 79528bfd0b7SJeremy L Thompson int CeedQFunctionContextRestoreDataRead(CeedQFunctionContext ctx, void *data) { 7962b730f8bSJeremy L Thompson if (ctx->num_readers == 0) { 79728bfd0b7SJeremy L Thompson // LCOV_EXCL_START 7982b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Cannot restore CeedQFunctionContext array access, access was not granted"); 79928bfd0b7SJeremy L Thompson // LCOV_EXCL_STOP 8002b730f8bSJeremy L Thompson } 80128bfd0b7SJeremy L Thompson 80275a19770SJeremy L Thompson ctx->num_readers--; 80375a19770SJeremy L Thompson if (ctx->num_readers == 0 && ctx->RestoreDataRead) { 8042b730f8bSJeremy L Thompson CeedCall(ctx->RestoreDataRead(ctx)); 80528bfd0b7SJeremy L Thompson } 80628bfd0b7SJeremy L Thompson *(void **)data = NULL; 80775a19770SJeremy L Thompson 808e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 809777ff853SJeremy L Thompson } 810777ff853SJeremy L Thompson 811777ff853SJeremy L Thompson /** 812cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a double precision value 813cdf32b93SJeremy L Thompson 814ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 815ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 816ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 817ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 818ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 819cdf32b93SJeremy L Thompson 820cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 821cdf32b93SJeremy L Thompson 822cdf32b93SJeremy L Thompson @ref User 823cdf32b93SJeremy L Thompson **/ 8242b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterDouble(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 825cdf32b93SJeremy L Thompson const char *field_description) { 8262b730f8bSJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_DOUBLE, sizeof(double), num_values); 827cdf32b93SJeremy L Thompson } 828cdf32b93SJeremy L Thompson 829cdf32b93SJeremy L Thompson /** 830cdf32b93SJeremy L Thompson @brief Register QFunctionContext a field holding a int32 value 831cdf32b93SJeremy L Thompson 832ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext 833ea61e9acSJeremy L Thompson @param[in] field_name Name of field to register 834ea61e9acSJeremy L Thompson @param[in] field_offset Offset of field to register 835ea61e9acSJeremy L Thompson @param[in] num_values Number of values to register, must be contiguous in memory 836ea61e9acSJeremy L Thompson @param[in] field_description Description of field, or NULL for none 837cdf32b93SJeremy L Thompson 838cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 839cdf32b93SJeremy L Thompson 840cdf32b93SJeremy L Thompson @ref User 841cdf32b93SJeremy L Thompson **/ 8422b730f8bSJeremy L Thompson int CeedQFunctionContextRegisterInt32(CeedQFunctionContext ctx, const char *field_name, size_t field_offset, size_t num_values, 843cdf32b93SJeremy L Thompson const char *field_description) { 8442b730f8bSJeremy L Thompson return CeedQFunctionContextRegisterGeneric(ctx, field_name, field_offset, field_description, CEED_CONTEXT_FIELD_INT32, sizeof(int), num_values); 845cdf32b93SJeremy L Thompson } 846cdf32b93SJeremy L Thompson 847cdf32b93SJeremy L Thompson /** 8483668ca4bSJeremy L Thompson @brief Get labels for all registered QFunctionContext fields 849cdf32b93SJeremy L Thompson 850ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 8513668ca4bSJeremy L Thompson @param[out] field_labels Variable to hold array of field labels 852cdf32b93SJeremy L Thompson @param[out] num_fields Length of field descriptions array 853cdf32b93SJeremy L Thompson 854cdf32b93SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 855cdf32b93SJeremy L Thompson 856cdf32b93SJeremy L Thompson @ref User 857cdf32b93SJeremy L Thompson **/ 8582b730f8bSJeremy L Thompson int CeedQFunctionContextGetAllFieldLabels(CeedQFunctionContext ctx, const CeedContextFieldLabel **field_labels, CeedInt *num_fields) { 8593668ca4bSJeremy L Thompson *field_labels = ctx->field_labels; 860cdf32b93SJeremy L Thompson *num_fields = ctx->num_fields; 861cdf32b93SJeremy L Thompson return CEED_ERROR_SUCCESS; 862cdf32b93SJeremy L Thompson } 863cdf32b93SJeremy L Thompson 864cdf32b93SJeremy L Thompson /** 8650f86cbe7SJeremy L Thompson @brief Get the descriptive information about a CeedContextFieldLabel 8660f86cbe7SJeremy L Thompson 8670f86cbe7SJeremy L Thompson @param[in] label CeedContextFieldLabel 8680f86cbe7SJeremy L Thompson @param[out] field_name Name of labeled field 8690f86cbe7SJeremy L Thompson @param[out] field_description Description of field, or NULL for none 8707bfe0f0eSJeremy L Thompson @param[out] num_values Number of values registered 8710f86cbe7SJeremy L Thompson @param[out] field_type CeedContextFieldType 8720f86cbe7SJeremy L Thompson 8730f86cbe7SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 8740f86cbe7SJeremy L Thompson 8750f86cbe7SJeremy L Thompson @ref User 8760f86cbe7SJeremy L Thompson **/ 8772b730f8bSJeremy L Thompson int CeedContextFieldLabelGetDescription(CeedContextFieldLabel label, const char **field_name, const char **field_description, size_t *num_values, 8780f86cbe7SJeremy L Thompson CeedContextFieldType *field_type) { 8790f86cbe7SJeremy L Thompson if (field_name) *field_name = label->name; 8800f86cbe7SJeremy L Thompson if (field_description) *field_description = label->description; 8817bfe0f0eSJeremy L Thompson if (num_values) *num_values = label->num_values; 8820f86cbe7SJeremy L Thompson if (field_type) *field_type = label->type; 8830f86cbe7SJeremy L Thompson return CEED_ERROR_SUCCESS; 8840f86cbe7SJeremy L Thompson } 8850f86cbe7SJeremy L Thompson 8860f86cbe7SJeremy L Thompson /** 88780a9ef05SNatalie Beams @brief Get data size for a Context 88880a9ef05SNatalie Beams 889ea61e9acSJeremy L Thompson @param[in] ctx CeedQFunctionContext 89080a9ef05SNatalie Beams @param[out] ctx_size Variable to store size of context data values 89180a9ef05SNatalie Beams 89280a9ef05SNatalie Beams @return An error code: 0 - success, otherwise - failure 89380a9ef05SNatalie Beams 89480a9ef05SNatalie Beams @ref User 89580a9ef05SNatalie Beams **/ 8962b730f8bSJeremy L Thompson int CeedQFunctionContextGetContextSize(CeedQFunctionContext ctx, size_t *ctx_size) { 89780a9ef05SNatalie Beams *ctx_size = ctx->ctx_size; 89880a9ef05SNatalie Beams return CEED_ERROR_SUCCESS; 89980a9ef05SNatalie Beams } 90080a9ef05SNatalie Beams 90180a9ef05SNatalie Beams /** 902777ff853SJeremy L Thompson @brief View a CeedQFunctionContext 903777ff853SJeremy L Thompson 904777ff853SJeremy L Thompson @param[in] ctx CeedQFunctionContext to view 905777ff853SJeremy L Thompson @param[in] stream Filestream to write to 906777ff853SJeremy L Thompson 907777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 908777ff853SJeremy L Thompson 909777ff853SJeremy L Thompson @ref User 910777ff853SJeremy L Thompson **/ 911777ff853SJeremy L Thompson int CeedQFunctionContextView(CeedQFunctionContext ctx, FILE *stream) { 912777ff853SJeremy L Thompson fprintf(stream, "CeedQFunctionContext\n"); 913d1d35e2fSjeremylt fprintf(stream, " Context Data Size: %ld\n", ctx->ctx_size); 9143668ca4bSJeremy L Thompson for (CeedInt i = 0; i < ctx->num_fields; i++) { 9153668ca4bSJeremy L Thompson // LCOV_EXCL_START 9162b730f8bSJeremy L Thompson fprintf(stream, " Labeled %s field: %s\n", CeedContextFieldTypes[ctx->field_labels[i]->type], ctx->field_labels[i]->name); 9173668ca4bSJeremy L Thompson // LCOV_EXCL_STOP 9183668ca4bSJeremy L Thompson } 919e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 920777ff853SJeremy L Thompson } 921777ff853SJeremy L Thompson 922777ff853SJeremy L Thompson /** 9232790b72bSJeremy L Thompson @brief Set additional destroy routine for CeedQFunctionContext user data 9242790b72bSJeremy L Thompson 925ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to set user destroy function 9262e64a2b9SJeremy L Thompson @param[in] f_mem_type Memory type to use when passing data into `f` 9272e64a2b9SJeremy L Thompson @param[in] f Additional routine to use to destroy user data 9282790b72bSJeremy L Thompson 9292790b72bSJeremy L Thompson @return An error code: 0 - success, otherwise - failure 9302790b72bSJeremy L Thompson 9312790b72bSJeremy L Thompson @ref User 9322790b72bSJeremy L Thompson **/ 9332b730f8bSJeremy L Thompson int CeedQFunctionContextSetDataDestroy(CeedQFunctionContext ctx, CeedMemType f_mem_type, CeedQFunctionContextDataDestroyUser f) { 9342b730f8bSJeremy L Thompson if (!f) { 9352790b72bSJeremy L Thompson // LCOV_EXCL_START 9362b730f8bSJeremy L Thompson return CeedError(ctx->ceed, 1, "Must provide valid callback function for destroying user data"); 9372790b72bSJeremy L Thompson // LCOV_EXCL_STOP 9382b730f8bSJeremy L Thompson } 9392790b72bSJeremy L Thompson ctx->data_destroy_mem_type = f_mem_type; 9402790b72bSJeremy L Thompson ctx->data_destroy_function = f; 9412790b72bSJeremy L Thompson return CEED_ERROR_SUCCESS; 9422790b72bSJeremy L Thompson } 9432790b72bSJeremy L Thompson 9442790b72bSJeremy L Thompson /** 945777ff853SJeremy L Thompson @brief Destroy a CeedQFunctionContext 946777ff853SJeremy L Thompson 947ea61e9acSJeremy L Thompson @param[in,out] ctx CeedQFunctionContext to destroy 948777ff853SJeremy L Thompson 949777ff853SJeremy L Thompson @return An error code: 0 - success, otherwise - failure 950777ff853SJeremy L Thompson 951777ff853SJeremy L Thompson @ref User 952777ff853SJeremy L Thompson **/ 953777ff853SJeremy L Thompson int CeedQFunctionContextDestroy(CeedQFunctionContext *ctx) { 954ad6481ceSJeremy L Thompson if (!*ctx || --(*ctx)->ref_count > 0) { 955ad6481ceSJeremy L Thompson *ctx = NULL; 956ad6481ceSJeremy L Thompson return CEED_ERROR_SUCCESS; 957ad6481ceSJeremy L Thompson } 9582b730f8bSJeremy L Thompson if ((*ctx) && ((*ctx)->state % 2) == 1) { 959777ff853SJeremy L Thompson // LCOV_EXCL_START 9602b730f8bSJeremy L Thompson return CeedError((*ctx)->ceed, 1, "Cannot destroy CeedQFunctionContext, the access lock is in use"); 961777ff853SJeremy L Thompson // LCOV_EXCL_STOP 9622b730f8bSJeremy L Thompson } 963777ff853SJeremy L Thompson 9642b730f8bSJeremy L Thompson CeedCall(CeedQFunctionContextDestroyData(*ctx)); 9652b730f8bSJeremy L Thompson if ((*ctx)->Destroy) CeedCall((*ctx)->Destroy(*ctx)); 966cdf32b93SJeremy L Thompson for (CeedInt i = 0; i < (*ctx)->num_fields; i++) { 9672b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->name)); 9682b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i]->description)); 9692b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels[i])); 970cdf32b93SJeremy L Thompson } 9712b730f8bSJeremy L Thompson CeedCall(CeedFree(&(*ctx)->field_labels)); 9722b730f8bSJeremy L Thompson CeedCall(CeedDestroy(&(*ctx)->ceed)); 9732b730f8bSJeremy L Thompson CeedCall(CeedFree(ctx)); 974cdf32b93SJeremy L Thompson 975e15f9bd0SJeremy L Thompson return CEED_ERROR_SUCCESS; 976777ff853SJeremy L Thompson } 977777ff853SJeremy L Thompson 978777ff853SJeremy L Thompson /// @} 979