ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4MPIutils.hh
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4MPIutils.hh
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 // Utility functions for MPI G4 interface
27 #ifndef G4MPIUTILS_HH
28 #define G4MPIUTILS_HH
29 #include <map>
30 #include <vector>
31 #include <functional>
32 #include <numeric>
33 
34 //Namespace with some utility functions for G4 MPI integration.
35 //Main utilities:
36 // G4mpi::Merge(...) : Merge results via a semi-optimized communication
37 // patterns between ranks. Note that this implementation
38 // is not topology aware. This means that MPI_Reduce and
39 // MPI_Gather are more performant. However if you cannot
40 // implement an appropriate MPI reducer or you cannot efford
41 // the memory overhead of Gather, this can be used instead of
42 // p2p communications.
43 namespace G4mpi {
44  //Simple data type representing a rank
45  typedef unsigned int rank_t;
46  //A couple of sending/receiving ranks
47  typedef std::pair<rank_t,rank_t> couple_t;
48  //This map represent, for each cycle (key) a set of communications
49  //pairs
50  typedef std::map<int,std::vector<couple_t> > commMap_t;
51 
52  //This function takes as input a vector of rank_t objects representing
53  //a communication node identified by an ID (rank:int).
54  //It returns a map of cycle:int -> vector<pairs<rank_t> >
55  //Representing a sequence of communciation cycles. At each communication cycle
56  //one or more p2p communications are established: in the pair the first element
57  //is the sender and the second element of the pair is the receiver
58  //At the end of the cycles all communications have been done to rank 0
59  //For example with 4 nodes: [0,1,2,3] we have:
60  // Cycle 0: (3->2),(1->0)
61  // Cycle 1: (2->0)
62  // With 5 nodes:
63  // Cycle 0: (4->3),(2->1)
64  // Cycle 1: (3->1)
65  // Cycle 2: (1->0)
66  // The algorithm can be used to implement a communication across mpi ranks
67  // optimizing the network trafic. Each rank (the nodes) can send/receive to another node.
68  // Once they have sent out the payload they become empty and non-active anymore.
69  commMap_t buildCommunicationMap( std::vector<rank_t>& input );
70 
71  //Performs merging to rank 0 using the provided sender, receiver and barrier functions.
72  //CommSize is the size of the communicator and myrank is the rank of the caller
73  //For example: assume a class UserMerger has two members Send(uint) and
74  // Receive(uint) and we are using a MPI::Intracomm object as
75  // communicator, then to use this function the ranks can:
76  // using std::placeholers::_1;
77  // std::function<void(unsigned int)> sender =
78  // std::bind(&Merger::Send,&mergerInst,_1);
79  // std::function<void(unsigned int)> receiver =
80  // std::bind(&Merger::Receiver,&mergerInst,_1);
81  // std::function<void(void)> barrier =
82  // std::bind(&MPI::Intracomm::Barrier,&commInst);
83  // G4mpi::Merge(sender,receiver,barrier,commSize,myrank);
84  void Merge( std::function<void(unsigned int)> senderF ,
85  std::function<void(unsigned int)> receiverF ,
86  std::function<void(void)> barrierF ,
87  unsigned int commSize , unsigned int myrank);
88  //Type representing a merging functions
89  typedef std::function<void(std::function<void(unsigned int)>,
90  std::function<void(unsigned int)>,
91  std::function<void(void)>,
92  unsigned int, unsigned int)>
94 }
95 
96 #endif //G4MPIUTILS_HH