]> AND Public Git Repository - simgrid.git/blobdiff - src/smpi/smpi_mpi_dt.c
Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
remove now useless functions
[simgrid.git] / src / smpi / smpi_mpi_dt.c
index 22be36c59ce300aa3e27bdae13eb8b58cffffe5a..2ad759ca9a01256f5171e4e3b4db1461e19ced11 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)");
@@ -120,14 +123,18 @@ CREATE_MPI_DATATYPE_NULL(MPI_PACKED);
 // Internal use only
 CREATE_MPI_DATATYPE(MPI_PTR, void*);
 
+/** Check if the datatype is usable for communications
+ */
+int is_datatype_valid(MPI_Datatype datatype) {
+    return datatype != MPI_DATATYPE_NULL
+        && (datatype->flags & DT_FLAG_COMMITED);
+}
 
 size_t smpi_datatype_size(MPI_Datatype datatype)
 {
   return datatype->size;
 }
 
-
-
 MPI_Aint smpi_datatype_lb(MPI_Datatype datatype)
 {
   return datatype->lb;
@@ -138,6 +145,15 @@ MPI_Aint smpi_datatype_ub(MPI_Datatype datatype)
   return datatype->ub;
 }
 
+MPI_Datatype smpi_datatype_dup(MPI_Datatype datatype)
+{
+  MPI_Datatype new_t= xbt_new(s_smpi_mpi_datatype_t,1);
+  memcpy(new_t, datatype, sizeof(s_smpi_mpi_datatype_t));
+  if (datatype->has_subtype)
+    memcpy(new_t->substruct, datatype->substruct, sizeof(s_smpi_subtype_t));
+  return new_t;
+}
+
 int smpi_datatype_extent(MPI_Datatype datatype, MPI_Aint * lb,
                          MPI_Aint * extent)
 {
@@ -154,7 +170,9 @@ int smpi_datatype_copy(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                        void *recvbuf, int recvcount, MPI_Datatype recvtype)
 {
   int count;
-
+  if(smpi_privatize_global_variables){
+    switch_data_segment(smpi_process_index());
+  }
   /* First check if we really have something to do */
   if (recvcount > 0 && recvbuf != sendbuf) {
     /* FIXME: treat packed cases */
@@ -163,7 +181,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 +198,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 +239,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 +276,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);
   }
 }
@@ -277,6 +301,7 @@ s_smpi_mpi_vector_t* smpi_datatype_vector_create( int block_stride,
   new_t->block_stride = block_stride;
   new_t->block_length = block_length;
   new_t->block_count = block_count;
+  smpi_datatype_use(old_type);
   new_t->old_type = old_type;
   new_t->size_oldtype = size_oldtype;
   return new_t;
@@ -293,6 +318,11 @@ void smpi_datatype_create(MPI_Datatype* new_type, int size,int lb, int ub, int h
   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){
@@ -310,17 +340,27 @@ void smpi_datatype_free(MPI_Datatype* type){
     xbt_free((*type)->substruct);
   }
   xbt_free(*type);
-
+  *type = MPI_DATATYPE_NULL;
 }
 
 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
 }
 
 
