X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/d17275a7f232bacf3d00279e3ba76c32cc6cf2c5..ad0539d141f7dfee1706fea560d6122cb3a92f13:/src/smpi/smpi_datatype.cpp diff --git a/src/smpi/smpi_datatype.cpp b/src/smpi/smpi_datatype.cpp index 59aac9886d..6dfe3bdf90 100644 --- a/src/smpi/smpi_datatype.cpp +++ b/src/smpi/smpi_datatype.cpp @@ -1,5 +1,5 @@ /* smpi_datatype.cpp -- MPI primitives to handle datatypes */ -/* Copyright (c) 2009-2015. The SimGrid Team. +/* Copyright (c) 2009-2017. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -8,22 +8,18 @@ #include "mc/mc.h" #include "private.h" #include "simgrid/modelchecker.h" -#include "xbt/replay.h" #include #include #include #include #include +#include #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_datatype, smpi, "Logging specific to SMPI (datatype)"); -xbt_dict_t smpi_type_keyvals = nullptr; -int type_keyval_id=0;//avoid collisions - - #define CREATE_MPI_DATATYPE(name, type) \ - static Datatype mpi_##name ( \ + static simgrid::smpi::Datatype mpi_##name ( \ (char*) # name, \ sizeof(type), /* size */ \ 0, /* lb */ \ @@ -33,7 +29,7 @@ int type_keyval_id=0;//avoid collisions const MPI_Datatype name = &mpi_##name; #define CREATE_MPI_DATATYPE_NULL(name) \ - static Datatype mpi_##name ( \ + static simgrid::smpi::Datatype mpi_##name ( \ (char*) # name, \ 0, /* size */ \ 0, /* lb */ \ @@ -107,101 +103,90 @@ CREATE_MPI_DATATYPE(MPI_PTR, void*); namespace simgrid{ namespace smpi{ -Datatype::Datatype(int size,MPI_Aint lb, MPI_Aint ub, int flags) : name_(nullptr), size_(size), lb_(lb), ub_(ub), flags_(flags), attributes_(nullptr), in_use_(1){ +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), refcount_(1){ #if HAVE_MC if(MC_is_active()) - MC_ignore(&(in_use_), sizeof(in_use_)); + MC_ignore(&(refcount_), sizeof(refcount_)); #endif } //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), 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), refcount_(0){ #if HAVE_MC if(MC_is_active()) - MC_ignore(&(in_use_), sizeof(in_use_)); + 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), in_use_(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_type_key_elem elem = - static_cast(xbt_dict_get_or_null_ext(smpi_type_keyvals, key, sizeof(int))); - if (elem != nullptr && elem->copy_fn != MPI_NULL_COPY_FN) { - *ret = elem->copy_fn(datatype, atoi(key), nullptr, value_in, &value_out, &flag); + 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, (*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}); + } } } } } Datatype::~Datatype(){ - xbt_assert(in_use_ >= 0); + xbt_assert(refcount_ >= 0); if(flags_ & DT_FLAG_PREDEFINED) return; //if still used, mark for deletion - if(in_use_!=0){ + if(refcount_!=0){ flags_ |=DT_FLAG_DESTROYED; return; } - if(attributes_ !=nullptr){ - xbt_dict_cursor_t cursor = nullptr; - char* key; - void * value; - int flag; - xbt_dict_foreach(attributes_, cursor, key, value){ - smpi_type_key_elem elem = - static_cast(xbt_dict_get_or_null_ext(smpi_type_keyvals, key, sizeof(int))); - if(elem!=nullptr && elem->delete_fn!=nullptr) - elem->delete_fn(this,*key, value, &flag); - } - xbt_dict_free(&attributes_); - } + cleanup_attr(); xbt_free(name_); } -void Datatype::use(){ +void Datatype::ref(){ - in_use_++; + refcount_++; #if HAVE_MC if(MC_is_active()) - MC_ignore(&(in_use_), sizeof(in_use_)); + MC_ignore(&(refcount_), sizeof(refcount_)); #endif } -void Datatype::unuse() +void Datatype::unref(MPI_Datatype datatype) { - if (in_use_ > 0) - in_use_--; + if (datatype->refcount_ > 0) + datatype->refcount_--; - if (in_use_ == 0) - this->~Datatype(); + if (datatype->refcount_ == 0 && !(datatype->flags_ & DT_FLAG_PREDEFINED)) + delete datatype; #if HAVE_MC if(MC_is_active()) - MC_ignore(&(in_use_), sizeof(in_use_)); + MC_ignore(&(datatype->refcount_), sizeof(datatype->refcount_)); #endif } @@ -223,6 +208,10 @@ int Datatype::flags(){ return flags_; } +int Datatype::refcount(){ + return refcount_; +} + void Datatype::addflag(int flag){ flags_ &= flag; } @@ -261,96 +250,6 @@ void Datatype::set_name(char* name){ name_ = xbt_strdup(name); } -int Datatype::attr_delete(int keyval){ - smpi_type_key_elem elem = - static_cast(xbt_dict_get_or_null_ext(smpi_type_keyvals, reinterpret_cast(&keyval), sizeof(int))); - if(elem==nullptr) - return MPI_ERR_ARG; - if(elem->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(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_type_key_elem elem = - static_cast(xbt_dict_get_or_null_ext(smpi_type_keyvals, reinterpret_cast(&keyval), sizeof(int))); - 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){ - if(smpi_type_keyvals==nullptr) - smpi_type_keyvals = xbt_dict_new_homogeneous(nullptr); - smpi_type_key_elem elem = - static_cast(xbt_dict_get_or_null_ext(smpi_type_keyvals, reinterpret_cast(&keyval), sizeof(int))); - if(elem==nullptr) - return MPI_ERR_ARG; - int flag; - void* value = nullptr; - this->attr_get(keyval, &value, &flag); - if(flag!=0 && elem->delete_fn!=MPI_NULL_DELETE_FN){ - int ret = elem->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::keyval_create(MPI_Type_copy_attr_function* copy_fn, MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state){ - if(smpi_type_keyvals==nullptr) - smpi_type_keyvals = xbt_dict_new_homogeneous(nullptr); - - smpi_type_key_elem value = (smpi_type_key_elem) xbt_new0(s_smpi_mpi_type_key_elem_t,1); - - value->copy_fn=copy_fn; - value->delete_fn=delete_fn; - - *keyval = type_keyval_id; - xbt_dict_set_ext(smpi_type_keyvals,reinterpret_cast(keyval), sizeof(int),reinterpret_cast(value), nullptr); - type_keyval_id++; - return MPI_SUCCESS; -} - -int Datatype::keyval_free(int* keyval){ - smpi_type_key_elem elem = - static_cast(xbt_dict_get_or_null_ext(smpi_type_keyvals, reinterpret_cast(keyval), sizeof(int))); - if(elem==0){ - return MPI_ERR_ARG; - } - xbt_dict_remove_ext(smpi_type_keyvals, reinterpret_cast(keyval), sizeof(int)); - xbt_free(elem); - 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; @@ -360,7 +259,7 @@ int Datatype::pack(void* inbuf, int incount, void* outbuf, int outcount, int* po } int Datatype::unpack(void* inbuf, int insize, int* position, void* outbuf, int outcount,MPI_Comm comm){ - if (outcount*(int)size_> insize) + if (outcount*static_cast(size_)> insize) return MPI_ERR_BUFFER; Datatype::copy(static_cast(inbuf) + *position, insize, MPI_CHAR, outbuf, outcount, this); *position += outcount * size_; @@ -371,8 +270,11 @@ int Datatype::unpack(void* inbuf, int insize, int* position, void* outbuf, int o int Datatype::copy(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype){ int count; - if(smpi_privatize_global_variables){ - smpi_switch_data_segment(smpi_process_index()); + +// FIXME Handle the case of a partial shared malloc. + + if(smpi_privatize_global_variables == SMPI_PRIVATIZE_MMAP){ + smpi_switch_data_segment(smpi_process()->index()); } /* First check if we really have something to do */ if (recvcount > 0 && recvbuf != sendbuf) { @@ -381,7 +283,7 @@ int Datatype::copy(void *sendbuf, int sendcount, MPI_Datatype sendtype, count = sendcount < recvcount ? sendcount : recvcount; if(!(sendtype->flags() & DT_FLAG_DERIVED) && !(recvtype->flags() & DT_FLAG_DERIVED)) { - if(!smpi_process_get_replaying()) + if(!smpi_process()->replaying()) memcpy(recvbuf, sendbuf, count); } else if (!(sendtype->flags() & DT_FLAG_DERIVED)) @@ -596,6 +498,10 @@ int Datatype::create_struct(int count, int* block_lengths, MPI_Aint* indices, MP return MPI_SUCCESS; } +Datatype* Datatype::f2c(int id){ + return static_cast(F2C::f2c(id)); +} + } }