Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Move Keyval handling to a new file, as it is shared between Comm and Datatype (and...
authordegomme <augustin.degomme@unibas.ch>
Wed, 15 Mar 2017 22:25:34 +0000 (23:25 +0100)
committerdegomme <augustin.degomme@unibas.ch>
Wed, 15 Mar 2017 22:32:44 +0000 (23:32 +0100)
Get rid of some xbt_dicts as well.

include/smpi/smpi.h
src/smpi/private.h
src/smpi/smpi_comm.cpp
src/smpi/smpi_comm.hpp
src/smpi/smpi_datatype.cpp
src/smpi/smpi_datatype.hpp
src/smpi/smpi_keyvals.cpp [new file with mode: 0644]
src/smpi/smpi_keyvals.hpp [new file with mode: 0644]
src/smpi/smpi_pmpi.cpp
tools/cmake/DefinePackages.cmake

index e392164..b52e366 100644 (file)
@@ -370,6 +370,20 @@ typedef SMPI_Request *MPI_Request;
 #define MPI_REQUEST_NULL ((MPI_Request)NULL)
 #define MPI_FORTRAN_REQUEST_NULL -1
 
 #define MPI_REQUEST_NULL ((MPI_Request)NULL)
 #define MPI_FORTRAN_REQUEST_NULL -1
 
+typedef int MPI_Copy_function(MPI_Comm oldcomm, int keyval, void* extra_state, void* attribute_val_in,
+                              void* attribute_val_out, int* flag);
+typedef int MPI_Delete_function(MPI_Comm comm, int keyval, void* attribute_val, void* extra_state);
+#define MPI_Comm_copy_attr_function MPI_Copy_function
+#define MPI_Comm_delete_attr_function MPI_Delete_function
+typedef int MPI_Type_copy_attr_function(MPI_Datatype type, int keyval, void* extra_state, void* attribute_val_in,
+                              void* attribute_val_out, int* flag);
+typedef int MPI_Type_delete_attr_function(MPI_Datatype type, int keyval, void* attribute_val, void* extra_state);
+#define MPI_COMM_NULL_COPY_FN ((MPI_Comm_copy_attr_function*)0)
+#define MPI_COMM_NULL_DELETE_FN ((MPI_Comm_delete_attr_function*)0)
+#define MPI_TYPE_NULL_COPY_FN ((MPI_Type_copy_attr_function*)0)
+#define MPI_TYPE_NULL_DELETE_FN ((MPI_Type_delete_attr_function*)0)
+
+
 MPI_CALL(XBT_PUBLIC(int), MPI_Init, (int *argc, char ***argv));
 MPI_CALL(XBT_PUBLIC(int), MPI_Finalize, (void));
 MPI_CALL(XBT_PUBLIC(int), MPI_Finalized, (int* flag));
 MPI_CALL(XBT_PUBLIC(int), MPI_Init, (int *argc, char ***argv));
 MPI_CALL(XBT_PUBLIC(int), MPI_Finalize, (void));
 MPI_CALL(XBT_PUBLIC(int), MPI_Finalized, (int* flag));
@@ -545,25 +559,11 @@ typedef void MPI_Handler_function(MPI_Comm*, int*, ...);
 
 typedef void* MPI_Errhandler;
 
 
 typedef void* MPI_Errhandler;
 
-typedef int MPI_Copy_function(MPI_Comm oldcomm, int keyval, void* extra_state, void* attribute_val_in,
-                              void* attribute_val_out, int* flag);
-typedef int MPI_Delete_function(MPI_Comm comm, int keyval, void* attribute_val, void* extra_state);
-#define MPI_Comm_copy_attr_function MPI_Copy_function
-#define MPI_Comm_delete_attr_function MPI_Delete_function
-typedef int MPI_Type_copy_attr_function(MPI_Datatype type, int keyval, void* extra_state, void* attribute_val_in,
-                              void* attribute_val_out, int* flag);
-typedef int MPI_Type_delete_attr_function(MPI_Datatype type, int keyval, void* attribute_val, void* extra_state);
 typedef void MPI_Comm_errhandler_function(MPI_Comm *, int *, ...);
 typedef int MPI_Grequest_query_function(void *extra_state, MPI_Status *status); 
 typedef int MPI_Grequest_free_function(void *extra_state); 
 typedef int MPI_Grequest_cancel_function(void *extra_state, int complete); 
 #define MPI_DUP_FN MPI_Comm_dup
 typedef void MPI_Comm_errhandler_function(MPI_Comm *, int *, ...);
 typedef int MPI_Grequest_query_function(void *extra_state, MPI_Status *status); 
 typedef int MPI_Grequest_free_function(void *extra_state); 
 typedef int MPI_Grequest_cancel_function(void *extra_state, int complete); 
 #define MPI_DUP_FN MPI_Comm_dup
-#define MPI_COMM_NULL_COPY_FN ((MPI_Comm_copy_attr_function*)0)
-#define MPI_COMM_NULL_DELETE_FN ((MPI_Comm_delete_attr_function*)0)
-#define MPI_COMM_DUP_FN  ((MPI_Comm_copy_attr_function *)MPI_DUP_FN)
-#define MPI_TYPE_NULL_COPY_FN ((MPI_Type_copy_attr_function*)0)
-#define MPI_TYPE_NULL_DELETE_FN ((MPI_Type_delete_attr_function*)0)
-#define MPI_TYPE_DUP_FN ((MPI_Type_copy_attr_function*)MPI_DUP_FN)
 
 typedef MPI_Comm_errhandler_function MPI_Comm_errhandler_fn;
 #define MPI_INFO_ENV 1
 
 typedef MPI_Comm_errhandler_function MPI_Comm_errhandler_fn;
 #define MPI_INFO_ENV 1
index d1a3799..cb38aaa 100644 (file)
@@ -122,16 +122,6 @@ XBT_PRIVATE void smpi_empty_status(MPI_Status * status);
 XBT_PRIVATE int smpi_mpi_get_count(MPI_Status * status, MPI_Datatype datatype);
 
 
 XBT_PRIVATE int smpi_mpi_get_count(MPI_Status * status, MPI_Datatype datatype);
 
 
-XBT_PRIVATE int smpi_comm_keyval_create(MPI_Comm_copy_attr_function* copy_fn, MPI_Comm_delete_attr_function* delete_fn,
-                                        int* keyval, void* extra_state);
-XBT_PRIVATE int smpi_comm_keyval_free(int* keyval);
-
-XBT_PRIVATE int smpi_type_attr_delete(MPI_Datatype type, int keyval);
-XBT_PRIVATE int smpi_type_attr_get(MPI_Datatype type, int keyval, void* attr_value, int* flag);
-XBT_PRIVATE int smpi_type_attr_put(MPI_Datatype type, int keyval, void* attr_value);
-XBT_PRIVATE int smpi_type_keyval_create(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn,
-                                        int* keyval, void* extra_state);
-XBT_PRIVATE int smpi_type_keyval_free(int* keyval);
 // utilities
 extern XBT_PRIVATE double smpi_cpu_threshold;
 extern XBT_PRIVATE double smpi_host_speed;
 // utilities
 extern XBT_PRIVATE double smpi_cpu_threshold;
 extern XBT_PRIVATE double smpi_host_speed;
index 7d67ca1..98e0599 100644 (file)
@@ -60,7 +60,6 @@ Comm::Comm(MPI_Group group, MPI_Topology topo) : group_(group), topo_(topo)
   non_uniform_map_ = nullptr;
   leaders_map_ = nullptr;
   is_blocked_=0;
   non_uniform_map_ = nullptr;
   leaders_map_ = nullptr;
   is_blocked_=0;
-  attributes_=nullptr;
 }
 
 void Comm::destroy(Comm* comm)
 }
 
 void Comm::destroy(Comm* comm)
