-
Notifications
You must be signed in to change notification settings - Fork 79
Blobs
A few application developers have requested the capability to store an arbitrarily-sized object in an exodus file. The size of the object is not related to any of the existing exodus entities -- nodes, elements, sides, edges, or faces. An example of a blob would be an arbitrary vector of floating-point values; the coefficients of a solution matrix.
The blob concept would allow one or more arbitrarily sized objects to be defined. The object would have:
- Size
- The type would correspond to the native floating point type specified for the exodus file (float or double)
- Unique id (required, positive, unique among blobs)
- Unique name (required, unique among all blobs/blocks/sets/assemblies)
- Zero or more named attributes.
- Attribute is per blob, not a value for each entry in the blob
- attribute can be of type -- integer, char* double
- if type is integer or double, then there can be multiple values per attribute.
- Transient data -- zero or more named floating point values which are output on each timestep.
- Value for each item in the blob for each variable
- Names should be unique across all transient reduction variable names in the model.
- Transient Reduction Data -- zero or more named floating point values which are output on each timestep.
- Single value per timestep per blob for each variable
- Names should be unique across all transient reduction variable names in the model.
- Zero or more "named maps" can be specified
- The map will have a size equal to the size of the blob
- The map entries will be 32- or 64-bit integers (based on exodus integer size)
- The value of the entries in the map(s) is arbitrary and it is the responsibility of the writer/reader to agree on the map conventions and the meaning of the values.
- Client will be responsible for handling all parallel issues.
- Assume that blobs will only be used in the "1->N->1" mode -- parallel application reads and writes from/to a single file on a parallel filesystem.
- Will need to provide partial read/write functions for variables and maps so client can efficiently read/write blob data in a parallel execution.
int num_blob = ex_inquire_int(exoid, EX_INQ_BLOB);
The number of blobs does not need to be specified prior to defining an blob.
Blob names are set and queried via the ex_put_blobs
and ex_get_blobs
functions.
They are somewhat different from other object types in that the names are not defined via the ex_put_name
calls. However, the names can be queried using ex_get_name()
although it is recommended to use the ex_get_blob()
function.
ex_get_name(exoid, EX_BLOB, blob_id, name);
ex_get_names(exoid, EX_BLOB, names[]);
typedef struct ex_blob
{
int64_t id;
char *name;
int64_t size;
} ex_blob;
ex_put_blob(exoid, ex_blob blob);
ex_put_blobs(exoid, num_blob, ex_blob *blobs);
Defines and outputs an blob with id id
and name name
of size size
entries.
NOTE: Efficiency -- it is more efficient to define multiple blobs via a call to ex_put_blobs()
then to call ex_put_blob()
multiple times.
/* conceptual; not real C code */
ex_blob blob[3];
blob.id = {11, 22, 3};
blob.name = {"Fred", "Wilma", "BamBam"};
blob.size = {200000, 100000, 2000000000};
ex_put_blobs(exoid, 3, blob);
int num_blob = ex_inquire_int(exoid, EX_INQ_BLOB);
int64_t ids[num_blob];
ex_get_ids(exoid, EX_BLOB, ids);
int name_len = ex_inquire_int(exoid, EX_INQ_DB_MAX_USED_NAME_LENGTH);
struct ex_blob blobs[num_blob];
for (int i=0; i < num_blob; i++) {
blobs[i].name = malloc(name_len + 1);
}
/* Get parameters for all blobs */
ex_get_blobs(exoid, blobs);
An blob attribute
is similar to an IOSS property consisting of a name, a type, and a value or values. It is not a value per entity in the blob, but a value for the blob. For now, they types will be limited to text, integer, and double to provide capability without the complexity of supporting the many types available in NetCDF-4 including user-defined types. Note that an attribute can have multiple values, for example if the attribute is a range, a single attributed could have two double values -- {1.0, 100.0}
NOTE: This type of attribute (value on entity instead of value per entities members, for example nodes in a nodeset) has also be added to the other entity types (blocks and sets).
NOTE: Need a better name or way of distinguishing from the attributes which are currently supported in Exodus.
- define and output an attribute
ex_attribute attribute = {EX_BLOB, 100, "Offset", EX_DOUBLE, 3, {1.1, 2.2, 3.3}};
ex_put_attribute(exoid, attribute);
- define and output multiple attributes
ex_attribute attributes[10];
/* ... Initialize `attributes` */
ex_put_attributes(exoid, 10, attributes);
- define and output a double attribute
ex_put_double_attribute(exoid, EX_BLOB, id, name, num_values, values);
- define and output an integer attribute
ex_put_integer_attribute(exoid, EX_BLOB, id, name, num_values, values);
- [The size of the integers used in
values
is based on int-size of the database] - define and output a text attribute....
ex_put_text_attribute(exoid, EX_BLOB, id, name, char *values);
- Query number of attributes on an blob
int num_attr = ex_get_attribute_count(exoid, EX_BLOB, id);
- Query names, types, size/length, values of all attributes on an blob
int num_attr = ex_get_attribute_count(exoid, EX_BLOB, id);
ex_attribute attributes[num_attr];
ex_get_attributes(exoid, EX_BLOB, id, attributes);
- Get values of all attributes on the specified entity (BLOB 100)
int count = ex_get_attribute_count(exoid, EX_BLOB, 100)
ex_attribute attributes[count];
memset(attributes, 0, sizeof(ex_attribute)*count);
ex_get_attribute_param(exoid, EX_BLOB, 100, attributes);
/* Get attribute values for all attributes listed in `attributes`
`ex_get_attributes()` will allocate memory for `attributes[i].values`
which must be freed by caller.
*/
ex_get_attributes(exoid, count, attributes);
- Get value of specific attribute on the specified entity (BLOB 100)
int count = ex_get_attribute_count(exoid, EX_BLOB, 100)
ex_attribute attributes[count];
ex_get_attribute_param(exoid, EX_BLOB, 100, attributes);
/* ... allocate space on specific attribute to store values. If
* not allocated, it will be allocated by `ex_get_attribute()`
*/
attributes[3].values = calloc(attributes[3].value_count, sizeof(double));
/* Get attribute values for attribute at index 3 */
ex_get_attribute(exoid, attributes[3]);
The ex_attribute
argument is the struct:
typedef struct ex_attribute
{
ex_entity_type entity_type,
int64_t entity_id,
char name[EX_MAX_NAME];
ex_type type; /* EX_INTEGER, EX_DOUBLE, EX_CHAR */
size_t value_count;
void* values; /* not accessed if NULL */
} ex_attribute;
NOTE: is there benefit to getting all attribute names/types/size in single call, or can we simplify API and just provide the query of individual attribute. Can do this in single call if only fill in non-NULL arguments
[ ] TODO: Add api functions
ex_put_variable_param(exoid, EX_BLOB, num_variables);
ex_get_variable_param(exoid, EX_BLOB, &num_variables);
[UNDECIDED] Can also define and query the blob truth table which will specify which variables are defined on which blobs.
ex_put_reduction_variable_param(exoid, EX_BLOB, num_variables);
ex_get_reduction_variable_param(exoid, EX_BLOB, &num_variables);
Note that there will be a value written to and read from the database for all variables on all blobs, but only the values corresponding to a defined variable will be valid values.
ex_put_variable_names(exoid, EX_BLOB, num_variables, names);
ex_get_variable_names(exoid, EX_BLOB, num_variables, names);
ex_put_variable_name(exoid, EX_BLOB, index, name);
ex_get_variable_name(exoid, EX_BLOB, index, name);
ex_put_reduction_variable_names(exoid, EX_BLOB, num_variables, names);
ex_get_reduction_variable_names(exoid, EX_BLOB, num_variables, names);
ex_put_reduction_variable_name(exoid, EX_BLOB, index, name);
ex_get_reduction_variable_name(exoid, EX_BLOB, index, name);
All variables for a single blob (with id id
):
ex_get_vars(exoid, step, EX_BLOB, id, num_assem_vars, values);
ex_put_vars(exoid, step, EX_BLOB, id, num_assem_vars, values);
[ ] Need partial get/put functions.
All variables for a single blob (with id id
):
ex_get_reduction_vars(exoid, step, EX_BLOB, id, num_assem_vars, values);
ex_put_reduction_vars(exoid, step, EX_BLOB, id, num_assem_vars, values);
- Not yet designed.
- A little different than the normal block or set types since there is really no non-transient CDF var to be defined for a blob. For example, nodes have coordinate vars and elements have connectivity vars which give us a place to store the node or element block in the NetCDF metadata. A blob has a
size
, but there is no non-transient data that depends on that size except for the optional maps.
- Add a
Blob
Ioss::GroupingEntity class * Will have name, id, size, properties, fields - An Ioss::Region will store a list of all blobs in the model.
- Read blob information from Exodus file.
- Blobs will not be supported in any of the SEACAS applications
- Blobs will be stripped out of a file if any of the existing SEACAS applications process an exodus file containing blobs (e.g. grepos)