2.8 Reducing Messaging

Reductions currently are implemented only over the entire set of processors. Therefore, one call to one of the forms below must be invoked exacly once from each processor. For the ``node'' forms, each node must invoke it once, and in particular on its rank zero. The handler function of every reduction is always called on processor zero.

void CmiReduce(void *msg, int size, void * (*mergeFn)(void*,void**,int));
Contribute a message msg of size size previously allocated with CmiAlloc. The message will be deallocated by the system by calling CmiFree. The destination handler will be taken by the converse header of the message itself. The last parameter is a function pointer to a merge function (described below).

void CmiReduceStruct((void *data, void (*pupFn)(void*,void*), void * (*mergeFn)(void*,void**,int), CmiHandler dest, void (*deleteFn)(void*));
Contribute a data structure data which is allocated on the heap, possibly in a distributed form (like a linked-list or a tree). On processor zero, the function specified by dest will be invoked with the data structure resulting from the reduction (the pointer returned by the last merge function). This handler does not need to be registered as a converse handler. The other parameters are function pointers whose purpose is described below.

void CmiNodeReduce(void *msg, int size, void * (*mergeFn)(void*,void**,int));
Similar to CmiReduce, only that the contribution is at the node level instead of the processor level.

void CmiNodeReduceStruct((void *data, void (*pupFn)(void*,void*), void * (*mergeFn)(void*,void**,int), CmiHandler dest, void (*deleteFn)(void*));
Similar to CmiNodeReduce, only that the contribution is at the node level instead of the processor level.

Other than the fuction pointer dest used to invoke the final handler on processor zero, there are several other function pointers passed in by the user:

void * (*mergeFn)(void *local, void **remore, int count)
This function is used in all the CmiReduce forms to merge the local message/data structure deposited on a processor with all the messages incoming from the children processors of the reduction spanning tree. The input parameters are in the order: the local data (the exact same pointer passed in as first parameter of CmiReduce and similar); a pointer to an array of incoming messages; the number of elements in the second parameter. The function returns a pointer to a freshly allocated message (or data structure for the Struct forms) corresponding to the merge of all the messages. All the messages in the remote array are deleted by the system; the data pointed by the first parameter should be deleted by this function. If the data can be merged ``in-place'' by modifying or augmenting local, the function can return the same pointer to local which can be considered freshly allocated. Each element in remote is the complete incoming message (including the converse header) for message reductions, and the data as it has been packed by the pup function (without any additional header) for struct reductions.

void (*pupFn)(pup_er p, void *data)
This function will use the PUP framework to pup the data passed in into a message for sending across the network. The data can be either the same data passed in as first parameter of CmiReduceStruct of CmiNodeReduceStruct, or the return of the merge function. It will be called for sizing and packing. (Note: It will not be called for unpacking.)

void (*deleteFn)(void *ptr)
This function is used to delete either the data stucture passed in as first parameter of CmiReduceStruct and CmiNodeReduceStruct, or the return of the merge function. It can be as simple as ``free'' or as complicated as needed to delete complex structures. If this function is NULL, the data structure will not be deleted, and the program can continue to use it. Note: even if this function is NULL, the input data structure can still be modified by the merge function.

June 29, 2008
Converse Homepage
Charm Homepage