@@ -81,25 +80,22 @@ int Comm::dup(MPI_Comm* newcomm){
   (*newcomm) = new  Comm(cp, this->topo());
   int ret = MPI_SUCCESS;
 
   (*newcomm) = new  Comm(cp, this->topo());
   int ret = MPI_SUCCESS;
 
-  if(attributes_ !=nullptr){
-    (*newcomm)->attributes_   = xbt_dict_new_homogeneous(nullptr);
-    xbt_dict_cursor_t cursor = nullptr;
-    char* key;
+  if(!attributes_.empty()){
     int flag;
     int flag;
-    void* value_in;
     void* value_out;
     void* value_out;
-    xbt_dict_foreach (attributes_, cursor, key, value_in) {
-      smpi_key_elem elem = keyvals_.at(*key);
+    for(auto it = attributes_.begin(); it != attributes_.end(); it++){
+      smpi_key_elem elem = keyvals_.at((*it).first);
       if (elem != nullptr && elem->copy_fn.comm_copy_fn != MPI_NULL_COPY_FN) {
       if (elem != nullptr && elem->copy_fn.comm_copy_fn != MPI_NULL_COPY_FN) {
-        ret = elem->copy_fn.comm_copy_fn(this, *key, nullptr, value_in, &value_out, &flag);
+        ret = elem->copy_fn.comm_copy_fn(this, (*it).first, nullptr, (*it).second, &value_out, &flag);
         if (ret != MPI_SUCCESS) {
           Comm::destroy(*newcomm);
           *newcomm = MPI_COMM_NULL;
         if (ret != MPI_SUCCESS) {
           Comm::destroy(*newcomm);
           *newcomm = MPI_COMM_NULL;
-          xbt_dict_cursor_free(&cursor);
           return ret;
         }
           return ret;
         }
-        if (flag)
-          xbt_dict_set_ext((*newcomm)->attributes_, key, sizeof(int), value_out, nullptr);
+        if (flag){
+          elem->refcount++;
+          (*newcomm)->attributes_.insert({(*it).first, value_out});
+        }
       }
       }
     }
       }
       }
     }
@@ -284,21 +280,17 @@ void Comm::ref(){
 }
 
 void Comm::cleanup_attributes(){
 }
 
 void Comm::cleanup_attributes(){
-  if(attributes_ !=nullptr){
-    xbt_dict_cursor_t cursor = nullptr;
-    char* key;
-    void* value;
+  if(!attributes_.empty()){
     int flag;
     int flag;
-    xbt_dict_foreach (attributes_, cursor, key, value) {
+    for(auto it = attributes_.begin(); it != attributes_.end(); it++){
       try{
       try{
-        smpi_key_elem elem = keyvals_.at(*key);
+        smpi_key_elem elem = keyvals_.at((*it).first);
         if (elem != nullptr && elem->delete_fn.comm_delete_fn != nullptr)
         if (elem != nullptr && elem->delete_fn.comm_delete_fn != nullptr)
-          elem->delete_fn.comm_delete_fn(this, *key, value, &flag);
+          elem->delete_fn.comm_delete_fn(this, (*it).first, (*it).second, &flag);
       }catch(const std::out_of_range& oor) {
         //already deleted, not a problem;
       }
     }
       }catch(const std::out_of_range& oor) {
         //already deleted, not a problem;
       }
     }
-    xbt_dict_free(&attributes_);
   }
 }
 
   }
 }
 
