X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/9d1a9a4b871895531b7e70f313691ef75dc47a96..b9625f82f86db0674e911887addce45dca31b57f:/src/smpi/mpi/smpi_datatype.cpp diff --git a/src/smpi/mpi/smpi_datatype.cpp b/src/smpi/mpi/smpi_datatype.cpp index 074c15891a..c28c526b3f 100644 --- a/src/smpi/mpi/smpi_datatype.cpp +++ b/src/smpi/mpi/smpi_datatype.cpp @@ -1,5 +1,5 @@ /* smpi_datatype.cpp -- MPI primitives to handle datatypes */ -/* Copyright (c) 2009-2019. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2009-2020. 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. */ @@ -11,6 +11,8 @@ #include "src/instr/instr_private.hpp" #include "src/smpi/include/smpi_actor.hpp" +#include +#include #include XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_datatype, smpi, "Logging specific to SMPI (datatype)"); @@ -107,14 +109,16 @@ Datatype::Datatype(int ident, int size, MPI_Aint lb, MPI_Aint ub, int flags) : D { id = std::to_string(ident); } -Datatype::Datatype(int size,MPI_Aint lb, MPI_Aint ub, int flags) : name_(nullptr), size_(size), lb_(lb), ub_(ub), flags_(flags), refcount_(1){ + +Datatype::Datatype(int size, MPI_Aint lb, MPI_Aint ub, int flags) : size_(size), lb_(lb), ub_(ub), flags_(flags) +{ #if SIMGRID_HAVE_MC if(MC_is_active()) MC_ignore(&(refcount_), sizeof(refcount_)); #endif } -//for predefined types, so in_use = 0. +// for predefined types, so refcount_ = 0. Datatype::Datatype(char* name, int ident, int size, MPI_Aint lb, MPI_Aint ub, int flags) : name_(name), id(std::to_string(ident)), size_(size), lb_(lb), ub_(ub), flags_(flags), refcount_(0) { @@ -125,10 +129,33 @@ Datatype::Datatype(char* name, int ident, int size, MPI_Aint lb, MPI_Aint ub, in #endif } -Datatype::Datatype(Datatype *datatype, int* ret) : name_(nullptr), size_(datatype->size_), lb_(datatype->lb_), ub_(datatype->ub_), flags_(datatype->flags_), refcount_(1) +Datatype::Datatype(Datatype* datatype, int* ret) + : size_(datatype->size_), lb_(datatype->lb_), ub_(datatype->ub_), flags_(datatype->flags_) +{ + *ret = this->copy_attrs(datatype); +} + +Datatype::~Datatype() { + xbt_assert(refcount_ >= 0); + + if(flags_ & DT_FLAG_PREDEFINED) + return; + + //if still used, mark for deletion + if(refcount_!=0){ + flags_ |=DT_FLAG_DESTROYED; + return; + } + + cleanup_attr(); + delete contents_; + xbt_free(name_); +} + +int Datatype::copy_attrs(Datatype* datatype){ flags_ &= ~DT_FLAG_PREDEFINED; - *ret = MPI_SUCCESS; + int ret = MPI_SUCCESS; if (not datatype->attributes()->empty()) { int flag=0; @@ -138,13 +165,13 @@ Datatype::Datatype(Datatype *datatype, int* ret) : name_(nullptr), size_(datatyp if (elem != nullptr){ if( elem->copy_fn.type_copy_fn != MPI_NULL_COPY_FN && elem->copy_fn.type_copy_fn != MPI_TYPE_DUP_FN) - *ret = elem->copy_fn.type_copy_fn(datatype, it.first, elem->extra_state, it.second, &value_out, &flag); + ret = elem->copy_fn.type_copy_fn(datatype, it.first, elem->extra_state, it.second, &value_out, &flag); else if ( elem->copy_fn.type_copy_fn_fort != MPI_NULL_COPY_FN && (*(int*)*elem->copy_fn.type_copy_fn_fort) != 1){ value_out=(int*)xbt_malloc(sizeof(int)); - elem->copy_fn.type_copy_fn_fort(datatype, it.first, elem->extra_state, it.second, value_out, &flag,ret); + elem->copy_fn.type_copy_fn_fort(datatype, it.first, elem->extra_state, it.second, value_out, &flag, &ret); } - if (*ret != MPI_SUCCESS) { + if (ret != MPI_SUCCESS) { break; } if(elem->copy_fn.type_copy_fn == MPI_TYPE_DUP_FN || @@ -158,27 +185,18 @@ Datatype::Datatype(Datatype *datatype, int* ret) : name_(nullptr), size_(datatyp } } } + contents_ = new Datatype_contents(MPI_COMBINER_DUP, 0, nullptr, 0, nullptr, 1, &datatype); + return ret; } -Datatype::~Datatype(){ - xbt_assert(refcount_ >= 0); - - if(flags_ & DT_FLAG_PREDEFINED) - return; - - //if still used, mark for deletion - if(refcount_!=0){ - flags_ |=DT_FLAG_DESTROYED; - return; - } - - cleanup_attr(); - - xbt_free(name_); +int Datatype::clone(MPI_Datatype* type){ + int ret; + *type = new Datatype(this, &ret); + return ret; } -void Datatype::ref(){ - +void Datatype::ref() +{ refcount_++; #if SIMGRID_HAVE_MC @@ -206,16 +224,17 @@ void Datatype::commit() flags_ |= DT_FLAG_COMMITED; } -bool Datatype::is_valid(){ +bool Datatype::is_valid() const +{ return (flags_ & DT_FLAG_COMMITED); } -bool Datatype::is_basic() +bool Datatype::is_basic() const { return (flags_ & DT_FLAG_BASIC); } -bool Datatype::is_replayable() +bool Datatype::is_replayable() const { return (simgrid::instr::trace_format == simgrid::instr::TraceFormat::Ti) && ((this == MPI_BYTE) || (this == MPI_DOUBLE) || (this == MPI_INT) || (this == MPI_CHAR) || @@ -231,13 +250,15 @@ void Datatype::addflag(int flag){ flags_ &= flag; } -int Datatype::extent(MPI_Aint * lb, MPI_Aint * extent){ +int Datatype::extent(MPI_Aint* lb, MPI_Aint* extent) const +{ *lb = lb_; *extent = ub_ - lb_; return MPI_SUCCESS; } -void Datatype::get_name(char* name, int* length){ +void Datatype::get_name(char* name, int* length) const +{ if(name_!=nullptr){ *length = strlen(name_); strncpy(name, name_, *length+1); @@ -252,7 +273,7 @@ void Datatype::set_name(const char* name){ name_ = xbt_strdup(name); } -int Datatype::pack(const void* inbuf, int incount, void* outbuf, int outcount, int* position, MPI_Comm) +int Datatype::pack(const void* inbuf, int incount, void* outbuf, int outcount, int* position, const Comm*) { if (outcount - *position < incount*static_cast(size_)) return MPI_ERR_OTHER; @@ -261,7 +282,7 @@ int Datatype::pack(const void* inbuf, int incount, void* outbuf, int outcount, i return MPI_SUCCESS; } -int Datatype::unpack(const void* inbuf, int insize, int* position, void* outbuf, int outcount, MPI_Comm) +int Datatype::unpack(const void* inbuf, int insize, int* position, void* outbuf, int outcount, const Comm*) { if (outcount*static_cast(size_)> insize) return MPI_ERR_OTHER; @@ -270,12 +291,46 @@ int Datatype::unpack(const void* inbuf, int insize, int* position, void* outbuf, return MPI_SUCCESS; } -int Datatype::copy(const void *sendbuf, int sendcount, MPI_Datatype sendtype, - void *recvbuf, int recvcount, MPI_Datatype recvtype){ +int Datatype::get_contents(int max_integers, int max_addresses, int max_datatypes, int* array_of_integers, + MPI_Aint* array_of_addresses, MPI_Datatype* array_of_datatypes) const +{ + if(contents_==nullptr) + return MPI_ERR_ARG; + if (static_cast(max_integers) < contents_->integers_.size()) + return MPI_ERR_COUNT; + std::copy(begin(contents_->integers_), end(contents_->integers_), array_of_integers); + if (static_cast(max_addresses) < contents_->addresses_.size()) + return MPI_ERR_COUNT; + std::copy(begin(contents_->addresses_), end(contents_->addresses_), array_of_addresses); + if (static_cast(max_datatypes) < contents_->datatypes_.size()) + return MPI_ERR_COUNT; + std::copy(begin(contents_->datatypes_), end(contents_->datatypes_), array_of_datatypes); + std::for_each(begin(contents_->datatypes_), end(contents_->datatypes_), std::mem_fn(&Datatype::ref)); + return MPI_SUCCESS; +} + +int Datatype::get_envelope(int* num_integers, int* num_addresses, int* num_datatypes, int* combiner) const +{ + if(contents_==nullptr){ + *num_integers = 0; + *num_addresses = 0; + *num_datatypes = 0; + *combiner = MPI_COMBINER_NAMED; + }else{ + *num_integers = contents_->integers_.size(); + *num_addresses = contents_->addresses_.size(); + *num_datatypes = contents_->datatypes_.size(); + *combiner = contents_->combiner_; + } + return MPI_SUCCESS; +} -// FIXME Handle the case of a partial shared malloc. +int Datatype::copy(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, + MPI_Datatype recvtype) +{ + // FIXME Handle the case of a partial shared malloc. - if (smpi_privatize_global_variables == SmpiPrivStrategies::MMAP) { + if (smpi_cfg_privatization() == SmpiPrivStrategies::MMAP) { smpi_switch_data_segment(simgrid::s4u::Actor::self()); } /* First check if we really have something to do */ @@ -284,11 +339,13 @@ int Datatype::copy(const void *sendbuf, int sendcount, MPI_Datatype sendtype, if(smpi_is_shared(sendbuf,private_blocks,&offset) && (private_blocks.size()==1 && (private_blocks[0].second - private_blocks[0].first)==(unsigned long)(sendcount * sendtype->get_extent()))){ + XBT_VERB("sendbuf is shared. Ignoring copies"); return 0; } if(smpi_is_shared(recvbuf,private_blocks,&offset) && (private_blocks.size()==1 && (private_blocks[0].second - private_blocks[0].first)==(unsigned long)(recvcount * recvtype->get_extent()))){ + XBT_VERB("recvbuf is shared. Ignoring copies"); return 0; } @@ -304,8 +361,7 @@ int Datatype::copy(const void *sendbuf, int sendcount, MPI_Datatype sendtype, recvtype->unserialize(sendbuf, recvbuf, count / recvtype->size(), MPI_REPLACE); } else if (not(recvtype->flags() & DT_FLAG_DERIVED)) { sendtype->serialize(sendbuf, recvbuf, count / sendtype->size()); - }else{ - + } else { void * buf_tmp = xbt_malloc(count); sendtype->serialize( sendbuf, buf_tmp,count/sendtype->size()); @@ -366,6 +422,8 @@ int Datatype::create_vector(int count, int block_length, int stride, MPI_Datatyp /* in this situation the data are contiguous thus it's not required to serialize and unserialize it*/ *new_type = new Datatype(count * block_length * old_type->size(), 0, ((count -1) * stride + block_length)* old_type->size(), DT_FLAG_CONTIGUOUS); + int ints[3] = {count, block_length, stride}; + (*new_type)->contents_ = new Datatype_contents(MPI_COMBINER_VECTOR, 3, ints, 0, nullptr, 1, &old_type); retval=MPI_SUCCESS; } return retval; @@ -390,6 +448,8 @@ int Datatype::create_hvector(int count, int block_length, MPI_Aint stride, MPI_D }else{ /* in this situation the data are contiguous thus it's not required to serialize and unserialize it*/ *new_type = new Datatype(count * block_length * old_type->size(), 0, count * block_length * old_type->size(), DT_FLAG_CONTIGUOUS); + int ints[2] = {count, block_length}; + (*new_type)->contents_ = new Datatype_contents(MPI_COMBINER_HVECTOR, 2, ints, 1, &stride, 1, &old_type); retval=MPI_SUCCESS; } return retval; @@ -581,11 +641,9 @@ int Datatype::create_resized(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent, return MPI_SUCCESS; } -Datatype* Datatype::f2c(int id){ +Datatype* Datatype::f2c(int id) +{ return static_cast(F2C::f2c(id)); } - - -} -} - +} // namespace smpi +} // namespace simgrid