The prototype for an external reduction operator function (MPI complient).
This is a typedef for a function pointer that gets past to MPI_Reduce(...)
and MPI_Allreduce(...)
. Therefore, this is the only MPI specific part of this design. Function pointers of this type are returned from RTOp_get_reduct_op()
. The prototype for this function is:
- Parameters
-
array_in | [in] (void *) Array, length len |
array_inout | [in/out] (void *) Array, length len |
len | [in] (int *) |
datatype | [in] (RTOp_Datatype*) Pointer to reduction object datatype (ala MPI) |
- Returns
- void
It is very important to note that the reduction objects passed in in array_in
and array_inout
are of a special form of the externalized object states. The arrays of the externalized state passed in and out of RTOp_extract_reduct_obj_state()
and RTOp_load_reduct_obj_state()
. The state arrays for a single reduction object must be compacted into a sinlge object reduct_obj_ext
as follows:
RTOp_value_type
*num_values = (RTOp_value_type*)reduct_obj_ext, // Number of elements in values[]
*num_indexes = num_values + sizeof(RTOp_value_type), // Number of elements in indexes[]
*num_chars = num_indexes + sizeof(RTOp_value_type); // Number of elements in chars[]
RTOp_value_type
*values = num_chars + sizeof(RTOp_value_type); // Array of num_values values
RTOp_index_type
*indexes = (RTOp_index_type*)(values+num_values); // Array of num_indexes indexes
RTOp_char_type
*chars = (RTOp_char_type*)(indexes+num_indexes); // Array of num_char characters
It may seem silly to delcare integer numbers as floating point numbers but the above specification should ensure that the object pointed to by reduct_obj_ext
will be portable in any heterogeneous environment if we assume that sizeof(RTOp_value_type) >= sizeof(RTOp_index_type) >= sizeof(RTOp_char_type)
which will be true on most platforms. Arranging the members this way will ensure that none of the individual members will be out of alignment. It is the responsibility of the vector implementation to create a compacted version of the externalized states of the reduction objects. The only portable way to ensure that the object pointed to by obj
will be compatible with the above specification is to allocate it as:
void *obj = mallac(
sizeof(RTOp_value_type)*(3 + num_values) +
sizeof(RTOp_index_type)*num_indexes +
sizeof(RTOp_char_type)*num_chars
);
Allocating objects in the above way (or by some means equivalent) and explicitly casting the get the individual members may be a little tedious but it is the only way to insure that the object will be layed out properly. On most platforms with most C compilers however, is may be possible to define structs that will be consistent with the above memory layout of its members but this is not guaranteed by the C standard.