diff --git a/src/synchronizer/communication_buffer.hh b/src/synchronizer/communication_buffer.hh index 5e0b0da8d..54586466c 100644 --- a/src/synchronizer/communication_buffer.hh +++ b/src/synchronizer/communication_buffer.hh @@ -1,182 +1,190 @@ /** * @file communication_buffer.hh * * @author Guillaume Anciaux * @author Nicolas Richart * * @date creation: Fri Jun 18 2010 * @date last modification: Wed Nov 08 2017 * * @brief Buffer for packing and unpacking data * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_array.hh" #include "aka_common.hh" #include "element.hh" #ifndef __AKANTU_COMMUNICATION_BUFFER_HH__ #define __AKANTU_COMMUNICATION_BUFFER_HH__ namespace akantu { template class CommunicationBufferTemplated { /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: explicit CommunicationBufferTemplated(UInt size) : buffer(size, 1) { ptr_pack = buffer.storage(); ptr_unpack = buffer.storage(); }; CommunicationBufferTemplated() : CommunicationBufferTemplated(0) {} CommunicationBufferTemplated(const CommunicationBufferTemplated & other) { buffer = other.buffer; ptr_pack = buffer.storage(); ptr_unpack = buffer.storage(); } CommunicationBufferTemplated & operator=(const CommunicationBufferTemplated & other) { if (this != &other) { buffer = other.buffer; ptr_pack = buffer.storage(); ptr_unpack = buffer.storage(); } return *this; } virtual ~CommunicationBufferTemplated() = default; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /// reset to "empty" inline void reset(); - /// resize the internal buffer + /// resize the internal buffer do not allocate on dynamic buffers inline void resize(UInt size); + /// resize the internal buffer allocate always + inline void reserve(UInt size); + /// clear buffer context inline void clear(); private: inline void packResize(UInt size); /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: inline char * storage() { return buffer.storage(); }; inline const char * storage() const { return buffer.storage(); }; /* ------------------------------------------------------------------------ */ /* Operators */ /* ------------------------------------------------------------------------ */ public: /// printing tool template inline std::string extractStream(UInt packet_size); /// packing data template inline CommunicationBufferTemplated & operator<<(const T & to_pack); template inline CommunicationBufferTemplated & operator<<(const Vector & to_pack); template inline CommunicationBufferTemplated & operator<<(const Matrix & to_pack); template inline CommunicationBufferTemplated & operator<<(const std::vector & to_pack); /// unpacking data template inline CommunicationBufferTemplated & operator>>(T & to_unpack); template inline CommunicationBufferTemplated & operator>>(Vector & to_unpack); template inline CommunicationBufferTemplated & operator>>(Matrix & to_unpack); template inline CommunicationBufferTemplated & operator>>(std::vector & to_unpack); inline CommunicationBufferTemplated & operator<<(const std::string & to_pack); inline CommunicationBufferTemplated & operator>>(std::string & to_unpack); private: template inline void packIterable(T & to_pack); template inline void unpackIterable(T & to_pack); /* ------------------------------------------------------------------------ */ /* Accessor */ /* ------------------------------------------------------------------------ */ public: template static inline UInt sizeInBuffer(const T & data); template static inline UInt sizeInBuffer(const Vector & data); template static inline UInt sizeInBuffer(const Matrix & data); template static inline UInt sizeInBuffer(const std::vector & data); static inline UInt sizeInBuffer(const std::string & data); /// return the size in bytes of the stored values inline UInt getPackedSize() const { return ptr_pack - buffer.storage(); }; /// return the size in bytes of data left to be unpacked inline UInt getLeftToUnpack() const { return buffer.size() - (ptr_unpack - buffer.storage()); }; /// return the global size allocated inline UInt size() const { return buffer.size(); }; + /// is the buffer empty + inline bool empty() const { + return (getPackedSize() == 0) and (getLeftToUnpack() == 0); + } + /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: /// current position for packing char * ptr_pack; /// current position for unpacking char * ptr_unpack; /// storing buffer Array buffer; }; /* -------------------------------------------------------------------------- */ /* inline functions */ /* -------------------------------------------------------------------------- */ #if defined(AKANTU_INCLUDE_INLINE_IMPL) #include "communication_buffer_inline_impl.cc" #endif using CommunicationBuffer = CommunicationBufferTemplated; using DynamicCommunicationBuffer = CommunicationBufferTemplated; } // namespace akantu #endif /* __AKANTU_COMMUNICATION_BUFFER_HH__ */ diff --git a/src/synchronizer/communication_buffer_inline_impl.cc b/src/synchronizer/communication_buffer_inline_impl.cc index d242a4b42..144e07d98 100644 --- a/src/synchronizer/communication_buffer_inline_impl.cc +++ b/src/synchronizer/communication_buffer_inline_impl.cc @@ -1,318 +1,327 @@ /** * @file communication_buffer_inline_impl.cc * * @author Guillaume Anciaux * @author Nicolas Richart * * @date creation: Thu Apr 14 2011 * @date last modification: Wed Nov 08 2017 * * @brief CommunicationBuffer inline implementation * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ template template inline UInt CommunicationBufferTemplated::sizeInBuffer(const T &) { return sizeof(T); } template template inline UInt CommunicationBufferTemplated::sizeInBuffer(const Vector & data) { UInt size = data.size() * sizeof(T); return size; } template template inline UInt CommunicationBufferTemplated::sizeInBuffer(const Matrix & data) { UInt size = data.size() * sizeof(T); return size; } template template inline UInt CommunicationBufferTemplated::sizeInBuffer( const std::vector & data) { UInt size = data.size() * sizeof(T) + sizeof(size_t); return size; } template inline UInt CommunicationBufferTemplated::sizeInBuffer( const std::string & data) { UInt size = data.size() * sizeof(std::string::value_type) + sizeof(size_t); return size; } /* -------------------------------------------------------------------------- */ template inline void CommunicationBufferTemplated::packResize(UInt size) { - if (!is_static) { + if (not is_static) { char * values = buffer.storage(); - buffer.resize(buffer.size() + size); - ptr_pack = buffer.storage() + (ptr_pack - values); + auto nb_packed = ptr_pack - values; + if(buffer.size() > nb_packed + size) return; + + buffer.resize(nb_packed + size); + ptr_pack = buffer.storage() + nb_packed; ptr_unpack = buffer.storage() + (ptr_unpack - values); } } /* -------------------------------------------------------------------------- */ template template inline CommunicationBufferTemplated & CommunicationBufferTemplated::operator<<(const T & to_pack) { UInt size = sizeInBuffer(to_pack); packResize(size); AKANTU_DEBUG_ASSERT( (buffer.storage() + buffer.size()) >= (ptr_pack + size), "Packing too much data in the CommunicationBufferTemplated"); memcpy(ptr_pack, reinterpret_cast(&to_pack), size); ptr_pack += size; return *this; } /* -------------------------------------------------------------------------- */ template template inline CommunicationBufferTemplated & CommunicationBufferTemplated::operator>>(T & to_unpack) { UInt size = sizeInBuffer(to_unpack); alignas(alignof(T)) std::array aligned_ptr; memcpy(aligned_ptr.data(), ptr_unpack, size); auto * tmp = reinterpret_cast(aligned_ptr.data()); AKANTU_DEBUG_ASSERT( (buffer.storage() + buffer.size()) >= (ptr_unpack + size), "Unpacking too much data in the CommunicationBufferTemplated"); to_unpack = *tmp; // memcpy(reinterpret_cast(&to_unpack), ptr_unpack, size); ptr_unpack += size; return *this; } /* -------------------------------------------------------------------------- */ /* Specialization */ /* -------------------------------------------------------------------------- */ /** * Vector */ /* -------------------------------------------------------------------------- */ template template inline CommunicationBufferTemplated & CommunicationBufferTemplated::operator<<(const Vector & to_pack) { UInt size = sizeInBuffer(to_pack); packResize(size); AKANTU_DEBUG_ASSERT( (buffer.storage() + buffer.size()) >= (ptr_pack + size), "Packing too much data in the CommunicationBufferTemplated"); memcpy(ptr_pack, to_pack.storage(), size); ptr_pack += size; return *this; } /* -------------------------------------------------------------------------- */ template template inline CommunicationBufferTemplated & CommunicationBufferTemplated::operator>>(Vector & to_unpack) { UInt size = sizeInBuffer(to_unpack); AKANTU_DEBUG_ASSERT( (buffer.storage() + buffer.size()) >= (ptr_unpack + size), "Unpacking too much data in the CommunicationBufferTemplated"); memcpy(to_unpack.storage(), ptr_unpack, size); ptr_unpack += size; return *this; } /** * Matrix */ /* -------------------------------------------------------------------------- */ template template inline CommunicationBufferTemplated & CommunicationBufferTemplated::operator<<(const Matrix & to_pack) { UInt size = sizeInBuffer(to_pack); packResize(size); AKANTU_DEBUG_ASSERT( (buffer.storage() + buffer.size()) >= (ptr_pack + size), "Packing too much data in the CommunicationBufferTemplated"); memcpy(ptr_pack, to_pack.storage(), size); ptr_pack += size; return *this; } /* -------------------------------------------------------------------------- */ template template inline CommunicationBufferTemplated & CommunicationBufferTemplated::operator>>(Matrix & to_unpack) { UInt size = sizeInBuffer(to_unpack); AKANTU_DEBUG_ASSERT( (buffer.storage() + buffer.size()) >= (ptr_unpack + size), "Unpacking too much data in the CommunicationBufferTemplated"); memcpy(to_unpack.storage(), ptr_unpack, size); ptr_unpack += size; return *this; } /* -------------------------------------------------------------------------- */ template template inline void CommunicationBufferTemplated::packIterable(T & to_pack) { operator<<(size_t(to_pack.size())); auto it = to_pack.begin(); auto end = to_pack.end(); for (; it != end; ++it) operator<<(*it); } /* -------------------------------------------------------------------------- */ template template inline void CommunicationBufferTemplated::unpackIterable(T & to_unpack) { size_t size; operator>>(size); to_unpack.resize(size); auto it = to_unpack.begin(); auto end = to_unpack.end(); for (; it != end; ++it) operator>>(*it); } /** * std::vector */ /* -------------------------------------------------------------------------- */ template template inline CommunicationBufferTemplated & CommunicationBufferTemplated:: operator<<(const std::vector & to_pack) { packIterable(to_pack); return *this; } /* -------------------------------------------------------------------------- */ template template inline CommunicationBufferTemplated & CommunicationBufferTemplated:: operator>>(std::vector & to_unpack) { unpackIterable(to_unpack); return *this; } /** * std::string */ /* -------------------------------------------------------------------------- */ template inline CommunicationBufferTemplated & CommunicationBufferTemplated:: operator<<(const std::string & to_pack) { packIterable(to_pack); return *this; } /* -------------------------------------------------------------------------- */ template inline CommunicationBufferTemplated & CommunicationBufferTemplated::operator>>(std::string & to_unpack) { unpackIterable(to_unpack); return *this; } /* -------------------------------------------------------------------------- */ template template inline std::string CommunicationBufferTemplated::extractStream(UInt block_size) { std::stringstream str; auto * ptr = reinterpret_cast(buffer.storage()); UInt sz = buffer.size() / sizeof(T); UInt sz_block = block_size / sizeof(T); UInt n_block = 0; for (UInt i = 0; i < sz; ++i) { if (i % sz_block == 0) { str << std::endl << n_block << " "; ++n_block; } str << *ptr << " "; ++ptr; } return str.str(); } /* -------------------------------------------------------------------------- */ template inline void CommunicationBufferTemplated::resize(UInt size) { if (!is_static) { buffer.resize(0); } else { buffer.resize(size); } reset(); #ifndef AKANTU_NDEBUG clear(); #endif } +/* -------------------------------------------------------------------------- */ +template +inline void CommunicationBufferTemplated::reserve(UInt size) { + packResize(size); +} + /* -------------------------------------------------------------------------- */ template inline void CommunicationBufferTemplated::clear() { buffer.clear(); } /* -------------------------------------------------------------------------- */ template inline void CommunicationBufferTemplated::reset() { ptr_pack = buffer.storage(); ptr_unpack = buffer.storage(); } /* -------------------------------------------------------------------------- */ // template // inline CommunicationBufferTemplated & // CommunicationBufferTemplated::packMeshData (const MeshData & // to_pack, const ElementType & type) { // UInt size = to_pack.size(); // operator<<(size); // typename std::vector::iterator it = to_pack.begin(); // typename std::vector::iterator end = to_pack.end(); // for(;it != end; ++it) operator<<(*it); // return *this; //} diff --git a/src/synchronizer/communicator.hh b/src/synchronizer/communicator.hh index e3ac8f462..c6486c3ac 100644 --- a/src/synchronizer/communicator.hh +++ b/src/synchronizer/communicator.hh @@ -1,436 +1,445 @@ /** * @file communicator.hh * * @author Nicolas Richart * * @date creation: Fri Jun 18 2010 * @date last modification: Wed Nov 15 2017 * * @brief Class handling the parallel communications * * @section LICENSE * * Copyright (©) 2010-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne) * Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides) * * Akantu is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation, either version 3 of the License, or (at your option) any * later version. * * Akantu is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with Akantu. If not, see . * */ /* -------------------------------------------------------------------------- */ #include "aka_array.hh" #include "aka_common.hh" #include "aka_event_handler_manager.hh" #include "communication_buffer.hh" #include "communication_request.hh" #include "communicator_event_handler.hh" /* -------------------------------------------------------------------------- */ #ifndef __AKANTU_STATIC_COMMUNICATOR_HH__ #define __AKANTU_STATIC_COMMUNICATOR_HH__ namespace akantu { namespace debug { class CommunicationException : public Exception { public: CommunicationException() : Exception("An exception happen during a communication process.") {} }; } // namespace debug /// @enum SynchronizerOperation reduce operation that the synchronizer can /// perform enum class SynchronizerOperation { _sum, _min, _max, _prod, _land, _band, _lor, _bor, _lxor, _bxor, _min_loc, _max_loc, _null }; enum class CommunicationMode { _auto, _synchronous, _ready }; namespace { int _any_source = -1; } } // namespace akantu namespace akantu { struct CommunicatorInternalData { virtual ~CommunicatorInternalData() = default; }; /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ class Communicator : public EventHandlerManager { struct private_member {}; /* ------------------------------------------------------------------------ */ /* Constructors/Destructors */ /* ------------------------------------------------------------------------ */ public: Communicator(int & argc, char **& argv, const private_member &); ~Communicator() override; /* ------------------------------------------------------------------------ */ /* Methods */ /* ------------------------------------------------------------------------ */ public: /* ------------------------------------------------------------------------ */ /* Point to Point */ + /* ------------------------------------------------------------------------ */ + template + void probe(Int sender, Int tag, CommunicationStatus & status) const; + + template + bool asyncProbe(Int sender, Int tag, CommunicationStatus & status) const; + /* ------------------------------------------------------------------------ */ template inline void receive(Array & values, Int sender, Int tag) const { return this->receiveImpl( values.storage(), values.size() * values.getNbComponent(), sender, tag); } template inline void receive(Tensor & values, Int sender, Int tag, std::enable_if_t::value> * = nullptr) const { return this->receiveImpl(values.storage(), values.size(), sender, tag); } - template - inline void receive(CommunicationBufferTemplated & values, + + inline void receive(CommunicationBufferTemplated & values, Int sender, Int tag) const { return this->receiveImpl(values.storage(), values.size(), sender, tag); } + + inline void receive(CommunicationBufferTemplated & values, + Int sender, Int tag) const { + CommunicationStatus status; + this->probe(sender, tag, status); + values.reserve(status.size()); + return this->receiveImpl(values.storage(), values.size(), sender, tag); + } + template inline void receive(T & values, Int sender, Int tag, std::enable_if_t::value> * = nullptr) const { return this->receiveImpl(&values, 1, sender, tag); } /* ------------------------------------------------------------------------ */ template inline void send(const Array & values, Int receiver, Int tag, const CommunicationMode & mode = CommunicationMode::_auto) const { return this->sendImpl(values.storage(), values.size() * values.getNbComponent(), receiver, tag, mode); } template inline void send(const Tensor & values, Int receiver, Int tag, const CommunicationMode & mode = CommunicationMode::_auto, std::enable_if_t::value> * = nullptr) const { return this->sendImpl(values.storage(), values.size(), receiver, tag, mode); } template inline void send(const CommunicationBufferTemplated & values, Int receiver, Int tag, const CommunicationMode & mode = CommunicationMode::_auto) const { return this->sendImpl(values.storage(), values.size(), receiver, tag, mode); } template inline void send(const T & values, Int receiver, Int tag, const CommunicationMode & mode = CommunicationMode::_auto, std::enable_if_t::value> * = nullptr) const { return this->sendImpl(&values, 1, receiver, tag, mode); } /* ------------------------------------------------------------------------ */ template inline CommunicationRequest asyncSend(const Array & values, Int receiver, Int tag, const CommunicationMode & mode = CommunicationMode::_auto) const { return this->asyncSendImpl(values.storage(), values.size() * values.getNbComponent(), receiver, tag, mode); } template inline CommunicationRequest asyncSend(const std::vector & values, Int receiver, Int tag, const CommunicationMode & mode = CommunicationMode::_auto) const { return this->asyncSendImpl(values.data(), values.size(), receiver, tag, mode); } template inline CommunicationRequest asyncSend(const Tensor & values, Int receiver, Int tag, const CommunicationMode & mode = CommunicationMode::_auto, std::enable_if_t::value> * = nullptr) const { return this->asyncSendImpl(values.storage(), values.size(), receiver, tag, mode); } template inline CommunicationRequest asyncSend(const CommunicationBufferTemplated & values, Int receiver, Int tag, const CommunicationMode & mode = CommunicationMode::_auto) const { return this->asyncSendImpl(values.storage(), values.size(), receiver, tag, mode); } template inline CommunicationRequest asyncSend(const T & values, Int receiver, Int tag, const CommunicationMode & mode = CommunicationMode::_auto, std::enable_if_t::value> * = nullptr) const { return this->asyncSendImpl(&values, 1, receiver, tag, mode); } /* ------------------------------------------------------------------------ */ template inline CommunicationRequest asyncReceive(Array & values, Int sender, Int tag) const { return this->asyncReceiveImpl( values.storage(), values.size() * values.getNbComponent(), sender, tag); } template inline CommunicationRequest asyncReceive(std::vector & values, Int sender, Int tag) const { return this->asyncReceiveImpl(values.data(), values.size(), sender, tag); } template ::value>> inline CommunicationRequest asyncReceive(Tensor & values, Int sender, Int tag) const { return this->asyncReceiveImpl(values.storage(), values.size(), sender, tag); } template inline CommunicationRequest asyncReceive(CommunicationBufferTemplated & values, Int sender, Int tag) const { return this->asyncReceiveImpl(values.storage(), values.size(), sender, tag); } - /* ------------------------------------------------------------------------ */ - template - void probe(Int sender, Int tag, CommunicationStatus & status) const; - - template - bool asyncProbe(Int sender, Int tag, CommunicationStatus & status) const; - /* ------------------------------------------------------------------------ */ /* Collectives */ /* ------------------------------------------------------------------------ */ template inline void allReduce(Array & values, const SynchronizerOperation & op) const { this->allReduceImpl(values.storage(), values.size() * values.getNbComponent(), op); } template inline void allReduce(Tensor & values, const SynchronizerOperation & op, std::enable_if_t::value> * = nullptr) const { this->allReduceImpl(values.storage(), values.size(), op); } template inline void allReduce(T & values, const SynchronizerOperation & op, std::enable_if_t::value> * = nullptr) const { this->allReduceImpl(&values, 1, op); } /* ------------------------------------------------------------------------ */ template inline void allGather(Array & values) const { AKANTU_DEBUG_ASSERT(UInt(psize) == values.size(), "The array size is not correct"); this->allGatherImpl(values.storage(), values.getNbComponent()); } template ::value>> inline void allGather(Tensor & values) const { AKANTU_DEBUG_ASSERT(values.size() / UInt(psize) > 0, "The vector size is not correct"); this->allGatherImpl(values.storage(), values.size() / UInt(psize)); } /* ------------------------------------------------------------------------ */ template inline void allGatherV(Array & values, const Array & sizes) const { this->allGatherVImpl(values.storage(), sizes.storage()); } /* ------------------------------------------------------------------------ */ template inline void reduce(Array & values, const SynchronizerOperation & op, int root = 0) const { this->reduceImpl(values.storage(), values.size() * values.getNbComponent(), op, root); } /* ------------------------------------------------------------------------ */ template inline void gather(Tensor & values, int root = 0, std::enable_if_t::value> * = nullptr) const { this->gatherImpl(values.storage(), values.getNbComponent(), root); } template inline void gather(T values, int root = 0, std::enable_if_t::value> * = nullptr) const { this->gatherImpl(&values, 1, root); } /* ------------------------------------------------------------------------ */ template inline void gather(Tensor & values, Array & gathered, std::enable_if_t::value> * = nullptr) const { AKANTU_DEBUG_ASSERT(values.size() == gathered.getNbComponent(), "The array size is not correct"); gathered.resize(psize); this->gatherImpl(values.data(), values.size(), gathered.storage(), gathered.getNbComponent()); } template inline void gather(T values, Array & gathered, std::enable_if_t::value> * = nullptr) const { this->gatherImpl(&values, 1, gathered.storage(), 1); } /* ------------------------------------------------------------------------ */ template inline void gatherV(Array & values, const Array & sizes, int root = 0) const { this->gatherVImpl(values.storage(), sizes.storage(), root); } /* ------------------------------------------------------------------------ */ template inline void broadcast(Array & values, int root = 0) const { this->broadcastImpl(values.storage(), values.size() * values.getNbComponent(), root); } template inline void broadcast(CommunicationBufferTemplated & values, int root = 0) const { this->broadcastImpl(values.storage(), values.size(), root); } template inline void broadcast(T & values, int root = 0) const { this->broadcastImpl(&values, 1, root); } /* ------------------------------------------------------------------------ */ void barrier() const; CommunicationRequest asyncBarrier() const; /* ------------------------------------------------------------------------ */ /* Request handling */ /* ------------------------------------------------------------------------ */ bool test(CommunicationRequest & request) const; bool testAll(std::vector & request) const; void wait(CommunicationRequest & request) const; void waitAll(std::vector & requests) const; UInt waitAny(std::vector & requests) const; inline void freeCommunicationRequest(CommunicationRequest & request) const; inline void freeCommunicationRequest(std::vector & requests) const; template inline void receiveAnyNumber(std::vector & send_requests, MsgProcessor && processor, Int tag) const; protected: template void sendImpl(const T * buffer, Int size, Int receiver, Int tag, const CommunicationMode & mode = CommunicationMode::_auto) const; template void receiveImpl(T * buffer, Int size, Int sender, Int tag) const; template CommunicationRequest asyncSendImpl( const T * buffer, Int size, Int receiver, Int tag, const CommunicationMode & mode = CommunicationMode::_auto) const; template CommunicationRequest asyncReceiveImpl(T * buffer, Int size, Int sender, Int tag) const; template void allReduceImpl(T * values, int nb_values, const SynchronizerOperation & op) const; template void allGatherImpl(T * values, int nb_values) const; template void allGatherVImpl(T * values, int * nb_values) const; template void reduceImpl(T * values, int nb_values, const SynchronizerOperation & op, int root = 0) const; template void gatherImpl(T * values, int nb_values, int root = 0) const; template void gatherImpl(T * values, int nb_values, T * gathered, int nb_gathered = 0) const; template void gatherVImpl(T * values, int * nb_values, int root = 0) const; template void broadcastImpl(T * values, int nb_values, int root = 0) const; /* ------------------------------------------------------------------------ */ /* Accessors */ /* ------------------------------------------------------------------------ */ public: Int getNbProc() const { return psize; }; Int whoAmI() const { return prank; }; static Communicator & getStaticCommunicator(); static Communicator & getStaticCommunicator(int & argc, char **& argv); int getMaxTag() const; int getMinTag() const; AKANTU_GET_MACRO(CommunicatorData, (*communicator_data), decltype(auto)); /* ------------------------------------------------------------------------ */ /* Class Members */ /* ------------------------------------------------------------------------ */ private: static std::unique_ptr static_communicator; protected: Int prank{0}; Int psize{1}; std::unique_ptr communicator_data; }; inline std::ostream & operator<<(std::ostream & stream, const CommunicationRequest & _this) { _this.printself(stream); return stream; } } // namespace akantu #include "communicator_inline_impl.hh" #endif /* __AKANTU_STATIC_COMMUNICATOR_HH__ */