@@ -499,64 +491,6 @@ void Comm::init_smp(){
     smpi_process_set_replaying(true); 
 }
 
     smpi_process_set_replaying(true); 
 }
 
-int Comm::attr_delete(int keyval){
-  smpi_key_elem elem = keyvals_.at(keyval);
-  if(elem==nullptr)
-    return MPI_ERR_ARG;
-  if(elem->delete_fn.comm_delete_fn!=MPI_NULL_DELETE_FN){
-    void* value = nullptr;
-    int flag;
-    if(this->attr_get(keyval, &value, &flag)==MPI_SUCCESS){
-      int ret = elem->delete_fn.comm_delete_fn(this, keyval, value, &flag);
-      if(ret!=MPI_SUCCESS) 
-        return ret;
-    }
-  }
-  if(attributes_==nullptr)
-    return MPI_ERR_ARG;
-
-  xbt_dict_remove_ext(attributes_, reinterpret_cast<const char*>(&keyval), sizeof(int));
-  return MPI_SUCCESS;
-}
-
-int Comm::attr_get(int keyval, void* attr_value, int* flag){
-  smpi_key_elem elem = keyvals_.at(keyval);
-  if(elem==nullptr)
-    return MPI_ERR_ARG;
-  if(attributes_==nullptr){
-    *flag=0;
-    return MPI_SUCCESS;
-  }
-  try {
-    *static_cast<void**>(attr_value) =
-        xbt_dict_get_ext(attributes_, reinterpret_cast<const char*>(&keyval), sizeof(int));
-    *flag=1;
-  }
-  catch (xbt_ex& ex) {
-    *flag=0;
-  }
-  return MPI_SUCCESS;
-}
-
-int Comm::attr_put(int keyval, void* attr_value){
-  smpi_key_elem elem = keyvals_.at(keyval);
-  if(elem==nullptr)
-    return MPI_ERR_ARG;
-  int flag;
-  void* value = nullptr;
-  this->attr_get(keyval, &value, &flag);
-  if(flag!=0 && elem->delete_fn.comm_delete_fn!=MPI_NULL_DELETE_FN){
-    int ret = elem->delete_fn.comm_delete_fn(this, keyval, value, &flag);
-    if(ret!=MPI_SUCCESS) 
-      return ret;
-  }
-  if(attributes_==nullptr)
-    attributes_ = xbt_dict_new_homogeneous(nullptr);
-
-  xbt_dict_set_ext(attributes_,  reinterpret_cast<const char*>(&keyval), sizeof(int), attr_value, nullptr);
-  return MPI_SUCCESS;
-}
-
 MPI_Comm Comm::f2c(int id) {
   if(id == -2) {
     return MPI_COMM_SELF;
 MPI_Comm Comm::f2c(int id) {
   if(id == -2) {
     return MPI_COMM_SELF;
index 2c44013..aedf39e 100644 (file)
@@ -33,7 +33,6 @@ class Comm : public F2C, public Keyval{
     int is_uniform_;
     int* non_uniform_map_; //set if smp nodes have a different number of processes allocated
     int is_blocked_;// are ranks allocated on the same smp node contiguous ?
     int is_uniform_;
     int* non_uniform_map_; //set if smp nodes have a different number of processes allocated
     int is_blocked_;// are ranks allocated on the same smp node contiguous ?
-    xbt_dict_t attributes_;
 
   public:
     static std::unordered_map<int, smpi_key_elem> keyvals_;
 
   public:
     static std::unordered_map<int, smpi_key_elem> keyvals_;
@@ -63,9 +62,6 @@ class Comm : public F2C, public Keyval{
     static void unref(MPI_Comm comm);
     static void destroy(MPI_Comm comm);
     void init_smp();
     static void unref(MPI_Comm comm);
     static void destroy(MPI_Comm comm);
     void init_smp();
-    int attr_delete(int keyval);
-    int attr_get(int keyval, void* attr_value, int* flag);
-    int attr_put(int keyval, void* attr_value);
 
     int add_f();
     static void free_f(int id);
 
     int add_f();
     static void free_f(int id);
index 086b0dd..5d39365 100644 (file)
@@ -106,7 +106,7 @@ namespace smpi{
 std::unordered_map<int, smpi_key_elem> Datatype::keyvals_;
 int Datatype::keyval_id_=0;
 
 std::unordered_map<int, smpi_key_elem> Datatype::keyvals_;
 int Datatype::keyval_id_=0;
 
-Datatype::Datatype(int size,MPI_Aint lb, MPI_Aint ub, int flags) : name_(nullptr), size_(size), lb_(lb), ub_(ub), flags_(flags), attributes_(nullptr), refcount_(1){
+Datatype::Datatype(int size,MPI_Aint lb, MPI_Aint ub, int flags) : name_(nullptr), size_(size), lb_(lb), ub_(ub), flags_(flags), refcount_(1){
 #if HAVE_MC
   if(MC_is_active())
     MC_ignore(&(refcount_), sizeof(refcount_));
 #if HAVE_MC
   if(MC_is_active())
     MC_ignore(&(refcount_), sizeof(refcount_));
@@ -114,36 +114,34 @@ Datatype::Datatype(int size,MPI_Aint lb, MPI_Aint ub, int flags) : name_(nullptr
 }
 
 //for predefined types, so in_use = 0.
 }
 
 //for predefined types, so in_use = 0.
-Datatype::Datatype(char* name, int size,MPI_Aint lb, MPI_Aint ub, int flags) : name_(name), size_(size), lb_(lb), ub_(ub), flags_(flags), attributes_(nullptr), refcount_(0){
+Datatype::Datatype(char* name, int size,MPI_Aint lb, MPI_Aint ub, int flags) : name_(name), size_(size), lb_(lb), ub_(ub), flags_(flags), refcount_(0){
 #if HAVE_MC
   if(MC_is_active())
     MC_ignore(&(refcount_), sizeof(refcount_));
 #endif
 }
 
 #if HAVE_MC
   if(MC_is_active())
     MC_ignore(&(refcount_), sizeof(refcount_));
 #endif
 }
 
-Datatype::Datatype(Datatype *datatype, int* ret) : name_(nullptr), lb_(datatype->lb_), ub_(datatype->ub_), flags_(datatype->flags_), attributes_(nullptr), refcount_(1)
+Datatype::Datatype(Datatype *datatype, int* ret) : name_(nullptr), lb_(datatype->lb_), ub_(datatype->ub_), flags_(datatype->flags_), refcount_(1)
 {
   flags_ &= ~DT_FLAG_PREDEFINED;
   *ret = MPI_SUCCESS;
   if(datatype->name_)
     name_ = xbt_strdup(datatype->name_);
 {
   flags_ &= ~DT_FLAG_PREDEFINED;
   *ret = MPI_SUCCESS;
   if(datatype->name_)
     name_ = xbt_strdup(datatype->name_);
-  if(datatype->attributes_ !=nullptr){
-    attributes_ = xbt_dict_new_homogeneous(nullptr);
-    xbt_dict_cursor_t cursor = nullptr;
-    char* key;
+  if(!(datatype->attributes_.empty())){
     int flag;
     int flag;
-    void* value_in;
     void* value_out;
     void* value_out;
-    xbt_dict_foreach (datatype->attributes_, cursor, key, value_in) {
-      smpi_key_elem elem = keyvals_.at(atoi(key));
+    for(auto it = datatype->attributes_.begin(); it != datatype->attributes_.end(); it++){
+      smpi_key_elem elem = keyvals_.at((*it).first);
+      
       if (elem != nullptr && elem->copy_fn.type_copy_fn != MPI_NULL_COPY_FN) {
       if (elem != nullptr && elem->copy_fn.type_copy_fn != MPI_NULL_COPY_FN) {
-        *ret = elem->copy_fn.type_copy_fn(datatype, atoi(key), nullptr, value_in, &value_out, &flag);
+        *ret = elem->copy_fn.type_copy_fn(datatype, (*it).first, nullptr, (*it).second, &value_out, &flag);
         if (*ret != MPI_SUCCESS) {
         if (*ret != MPI_SUCCESS) {
-          xbt_dict_cursor_free(&cursor);
           break;
         }
           break;
         }
-        if (flag)
-          xbt_dict_set_ext(attributes_, key, sizeof(int), value_out, nullptr);
+        if (flag){
+          elem->refcount++;
+          attributes_.insert({(*it).first, value_out});
+        }
       }
     }
   }
       }
     }
   }
@@ -161,21 +159,17 @@ Datatype::~Datatype(){
       return;
   }
 
       return;
   }
 
-  if(attributes_ !=nullptr){
-    xbt_dict_cursor_t cursor = nullptr;
-    char* key;
-    void * value;
+  if(!attributes_.empty()){
     int flag;
     int flag;
-    xbt_dict_foreach(attributes_, cursor, key, value){
+    for(auto it = attributes_.begin(); it != attributes_.end(); it++){
       try{
       try{
-        smpi_key_elem elem = keyvals_.at(atoi(key));
-        if(elem!=nullptr && elem->delete_fn.type_delete_fn!=nullptr)
-          elem->delete_fn.type_delete_fn(this,*key, value, &flag);
+        smpi_key_elem elem = keyvals_.at((*it).first);
+        if (elem != nullptr && elem->delete_fn.type_delete_fn != nullptr)
+          elem->delete_fn.type_delete_fn(this, (*it).first, (*it).second, &flag);
       }catch(const std::out_of_range& oor) {
         //already deleted, not a problem;
       }
     }
       }catch(const std::out_of_range& oor) {
         //already deleted, not a problem;
       }
     }
-    xbt_dict_free(&attributes_);
   }
 
   xbt_free(name_);
   }
 
   xbt_free(name_);
@@ -262,64 +256,6 @@ void Datatype::set_name(char* name){
   name_ = xbt_strdup(name);
 }
 
   name_ = xbt_strdup(name);
 }
 
-int Datatype::attr_delete(int keyval){
-  smpi_key_elem elem = keyvals_.at(keyval);
-  if(elem==nullptr)
-    return MPI_ERR_ARG;
-  if(elem->delete_fn.type_delete_fn!=MPI_NULL_DELETE_FN){
-    void * value = nullptr;
-    int flag;
-    if(this->attr_get(keyval, &value, &flag)==MPI_SUCCESS){
-      int ret = elem->delete_fn.type_delete_fn(this, keyval, value, &flag);
-      if(ret!=MPI_SUCCESS) 
-        return ret;
-    }
-  }  
-  if(attributes_==nullptr)
-    return MPI_ERR_ARG;
-
-  xbt_dict_remove_ext(attributes_, reinterpret_cast<const char*>(&keyval), sizeof(int));
-  return MPI_SUCCESS;
-}
-
-
-int Datatype::attr_get(int keyval, void* attr_value, int* flag){
-  smpi_key_elem elem = keyvals_.at(keyval);
-  if(elem==nullptr)
-    return MPI_ERR_ARG;
-  if(attributes_==nullptr){
-    *flag=0;
-    return MPI_SUCCESS;
-  }
-  try {
-    *static_cast<void**>(attr_value) = xbt_dict_get_ext(attributes_, reinterpret_cast<const char*>(&keyval), sizeof(int));
-    *flag=1;
-  }
-  catch (xbt_ex& ex) {
-    *flag=0;
-  }
-  return MPI_SUCCESS;
-}
-
-int Datatype::attr_put(int keyval, void* attr_value){
-  smpi_key_elem elem = keyvals_.at(keyval);
-  if(elem==nullptr)
-    return MPI_ERR_ARG;
-  int flag;
-  void* value = nullptr;
-  this->attr_get(keyval, &value, &flag);
-  if(flag!=0 && elem->delete_fn.type_delete_fn!=MPI_NULL_DELETE_FN){
-    int ret = elem->delete_fn.type_delete_fn(this, keyval, value, &flag);
-    if(ret!=MPI_SUCCESS) 
-      return ret;
-  }
-  if(attributes_==nullptr)
-    attributes_ = xbt_dict_new_homogeneous(nullptr);
-
-  xbt_dict_set_ext(attributes_, reinterpret_cast<const char*>(&keyval), sizeof(int), attr_value, nullptr);
-  return MPI_SUCCESS;
-}
-
 int Datatype::pack(void* inbuf, int incount, void* outbuf, int outcount, int* position,MPI_Comm comm){
   if (outcount - *position < incount*static_cast<int>(size_))
     return MPI_ERR_BUFFER;
 int Datatype::pack(void* inbuf, int incount, void* outbuf, int outcount, int* position,MPI_Comm comm){
   if (outcount - *position < incount*static_cast<int>(size_))
     return MPI_ERR_BUFFER;
index 29cd8ae..c652695 100644 (file)
@@ -85,7 +85,6 @@ class Datatype : public F2C, public Keyval{
     MPI_Aint lb_;
     MPI_Aint ub_;
     int flags_;
     MPI_Aint lb_;
     MPI_Aint ub_;
     int flags_;
-    xbt_dict_t attributes_;
     int refcount_;
 
   public:
     int refcount_;
 
   public:
@@ -116,9 +115,6 @@ class Datatype : public F2C, public Keyval{
                             int count);
     virtual void unserialize( void* contiguous, void *noncontiguous, 
                               int count, MPI_Op op);
                             int count);
     virtual void unserialize( void* contiguous, void *noncontiguous, 
                               int count, MPI_Op op);
-    int attr_delete(int keyval);
-    int attr_get(int keyval, void* attr_value, int* flag);
-    int attr_put(int keyval, void* attr_value);
     static int keyval_create(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state);
     static int keyval_free(int* keyval);
     int pack(void* inbuf, int incount, void* outbuf, int outcount, int* position, MPI_Comm comm);
     static int keyval_create(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state);
     static int keyval_free(int* keyval);
     int pack(void* inbuf, int incount, void* outbuf, int outcount, int* position, MPI_Comm comm);
diff --git a/src/smpi/smpi_keyvals.cpp b/src/smpi/smpi_keyvals.cpp
new file mode 100644 (file)
index 0000000..9eb473f
--- /dev/null
@@ -0,0 +1,43 @@
+/* Copyright (c) 2007-2017. The SimGrid Team.
+ * 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. */
+
+#include "private.h"
+#include <unordered_map>
+#include <xbt/ex.hpp>
+
+namespace simgrid{
+namespace smpi{
+
+
+template <> int Keyval::call_deleter<Comm>(Comm* obj, smpi_key_elem elem, int keyval, void * value, int* flag){
+  if(elem->delete_fn.comm_delete_fn!=MPI_NULL_DELETE_FN){
+    int ret = elem->delete_fn.comm_delete_fn(obj, keyval, value, flag);
+    if(ret!=MPI_SUCCESS) 
+      return ret;
+  }
+  return MPI_SUCCESS;
+}
+
+template <> int Keyval::call_deleter<Win>(Win* obj, smpi_key_elem elem, int keyval, void * value, int* flag){
+  if(elem->delete_fn.win_delete_fn!=MPI_NULL_DELETE_FN){
+    int ret = elem->delete_fn.win_delete_fn(obj, keyval, value, flag);
+    if(ret!=MPI_SUCCESS) 
+      return ret;
+  }
+  return MPI_SUCCESS;
+}
+
+template <> int Keyval::call_deleter<Datatype>(Datatype* obj, smpi_key_elem elem, int keyval, void * value, int* flag){
+  if(elem->delete_fn.type_delete_fn!=MPI_NULL_DELETE_FN){
+    int ret = elem->delete_fn.type_delete_fn(obj, keyval, value, flag);
+    if(ret!=MPI_SUCCESS) 
+      return ret;
+  }
+  return MPI_SUCCESS;
+}
+
+}
+}
diff --git a/src/smpi/smpi_keyvals.hpp b/src/smpi/smpi_keyvals.hpp
new file mode 100644 (file)
index 0000000..0508f33
--- /dev/null
@@ -0,0 +1,144 @@
+/* Copyright (c) 2010, 2013-2017. The SimGrid Team.
+ * 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. */
+
+#ifndef SMPI_KEYVALS_HPP_INCLUDED
+#define SMPI_KEYVALS_HPP_INCLUDED
+
+#include "private.h"
+#include <unordered_map>
+#include <xbt/ex.hpp>
+
+namespace simgrid{
+namespace smpi{
+
+
+typedef union smpi_delete_fn{
+  MPI_Comm_delete_attr_function          *comm_delete_fn;
+  MPI_Type_delete_attr_function          *type_delete_fn;
+  MPI_Win_delete_attr_function           *win_delete_fn;
+} smpi_delete_fn;
+
+typedef union smpi_copy_fn{
+  MPI_Comm_copy_attr_function          *comm_copy_fn;
+  MPI_Type_copy_attr_function          *type_copy_fn;
+  MPI_Win_copy_attr_function           *win_copy_fn;
+} smpi_copy_fn;
+
+typedef struct s_smpi_key_elem {
+  smpi_copy_fn copy_fn;
+  smpi_delete_fn delete_fn;
+  int refcount;
+} s_smpi_mpi_key_elem_t; 
+typedef struct s_smpi_key_elem *smpi_key_elem;
+
+class Keyval{
+  protected:
+    std::unordered_map<int, void*> attributes_;
+  public:
+// Each subclass should have two members, as we want to separate the ones for Win, Comm, and Datatypes :  
+//    static std::unordered_map<int, smpi_key_elem> keyvals_;
+//    static int keyval_id_;
+    template <typename T> static int keyval_create(smpi_copy_fn copy_fn, smpi_delete_fn delete_fn, int* keyval, void* extra_statee);
+    template <typename T> static int keyval_free(int* keyval);
+    template <typename T> int attr_delete(int keyval);
+    template <typename T> int attr_get(int keyval, void* attr_value, int* flag);
+    template <typename T> int attr_put(int keyval, void* attr_value);
+    template <typename T> static int call_deleter(T* obj, smpi_key_elem elem, int keyval, void * value, int* flag);
+};
+
+template <typename T> int Keyval::keyval_create(smpi_copy_fn copy_fn, smpi_delete_fn delete_fn, int* keyval, void* extra_state){
+
+  smpi_key_elem value = (smpi_key_elem) xbt_new0(s_smpi_mpi_key_elem_t,1);
+
+  value->copy_fn=copy_fn;
+  value->delete_fn=delete_fn;
+  value->refcount=1;
+
+  *keyval = T::keyval_id_;
+  T::keyvals_.insert({*keyval, value});
+  T::keyval_id_++;
+  return MPI_SUCCESS;
+}
+
+template <typename T> int Keyval::keyval_free(int* keyval){
+/* See MPI-1, 5.7.1.  Freeing the keyval does not remove it if it
+         * is in use in an attribute */
+  smpi_key_elem elem = T::keyvals_.at(*keyval);
+  if(elem==0){
+    return MPI_ERR_ARG;
+  }
+  if(elem->refcount==1){
+    T::keyvals_.erase(*keyval);
+    xbt_free(elem);
+  }else{
+    elem->refcount--;
+  }
+  return MPI_SUCCESS;
+}
+
+//specialized in smpi_keyvals.cpp
+template <typename T> int Keyval::call_deleter(T* obj, smpi_key_elem elem, int keyval, void * value, int* flag){
+  return MPI_SUCCESS;
+}
+
+template <typename T> int Keyval::attr_delete(int keyval){
+  smpi_key_elem elem = T::keyvals_.at(keyval);
+  if(elem==nullptr)
+    return MPI_ERR_ARG;
+  elem->refcount--;
+  void * value = nullptr;
+  int flag;
+  if(this->attr_get<T>(keyval, &value, &flag)==MPI_SUCCESS){
+    int ret = call_deleter<T>((T*)this, elem, keyval,value,&flag);
+    if(ret!=MPI_SUCCESS)
+        return ret;
+  }
+  if(attributes_.empty())
+    return MPI_ERR_ARG;
+  attributes_.erase(keyval);
+  return MPI_SUCCESS;
+}
+
+
+template <typename T> int Keyval::attr_get(int keyval, void* attr_value, int* flag){
+  smpi_key_elem elem = T::keyvals_.at(keyval);
+  if(elem==nullptr)
+    return MPI_ERR_ARG;
+  if(attributes_.empty()){
+    *flag=0;
+    return MPI_SUCCESS;
+  }
+  try {
+    *static_cast<void**>(attr_value) = attributes_.at(keyval);
+    *flag=1;
+  }
+  catch (const std::out_of_range& oor) {
+    *flag=0;
+  }
+  return MPI_SUCCESS;
+}
+
+template <typename T> int Keyval::attr_put(int keyval, void* attr_value){
+  smpi_key_elem elem = T::keyvals_.at(keyval);
+  if(elem==nullptr)
+    return MPI_ERR_ARG;
+  elem->refcount++;
+  void * value = nullptr;
+  int flag;
+  this->attr_get<T>(keyval, &value, &flag);
+  if(flag!=0){
+    int ret = call_deleter<T>((T*)this, elem, keyval,value,&flag);
+    if(ret!=MPI_SUCCESS)
+        return ret;
+  }
+  attributes_.insert({keyval, attr_value});
+  return MPI_SUCCESS;
+}
+
+}
+}
+
+#endif
index 73a103e..81395f1 100644 (file)
@@ -2790,7 +2790,7 @@ int PMPI_Attr_delete(MPI_Comm comm, int keyval) {
   else if (comm==MPI_COMM_NULL)
     return MPI_ERR_COMM;
   else
   else if (comm==MPI_COMM_NULL)
     return MPI_ERR_COMM;
   else
-    return comm->attr_delete(keyval);
+    return comm->attr_delete<Comm>(keyval);
 }
 
 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
 }
 
 int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
@@ -2828,7 +2828,7 @@ int PMPI_Attr_get(MPI_Comm comm, int keyval, void* attr_value, int* flag) {
     *static_cast<int**>(attr_value) = &one;
     return MPI_SUCCESS;
   default:
     *static_cast<int**>(attr_value) = &one;
     return MPI_SUCCESS;
   default:
-    return comm->attr_get(keyval, attr_value, flag);
+    return comm->attr_get<Comm>(keyval, attr_value, flag);
   }
 }
 
   }
 }
 
@@ -2839,7 +2839,7 @@ int PMPI_Attr_put(MPI_Comm comm, int keyval, void* attr_value) {
   else if (comm==MPI_COMM_NULL)
     return MPI_ERR_COMM;
   else
   else if (comm==MPI_COMM_NULL)
     return MPI_ERR_COMM;
   else
-  return comm->attr_put(keyval, attr_value);
+  return comm->attr_put<Comm>(keyval, attr_value);
 }
 
 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
 }
 
 int PMPI_Comm_get_attr (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)
@@ -2872,7 +2872,7 @@ int PMPI_Type_get_attr (MPI_Datatype type, int type_keyval, void *attribute_val,
   if (type==MPI_DATATYPE_NULL)
     return MPI_ERR_TYPE;
   else
   if (type==MPI_DATATYPE_NULL)
     return MPI_ERR_TYPE;
   else
-    return type->attr_get(type_keyval, attribute_val, flag);
+    return type->attr_get<Datatype>(type_keyval, attribute_val, flag);
 }
 
 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
 }
 
 int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
@@ -2880,7 +2880,7 @@ int PMPI_Type_set_attr (MPI_Datatype type, int type_keyval, void *attribute_val)
   if (type==MPI_DATATYPE_NULL)
     return MPI_ERR_TYPE;
   else
   if (type==MPI_DATATYPE_NULL)
     return MPI_ERR_TYPE;
   else
-    return type->attr_put(type_keyval, attribute_val);
+    return type->attr_put<Datatype>(type_keyval, attribute_val);
 }
 
 int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
 }
 
 int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
@@ -2888,7 +2888,7 @@ int PMPI_Type_delete_attr (MPI_Datatype type, int type_keyval)
   if (type==MPI_DATATYPE_NULL)
     return MPI_ERR_TYPE;
   else
   if (type==MPI_DATATYPE_NULL)
     return MPI_ERR_TYPE;
   else
-    return type->attr_delete(type_keyval);
+    return type->attr_delete<Datatype>(type_keyval);
 }
 
 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
 }
 
 int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval,
index 9bd28d7..e623b06 100644 (file)
@@ -225,6 +225,7 @@ set(SMPI_SRC
   src/smpi/smpi_datatype.hpp
   src/smpi/smpi_info.cpp
   src/smpi/smpi_info.hpp
   src/smpi/smpi_datatype.hpp
   src/smpi/smpi_info.cpp
   src/smpi/smpi_info.hpp
+  src/smpi/smpi_keyvals.cpp
   src/smpi/smpi_keyvals.hpp
   src/smpi/smpi_datatype_derived.cpp
   src/smpi/smpi_datatype_derived.hpp
   src/smpi/smpi_keyvals.hpp
   src/smpi/smpi_datatype_derived.cpp
   src/smpi/smpi_datatype_derived.hpp