Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
- implemented MPI_MAXLOC & MPI_MINLOC in operations
authorgenaud <genaud@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Tue, 23 Mar 2010 12:59:10 +0000 (12:59 +0000)
committergenaud <genaud@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Tue, 23 Mar 2010 12:59:10 +0000 (12:59 +0000)
- added fields _count and _cancelled to MPI_Status struct
- implemented MPI_Get_count()

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@7314 48e7efb5-ca39-0410-a469-dd3cf9ba447f

src/smpi/private.h
src/smpi/smpi_base.c
src/smpi/smpi_mpi.c
src/smpi/smpi_mpi_dt.c

index fd22172..bc1580e 100644 (file)
@@ -68,6 +68,7 @@ void smpi_mpi_send(void* buf, int count, MPI_Datatype datatype, int src, int tag
 void smpi_mpi_sendrecv(void* sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag, void* recvbuf, int recvcount, MPI_Datatype recvtype, int src, int recvtag, MPI_Comm comm, MPI_Status* status);
 int smpi_mpi_test(MPI_Request* request, MPI_Status* status);
 int smpi_mpi_testany(int count, MPI_Request requests[], int* index, MPI_Status* status);
+void smpi_mpi_get_count(MPI_Status *status, MPI_Datatype datatype, int *count);
 void smpi_mpi_wait(MPI_Request* request, MPI_Status* status);
 int smpi_mpi_waitany(int count, MPI_Request requests[], MPI_Status* status);
 void smpi_mpi_waitall(int count, MPI_Request requests[],  MPI_Status status[]);
index 05a391a..a48592d 100644 (file)
@@ -105,6 +105,8 @@ static void finish_wait(MPI_Request* request, MPI_Status* status) {
     status->MPI_SOURCE = (*request)->src;
     status->MPI_TAG = (*request)->tag;
     status->MPI_ERROR = MPI_SUCCESS;
+    status->_count = (*request)->size; // size in bytes
+    status->_cancelled = 0;            // FIXME: cancellation of requests not handled yet 
   }
   DEBUG3("finishing wait for %p [data = %p, complete = %d]", *request, data, data->complete);
   // data == *request if sender is first to finish its wait
@@ -160,6 +162,15 @@ int smpi_mpi_testany(int count, MPI_Request requests[], int* index, MPI_Status*
   return flag;
 }
 
+
+void smpi_mpi_get_count(MPI_Status *status, MPI_Datatype datatype, int *count) {
+ int size = smpi_datatype_size(datatype);
+         *count = (int)(status->_count / size);
+         if ( (int)((*count) * size) != status->_count )
+                   *count = MPI_UNDEFINED;
+}
+
+
 void smpi_mpi_wait(MPI_Request* request, MPI_Status* status) {
   MPI_Request data = (*request)->data;
 
index 7bb89d2..3dda18f 100644 (file)
@@ -732,6 +732,30 @@ int MPI_Sendrecv_replace(void* buf, int count, MPI_Datatype datatype, int dst, i
   return retval;
 }
 
+int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count) {
+  int retval;
+/*
+ * Returns the number of entries received. (Again, we count entries, each of type datatype, not bytes.) 
+ * The datatype argument should match the argument provided by the receive call that set the status variable.
+ * If the size of the datatype is zero, this routine will return a count of zero. 
+ * If the amount of data in status is not an exact multiple of the size of datatype 
+ * (so that count would not be integral), a count of MPI_UNDEFINED is returned instead.
+ *
+ */
+  smpi_bench_end(-1, NULL); //FIXME
+
+  if( 0==smpi_datatype_size(datatype)) {
+          // also check that the type is 'committed' when we have MPI_Type_commit (s.g. 23/03/21010)
+           retval = MPI_ERR_TYPE;
+  } else {
+           smpi_mpi_get_count(status, datatype, count);
+           retval = MPI_SUCCESS;
+  }
+  smpi_bench_begin(-1, NULL);
+  return retval;
+}
+
+
 int MPI_Test(MPI_Request* request, int* flag, MPI_Status* status) {
   int retval;
   int rank = request && (*request)->comm != MPI_COMM_NULL
@@ -1072,8 +1096,7 @@ int MPI_Alltoallv(void* sendbuf, int* sendcounts, int* senddisps, MPI_Datatype s
 int MPI_Get_processor_name( char *name, int *resultlen ) {
   int retval = MPI_SUCCESS;
   smpi_bench_end(-1, NULL);
-  strcpy( name , SIMIX_host_get_name(SIMIX_host_self()));
-  name[MPI_MAX_PROCESSOR_NAME-1]='\0';
+  strncpy( name , SIMIX_host_get_name(SIMIX_host_self()), MPI_MAX_PROCESSOR_NAME-1);
   *resultlen= strlen(name) > MPI_MAX_PROCESSOR_NAME ? MPI_MAX_PROCESSOR_NAME : strlen(name);
 
   smpi_bench_begin(-1, NULL);
index 30575b5..672a5f8 100644 (file)
@@ -37,6 +37,15 @@ typedef struct s_smpi_mpi_datatype {
   };                                          \
   MPI_Datatype name = &mpi_##name;
 
+
+//The following are datatypes for the MPI functions MPI_MAXLOC and MPI_MINLOC.
+typedef struct { float       value; int index;} float_int;
+typedef struct { long        value; int index;} long_int ; 
+typedef struct { double      value; int index;} double_int;
+typedef struct { short       value; int index;} short_int;
+typedef struct { int         value; int index;} int_int;
+typedef struct { long double value; int index;} long_double_int; 
+
 // Predefined data types
 CREATE_MPI_DATATYPE(MPI_CHAR,                  char);
 CREATE_MPI_DATATYPE(MPI_SHORT,                 short);
@@ -68,6 +77,9 @@ CREATE_MPI_DATATYPE(MPI_C_LONG_DOUBLE_COMPLEX, long double _Complex);
 CREATE_MPI_DATATYPE(MPI_AINT,                  MPI_Aint);
 CREATE_MPI_DATATYPE(MPI_OFFSET,                MPI_Offset);
 
+CREATE_MPI_DATATYPE(MPI_FLOAT_INT,                float_int);
+
+
 size_t smpi_datatype_size(MPI_Datatype datatype) {
   return datatype->size;
 }
@@ -129,6 +141,8 @@ typedef struct s_smpi_mpi_op {
 #define BAND_OP(a, b) (b) &= (a)
 #define BOR_OP(a, b)  (b) |= (a)
 #define BXOR_OP(a, b) (b) ^= (a)
+#define MAXLOC_OP(a, b)  (b) = (a.value) < (b.value) ? (b) : (a)
+#define MINLOC_OP(a, b)  (b) = (a.value) < (b.value) ? (a) : (b)
 //TODO : MINLOC & MAXLOC
 
 #define APPLY_FUNC(a, b, length, type, func) \
@@ -349,20 +363,55 @@ static void bxor_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
   }
 }
 
+static void minloc_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
+  if(*datatype == MPI_FLOAT_INT) {
+    APPLY_FUNC(a, b, length, float_int, MINLOC_OP);
+  } else if(*datatype == MPI_LONG_INT) {
+    APPLY_FUNC(a, b, length, long_int, MINLOC_OP);
+  } else if(*datatype == MPI_DOUBLE_INT) {
+    APPLY_FUNC(a, b, length, double_int, MINLOC_OP);
+  } else if(*datatype == MPI_SHORT_INT) {
+    APPLY_FUNC(a, b, length, short_int, MINLOC_OP);
+  } else if(*datatype == MPI_2INT) {
+    APPLY_FUNC(a, b, length, int_int, MINLOC_OP);
+  } else if(*datatype == MPI_LONG_DOUBLE_INT) {
+    APPLY_FUNC(a, b, length, long_double_int, MINLOC_OP);
+  }
+}
+
+static void maxloc_func(void* a, void* b, int* length, MPI_Datatype* datatype) {
+  if(*datatype == MPI_FLOAT_INT) {
+    APPLY_FUNC(a, b, length, float_int, MAXLOC_OP);
+  } else if(*datatype == MPI_LONG_INT) {
+    APPLY_FUNC(a, b, length, long_int, MAXLOC_OP);
+  } else if(*datatype == MPI_DOUBLE_INT) {
+    APPLY_FUNC(a, b, length, double_int, MAXLOC_OP);
+  } else if(*datatype == MPI_SHORT_INT) {
+    APPLY_FUNC(a, b, length, short_int, MAXLOC_OP);
+  } else if(*datatype == MPI_2INT) {
+    APPLY_FUNC(a, b, length, int_int, MAXLOC_OP);
+  } else if(*datatype == MPI_LONG_DOUBLE_INT) {
+    APPLY_FUNC(a, b, length, long_double_int, MAXLOC_OP);
+  }
+}
+
+
 #define CREATE_MPI_OP(name, func)                             \
   static s_smpi_mpi_op_t mpi_##name = { &(func) /* func */ }; \
   MPI_Op name = &mpi_##name;
 
-CREATE_MPI_OP(MPI_MAX,  max_func);
-CREATE_MPI_OP(MPI_MIN,  min_func);
-CREATE_MPI_OP(MPI_SUM,  sum_func);
-CREATE_MPI_OP(MPI_PROD, prod_func);
-CREATE_MPI_OP(MPI_LAND, land_func);
-CREATE_MPI_OP(MPI_LOR,  lor_func);
-CREATE_MPI_OP(MPI_LXOR, lxor_func);
-CREATE_MPI_OP(MPI_BAND, band_func);
-CREATE_MPI_OP(MPI_BOR,  bor_func);
-CREATE_MPI_OP(MPI_BXOR, bxor_func);
+CREATE_MPI_OP(MPI_MAX,     max_func);
+CREATE_MPI_OP(MPI_MIN,     min_func);
+CREATE_MPI_OP(MPI_SUM,     sum_func);
+CREATE_MPI_OP(MPI_PROD,    prod_func);
+CREATE_MPI_OP(MPI_LAND,    land_func);
+CREATE_MPI_OP(MPI_LOR,     lor_func);
+CREATE_MPI_OP(MPI_LXOR,    lxor_func);
+CREATE_MPI_OP(MPI_BAND,    band_func);
+CREATE_MPI_OP(MPI_BOR,     bor_func);
+CREATE_MPI_OP(MPI_BXOR,    bxor_func);
+CREATE_MPI_OP(MPI_MAXLOC,  maxloc_func);
+CREATE_MPI_OP(MPI_MINLOC,  minloc_func);
 
 MPI_Op smpi_op_new(MPI_User_function* function, int commute) {
   MPI_Op op;