[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [mpi-21] [mpi-3] Some thoughts on MPI 2.1, 2.2, 3.0




* Jesper Larsson Traeff <traff@xxxxxxxxxxxx> [2008-01-09 12:09:20]:

> It would be tempting to use the MPI pair-datatypes for segmented
> scans/reductions (start of each segment is marked), selective
> reductions (only marked elements are reduced), and for the following
> problem: find out whether all processes have contributed the same value
> (this seems to require - correct me if I'm wrong - two MPI_Allreduce's,
> first to find a global min or max, second to determine if all processes
> did contribute this value). Operators like
Maybe a user defined operation could do this?:

func(A,B)

If A == B return A otherwise return 0/-1/whatever/invalid

This special invalid value would then propagate op to the root of the
tree, and every rank just needs to check if the return value is the
special value or not.

I've made a test/example prog, see attachment.
Seems to work.


  Dries



Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm

#include <stdio.h>
#include <mpi.h>
#include <assert.h>
#include <unistd.h>

#define LOOPCOUNT 1000

MPI_Op myop; 
int commsize;
int commrank; 

void myopfunc (void * a, void * b, int * len, MPI_Datatype * type)
{
   assert (*type==MPI_INT); 
   assert (*len==1); 
   if (*(int*)a==*(int*)b)
      return;
   *(int*)b=-1; 
}

void doerror (int val, int ret)
{
   int buf[commsize];  
   int i; 

   MPI_Gather (&val, 1, MPI_INT, &buf[0], 1, MPI_INT, 0, MPI_COMM_WORLD); 
   if (!commrank)
   {
      fprintf (stderr, "myfunc said: %i, Error sequence: ", ret); 
      for (i=0; i<commsize; ++i)
         fprintf (stderr, "%i ", buf[i]); 
      fprintf (stderr, "\n"); 
   }
}

int tryop (int val)
{
   int ret; 
   MPI_Allreduce (&val, &ret, 1, MPI_INT, myop, MPI_COMM_WORLD); 
   return ret; 
}

int docheck (int val, int ret)
{
   int min,max; 
   MPI_Allreduce (&val, &min, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD); 
   MPI_Allreduce (&val, &max, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD); 

   if (ret && (min != max) || (!ret && (min == max)))
   {
      doerror (val, ret); 
      return 0; 
   }

   if (!commrank)
   {
      printf ("."); 
      fflush (stdout); 
   }
   return 1; 
}

int main (int argc, char ** args)
{
   unsigned int i; 


   MPI_Init (0,0); 
   
   MPI_Comm_size (MPI_COMM_WORLD, &commsize); 
   MPI_Comm_rank (MPI_COMM_WORLD, &commrank); 
   
   MPI_Op_create (myopfunc, 1, &myop); 
   srand (getpid()); 

   for (i=0; i<LOOPCOUNT; ++i)
   {
      int val = rand(); 
      int ret = (tryop (val) < 0 ? 0 : 1); 
      if (!docheck (val, ret))
         break; 
   }

   MPI_Finalize (); 
}