#ifndef MESSENGER_HPP #define MESSENGER_HPP #include <PastisMacros.hpp> #include <PastisAssert.hpp> #include <Array.hpp> class Messenger { private: static Messenger* m_instance; Messenger(int& argc, char* argv[]); int m_rank{0}; int m_size{1}; Array<int> _broadcast(Array<int>& array, int root_rank) const; public: static void create(int& argc, char* argv[]); static void destroy(); PASTIS_INLINE static Messenger& getInstance() { Assert(m_instance != nullptr); return *m_instance; } PASTIS_INLINE const int& rank() const { return m_rank; } PASTIS_INLINE const int& size() const { return m_size; } void barrier() const; template <typename DataType> PASTIS_INLINE Array<DataType> broadcast(const Array<DataType>& array, int root_rank) const { if constexpr(std::is_same<DataType, int>()) { Array<int> int_array = array; return _broadcast(int_array, root_rank); } else { static_assert(std::is_same<DataType, int>(), "unexpected type of data"); } } Messenger(const Messenger&) = delete; ~Messenger(); }; PASTIS_INLINE const Messenger& messenger() { return Messenger::getInstance(); } [[deprecated("use better name")]] PASTIS_INLINE const int& commRank() { return messenger().rank(); } [[deprecated("use better name")]] PASTIS_INLINE const int& commSize() { return messenger().size(); } PASTIS_INLINE void barrier() { return messenger().barrier(); } template <typename DataType> PASTIS_INLINE Array<DataType> broadcast(const Array<DataType>& array, int root_rank) { return messenger().broadcast(array, root_rank); } #endif // MESSENGER_HPP