@@ -374,6 +414,7 @@ void unserialize_contiguous( const void *contiguous_vector,
 }
 
 void free_contiguous(MPI_Datatype* d){
+  smpi_datatype_unuse(((s_smpi_mpi_indexed_t *)(*d)->substruct)->old_type);
 }
 
 /*
@@ -394,6 +435,7 @@ s_smpi_mpi_contiguous_t* smpi_datatype_contiguous_create( MPI_Aint lb,
   new_t->block_count = block_count;
   new_t->old_type = old_type;
   new_t->size_oldtype = size_oldtype;
+  smpi_datatype_use(old_type);
   return new_t;
 }
 
@@ -461,6 +503,7 @@ int smpi_datatype_vector(int count, int blocklen, int stride, MPI_Datatype old_t
 }
 
 void free_vector(MPI_Datatype* d){
+  smpi_datatype_unuse(((s_smpi_mpi_indexed_t *)(*d)->substruct)->old_type);
 }
 
 /*
@@ -498,6 +541,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 +577,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;
   }
 }
@@ -555,11 +604,13 @@ s_smpi_mpi_hvector_t* smpi_datatype_hvector_create( MPI_Aint block_stride,
   new_t->block_count = block_count;
   new_t->old_type = old_type;
   new_t->size_oldtype = size_oldtype;
+  smpi_datatype_use(old_type);
   return new_t;
 }
 
 //do nothing for vector types
 void free_hvector(MPI_Datatype* d){
+  smpi_datatype_unuse(((s_smpi_mpi_indexed_t *)(*d)->substruct)->old_type);
 }
 
 int smpi_datatype_hvector(int count, int blocklen, MPI_Aint stride, MPI_Datatype old_type, MPI_Datatype* new_type)
@@ -681,6 +732,7 @@ void unserialize_indexed( const void *contiguous_indexed,
 void free_indexed(MPI_Datatype* type){
   xbt_free(((s_smpi_mpi_indexed_t *)(*type)->substruct)->block_lengths);
   xbt_free(((s_smpi_mpi_indexed_t *)(*type)->substruct)->block_indices);
+  smpi_datatype_unuse(((s_smpi_mpi_indexed_t *)(*type)->substruct)->old_type);
 }
 
 /*
@@ -706,6 +758,7 @@ s_smpi_mpi_indexed_t* smpi_datatype_indexed_create( int* block_lengths,
     new_t->block_indices[i]=block_indices[i];
   }
   new_t->block_count = block_count;
+  smpi_datatype_use(old_type);
   new_t->old_type = old_type;
   new_t->size_oldtype = size_oldtype;
   return new_t;
@@ -842,6 +895,7 @@ void unserialize_hindexed( const void *contiguous_hindexed,
 void free_hindexed(MPI_Datatype* type){
   xbt_free(((s_smpi_mpi_hindexed_t *)(*type)->substruct)->block_lengths);
   xbt_free(((s_smpi_mpi_hindexed_t *)(*type)->substruct)->block_indices);
+  smpi_datatype_unuse(((s_smpi_mpi_indexed_t *)(*type)->substruct)->old_type);
 }
 
 /*
@@ -1005,6 +1059,9 @@ void unserialize_struct( const void *contiguous_struct,
 void free_struct(MPI_Datatype* type){
   xbt_free(((s_smpi_mpi_struct_t *)(*type)->substruct)->block_lengths);
   xbt_free(((s_smpi_mpi_struct_t *)(*type)->substruct)->block_indices);
+  int i=0;
+  for (i = 0; i < ((s_smpi_mpi_struct_t *)(*type)->substruct)->block_count; i++)
+    smpi_datatype_unuse(((s_smpi_mpi_struct_t *)(*type)->substruct)->old_types[i]);
   xbt_free(((s_smpi_mpi_struct_t *)(*type)->substruct)->old_types);
 }
 
@@ -1030,6 +1087,7 @@ s_smpi_mpi_struct_t* smpi_datatype_struct_create( int* block_lengths,
     new_t->block_lengths[i]=block_lengths[i];
     new_t->block_indices[i]=block_indices[i];
     new_t->old_types[i]=old_types[i];
+    smpi_datatype_use(new_t->old_types[i]);
   }
   //new_t->block_lengths = block_lengths;
   //new_t->block_indices = block_indices;
@@ -1114,7 +1172,7 @@ typedef struct s_smpi_mpi_op {
 #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 REPLACE_OP(a,b) (b) = (a)
 
 #define APPLY_FUNC(a, b, length, type, func) \
 {                                          \
@@ -1419,6 +1477,27 @@ static void maxloc_func(void *a, void *b, int *length,
   }
 }
 
+static void replace_func(void *a, void *b, int *length,
+                        MPI_Datatype * datatype)
+{
+  if (*datatype == MPI_CHAR) {
+    APPLY_FUNC(a, b, length, char, REPLACE_OP);
+  } else if (*datatype == MPI_SHORT) {
+    APPLY_FUNC(a, b, length, short, REPLACE_OP);
+  } else if (*datatype == MPI_INT) {
+    APPLY_FUNC(a, b, length, int, REPLACE_OP);
+  } else if (*datatype == MPI_LONG) {
+    APPLY_FUNC(a, b, length, long, REPLACE_OP);
+  } else if (*datatype == MPI_UNSIGNED_SHORT) {
+    APPLY_FUNC(a, b, length, unsigned short, REPLACE_OP);
+  } else if (*datatype == MPI_UNSIGNED) {
+    APPLY_FUNC(a, b, length, unsigned int, REPLACE_OP);
+  } else if (*datatype == MPI_UNSIGNED_LONG) {
+    APPLY_FUNC(a, b, length, unsigned long, REPLACE_OP);
+  } else if (*datatype == MPI_BYTE) {
+    APPLY_FUNC(a, b, length, uint8_t, REPLACE_OP);
+  }
+}
 
 #define CREATE_MPI_OP(name, func)                             \
   static s_smpi_mpi_op_t mpi_##name = { &(func) /* func */, TRUE }; \
@@ -1436,6 +1515,8 @@ 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);
+CREATE_MPI_OP(MPI_REPLACE, replace_func);
+
 
 MPI_Op smpi_op_new(MPI_User_function * function, int commute)
 {
@@ -1448,7 +1529,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 +1540,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);
 }