From: degomme Date: Wed, 15 Mar 2017 22:25:34 +0000 (+0100) Subject: Move Keyval handling to a new file, as it is shared between Comm and Datatype (and... X-Git-Tag: v3_15~101 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/d4f3a012fbbb4484ed74c6cec7b5444ffb15f27f Move Keyval handling to a new file, as it is shared between Comm and Datatype (and Win). Get rid of some xbt_dicts as well. --- diff --git a/include/smpi/smpi.h b/include/smpi/smpi.h index e392164f10..b52e36696f 100644 --- a/include/smpi/smpi.h +++ b/include/smpi/smpi.h @@ -370,6 +370,20 @@ typedef SMPI_Request *MPI_Request; #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)); @@ -545,25 +559,11 @@ typedef void MPI_Handler_function(MPI_Comm*, int*, ...); 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 -#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 diff --git a/src/smpi/private.h b/src/smpi/private.h index d1a37995fb..cb38aaa2f3 100644 --- a/src/smpi/private.h +++ b/src/smpi/private.h @@ -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_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; diff --git a/src/smpi/smpi_comm.cpp b/src/smpi/smpi_comm.cpp index 7d67ca1cf5..98e0599011 100644 --- a/src/smpi/smpi_comm.cpp +++ b/src/smpi/smpi_comm.cpp @@ -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; - attributes_=nullptr; } 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; - if(attributes_ !=nullptr){ - (*newcomm)->attributes_ = xbt_dict_new_homogeneous(nullptr); - xbt_dict_cursor_t cursor = nullptr; - char* key; + if(!attributes_.empty()){ int flag; - void* value_in; 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) { - 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; - xbt_dict_cursor_free(&cursor); 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(){ - if(attributes_ !=nullptr){ - xbt_dict_cursor_t cursor = nullptr; - char* key; - void* value; + if(!attributes_.empty()){ int flag; - xbt_dict_foreach (attributes_, cursor, key, value) { + for(auto it = attributes_.begin(); it != attributes_.end(); it++){ 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) - 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; } } - xbt_dict_free(&attributes_); } } @@ -499,64 +491,6 @@ void Comm::init_smp(){ 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(&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(attr_value) = - xbt_dict_get_ext(attributes_, reinterpret_cast(&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(&keyval), sizeof(int), attr_value, nullptr); - return MPI_SUCCESS; -} - MPI_Comm Comm::f2c(int id) { if(id == -2) { return MPI_COMM_SELF; diff --git a/src/smpi/smpi_comm.hpp b/src/smpi/smpi_comm.hpp index 2c4401394a..aedf39e845 100644 --- a/src/smpi/smpi_comm.hpp +++ b/src/smpi/smpi_comm.hpp @@ -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 ? - xbt_dict_t attributes_; public: static std::unordered_map 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(); - 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); diff --git a/src/smpi/smpi_datatype.cpp b/src/smpi/smpi_datatype.cpp index 086b0ddb65..5d39365f41 100644 --- a/src/smpi/smpi_datatype.cpp +++ b/src/smpi/smpi_datatype.cpp @@ -106,7 +106,7 @@ namespace smpi{ std::unordered_map 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_)); @@ -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. -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 } -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_); - if(datatype->attributes_ !=nullptr){ - attributes_ = xbt_dict_new_homogeneous(nullptr); - xbt_dict_cursor_t cursor = nullptr; - char* key; + if(!(datatype->attributes_.empty())){ int flag; - void* value_in; 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) { - *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) { - xbt_dict_cursor_free(&cursor); 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; } - if(attributes_ !=nullptr){ - xbt_dict_cursor_t cursor = nullptr; - char* key; - void * value; + if(!attributes_.empty()){ int flag; - xbt_dict_foreach(attributes_, cursor, key, value){ + for(auto it = attributes_.begin(); it != attributes_.end(); it++){ 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; } } - xbt_dict_free(&attributes_); } xbt_free(name_); @@ -262,64 +256,6 @@ void Datatype::set_name(char* 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(&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(attr_value) = xbt_dict_get_ext(attributes_, reinterpret_cast(&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(&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(size_)) return MPI_ERR_BUFFER; diff --git a/src/smpi/smpi_datatype.hpp b/src/smpi/smpi_datatype.hpp index 29cd8aee6c..c652695990 100644 --- a/src/smpi/smpi_datatype.hpp +++ b/src/smpi/smpi_datatype.hpp @@ -85,7 +85,6 @@ class Datatype : public F2C, public Keyval{ MPI_Aint lb_; MPI_Aint ub_; int flags_; - xbt_dict_t attributes_; 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 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); diff --git a/src/smpi/smpi_keyvals.cpp b/src/smpi/smpi_keyvals.cpp new file mode 100644 index 0000000000..9eb473f6eb --- /dev/null +++ b/src/smpi/smpi_keyvals.cpp @@ -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 +#include + +namespace simgrid{ +namespace smpi{ + + +template <> int Keyval::call_deleter(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* 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* 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 index 0000000000..0508f33392 --- /dev/null +++ b/src/smpi/smpi_keyvals.hpp @@ -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 +#include + +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 attributes_; + public: +// Each subclass should have two members, as we want to separate the ones for Win, Comm, and Datatypes : +// static std::unordered_map keyvals_; +// static int keyval_id_; + template static int keyval_create(smpi_copy_fn copy_fn, smpi_delete_fn delete_fn, int* keyval, void* extra_statee); + template static int keyval_free(int* keyval); + template int attr_delete(int keyval); + template int attr_get(int keyval, void* attr_value, int* flag); + template int attr_put(int keyval, void* attr_value); + template static int call_deleter(T* obj, smpi_key_elem elem, int keyval, void * value, int* flag); +}; + +template 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 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 int Keyval::call_deleter(T* obj, smpi_key_elem elem, int keyval, void * value, int* flag){ + return MPI_SUCCESS; +} + +template 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(keyval, &value, &flag)==MPI_SUCCESS){ + int ret = call_deleter((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 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(attr_value) = attributes_.at(keyval); + *flag=1; + } + catch (const std::out_of_range& oor) { + *flag=0; + } + return MPI_SUCCESS; +} + +template 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(keyval, &value, &flag); + if(flag!=0){ + int ret = call_deleter((T*)this, elem, keyval,value,&flag); + if(ret!=MPI_SUCCESS) + return ret; + } + attributes_.insert({keyval, attr_value}); + return MPI_SUCCESS; +} + +} +} + +#endif diff --git a/src/smpi/smpi_pmpi.cpp b/src/smpi/smpi_pmpi.cpp index 73a103eabf..81395f16a1 100644 --- a/src/smpi/smpi_pmpi.cpp +++ b/src/smpi/smpi_pmpi.cpp @@ -2790,7 +2790,7 @@ int PMPI_Attr_delete(MPI_Comm comm, int keyval) { else if (comm==MPI_COMM_NULL) return MPI_ERR_COMM; else - return comm->attr_delete(keyval); + return comm->attr_delete(keyval); } 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(attr_value) = &one; return MPI_SUCCESS; default: - return comm->attr_get(keyval, attr_value, flag); + return comm->attr_get(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 - return comm->attr_put(keyval, attr_value); + return comm->attr_put(keyval, attr_value); } 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 - return type->attr_get(type_keyval, attribute_val, flag); + return type->attr_get(type_keyval, attribute_val, flag); } 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 - return type->attr_put(type_keyval, attribute_val); + return type->attr_put(type_keyval, attribute_val); } 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 - return type->attr_delete(type_keyval); + return type->attr_delete(type_keyval); } int PMPI_Type_create_keyval(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, diff --git a/tools/cmake/DefinePackages.cmake b/tools/cmake/DefinePackages.cmake index 9bd28d7f82..e623b06e72 100644 --- a/tools/cmake/DefinePackages.cmake +++ b/tools/cmake/DefinePackages.cmake @@ -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_keyvals.cpp src/smpi/smpi_keyvals.hpp src/smpi/smpi_datatype_derived.cpp src/smpi/smpi_datatype_derived.hpp