RTOpPack: Extra C/C++ Code for Vector Reduction/Transformation Operators
Version of the Day
|
Functions | |
int | RTOp_get_op_name (const struct RTOp_RTOp *op, const char **op_name) |
int | RTOp_get_op_type_num_entries (const struct RTOp_RTOp *op, int *num_values, int *num_indexes, int *num_chars) |
int | RTOp_extract_op_state (const struct RTOp_RTOp *op, int num_values, RTOp_value_type value_data[], int num_indexes, RTOp_index_type index_data[], int num_chars, RTOp_char_type char_data[]) |
int | RTOp_load_op_state (int num_values, const RTOp_value_type value_data[], int num_indexes, const RTOp_index_type index_data[], int num_chars, const RTOp_char_type char_data[], struct RTOp_RTOp *op) |
int | RTOp_free_op (struct RTOp_RTOp *op) |
int | RTOp_get_reduct_type_num_entries (const struct RTOp_RTOp *op, int *num_values, int *num_indexes, int *num_chars) |
int | RTOp_reduct_obj_create (const struct RTOp_RTOp *op, RTOp_ReductTarget *reduct_obj) |
int | RTOp_reduct_obj_reinit (const struct RTOp_RTOp *op, RTOp_ReductTarget reduct_obj) |
int | RTOp_reduct_obj_free (const struct RTOp_RTOp *op, RTOp_ReductTarget *reduct_obj) |
int | RTOp_extract_reduct_obj_state (const struct RTOp_RTOp *op, const RTOp_ReductTarget reduct_obj, int num_values, RTOp_value_type value_data[], int num_indexes, RTOp_index_type index_data[], int num_chars, RTOp_char_type char_data[]) |
int | RTOp_load_reduct_obj_state (const struct RTOp_RTOp *op, int num_values, const RTOp_value_type value_data[], int num_indexes, const RTOp_index_type index_data[], int num_chars, const RTOp_char_type char_data[], RTOp_ReductTarget reduct_obj) |
int | RTOp_coord_invariant (const struct RTOp_RTOp *op, int *coord_invariant) |
int | RTOp_apply_op (const struct RTOp_RTOp *op, const int num_vecs, const struct RTOp_SubVector sub_vecs[], const int num_targ_vecs, const struct RTOp_MutableSubVector targ_sub_vecs[], RTOp_ReductTarget reduct_obj) |
int | RTOp_reduce_reduct_objs (const struct RTOp_RTOp *op, RTOp_ReductTarget in_reduct_obj, RTOp_ReductTarget inout_reduct_obj) |
int | RTOp_get_reduct_op (const struct RTOp_RTOp *op, RTOp_reduct_op_func_ptr_t *reduct_op_func_ptr) |
Functions that act virtual with respect to reduction/transformation operators and are used by clients of abstract vectors and by vector implementations to apply these operators.
These functions are used as conveniences and call the virtual functions in the vtbl
of the RTOp_RTOp object and pass in the obj_data
pointer. Therefore, these nonmember functions act polymorphically with respect to the operator object. These functions could be implemented as macros to allow them to be inlined but we all know the problems with macros. The extra function call should not impose too much extra overhead. Because of the potential for macro inlining, the client should not (and should never need to) take the address of one of these functions.
The functions RTOp_get_op_type_num_entries<tt>(...) and RTOp_get_reduct_type_num_entries<tt>(...) are used for externalizing information about the structure of the instance data for reduction/transformation operator objects and for reduction objects. These functions are needed to externalize the representation of these objects so that these objects can be copied by the client and passed over networks between heterogeneous computers. This is needed to allow a client/server usage with reduction/transformation operators (see RTOp_Server).
To better understand the functions that deal with the opaque reduction target objects, the relationship between reduction/transformation operators and reduction target objects must be clarified. A reduction object is intimately associated with and is completely owned by an operator object. In any process, an reduction object can only come into existance by calling the method ::RTOp_reduct_obj_create<tt>(op,&reduct_obj). Once a reduct_obj
is created, the memory footprint of the object is set. If the operator object is later modified in any way (i.e. by RTOp_load_op_state<tt>(op,...)) the the earlier created reduct_obj
may no longer be compatible with its op
object. The implementation of RTOp_load_reduct_obj_state<tt>(op,...,reduct_obj) is not allowed to change the memory footprint of reduct_obj
. All of these restrictions are meant to allow for more simplicity in RTOp
operator implementations.
int RTOp_get_op_name | ( | const struct RTOp_RTOp * | op, |
const char ** | op_name | ||
) |
Return the name (as a null-terminated C-style string) of the operator.
This name is used to differentate an operator subclass from all other operator subclasses. This is an important property needed for a client/server and other advanced computing configurations.
op | [in] The polymorphic reduction/transformation operator object |
op_name | [out] Null-terminated string for the name of the operator type |
0
if successful and !=0
otherwise. int RTOp_get_op_type_num_entries | ( | const struct RTOp_RTOp * | op, |
int * | num_values, | ||
int * | num_indexes, | ||
int * | num_chars | ||
) |
Get the number of members of each datatype in the object's externalized state data.
See RTOp_obj_type_vtbl_t for a description of this function.
op | [in] The polymorphic reduction/transformation operator object |
num_values | [out] Number of RTOp_value_type members |
num_indexes | [out] Number of RTOp_index_type members |
num_chars | [out] Number of RTOp_char_type members |
0
if successful and !=0
otherwise. int RTOp_extract_op_state | ( | const struct RTOp_RTOp * | op, |
int | num_values, | ||
RTOp_value_type | value_data[], | ||
int | num_indexes, | ||
RTOp_index_type | index_data[], | ||
int | num_chars, | ||
RTOp_char_type | char_data[] | ||
) |
Externalize the state of the operator object to a portable format.
This function allows the state of an arbitrary reduction/transformation operator to be transported across a hetergeneous network and have it reconstructed in other processes (using RTOp_load_op_state<tt>(...)).
See RTOp_obj_type_vtbl_t for a description of this function.
0
if successful, !=0
otherwise. int RTOp_load_op_state | ( | int | num_values, |
const RTOp_value_type | value_data[], | ||
int | num_indexes, | ||
const RTOp_index_type | index_data[], | ||
int | num_chars, | ||
const RTOp_char_type | char_data[], | ||
struct RTOp_RTOp * | op | ||
) |
Load the state of the operator object from a portable format.
Note that this function can be called on an uninitilized operator object (i.e. op->obj_data == NULL
) and in this case, the state data will be dynamicallly allocated in a way that is compatible with the constructors and destructors for the operator class (not given here obviously). The memory footprint for the operator object may change as a result of this operation even if it has already been initialized.
See RTOp_obj_type_vtbl_t for a description of this function.
0
if successful and !=0
otherwise. int RTOp_free_op | ( | struct RTOp_RTOp * | op | ) |
Destroy the state data for this object.
op | [in/out] On input, if op->obj_data != NULL then this data will be freed in a way that is compatible with the classes concrete constructors (not given here of course) and with RTOp_load_op_state<tt>(...). On output, op->obj_data and op->vtbl will be set to NULL . |
0
if successful and !=0
otherwise. int RTOp_get_reduct_type_num_entries | ( | const struct RTOp_RTOp * | op, |
int * | num_values, | ||
int * | num_indexes, | ||
int * | num_chars | ||
) |
Get the number of members of each datatype in the reduction object.
See RTOp_obj_type_vtbl_t for a description of this function.
op | [in] The polymorphic reduction/transformation operator object. |
num_values | [out] Number of RTOp_value_type members in the object op.obj_data . |
num_indexes | [out] Number of RTOp_index_type members in the object op.obj_data . |
num_chars | [out] Number of RTOp_char_type members in the object op.obj_data . |
0
if successful and !=0
otherwise. int RTOp_reduct_obj_create | ( | const struct RTOp_RTOp * | op, |
RTOp_ReductTarget * | reduct_obj | ||
) |
Allocate and initialize the reduction object that will be used in the reduction operations.
If RTOp_get_reduct_type_num_entries<tt>(...) returns num_values == 0
, num_indexes == 0
and num_chars == 0
then this function should not be called and may be an error if attempted.
op | [in] The polymorphic reduction/transformation operator object |
reduct_obj | [out] On output *reduct_obj contains the pointer to the allocated target object. Also, *reduct_obj will be initialized ready for use in the reduction operations. If *reduct_obj contains the pointer to an already allocated object on input, it will not be freed (see RTOp_reduct_obj_free<tt>(...)). |
0
if successful and !=0
otherwise. int RTOp_reduct_obj_reinit | ( | const struct RTOp_RTOp * | op, |
RTOp_ReductTarget | reduct_obj | ||
) |
Reinitialize an already allocated target object.
If RTOp_get_reduct_type_num_entries<tt>(...) returns num_values == 0
, num_indexes == 0
and num_chars == 0
then this function should not be called and may be an error if attempted.
op | [in] The reduction/transformation operator object. This must be the same object that was used in the call to ::RTOp_reduct_obj_create<tt>(op,reduct_obj) |
reduct_obj | [out] On output reduct_obj will be reinitialized ready for use in reduction operations. This object must have been created by the ::RTOp_reduct_obj_create<tt>(op,reduct_obj) function first. |
0
if successful and !=0
otherwise. int RTOp_reduct_obj_free | ( | const struct RTOp_RTOp * | op, |
RTOp_ReductTarget * | reduct_obj | ||
) |
Free a target object that was previously allocated.
If RTOp_get_reduct_type_num_entries<tt>(...) returns num_values == 0
, num_indexes == 0
and num_chars == 0
then this function should not be called and may be an error if attempted.
op | [in] The reduction/transformation operator object. This must be the same object that was used in the call to ::RTOp_reduct_obj_create<tt>(op,reduct_obj) |
reduct_obj | [in/out] On input *reduct_obj is the pointer to an allocated target object. It is allowed that *reduct_obj == RTOp_REDUCT_OBJ_NULL on input and if so then nothing happens. This object is then freed and then on output *reduct_obj will be set to RTOp_REDUCT_OBJ_NULL |
0
if successful and !=0
otherwise. int RTOp_extract_reduct_obj_state | ( | const struct RTOp_RTOp * | op, |
const RTOp_ReductTarget | reduct_obj, | ||
int | num_values, | ||
RTOp_value_type | value_data[], | ||
int | num_indexes, | ||
RTOp_index_type | index_data[], | ||
int | num_chars, | ||
RTOp_char_type | char_data[] | ||
) |
Externalize the state of the reduction object to a portable format.
This allows the state of a reduction object to be transported across a heterogeneous network and also allows the use in MPI global reduction operations.
See RTOp_obj_type_vtbl_t for a description of this function.
0
if successful and !=0
otherwise. int RTOp_load_reduct_obj_state | ( | const struct RTOp_RTOp * | op, |
int | num_values, | ||
const RTOp_value_type | value_data[], | ||
int | num_indexes, | ||
const RTOp_index_type | index_data[], | ||
int | num_chars, | ||
const RTOp_char_type | char_data[], | ||
RTOp_ReductTarget | reduct_obj | ||
) |
Load the state of the reduction object from a portable format.
Note that reduct_obj
must be constructed prior to this and therefore the input data must be compatible with the already constructed reduct_obj
object.
See RTOp_obj_type_vtbl_t for a description of this function.
0
if successful and !=0
otherwise. int RTOp_coord_invariant | ( | const struct RTOp_RTOp * | op, |
int * | coord_invariant | ||
) |
int RTOp_apply_op | ( | const struct RTOp_RTOp * | op, |
const int | num_vecs, | ||
const struct RTOp_SubVector | sub_vecs[], | ||
const int | num_targ_vecs, | ||
const struct RTOp_MutableSubVector | targ_sub_vecs[], | ||
RTOp_ReductTarget | reduct_obj | ||
) |
op(sub_vecs[],targ_sub_vecs[]),reduct_obj) -> targ_sub_vecs[],reduct_obj
.
This is the bread and butter of the whole design. Through this method, a vector implementation applies a reduction/transformation operator to a set of sub-vectors.
Preconditions:
num_vecs > 0 || num_targ_vecs > 0
num_vecs > 0 || sub_vecs == NULL
num_targ_vecs > 0 || targ_sub_vecs == NULL
num_vecs > 0
] global_offset == sub_vecs[k].global_offset
, for k = 1,...,num_vecs
num_targ_vecs > 0
] global_offset == targ_sub_vecs[k].global_offset
, for k = 1,...,num_targ_vecs
num_vecs > 0
] sub_dim == sub_vecs[k].sub_dim
, for k = 1,...,num_vecs
num_targ_vecs > 0
] sub_dim == targ_sub_vecs[k].sub_dim
, for k = 1,...,num_targ_vecs
op | [in] Reduction/transformation operator to apply over the sub-vectors. |
num_vecs | [in] Number of non-mutable sub-vectors sub_vec[*] . |
sub_vecs | [in] Array (length num_vecs ) of non-mutable vectors to apply the operator over. The ordering of these sub-vectors sub_vecs[k], for k = 0...num_vecs-1 , is significant to the op object. If num_vecs == 0 then sub_vecs can be NULL . |
num_targ_vecs | [in] Number of mutable sub-vectors targ_sub_vec[*] . |
targ_sub_vecs | [in] Array (length num_targ_vecs ) of mutable vectors to apply the operator over and be mutated. The ordering of these sub-vectors targ_sub_vecs[k], for k = 0...num_targ_vecs-1 , is significant to the op object. If num_targ_vecs == 0 then targ_sub_vecs can be NULL . |
reduct_obj | [in/out] This reduction object must have been created by the ::RTOp_reduct_obj_create<tt>(op,reduct_obj) function and it may have already passed through one or more other reduction operations (accumulating the reductions along the way). The reduction operation will be: |
op(op(sub_vecs[],targ_sub_vecs[]),reduct_obj) -> reduct_obj
By allowing an in/out reduct_obj
and an accumulation of the reduction, the maximum reuse of memory is achieved. If RTOp_reduct_obj_create(op,reduct_obj)
or ::RTOp_reduct_obj_reinit<tt>(op,reduct_obj) was called immediately before this function, then reduct_obj
will of course only contain the reduction from this operation. If RTOp_get_reduct_type_num_entries(...)
returns num_values == 0
, num_indexes == 0
and num_chars == 0
then reduct_obj
should be set to RTOp_REDUCT_OBJ_NULL
and no reduction will be performed.
0
if the operation was successfully executed. If num_vecs
is incompatible with the underlying operator object then ::RTOp_ERR_INVALID_NUM_VECS is returned and the operation is not performed. If num_targ_vecs
is incompatible with the underlying operator object then ::RTOp_ERR_INVALID_NUM_TARG_VECS is returned and the operation is not performed. If the sub-vectors are not compatible (i.e. global_offset
and/or sub_dim
not the same) then ::RTOp_ERR_INCOMPATIBLE_VECS
is returned. int RTOp_reduce_reduct_objs | ( | const struct RTOp_RTOp * | op, |
RTOp_ReductTarget | in_reduct_obj, | ||
RTOp_ReductTarget | inout_reduct_obj | ||
) |
op(in_reduct_obj,inout_reduct_obj) -> inout_reduct_obj
.
This function reduces the reduction objects from reduced sub-vectors by the RTOp_apply_op(op...)
function or those reduced by prior calls to this function.
If reduct_obj == RTOP_REDUCT_OBJ_NULL
after the return of RTOp_reduct_obj_create(op,&reduct_obj)
, then this function should not be called and if it is called with arguments that are not RTOP_REDUCT_OBJ_NULL
then an exception an error value will be returned.
op | [in] The reduction/transformation operation used in the calls to RTOp_apply_op(op,...) and prior calls to this function. |
in_reduct_obj | [in] A target object from a previous reduction. |
inout_reduct_obj | [in/out] On input, contains the result from a previous reduction. On output, contains the the reduction of the two target objects. |
0
if successful and !=0
otherwise. int RTOp_get_reduct_op | ( | const struct RTOp_RTOp * | op, |
RTOp_reduct_op_func_ptr_t * | reduct_op_func_ptr | ||
) |
Externalize the reduction operation for intermediate target objects.
op | [in] The reduction operation used in the calls to RTOp_apply_op(op,...) . |
reduct_op_func_ptr | [out] On output, *reduct_op_func_ptr will point to an external reduction function that can be applied to intermediate reduction target objects. This function is MPI compatible and is designed to be used in MPI reduction operations but may be used in other contexts. Any context specific data needed to perform this reduction must be contained in the externalized format of the target objects used with this externalized reduction function. It is allowed for an operator class to return *reduct_op_func_ptr == NULL in which case the client will just have to make due without this function. |
0
if successful and !=0
otherwise.