Write the data for a field¶
saf_write_field
is a function defined in field.c.
Synopsis:
-
int
saf_write_field
(SAF_ParMode pmode, SAF_Field *field, int member_count, SAF_RelRep *req_type, int *member_ids, int nbufs, hid_t buf_type, void **bufs, SAF_Db *file)¶
Formal Arguments:
pmode
: The parallel mode.field
: The field to write.member_count
: A count of the number of members of the collection in which the field’s dofs aren:1
associated that are actually being written in this call. This value is ignored if you are writing the entire field’s dofs in this call (i.e.,req_type
isSAF__TOTALITY
). Also note that as a convenience, we provide the macroSAF__WHOLE_FIELD
which expands to a comma separated list of appropriate values for this argument and the next two, for the case in which the whole field is being written in this call.req_type
: The type of I/O request. We use a relation representation type here to specify the type of the partial request because it captures the necessary information. PassSAF__HSLAB
if you are writing the dofs of a partial hyperslab of the members of the associated collection. In this case,member_ids
points to 3N
-tuples of starts, counts and strides of the hyperslab (hypersample) request. PassSAF__TUPLES
, if you are writing the dofs for an arbitrary list of members of the associated collection. In this case, themember_ids
points to a list ofN
-tuples. In both cases, ‘N
’ is the number of indexing dimensions in the associated collection. Finally, passSAF__TOTALITY
if you are writing the entire field’s set of dofs.member_ids
: Depending on the value ofreq_type
, this argument points to 3N
-tuples storing, respectively, the starts, counts and strides in each dimension of the associated collection or to a list ofmember_count
N
-tuples, each one identifying a single member of the associated collection or toNULL
in the case of aSAF__TOTALITY
request.nbufs
: The number of buffers. Valid values are either 1 or a value equal to the number of components of the field. A value greater than 1 indicates that the field is stored component by component, one buffer for each component. Note, however, that current limitations of partial requests support only fields that are interleaved bySAF__INTERLEAVE_VECTOR
. This, in turn, means that in a partial I/O request,nbufs
can only ever be one.buf_type
: The type of the objects in the buffer(s). If the buffer datatype was provided in the saf_declare_field call that produced the field handle then this parameter should have a negative value. If however the datatype was not provided in the saf_declare_field or if the handle was the result of a find operation then the datatype must be provided in this call.bufs
: The buffers.file
: Optional file into which the data is written. If none is supplied then the data is written to the same file as thefield
.
Description: This function is used to write a field’s data. If the field is not an indirect reference to other fields, this call involves real disk I/O. All functions in SAF with either “read” or “write” in the name potentially involve real disk I/O.
This function allows a client to write either the entire field’s data or a portion of the field’s data. Recall
that the degrees of freedom (dofs) of a field are n:1
associated with the members of some collection in
the set upon which the field is defined. We call this collection the associated collection.
In order to specify a partial request, the client is required to
specify which members of the associated collection it is writing the dofs for. Ultimately, those members may be
specified using a N
dimensional hyperslab (or hypersample) or an arbitrary list of N
-tuples. In either case,
the number of dimensions, ‘N
’, is the number of indexing dimensions in the associated collection.
At present, there are several limitations. First, the collection must be 1 dimensionally indexed. Next,
only the hyperslab mode or a single member in tuple-mode are supported, not hypersamples and not an
arbitrary list. Finally, if the field is a multi-component field, then the only supported interleave mode is
SAF__INTERLEAVE_VECTOR
.
For indirect fields, the notion of writing on the composite or component fields is lost. On an indirect, composite field, the values written must be handles to other composite fields. Likewise for its component fields. The values written must be handles for other component fields.
Finally, we provide as a convenience the macro SAF__WHOLE_FIELD
which expands to a comma separated list of
values, 0, SAF__TOTALITY
, NULL
, for the three arguments member_count
, req_type
, member_ids
for the case in
which the client is writing the whole field in this call.
Preconditions:
pmode
must be valid. (low-cost)field
must be a valid field handle. (low-cost)bufs
must be specified here or in the saf_declare_field call (not both). (low-cost)- Pass either valid
bufs
andnbufs``>0 or ``NULL
and ``nbufs``==0. (low-cost) - If partial I/O request, collection must be 1D indexed,
req_type
must beSAF__HSLAB
. (high-cost) - Buffer datatype must be specified in field declaration or write. (low-cost)
- Buffer datatype must be consistent between field declaration and write. (low-cost)
Return Value: The constant SAF__SUCCESS
is returned when this function is successful. Otherwise this function either returns
an error number or throws an exception, depending on the value of the library’s error handling property.
Parallel Notes: SAF_EACH
mode is a collective call where each of the N
tasks provides a unique relation. SAF will create a
single HDF5 dataset to hold all the data and will create N
blobs to point into nonoverlapping regions in that
dataset. In SAF__EACH
mode the call must still be collective across the file
communicator (or the communicator
of the dataset to which field
belongs if file
is null). This requirement is due to the fact that an HDF5
dataset may need to be created and such an operation is collective.
Issues: A partial I/O request looks a lot like a subset relation. In fact, we even use the same data type, SAF__SRType
,
to identify the type of partial I/O request. It may be difficult for a client to distinguish between making
a partial I/O request and making real subsets. In theory, there really should be no difference. The act
of writing a portion of a field is the act of defining a subset of the base space the field is defined on
and then restricting the field to that subset. In the current implementation, this requires, at a minimum, the
ability to create transient objects such as the subset representing the piece of the field being written in
this call. In addition, it really requires decoupling the storage containers into which field’s data goes
from declaring and writing fields.
For a compound data-type on a composite field, we probably ought to confirm a) the rank of the compound type is equal to the number of components, b) the type of each member of the compound type is equal to the type of each of the component fields (assuming both are ordered the same), and c) the names of the member types are the same as the component fields. Currently we are only checking a).
Computing the actual size of the I/O request here is NO
SMALL
TASK
. It depends on a combination of factors
including the number of buffers, the number of members whose dofs are being written, the association ratio,
the data-type and whether the field is direct or indirect.
Is it possible that a SAF__EACH
call will have a different offset and data for each task? If so we’ll have to
do some communicating first otherwise :file:`ss_file_synchronize
../sslib_refman.rest/ss_file_synchronize.rst` will see that each task made incompatible
modifications to this object. This code just checks that for now. [rpm 2004-06-07]
See Also:
- saf_declare_field: 16.12: Declare a field
- Fields: Introduction for current chapter