Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge remote-tracking branch 'origin/master'
authorjean-noel quintin <jnquintin@dhcp-892b9b4c.ucd.ie>
Wed, 3 Oct 2012 15:28:45 +0000 (16:28 +0100)
committerjean-noel quintin <jnquintin@dhcp-892b9b4c.ucd.ie>
Wed, 3 Oct 2012 15:28:45 +0000 (16:28 +0100)
Conflicts:
src/smpi/smpi_base.c

1  2 
src/smpi/private.h
src/smpi/smpi_base.c

diff --combined src/smpi/private.h
@@@ -23,49 -23,8 +23,49 @@@ typedef struct s_smpi_process_data *smp
  #define SEND           0x4
  #define RECV           0x8
  
 +
 +//*****************************************************************************************
 +
 +// this struct is here to handle the problem of non-contignous data
 +// for each such structure these function should be implemented (vector
 +// index hvector hindex struct)
 +typedef struct s_smpi_subtype{
 +  void (*serialize)(const void * input, void *output, size_t count, void* subtype);
 +  void (*unserialize)(const void * input, void *output, size_t count, void* subtype);
 +} s_smpi_subtype_t;
 +
 +/*one exemple of implementation for the vector is already here*/
 +typedef struct s_smpi_mpi_vector{
 +  s_smpi_subtype_t base;
 +  size_t block_stride;
 +  size_t block_length;
 +  size_t block_count;
 +  MPI_Datatype old_type;
 +  size_t size_oldtype;
 +} s_smpi_mpi_vector_t;
 +
 +typedef struct s_smpi_mpi_datatype{
 +  size_t size;
 +  /* this let us know if a serialization is required*/
 +  size_t has_subtype;
 +  MPI_Aint lb;
 +  MPI_Aint ub;
 +  int flags;
 +  /* this let us know how to serialize and unserialize*/
 +  void *substruct;
 +} s_smpi_mpi_datatype_t;
 +
 +
 +//*****************************************************************************************
 +
  typedef struct s_smpi_mpi_request {
    void *buf;
 +  /* in the case of non-contignous memory the user address shoud be keep
 +   * to unserialize the data inside the user memory*/
 +  void *old_buf;
 +  /* this let us know how tounserialize at the end of
 +   * the communication*/
 +  MPI_Datatype old_type;
    size_t size;
    int src;
    int dst;
@@@ -122,15 -81,12 +122,15 @@@ int smpi_datatype_hindexed(int count, i
                       MPI_Datatype old_type, MPI_Datatype* new_type);
  int smpi_datatype_struct(int count, int* blocklens, MPI_Aint* indices,
                      MPI_Datatype* old_types, MPI_Datatype* new_type);
 -void smpi_datatype_create(MPI_Datatype* new_type, int size, int flags);
 +
 +void smpi_datatype_create(MPI_Datatype* new_type, int size, int has_subtype, void *struct_type, int flags);
 +
 +
  void smpi_datatype_free(MPI_Datatype* type);
  void smpi_datatype_commit(MPI_Datatype* datatype);
  
  
+ void smpi_empty_status(MPI_Status * status);
  MPI_Op smpi_op_new(MPI_User_function * function, int commute);
  void smpi_op_destroy(MPI_Op op);
  void smpi_op_apply(MPI_Op op, void *invec, void *inoutvec, int *len,
@@@ -183,7 -139,7 +183,7 @@@ int smpi_mpi_testany(int count, MPI_Req
  int smpi_mpi_testall(int count, MPI_Request requests[],
                       MPI_Status status[]);
  void smpi_mpi_probe(int source, int tag, MPI_Comm comm, MPI_Status* status);
MPI_Request smpi_mpi_iprobe(int source, int tag, MPI_Comm comm, int* flag,
void smpi_mpi_iprobe(int source, int tag, MPI_Comm comm, int* flag,
                      MPI_Status* status);
  int smpi_mpi_get_count(MPI_Status * status, MPI_Datatype datatype);
  void smpi_mpi_wait(MPI_Request * request, MPI_Status * status);
@@@ -192,6 -148,8 +192,8 @@@ int smpi_mpi_waitany(int count, MPI_Req
  void smpi_mpi_waitall(int count, MPI_Request requests[],
                        MPI_Status status[]);
  int smpi_mpi_waitsome(int incount, MPI_Request requests[], int *indices,
+                       MPI_Status status[]);
+ int smpi_mpi_testsome(int incount, MPI_Request requests[], int *indices,
                        MPI_Status status[]);
  void smpi_mpi_bcast(void *buf, int count, MPI_Datatype datatype, int root,
                      MPI_Comm comm);
@@@ -289,7 -247,7 +291,7 @@@ void mpi_reduce__(void* sendbuf, void* 
  void mpi_allreduce__(void* sendbuf, void* recvbuf, int* count, int* datatype,
                       int* op, int* comm, int* ierr);
  void mpi_scatter__(void* sendbuf, int* sendcount, int* sendtype,
 -                   void* recvbuf, int* recvcount, int* recvtype, 
 +                   void* recvbuf, int* recvcount, int* recvtype,
                     int* root, int* comm, int* ierr);
  void mpi_gather__(void* sendbuf, int* sendcount, int* sendtype,
                    void* recvbuf, int* recvcount, int* recvtype,
diff --combined src/smpi/smpi_base.c
@@@ -2,7 -2,7 +2,7 @@@
   * All rights reserved.                                                     */
  
  /* This program is free software; you can redistribute it and/or modify it
 -  * under the terms of the license (GNU LGPL) which comes with this package. */
 + * under the terms of the license (GNU LGPL) which comes with this package. */
  
  #include "private.h"
  #include "xbt/time.h"
  #include <errno.h>
  #include "surf/surf.h"
  
 -XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_base, smpi,
 -                                "Logging specific to SMPI (base)");
 +
 +XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_base, smpi, "Logging specific to SMPI (base)");
 +
  
  static int match_recv(void* a, void* b, smx_action_t ignored) {
-   MPI_Request ref = (MPI_Request)a;
-   MPI_Request req = (MPI_Request)b;
+    MPI_Request ref = (MPI_Request)a;
+    MPI_Request req = (MPI_Request)b;
+    XBT_DEBUG("Trying to match a recv of src %d against %d, tag %d against %d",ref->src,req->src, ref->tag, req->tag);
  
 -   xbt_assert(ref, "Cannot match recv against null reference");
 -   xbt_assert(req, "Cannot match recv against null request");
 -   return (ref->src == MPI_ANY_SOURCE || req->src == ref->src)
 -          && (ref->tag == MPI_ANY_TAG || req->tag == ref->tag);
 +  xbt_assert(ref, "Cannot match recv against null reference");
 +  xbt_assert(req, "Cannot match recv against null request");
 +  return (ref->src == MPI_ANY_SOURCE || req->src == ref->src)
 +    && (ref->tag == MPI_ANY_TAG || req->tag == ref->tag);
  }
  
  static int match_send(void* a, void* b,smx_action_t ignored) {
-   MPI_Request ref = (MPI_Request)a;
-   MPI_Request req = (MPI_Request)b;
-   xbt_assert(ref, "Cannot match send against null reference");
-   xbt_assert(req, "Cannot match send against null request");
-   return (req->src == MPI_ANY_SOURCE || req->src == ref->src)
-     && (req->tag == MPI_ANY_TAG || req->tag == ref->tag);
+    MPI_Request ref = (MPI_Request)a;
+    MPI_Request req = (MPI_Request)b;
+    XBT_DEBUG("Trying to match a send of src %d against %d, tag %d against %d",ref->src,req->src, ref->tag, req->tag);
+    xbt_assert(ref, "Cannot match send against null reference");
+    xbt_assert(req, "Cannot match send against null request");
+    return (req->src == MPI_ANY_SOURCE || req->src == ref->src)
+           && (req->tag == MPI_ANY_TAG || req->tag == ref->tag);
  }
  
  static MPI_Request build_request(void *buf, int count,
  {
    MPI_Request request;
  
 +  void *old_buf;
 +
    request = xbt_new(s_smpi_mpi_request_t, 1);
 +
 +  s_smpi_subtype_t *subtype = datatype->substruct;
 +
 +  if(datatype->has_subtype == 1){
 +    // This part handles the problem of non-contignous memory
 +    old_buf = buf;
 +    buf = malloc(count*smpi_datatype_size(datatype));
 +    if (flags & SEND) {
 +      subtype->serialize(old_buf, buf, count, datatype->substruct);
 +    }
 +  }
 +
    request->buf = buf;
 -  // FIXME: this will have to be changed to support non-contiguous datatypes
 +  // This part handles the problem of non-contignous memory (for the
 +  // unserialisation at the reception)
 +  request->old_buf = old_buf;
 +  request->old_type = datatype;
 +
    request->size = smpi_datatype_size(datatype) * count;
    request->src = src;
    request->dst = dst;
    return request;
  }
  
+ void smpi_empty_status(MPI_Status * status) {
+   if(status != MPI_STATUS_IGNORE) {
+       status->MPI_SOURCE=MPI_ANY_SOURCE;
+       status->MPI_TAG=MPI_ANY_TAG;
+       status->count=0;
+   }
+ }
  void smpi_action_trace_run(char *path)
  {
    char *name;
    if (path) {
      action_fp = fopen(path, "r");
      xbt_assert(action_fp != NULL, "Cannot open %s: %s", path,
 -                strerror(errno));
 +               strerror(errno));
    }
  
    if (!xbt_dict_is_empty(action_queues)) {
      XBT_WARN
 -        ("Not all actions got consumed. If the simulation ended successfully (without deadlock), you may want to add new processes to your deployment file.");
 +      ("Not all actions got consumed. If the simulation ended successfully (without deadlock), you may want to add new processes to your deployment file.");
  
  
      xbt_dict_foreach(action_queues, cursor, name, todo) {
@@@ -116,8 -107,8 +126,8 @@@ MPI_Request smpi_mpi_send_init(void *bu
                                 int dst, int tag, MPI_Comm comm)
  {
    MPI_Request request =
 -      build_request(buf, count, datatype, smpi_comm_rank(comm), dst, tag,
 -                    comm, PERSISTENT | SEND);
 +    build_request(buf, count, datatype, smpi_comm_rank(comm), dst, tag,
 +                  comm, PERSISTENT | SEND);
  
    return request;
  }
@@@ -126,8 -117,8 +136,8 @@@ MPI_Request smpi_mpi_recv_init(void *bu
                                 int src, int tag, MPI_Comm comm)
  {
    MPI_Request request =
 -      build_request(buf, count, datatype, src, smpi_comm_rank(comm), tag,
 -                    comm, PERSISTENT | RECV);
 +    build_request(buf, count, datatype, src, smpi_comm_rank(comm), tag,
 +                  comm, PERSISTENT | RECV);
  
    return request;
  }
@@@ -138,26 -129,25 +148,25 @@@ void smpi_mpi_start(MPI_Request request
    int detached = 0;
  
    xbt_assert(!request->action,
 -              "Cannot (re)start a non-finished communication");
 +             "Cannot (re)start a non-finished communication");
    if(request->flags & RECV) {
      print_request("New recv", request);
      if (request->size < xbt_cfg_get_int(_surf_cfg_set, "smpi/async_small_thres"))
 -    mailbox = smpi_process_mailbox_small();
 +      mailbox = smpi_process_mailbox_small();
      else
 -    mailbox = smpi_process_mailbox();
 +      mailbox = smpi_process_mailbox();
  
      // FIXME: SIMIX does not yet support non-contiguous datatypes
      request->action = simcall_comm_irecv(mailbox, request->buf, &request->size, &match_recv, request);
    } else {
      print_request("New send", request);
-     if (request->size < xbt_cfg_get_int(_surf_cfg_set, "smpi/async_small_thres")) { // eager mode => detached send (FIXME: this limit should be configurable)
+     if (request->size < xbt_cfg_get_int(_surf_cfg_set, "smpi/async_small_thres")) { // eager mode
        mailbox = smpi_process_remote_mailbox_small(
 -            smpi_group_index(smpi_comm_group(request->comm), request->dst));
 +                                                  smpi_group_index(smpi_comm_group(request->comm), request->dst));
      }else{
        XBT_DEBUG("Send request %p is not in the permanent receive mailbox (buf: %p)",request,request->buf);
        mailbox = smpi_process_remote_mailbox(
 -                  smpi_group_index(smpi_comm_group(request->comm), request->dst));
 +                                            smpi_group_index(smpi_comm_group(request->comm), request->dst));
      }
      if (request->size < 64*1024 ) { //(FIXME: this limit should be configurable)
        void *oldbuf = request->buf;
        XBT_DEBUG("Send request %p is detached; buf %p copied into %p",request,oldbuf,request->buf);
      }
  
 -      request->action =
 +    request->action =
        simcall_comm_isend(mailbox, request->size, -1.0,
 -              request->buf, request->size,
 -              &match_send,
 -              &smpi_mpi_request_free_voidp, // how to free the userdata if a detached send fails
 -              request,
 -              // detach if msg size < eager/rdv switch limit
 -              detached);
 -
 -  #ifdef HAVE_TRACING
 -      /* FIXME: detached sends are not traceable (request->action == NULL) */
 -      if (request->action)
 -        simcall_set_category(request->action, TRACE_internal_smpi_get_category());
 -  #endif
 +                         request->buf, request->size,
 +                         &match_send,
 +                         &smpi_mpi_request_free_voidp, // how to free the userdata if a detached send fails
 +                         request,
 +                         // detach if msg size < eager/rdv switch limit
 +                         detached);
  
 -    }
 +#ifdef HAVE_TRACING
 +    /* FIXME: detached sends are not traceable (request->action == NULL) */
 +    if (request->action)
 +      simcall_set_category(request->action, TRACE_internal_smpi_get_category());
 +#endif
 +
 +  }
  
  }
  
  void smpi_mpi_startall(int count, MPI_Request * requests)
  {
 -    int i;
 +  int i;
  
    for(i = 0; i < count; i++) {
      smpi_mpi_start(requests[i]);
@@@ -206,8 -196,8 +215,8 @@@ MPI_Request smpi_isend_init(void *buf, 
                              int dst, int tag, MPI_Comm comm)
  {
    MPI_Request request =
 -      build_request(buf, count, datatype, smpi_comm_rank(comm), dst, tag,
 -                    comm, NON_PERSISTENT | SEND);
 +    build_request(buf, count, datatype, smpi_comm_rank(comm), dst, tag,
 +                  comm, NON_PERSISTENT | SEND);
  
    return request;
  }
@@@ -216,7 -206,7 +225,7 @@@ MPI_Request smpi_mpi_isend(void *buf, i
                             int dst, int tag, MPI_Comm comm)
  {
    MPI_Request request =
 -      smpi_isend_init(buf, count, datatype, dst, tag, comm);
 +    smpi_isend_init(buf, count, datatype, dst, tag, comm);
  
    smpi_mpi_start(request);
    return request;
@@@ -226,8 -216,9 +235,8 @@@ MPI_Request smpi_irecv_init(void *buf, 
                              int src, int tag, MPI_Comm comm)
  {
    MPI_Request request =
 -      build_request(buf, count, datatype, src, smpi_comm_rank(comm), tag,
 -                    comm, NON_PERSISTENT | RECV);
 -
 +    build_request(buf, count, datatype, src, smpi_comm_rank(comm), tag,
 +                  comm, NON_PERSISTENT | RECV);
    return request;
  }
  
@@@ -235,7 -226,7 +244,7 @@@ MPI_Request smpi_mpi_irecv(void *buf, i
                             int src, int tag, MPI_Comm comm)
  {
    MPI_Request request =
 -      smpi_irecv_init(buf, count, datatype, src, tag, comm);
 +    smpi_irecv_init(buf, count, datatype, src, tag, comm);
  
    smpi_mpi_start(request);
    return request;
@@@ -245,6 -236,7 +254,6 @@@ void smpi_mpi_recv(void *buf, int count
                     int tag, MPI_Comm comm, MPI_Status * status)
  {
    MPI_Request request;
 -
    request = smpi_mpi_irecv(buf, count, datatype, src, tag, comm);
    smpi_mpi_wait(&request, status);
  }
  void smpi_mpi_send(void *buf, int count, MPI_Datatype datatype, int dst,
                     int tag, MPI_Comm comm)
  {
 -        MPI_Request request;
 -        request = smpi_mpi_isend(buf, count, datatype, dst, tag, comm);
 -        smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
 +  MPI_Request request;
 +
 +  request = smpi_mpi_isend(buf, count, datatype, dst, tag, comm);
 +  smpi_mpi_wait(&request, MPI_STATUS_IGNORE);
  }
  
  void smpi_mpi_sendrecv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
    MPI_Status stats[2];
  
    requests[0] =
 -      smpi_isend_init(sendbuf, sendcount, sendtype, dst, sendtag, comm);
 +    smpi_isend_init(sendbuf, sendcount, sendtype, dst, sendtag, comm);
    requests[1] =
 -      smpi_irecv_init(recvbuf, recvcount, recvtype, src, recvtag, comm);
 +    smpi_irecv_init(recvbuf, recvcount, recvtype, src, recvtag, comm);
    smpi_mpi_startall(2, requests);
    smpi_mpi_waitall(2, requests, stats);
    if(status != MPI_STATUS_IGNORE) {
@@@ -290,7 -281,7 +299,7 @@@ static void finish_wait(MPI_Request * r
    MPI_Request req = *request;
    // if we have a sender, we should use its data, and not the data from the receive
    if((req->action)&&
 -      (req->src==MPI_ANY_SOURCE || req->tag== MPI_ANY_TAG))
 +     (req->src==MPI_ANY_SOURCE || req->tag== MPI_ANY_TAG))
      req = (MPI_Request)SIMIX_comm_get_src_data((*request)->action);
  
    if(status != MPI_STATUS_IGNORE) {
    req = *request;
  
    print_request("Finishing", req);
 +  MPI_Datatype datatype = req->old_type;
 +  if(datatype->has_subtype == 1){
 +      // This part handles the problem of non-contignous memory
 +      // the unserialization at the reception
 +    s_smpi_subtype_t *subtype = datatype->substruct;
 +    if(req->flags & RECV) {
 +      subtype->unserialize(req->buf, req->old_buf, req->size/smpi_datatype_size(datatype) , datatype->substruct);
 +    }
 +    //FIXME: I am not sure that if the send is detached we have to free
 +    //the sender buffer thus I do it only for the reciever
 +    if(req->flags & RECV) free(req->buf);
 +  }
 +
    if(req->flags & NON_PERSISTENT) {
      smpi_mpi_request_free(request);
    } else {
  
  int smpi_mpi_test(MPI_Request * request, MPI_Status * status) {
    int flag;
 +
+   //assume that request is not MPI_REQUEST_NULL (filtered in PMPI_Test or smpi_mpi_testall before)
    if ((*request)->action == NULL)
      flag = 1;
    else
      flag = simcall_comm_test((*request)->action);
    if(flag) {
      finish_wait(request, status);
+   }else{
+     smpi_empty_status(status);
    }
    return flag;
  }
@@@ -351,24 -331,29 +363,29 @@@ int smpi_mpi_testany(int count, MPI_Req
      map = xbt_new(int, count);
      size = 0;
      for(i = 0; i < count; i++) {
-       if(requests[i]->action) {
-         xbt_dynar_push(comms, &requests[i]->action);
-         map[size] = i;
-         size++;
+       if((requests[i]!=MPI_REQUEST_NULL) && requests[i]->action) {
+          xbt_dynar_push(comms, &requests[i]->action);
+          map[size] = i;
+          size++;
        }
      }
      if(size > 0) {
        i = simcall_comm_testany(comms);
-       // FIXME: MPI_UNDEFINED or does SIMIX have a return code?
-       if(i != MPI_UNDEFINED) {
+       // not MPI_UNDEFINED, as this is a simix return code
+       if(i != -1) {
          *index = map[i];
-         smpi_mpi_wait(&requests[*index], status);
+         finish_wait(&requests[*index], status);
          flag = 1;
        }
+     }else{
+         //all requests are null or inactive, return true
+         flag=1;
+         smpi_empty_status(status);
      }
      xbt_free(map);
      xbt_dynar_free(&comms);
    }
    return flag;
  }
  
  int smpi_mpi_testall(int count, MPI_Request requests[],
                       MPI_Status status[])
  {
+   MPI_Status stat;
+   MPI_Status *pstat = status == MPI_STATUSES_IGNORE ? MPI_STATUS_IGNORE : &stat;
    int flag=1;
    int i;
-   for(i=0; i<count; i++)
-     if (smpi_mpi_test(&requests[i], &status[i])!=1)
-       flag=0;
+   for(i=0; i<count; i++){
+     if(requests[i]!= MPI_REQUEST_NULL){
+       if (smpi_mpi_test(&requests[i], pstat)!=1){
+         flag=0;
+       }
+     }else{
+       smpi_empty_status(pstat);
+     }
+     if(status != MPI_STATUSES_IGNORE) {
+       memcpy(&status[i], pstat, sizeof(*pstat));
+     }
+   }
    return flag;
  }
  
@@@ -389,34 -384,34 +416,34 @@@ void smpi_mpi_probe(int source, int tag
    int flag=0;
    //FIXME find another wait to avoid busy waiting ?
    // the issue here is that we have to wait on a nonexistent comm
-   MPI_Request request;
    while(flag==0){
-     request = smpi_mpi_iprobe(source, tag, comm, &flag, status);
+     smpi_mpi_iprobe(source, tag, comm, &flag, status);
      XBT_DEBUG("Busy Waiting on probing : %d", flag);
      if(!flag) {
-       smpi_mpi_request_free(&request);
        simcall_process_sleep(0.0001);
      }
    }
  }
  
- MPI_Request smpi_mpi_iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status){
-   MPI_Request request = build_request(NULL, 0, MPI_CHAR, source, smpi_comm_rank(comm), tag,
-                                      comm, NON_PERSISTENT | RECV);
+ void smpi_mpi_iprobe(int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status){
+   MPI_Request request =build_request(NULL, 0, MPI_CHAR, source, smpi_comm_rank(comm), tag,
+             comm, NON_PERSISTENT | RECV);
    // behave like a receive, but don't do it
    smx_rdv_t mailbox;
  
    print_request("New iprobe", request);
    // We have to test both mailboxes as we don't know if we will receive one one or another
-   if (xbt_cfg_get_int(_surf_cfg_set, "smpi/async_small_thres")>0){
-     mailbox = smpi_process_mailbox_small();
-     request->action = simcall_comm_iprobe(mailbox, request->src, request->tag, &match_recv, (void*)request);
-   }
-   if (request->action==NULL){
-     mailbox = smpi_process_mailbox();
-     request->action = simcall_comm_iprobe(mailbox, request->src, request->tag, &match_recv, (void*)request);
-   }
+     if (xbt_cfg_get_int(_surf_cfg_set, "smpi/async_small_thres")>0){
+         mailbox = smpi_process_mailbox_small();
+         XBT_DEBUG("trying to probe the perm recv mailbox");
+         request->action = simcall_comm_iprobe(mailbox, request->src, request->tag, &match_recv, (void*)request);
+     }
+     if (request->action==NULL){
+       mailbox = smpi_process_mailbox();
+         XBT_DEBUG("trying to probe the other mailbox");
+         request->action = simcall_comm_iprobe(mailbox, request->src, request->tag, &match_recv, (void*)request);
+     }
  
    if(request->action){
      MPI_Request req = (MPI_Request)SIMIX_comm_get_src_data(request->action);
      }
    }
    else *flag=false;
+   smpi_mpi_request_free(&request);
  
-   return request;
+   return;
  }
  
  void smpi_mpi_wait(MPI_Request * request, MPI_Status * status)
@@@ -468,38 -464,54 +496,54 @@@ int smpi_mpi_waitany(int count, MPI_Req
      if(size > 0) {
        i = simcall_comm_waitany(comms);
  
-       // FIXME: MPI_UNDEFINED or does SIMIX have a return code?
-       if (i != MPI_UNDEFINED) {
+       // not MPI_UNDEFINED, as this is a simix return code
+       if (i != -1) {
          index = map[i];
          finish_wait(&requests[index], status);
        }
      }
      xbt_free(map);
      xbt_dynar_free(&comms);
    }
+   if (index==MPI_UNDEFINED)
+     smpi_empty_status(status);
    return index;
  }
  
  void smpi_mpi_waitall(int count, MPI_Request requests[],
                        MPI_Status status[])
  {
-   int index, c;
+   int  index, c;
    MPI_Status stat;
-   MPI_Status *pstat = status == MPI_STATUS_IGNORE ? MPI_STATUS_IGNORE : &stat;
+   MPI_Status *pstat = status == MPI_STATUSES_IGNORE ? MPI_STATUS_IGNORE : &stat;
+   //tag invalid requests in the set
    for(c = 0; c < count; c++) {
-     if(MC_IS_ENABLED) {
-       smpi_mpi_wait(&requests[c], pstat);
-       index = c;
-     } else {
-       index = smpi_mpi_waitany(count, requests, pstat);
-       if(index == MPI_UNDEFINED) {
-         break;
+     if(requests[c]==MPI_REQUEST_NULL || requests[c]->dst == MPI_PROC_NULL ){
+       if(status != MPI_STATUSES_IGNORE)
+         smpi_empty_status(&status[c]);
+     }else if(requests[c]->src == MPI_PROC_NULL ){
+       if(status != MPI_STATUSES_IGNORE) {
+         smpi_empty_status(&status[c]);
+         status[c].MPI_SOURCE=MPI_PROC_NULL;
        }
      }
-     if(status != MPI_STATUS_IGNORE) {
-       memcpy(&status[index], pstat, sizeof(*pstat));
+   }
+   for(c = 0; c < count; c++) {
+       if(MC_IS_ENABLED) {
+         smpi_mpi_wait(&requests[c], pstat);
+         index = c;
+       } else {
+         index = smpi_mpi_waitany(count, requests, pstat);
+         if(index == MPI_UNDEFINED) {
+           break;
+        }
+       if(status != MPI_STATUSES_IGNORE) {
+         memcpy(&status[index], pstat, sizeof(*pstat));
+       }
      }
    }
  }
@@@ -508,17 -520,51 +552,51 @@@ int smpi_mpi_waitsome(int incount, MPI_
                        MPI_Status status[])
  {
    int i, count, index;
+   MPI_Status stat;
+   MPI_Status *pstat = status == MPI_STATUSES_IGNORE ? MPI_STATUS_IGNORE : &stat;
  
    count = 0;
-   for(i = 0; i < incount; i++) {
-     if(smpi_mpi_testany(incount, requests, &index, status)) {
+   for(i = 0; i < incount; i++)
+   {
+     index=smpi_mpi_waitany(incount, requests, pstat);
+     if(index!=MPI_UNDEFINED){
        indices[count] = index;
        count++;
+       if(status != MPI_STATUSES_IGNORE) {
+         memcpy(&status[index], pstat, sizeof(*pstat));
+       }
+     }else{
+       return MPI_UNDEFINED;
      }
    }
    return count;
  }
  
+ int smpi_mpi_testsome(int incount, MPI_Request requests[], int *indices,
+                       MPI_Status status[])
+ {
+   int i, count, count_dead;
+   MPI_Status stat;
+   MPI_Status *pstat = status == MPI_STATUSES_IGNORE ? MPI_STATUS_IGNORE : &stat;
+   count = 0;
+   for(i = 0; i < incount; i++) {
+     if((requests[i] != MPI_REQUEST_NULL)) {
+       if(smpi_mpi_test(&requests[i], pstat)) {
+          indices[count] = i;
+          count++;
+          if(status != MPI_STATUSES_IGNORE) {
+             memcpy(&status[i], pstat, sizeof(*pstat));
+          }
+       }
+     }else{
+       count_dead++;
+     }
+   }
+   if(count_dead==incount)return MPI_UNDEFINED;
+   else return count;
+ }
  void smpi_mpi_bcast(void *buf, int count, MPI_Datatype datatype, int root,
                      MPI_Comm comm)
  {
@@@ -550,15 -596,15 +628,15 @@@ void smpi_mpi_gather(void *sendbuf, in
      // FIXME: check for errors
      smpi_datatype_extent(recvtype, &lb, &recvext);
      // Local copy from root
 -    smpi_datatype_copy(sendbuf, sendcount, sendtype, 
 -        (char *)recvbuf + root * recvcount * recvext, recvcount, recvtype);
 +    smpi_datatype_copy(sendbuf, sendcount, sendtype,
 +                       (char *)recvbuf + root * recvcount * recvext, recvcount, recvtype);
      // Receive buffers from senders
      requests = xbt_new(MPI_Request, size - 1);
      index = 0;
      for(src = 0; src < size; src++) {
        if(src != root) {
 -        requests[index] = smpi_irecv_init((char *)recvbuf + src * recvcount * recvext, 
 -                                          recvcount, recvtype, 
 +        requests[index] = smpi_irecv_init((char *)recvbuf + src * recvcount * recvext,
 +                                          recvcount, recvtype,
                                            src, system_tag, comm);
          index++;
        }
@@@ -588,8 -634,8 +666,8 @@@ void smpi_mpi_gatherv(void *sendbuf, in
      // FIXME: check for errors
      smpi_datatype_extent(recvtype, &lb, &recvext);
      // Local copy from root
 -    smpi_datatype_copy(sendbuf, sendcount, sendtype, 
 -                       (char *)recvbuf + displs[root] * recvext, 
 +    smpi_datatype_copy(sendbuf, sendcount, sendtype,
 +                       (char *)recvbuf + displs[root] * recvext,
                         recvcounts[root], recvtype);
      // Receive buffers from senders
      requests = xbt_new(MPI_Request, size - 1);
      for(src = 0; src < size; src++) {
        if(src != root) {
          requests[index] =
 -            smpi_irecv_init((char *)recvbuf + displs[src] * recvext, 
 -                            recvcounts[src], recvtype, src, system_tag, comm);
 +          smpi_irecv_init((char *)recvbuf + displs[src] * recvext,
 +                          recvcounts[src], recvtype, src, system_tag, comm);
          index++;
        }
      }
@@@ -624,8 -670,8 +702,8 @@@ void smpi_mpi_allgather(void *sendbuf, 
    // FIXME: check for errors
    smpi_datatype_extent(recvtype, &lb, &recvext);
    // Local copy from self
 -  smpi_datatype_copy(sendbuf, sendcount, sendtype, 
 -                     (char *)recvbuf + rank * recvcount * recvext, recvcount, 
 +  smpi_datatype_copy(sendbuf, sendcount, sendtype,
 +                     (char *)recvbuf + rank * recvcount * recvext, recvcount,
                       recvtype);
    // Send/Recv buffers to/from others;
    requests = xbt_new(MPI_Request, 2 * (size - 1));
    for(other = 0; other < size; other++) {
      if(other != rank) {
        requests[index] =
 -          smpi_isend_init(sendbuf, sendcount, sendtype, other, system_tag,
 -                          comm);
 +        smpi_isend_init(sendbuf, sendcount, sendtype, other, system_tag,
 +                        comm);
        index++;
 -      requests[index] = smpi_irecv_init((char *)recvbuf + other * recvcount * recvext, 
 -                                        recvcount, recvtype, other, 
 +      requests[index] = smpi_irecv_init((char *)recvbuf + other * recvcount * recvext,
 +                                        recvcount, recvtype, other,
                                          system_tag, comm);
        index++;
      }
@@@ -663,8 -709,8 +741,8 @@@ void smpi_mpi_allgatherv(void *sendbuf
    // FIXME: check for errors
    smpi_datatype_extent(recvtype, &lb, &recvext);
    // Local copy from self
 -  smpi_datatype_copy(sendbuf, sendcount, sendtype, 
 -                     (char *)recvbuf + displs[rank] * recvext, 
 +  smpi_datatype_copy(sendbuf, sendcount, sendtype,
 +                     (char *)recvbuf + displs[rank] * recvext,
                       recvcounts[rank], recvtype);
    // Send buffers to others;
    requests = xbt_new(MPI_Request, 2 * (size - 1));
    for(other = 0; other < size; other++) {
      if(other != rank) {
        requests[index] =
 -          smpi_isend_init(sendbuf, sendcount, sendtype, other, system_tag,
 -                          comm);
 +        smpi_isend_init(sendbuf, sendcount, sendtype, other, system_tag,
 +                        comm);
        index++;
        requests[index] =
 -          smpi_irecv_init((char *)recvbuf + displs[other] * recvext, recvcounts[other],
 -                          recvtype, other, system_tag, comm);
 +        smpi_irecv_init((char *)recvbuf + displs[other] * recvext, recvcounts[other],
 +                        recvtype, other, system_tag, comm);
        index++;
      }
    }
@@@ -707,13 -753,13 +785,13 @@@ void smpi_mpi_scatter(void *sendbuf, in
      smpi_datatype_extent(sendtype, &lb, &sendext);
      // Local copy from root
      smpi_datatype_copy((char *)sendbuf + root * sendcount * sendext,
 -      sendcount, sendtype, recvbuf, recvcount, recvtype);
 +                       sendcount, sendtype, recvbuf, recvcount, recvtype);
      // Send buffers to receivers
      requests = xbt_new(MPI_Request, size - 1);
      index = 0;
      for(dst = 0; dst < size; dst++) {
        if(dst != root) {
 -        requests[index] = smpi_isend_init((char *)sendbuf + dst * sendcount * sendext, 
 +        requests[index] = smpi_isend_init((char *)sendbuf + dst * sendcount * sendext,
                                            sendcount, sendtype, dst,
                                            system_tag, comm);
          index++;
@@@ -745,7 -791,7 +823,7 @@@ void smpi_mpi_scatterv(void *sendbuf, i
      // FIXME: check for errors
      smpi_datatype_extent(sendtype, &lb, &sendext);
      // Local copy from root
 -    smpi_datatype_copy((char *)sendbuf + displs[root] * sendext, sendcounts[root], 
 +    smpi_datatype_copy((char *)sendbuf + displs[root] * sendext, sendcounts[root],
                         sendtype, recvbuf, recvcount, recvtype);
      // Send buffers to receivers
      requests = xbt_new(MPI_Request, size - 1);
      for(dst = 0; dst < size; dst++) {
        if(dst != root) {
          requests[index] =
 -            smpi_isend_init((char *)sendbuf + displs[dst] * sendext, sendcounts[dst], 
 -                            sendtype, dst, system_tag, comm);
 +          smpi_isend_init((char *)sendbuf + displs[dst] * sendext, sendcounts[dst],
 +                          sendtype, dst, system_tag, comm);
          index++;
        }
      }
@@@ -797,8 -843,8 +875,8 @@@ void smpi_mpi_reduce(void *sendbuf, voi
          //  mapping...
          tmpbufs[index] = xbt_malloc(count * dataext);
          requests[index] =
 -            smpi_irecv_init(tmpbufs[index], count, datatype, src,
 -                            system_tag, comm);
 +          smpi_irecv_init(tmpbufs[index], count, datatype, src,
 +                          system_tag, comm);
          index++;
        }
      }
      smpi_mpi_startall(size - 1, requests);
      for(src = 0; src < size - 1; src++) {
        index = smpi_mpi_waitany(size - 1, requests, MPI_STATUS_IGNORE);
-       XBT_VERB("finished waiting any request with index %d", index);
+       XBT_DEBUG("finished waiting any request with index %d", index);
        if(index == MPI_UNDEFINED) {
          break;
        }
@@@ -851,17 -897,17 +929,17 @@@ void smpi_mpi_scan(void *sendbuf, void 
    tmpbufs = xbt_new(void *, rank);
    index = 0;
    for(other = 0; other < rank; other++) {
 -    // FIXME: possibly overkill we we have contiguous/noncontiguous data 
 +    // FIXME: possibly overkill we we have contiguous/noncontiguous data
      // mapping...
      tmpbufs[index] = xbt_malloc(count * dataext);
      requests[index] =
 -        smpi_irecv_init(tmpbufs[index], count, datatype, other, system_tag,
 -                        comm);
 +      smpi_irecv_init(tmpbufs[index], count, datatype, other, system_tag,
 +                      comm);
      index++;
    }
    for(other = rank + 1; other < size; other++) {
      requests[index] =
 -        smpi_isend_init(sendbuf, count, datatype, other, system_tag, comm);
 +      smpi_isend_init(sendbuf, count, datatype, other, system_tag, comm);
      index++;
    }
    // Wait for completion of all comms.