Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add a first draft for automatic privatization of global variables for smpi.
[simgrid.git] / src / smpi / smpi_mpi_dt.c
index e42513b..ee348b8 100644 (file)
@@ -1,7 +1,7 @@
 /* smpi_mpi_dt.c -- MPI primitives to handle datatypes                        */
 /* FIXME: a very incomplete implementation                                    */
 
-/* Copyright (c) 2009, 2010. The SimGrid Team.
+/* Copyright (c) 2009-2014. The SimGrid Team.
  * All rights reserved.                                                     */
 
 /* This program is free software; you can redistribute it and/or modify it
@@ -13,6 +13,9 @@
 
 #include "private.h"
 #include "smpi_mpi_dt_private.h"
+#include "mc/mc.h"
+#include "xbt/replay.h"
+#include "simgrid/modelchecker.h"
 
 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_mpi_dt, smpi,
                                 "Logging specific to SMPI (datatype)");
@@ -163,7 +166,7 @@ int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
     count = sendcount < recvcount ? sendcount : recvcount;
 
     if(sendtype->has_subtype == 0 && recvtype->has_subtype == 0) {
-      memcpy(recvbuf, sendbuf, count);
+      if(!_xbt_replay_is_active()) memcpy(recvbuf, sendbuf, count);
     }
     else if (sendtype->has_subtype == 0)
     {
@@ -180,9 +183,9 @@ int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
 
       void * buf_tmp = xbt_malloc(count);
 
-      subtype->serialize( sendbuf, buf_tmp,1, subtype);
+      subtype->serialize( sendbuf, buf_tmp,count/smpi_datatype_size(sendtype), subtype);
       subtype =  recvtype->substruct;
-      subtype->unserialize( buf_tmp, recvbuf,1, subtype);
+      subtype->unserialize( buf_tmp, recvbuf,count/smpi_datatype_size(recvtype), subtype);
 
       free(buf_tmp);
     }
@@ -221,6 +224,9 @@ void serialize_vector( const void *noncontiguous_vector,
                                                                      type_c->old_type->substruct);
 
     contiguous_vector_char += type_c->block_length*type_c->size_oldtype;
+    if((i+1)%type_c->block_count ==0)
+    noncontiguous_vector_char += type_c->block_length*smpi_datatype_get_extent(type_c->old_type);
+    else
     noncontiguous_vector_char += type_c->block_stride*smpi_datatype_get_extent(type_c->old_type);
   }
 }
@@ -255,6 +261,9 @@ void unserialize_vector( const void *contiguous_vector,
                                                                      type_c->block_length,
                                                                      type_c->old_type->substruct);
     contiguous_vector_char += type_c->block_length*type_c->size_oldtype;
+    if((i+1)%type_c->block_count ==0)
+    noncontiguous_vector_char += type_c->block_length*smpi_datatype_get_extent(type_c->old_type);
+    else
     noncontiguous_vector_char += type_c->block_stride*smpi_datatype_get_extent(type_c->old_type);
   }
 }
@@ -286,13 +295,18 @@ void smpi_datatype_create(MPI_Datatype* new_type, int size,int lb, int ub, int h
                           void *struct_type, int flags){
   MPI_Datatype new_t= xbt_new(s_smpi_mpi_datatype_t,1);
   new_t->size = size;
-  new_t->has_subtype = has_subtype;
+  new_t->has_subtype = size>0? has_subtype:0;
   new_t->lb = lb;
   new_t->ub = ub;
   new_t->flags = flags;
   new_t->substruct = struct_type;
   new_t->in_use=0;
   *new_type = new_t;
+
+#ifdef HAVE_MC
+  if(MC_is_active())
+    MC_ignore(&(new_t->in_use), sizeof(new_t->in_use));
+#endif
 }
 
 void smpi_datatype_free(MPI_Datatype* type){
@@ -315,12 +329,22 @@ void smpi_datatype_free(MPI_Datatype* type){
 
 void smpi_datatype_use(MPI_Datatype type){
   if(type)type->in_use++;
+
+#ifdef HAVE_MC
+  if(MC_is_active())
+    MC_ignore(&(type->in_use), sizeof(type->in_use));
+#endif
 }
 
 
 void smpi_datatype_unuse(MPI_Datatype type){
   if(type && type->in_use-- == 0 && (type->flags & DT_FLAG_DESTROYED))
     smpi_datatype_free(&type);
+  
+#ifdef HAVE_MC
+  if(MC_is_active())
+    MC_ignore(&(type->in_use), sizeof(type->in_use));
+#endif
 }
 
 
@@ -424,7 +448,7 @@ int smpi_datatype_contiguous(int count, MPI_Datatype old_type, MPI_Datatype* new
 int smpi_datatype_vector(int count, int blocklen, int stride, MPI_Datatype old_type, MPI_Datatype* new_type)
 {
   int retval;
-  if (blocklen<=0) return MPI_ERR_ARG;
+  if (blocklen<0) return MPI_ERR_ARG;
   MPI_Aint lb = 0;
   MPI_Aint ub = 0;
   if(count>0){
@@ -498,6 +522,9 @@ void serialize_hvector( const void *noncontiguous_hvector,
                                                                    type_c->old_type->substruct);
 
     contiguous_vector_char += type_c->block_length*type_c->size_oldtype;
+    if((i+1)%type_c->block_count ==0)
+    noncontiguous_vector_char += type_c->block_length*type_c->size_oldtype;
+    else
     noncontiguous_vector_char += type_c->block_stride;
   }
 }
@@ -531,6 +558,9 @@ void unserialize_hvector( const void *contiguous_vector,
                                                                      type_c->block_length,
                                                                      type_c->old_type->substruct);
     contiguous_vector_char += type_c->block_length*type_c->size_oldtype;
+    if((i+1)%type_c->block_count ==0)
+    noncontiguous_vector_char += type_c->block_length*type_c->size_oldtype;
+    else
     noncontiguous_vector_char += type_c->block_stride;
   }
 }
@@ -565,7 +595,7 @@ void free_hvector(MPI_Datatype* d){
 int smpi_datatype_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type)
 {
   int retval;
-  if (blocklen<=0) return MPI_ERR_ARG;
+  if (blocklen<0) return MPI_ERR_ARG;
   MPI_Aint lb = 0;
   MPI_Aint ub = 0;
   if(count>0){
@@ -726,7 +756,7 @@ int smpi_datatype_indexed(int count, int* blocklens, int* indices, MPI_Datatype
   }
 
   for(i=0; i< count; i++){
-    if   (blocklens[i]<=0)
+    if   (blocklens[i]<0)
       return MPI_ERR_ARG;
     size += blocklens[i];
 
@@ -886,7 +916,7 @@ int smpi_datatype_hindexed(int count, int* blocklens, MPI_Aint* indices, MPI_Dat
     ub=indices[0] + blocklens[0]*smpi_datatype_ub(old_type);
   }
   for(i=0; i< count; i++){
-    if   (blocklens[i]<=0)
+    if   (blocklens[i]<0)
       return MPI_ERR_ARG;
     size += blocklens[i];
 
@@ -1054,7 +1084,7 @@ int smpi_datatype_struct(int count, int* blocklens, MPI_Aint* indices, MPI_Datat
   int forced_lb=0;
   int forced_ub=0;
   for(i=0; i< count; i++){
-    if (blocklens[i]<=0)
+    if (blocklens[i]<0)
       return MPI_ERR_ARG;
     if (old_types[i]->has_subtype == 1)
       contiguous=0;
@@ -1448,7 +1478,7 @@ MPI_Op smpi_op_new(MPI_User_function * function, int commute)
 
 int smpi_op_is_commute(MPI_Op op)
 {
-  return op-> is_commute;
+  return (op==MPI_OP_NULL) ? 1 : op-> is_commute;
 }
 
 void smpi_op_destroy(MPI_Op op)
@@ -1459,5 +1489,11 @@ void smpi_op_destroy(MPI_Op op)
 void smpi_op_apply(MPI_Op op, void *invec, void *inoutvec, int *len,
                    MPI_Datatype * datatype)
 {
+  if(smpi_privatize_global_variables){ //we need to switch here, as the called function may silently touch global variables
+    XBT_VERB("Applying operation, switch to the right data frame ");
+    switch_data_segment(smpi_process_index());
+  }
+
+  if(!_xbt_replay_is_active())
   op->func(invec, inoutvec, len, datatype);
 }