Skip to content
Snippets Groups Projects
Select Git revision
  • 067d0fa4624b166c6c2eeff3b2048e590cb4c952
  • develop default protected
  • feature/variational-hydro
  • origin/stage/bouguettaia
  • feature/gmsh-reader
  • feature/reconstruction
  • save_clemence
  • feature/kinetic-schemes
  • feature/local-dt-fsi
  • feature/composite-scheme-sources
  • feature/composite-scheme-other-fluxes
  • feature/serraille
  • feature/composite-scheme
  • hyperplastic
  • feature/polynomials
  • feature/gks
  • feature/implicit-solver-o2
  • feature/coupling_module
  • feature/implicit-solver
  • feature/merge-local-dt-fsi
  • master protected
  • v0.5.0 protected
  • v0.4.1 protected
  • v0.4.0 protected
  • v0.3.0 protected
  • v0.2.0 protected
  • v0.1.0 protected
  • Kidder
  • v0.0.4 protected
  • v0.0.3 protected
  • v0.0.2 protected
  • v0 protected
  • v0.0.1 protected
33 results

MeshVariant.hpp

Blame
  • Messenger.cpp 4.55 KiB
    #include <Messenger.hpp>
    #include <PastisOStream.hpp>
    
    #include <pastis_config.hpp>
    
    #ifdef PASTIS_HAS_MPI
    #include <mpi.h>
    #endif // PASTIS_HAS_MPI
    
    Messenger* Messenger::m_instance = nullptr;
    
    void Messenger::create(int& argc, char* argv[])
    {
      if (Messenger::m_instance == nullptr) {
        Messenger::m_instance = new Messenger(argc, argv);
      } else {
        std::cerr << "Messenger already created\n";
        std::exit(1);
      }
    }
    
    void Messenger::destroy()
    {
      // One allows multiple destruction to handle unexpected code exit
      if (Messenger::m_instance != nullptr) {
        delete Messenger::m_instance;
        Messenger::m_instance = nullptr;
      }
    }
    
    Messenger::
    Messenger(int& argc, char* argv[])
    {
    #ifdef PASTIS_HAS_MPI
      MPI_Init(&argc, &argv);
      MPI_Comm_rank(MPI_COMM_WORLD, &m_rank);
      MPI_Comm_size(MPI_COMM_WORLD, &m_size);
    
      if (m_rank != 0) {
        pout.setOutput(null_stream);
        perr.setOutput(null_stream);
      }
    #endif // PASTIS_HAS_MPI
    }
    
    Messenger::
    ~Messenger()
    {
    #ifdef PASTIS_HAS_MPI
      MPI_Finalize();
    #endif // PASTIS_HAS_MPI
    }
    
    void Messenger::barrier() const
    {
    #ifdef PASTIS_HAS_MPI
      MPI_Barrier(MPI_COMM_WORLD);
    #endif // PASTIS_HAS_MPI
    }
    
    Array<int> Messenger::
    _allGather(int& data) const
    {
      Array<int> gather(m_size);
    
    #ifdef PASTIS_HAS_MPI
      MPI_Allgather(&data, 1,  MPI_INT, &(gather[0]), 1,  MPI_INT,
                    MPI_COMM_WORLD);
    #else // PASTIS_HAS_MPI
      gather[0] = data;
    #endif // PASTIS_HAS_MPI
    
      return gather;
    }
    
    Array<int> Messenger::
    _allToAll(const Array<int>& sent_array, Array<int>& recv_array) const
    {
    #ifdef PASTIS_HAS_MPI
      Assert(sent_array.size() == m_size);
      Assert(recv_array.size() == m_size);
    
      MPI_Alltoall(&(sent_array[0]), 1, MPI_INT,
                   &(recv_array[0]), 1, MPI_INT,
                   MPI_COMM_WORLD);
    #else  // PASTIS_HAS_MPI
      recv_array = copy(sent_array);
    #endif // PASTIS_HAS_MPI
      return recv_array;
    }
    
    
    int Messenger::
    _broadcast(int& data, int root_rank) const
    {
    #ifdef PASTIS_HAS_MPI
      MPI_Bcast(&data, 1,  MPI_INT, root_rank, MPI_COMM_WORLD);
    #endif // PASTIS_HAS_MPI
      return data;
    }
    
    
    Array<int> Messenger::
    _broadcast(Array<int>& array, int root_rank) const
    {
    #ifdef PASTIS_HAS_MPI
      int size = array.size();
      _broadcast(size, root_rank);
      if (commRank() != root_rank) {
        array = Array<int>(size);
      }
      MPI_Bcast(&(array[0]), array.size(), MPI_INT, root_rank, MPI_COMM_WORLD);
    #endif // PASTIS_HAS_MPI
      return array;
    }
    
    template <typename DataType>
    void Messenger::
    _exchange(const std::vector<Array<DataType>>& sent_array_list,
              std::vector<Array<std::remove_const_t<DataType>>>& recv_array_list) const
    {
    #ifdef PASTIS_HAS_MPI
      std::vector<MPI_Request> request_list;
    
      MPI_Datatype type = [&] () -> MPI_Datatype {
                    if constexpr (std::is_same_v<int,std::remove_const_t<DataType>>) {
                      return MPI_INT;
                    } else if constexpr (std::is_same_v<CellType,std::remove_const_t<DataType>>) {
                      return MPI_SHORT;
                    }
                  } ();
      for (size_t i_send=0; i_send<sent_array_list.size(); ++i_send) {
        const Array<DataType> sent_array = sent_array_list[i_send];
        if (sent_array.size()>0) {
          MPI_Request request;
          MPI_Isend(&(sent_array[0]), sent_array.size(), type, i_send, 0, MPI_COMM_WORLD, &request);
          request_list.push_back(request);
        }
      }
    
      for (size_t i_recv=0; i_recv<recv_array_list.size(); ++i_recv) {
        Array<std::remove_const_t<DataType>> recv_array = recv_array_list[i_recv];
        if (recv_array.size()>0) {
          MPI_Request request;
          MPI_Irecv(&(recv_array[0]), recv_array.size(), type, i_recv, 0, MPI_COMM_WORLD, &request);
          request_list.push_back(request);
        }
      }
    
      std::vector<MPI_Status> status_list(request_list.size());
      if (MPI_SUCCESS != MPI_Waitall(request_list.size(), &(request_list[0]), &(status_list[0]))) {
        std::cerr << "Communication error!\n";
        std::exit(1);
      }
    
    #else // PASTIS_HAS_MPI
      std::cerr << "NIY\n";
      std::exit(1);
    #endif // PASTIS_HAS_MPI
    }
    
    template
    void Messenger::_exchange(const std::vector<Array<int>>& sent_array_list,
                              std::vector<Array<int>>& recv_array_list) const;
    template
    void Messenger::_exchange(const std::vector<Array<const int>>& sent_array_list,
                              std::vector<Array<int>>& recv_array_list) const;
    
    template
    void Messenger::_exchange(const std::vector<Array<CellType>>& sent_array_list,
                              std::vector<Array<CellType>>& recv_array_list) const;
    template
    void Messenger::_exchange(const std::vector<Array<const CellType>>& sent_array_list,
                              std::vector<Array<CellType>>& recv_array_list) const;