Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
some preliminary additions to implement more collectives
[simgrid.git] / src / smpi / smpi_mpi.c
index 5fa4121..d19913a 100644 (file)
@@ -186,6 +186,9 @@ int SMPI_MPI_Wait(MPI_Request * request, MPI_Status * status)
   return smpi_mpi_wait(*request, status);
 }
 
+/**
+ * MPI_Bcast
+ **/
 int SMPI_MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root,
                    MPI_Comm comm)
 {
@@ -217,6 +220,73 @@ int SMPI_MPI_Bcast(void *buf, int count, MPI_Datatype datatype, int root,
   return retval;
 }
 
+/**
+ * MPI_Reduce
+ **/
+
+int SMPI_MPI_Reduce( void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, 
+                        MPI_Op op, int root, MPI_Comm comm )
+{
+  int retval = MPI_SUCCESS;
+  int rank;
+  int size;
+  int i;
+  smpi_mpi_request_t *tabrequest; 
+
+  smpi_bench_end();
+
+  rank = smpi_mpi_comm_rank(comm);
+  size = comm->size; 
+
+  tabrequest = malloc((size)*sizeof(smpi_mpi_request_t));
+  if (NULL==tabrequest) {
+       fprintf(stderr,"[smpi] %s:%d : cannot alloc memory for %d requests. Exiting.\n",__FILE__,__LINE__,size);
+       exit(1);
+  }
+
+  if (rank != root) { // if i am not root, simply send my buffer to root
+           retval = smpi_create_request(sendbuf, count, datatype, 
+                                 rank, root, 0, comm, &(tabrequest[rank]));
+           smpi_mpi_isend(tabrequest[rank]);
+           smpi_mpi_wait(tabrequest[rank], MPI_STATUS_IGNORE);
+           //printf("DEBUG: rank %d sent my sendbuf to root (rank %d)\n",rank,root);
+  } else {
+           // i am the root: wait for all buffers by creating requests
+           // i can not use: 'request->forward = size-1;' (which would progagate size-1 receive reqs)
+           // since we should op values as soon as one receiving request matches.
+           for (i=0; i<comm->size; i++) {
+                       if ( rank != i ) { // except for me
+                                 // reminder: for smpi_create_request() the src is always the process sending.
+                                 retval = smpi_create_request(recvbuf, count, datatype, MPI_ANY_SOURCE, root, 
+                                                       0, comm, &(tabrequest[i]));
+                                 if (NULL != tabrequest[i] && MPI_SUCCESS == retval) {
+                                           if (MPI_SUCCESS == retval) {
+                                                       smpi_mpi_irecv(tabrequest[i]);
+                                           }
+                                 }
+                       }
+           }
+           // now, wait for completion of all irecv's.
+           // FIXME: we should implement smpi_waill_all for a more asynchronous behavior
+           for (i=0; i<comm->size; i++) {
+                       if ( rank != i ) { // except for me
+                                 smpi_mpi_wait(tabrequest[i], MPI_STATUS_IGNORE);
+
+                                 // FIXME: the core part is here. To be written ...
+                                 fprintf(stderr,"[smpi] %s:%d : MPI_Reduce *Not yet implemented*.\n",__FILE__,__LINE__);
+
+                       }
+
+           }
+  }
+  for (i=0; i<comm->size; i++) 
+           xbt_mallocator_release(smpi_global->request_mallocator, tabrequest[i]);
+
+  smpi_bench_begin();
+
+  return retval;
+}
+
 // used by comm_split to sort ranks based on key values
 int smpi_compare_rankkeys(const void *a, const void *b);
 int smpi_compare_rankkeys(const void *a, const void *b)
@@ -252,7 +322,7 @@ int SMPI_MPI_Comm_split(MPI_Comm comm, int color, int key,
 
   // FIXME: need to test parameters
 
-  index = smpi_host_index();
+  index = smpi_process_index();
   rank = comm->index_to_rank_map[index];
 
   // default output
@@ -305,8 +375,8 @@ int SMPI_MPI_Comm_split(MPI_Comm comm, int color, int key,
       tempcomm->barrier_mutex = SIMIX_mutex_init();
       tempcomm->barrier_cond = SIMIX_cond_init();
       tempcomm->rank_to_index_map = xbt_new(int, count);
-      tempcomm->index_to_rank_map = xbt_new(int, smpi_global->host_count);
-      for (j = 0; j < smpi_global->host_count; j++) {
+      tempcomm->index_to_rank_map = xbt_new(int, smpi_global->process_count);
+      for (j = 0; j < smpi_global->process_count; j++) {
         tempcomm->index_to_rank_map[j] = -1;
       }
       for (j = 0; j < count; j++) {
@@ -348,3 +418,8 @@ int SMPI_MPI_Comm_split(MPI_Comm comm, int color, int key,
 
   return retval;
 }
+
+double SMPI_MPI_Wtime( void ) 
+{ 
+         return ( SIMIX_get_clock() );
+}