Line data Source code
1 : // SPDX-FileCopyrightText: 2024 Daniel Abele <daniel.abele@dlr.de> 2 : // 3 : // SPDX-License-Identifier: BSD-3-Clause 4 : 5 : #pragma once 6 : 7 : #include "mpi.h" 8 : #include <string> 9 : 10 : namespace ipc 11 : { 12 : 13 : /** 14 : * RAII class for initializing and finalizing MPI. 15 : * On construction initializes MPI. 16 : * On destruction finalizes MPI. 17 : */ 18 : class [[nodiscard]] MpiInit 19 : { 20 : public: 21 : /** 22 : * Initialize MPI if not initialized yet. 23 : */ 24 3 : [[nodiscard]] MpiInit(int* argc, char*** argv) : m_is_initialized(0) 25 : { 26 3 : MPI_Initialized(&m_is_initialized); 27 3 : if (!m_is_initialized) 28 : { 29 3 : MPI_Init(argc, argv); 30 : } 31 3 : } 32 : 33 : /** 34 : * Finalize MPI if it was initialized by this object. 35 : */ 36 3 : ~MpiInit() 37 : { 38 3 : if (!m_is_initialized) 39 : { 40 3 : MPI_Finalize(); 41 : } 42 3 : } 43 : 44 : private: 45 : int m_is_initialized; 46 : }; 47 : 48 : /** 49 : * Get the rank of the MPI process. 50 : */ 51 249 : inline int mpi_rank(MPI_Comm comm) 52 : { 53 : int rank; 54 249 : MPI_Comm_rank(comm, &rank); 55 249 : return rank; 56 : } 57 : 58 : /** 59 : * Split a communicator based on the given category. 60 : */ 61 0 : inline MPI_Comm split_comm(MPI_Comm comm, const std::string& category) 62 : { 63 0 : auto hash_fnv1a = [](const std::string& str) 64 : { 65 0 : uint32_t hash = 2166136261; 66 0 : for (auto&& c : str) 67 : { 68 0 : hash ^= c; 69 0 : hash *= 16777619; 70 : } 71 0 : return hash; 72 : }; 73 : 74 : MPI_Comm new_comm; 75 0 : auto comm_key = std::abs(int(hash_fnv1a(category))); 76 0 : MPI_Comm_split(comm, comm_key, 0, &new_comm); 77 0 : return new_comm; 78 : } 79 : 80 : } // namespace ipc