AutoMap

Creating a reduce operation for AutoMap data-types



Quick Links  :  Main Page  |  AutoMap  |  AutoLink  |  Mailing List  |  License  |  Award  |  Papers  |  Acknowledgments

1) General presentation of reduce operations

Reduce operations are useful to perform a global operation on all the processors of a group. The MPI documentation defines 2 functions that implement the reduce operations :

2) Creating a reduce operation

There are some built-in operations that are available in MPI (like MPI_MAX and MPI_MIN to compute the maximum and the minimum of some values of basic type, MPI_INT, MPI_LONG, MPI_SHORT, MPI_UNSIGNED_SHORT, MPI_UNSIGNED, MPI_UNSIGNED_LONG, MPI_FLOAT, MPI_DOUBLE, MPI_REAL, MPI_DOUBLE_PRECISION, MPI_LONG_DOUBLE, MPI_SUM and MPI_PROD, to make the sum and the product of precedent datatypes, and for MPI_COMPLEX, as well as other logical operations MPI_AND, MPI_BAND, MPI_LOR, MPI_BOR, MPI_LXOR ). But there is also the possibility to create one's own operations on one's own MPI_Datatype. This last feature can be useful when using AutoMap created data-types.
To create a reduce operations use the MPI function, MPI_Op_create(MPI_User_function *function, int commute, MPI_Op *op), where : To delete a created reduction operation, one just have to use the MPI_op_free( MPI_Op *op) function, this can be useful to change a reduce function's functionality, but keep the same name for the function.

3) Example of use

Here is an example showing how to proceed to create such a reduce operation. Suppose one wants to create an operation to compare two complex numbers, as such an operations doesn't exist in the MPI basic functions.
The file "struct.h" contains this simple structure (formatted for use with AutoMap) :
/*~ AM_Begin */

struct{
  double real, imag;
}_Complex;
typedef struct _Complex Complex/*~AM*/;

/*~ AM_End */
    
Once the "mpitypes.inc" file has been generated using AutoMap, you can create a reduce operation in your source code. Here is an example showing how to compute the complex with the biggest module for each index of an array.
#include <mpi.h>
#include "struct.h"     /* Data-types file */
#include "mpitypes.inc" /* AutoMap generated output from data-types file */
#define true (1==1)
#define false (0==0)

void complexcompare(Complex * in, Complex * inout, int * len, MPI_Datatype * dptr)
{
 int i;
  Complex c;
  for (i = 0; i < *len; i++) {
    if (((in->real*in->real) + (in->imag*in->imag))  >
    ((inout->real*inout->real)+(inout->imag*inout->imag))){
      /* compares the module of the complex in *in and the complex in *inout */
      *inout = *in;
    }
   in++;
   inout++;
 }
}

main(int argc, char* argv[])
{
  MPI_Op myOp;
  Complex a[3], answer[3];

  MPI_Init(&argc, &argv); 
  /* Initialzes MPI */
  Build_MPI_Types();
  /* build the Data-types created by AutoMap */
  
  MPI_Op_create((MPI_User_function *) complexcompare, true, &myOp);
  /* creates the commutative MPI reduce operation associated
     with the function complexcompare under the name myOp */

  [...]

  MPI_Reduce (a, answer, 100, AutoMap_complex , myOp, 0, MPI_COMM_WORLD);
  /* performs the reduce operation over the a array of all the procesors
     in the answer array in the processor of rank 0 */
  MPI_Finalize();
  /* Finalizes MPI */
}
    
If we consider a run of this program on a 3 nodes architecture, with the following arrays [4.5+0i, -5+0.1*i, 6-5.1i] on node 0, [2.1+9i, -3.84+3*i, 0.2+0.8i] on node 1, and [-1.5+0.4i, 7.3+8.1*i, 2.4-1i] on node 2, the array answer finally obtained in node 0, will be [2.1+9i, 7.3+8.1*i, 6-5.1i].
Page created : 1997
Last update : 26 Oct 2001
By : SAVG