TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Comm_Group.h
1/****************************************************************************
2* Copyright (c) 2026, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#ifndef Comm_Group_included
17#define Comm_Group_included
18
19#include <TRUST_Deriv.h>
20#include <TRUSTArray.h>
21#include <assert.h>
22
23/*! @brief : This class describes a group of processors on which
24 *
25 * a portion of code executes simultaneously. It provides all the methods
26 * for exchanging data between the processors of the group (mpsum, send, recv, ...),
27 * and for synchronizing processors (barrier).
28 * It is specialized according to the network layer (MPI, PVM, ...).
29 * Note: these methods are reserved for low-level operations (TRUST kernel).
30 * In normal code, use the high-level communication class methods:
31 * (envoyer(), envoyer_broadcast(), class Schema_Comm, class Process, etc.)
32 * To create a new group and use it, see class PE_Groups.
33 * For the initialization procedure, see PE_Groups::Initialize().
34 *
35 */
36class Comm_Group : public Objet_U
37{
38 Declare_base_sans_constructeur_ni_destructeur(Comm_Group);
39public:
40 Comm_Group();
41 ~Comm_Group() override;
42 virtual void abort() const = 0;
43
44 // COLL_SUM: sum over all procs
45 // COLL_MIN: minimum
46 // COLL_MAX: max
47 // COLL_PARTIAL_SUM computes the partial sum of values over processors with rank
48 // strictly less than me() (the result is always 0 on processor 0).
50 virtual void mp_collective_op(const double *x, double *resu, int n, Collective_Op op) const = 0;
51 virtual void mp_collective_op(const double *x, double *resu, const Collective_Op *op, int n) const = 0;
52 virtual void mp_collective_op(const float *x, float *resu, int n, Collective_Op op) const = 0;
53 virtual void mp_collective_op(const float *x, float *resu, const Collective_Op *op, int n) const = 0;
54 virtual void mp_collective_op(const int *x, int *resu, int n, Collective_Op op) const = 0;
55 virtual void mp_collective_op(const int *x, int *resu, const Collective_Op *op, int n) const = 0;
56#if INT_is_64_ == 2
57 virtual void mp_collective_op(const trustIdType *x, trustIdType *resu, int n, Collective_Op op) const = 0;
58 virtual void mp_collective_op(const trustIdType *x, trustIdType *resu, const Collective_Op *op, int n) const = 0;
59#endif
60
61 virtual void barrier(int tag) const = 0;
62
63 // Computes a new communication tag that allows identifying exchanges
64 // uniquely across all groups.
65 inline int get_new_tag() const;
66
67 inline int rank() const;
68 inline int nproc() const;
69
70 inline int get_node_id() const;
71 inline int get_number_of_nodes() const;
72
73
74 // Do we want to perform additional checks on communications?
75 // These checks imply extra communications, which modifies the program flow.
76 // This is therefore a separate mechanism from "assert".
77 inline static int check_enabled();
78
80 // Starts the exchange of buffers.
81 // send_list / recv_list = list of PEs (ranks within the current group)
82 // send_size / recv_size = size of messages in bytes
83 // send_buffers / recv_buffers = address of buffers
84 // Reception buffers must have sufficient size.
85 // Note about const:
86 // send_buffers is completely const, nothing may be modified
87 // recv_buffers is const, recv_buffers[i] is const but *(recv_buffers[i])
88 // is not const because received data is stored there.
89 virtual void send_recv_start(const ArrOfInt& send_list,
90 const ArrOfInt& send_size,
91 const char * const * const send_buffers,
92 const ArrOfInt& recv_list,
93 const ArrOfInt& recv_size,
94 char * const * const recv_buffers,
95 TypeHint typehint = CHAR) const = 0;
96 // Waits until communications started by send_recv are finished.
97 virtual void send_recv_finish() const = 0;
98
99 // Blocking send/receive methods: each send must be matched
100 // simultaneously by a recv on the destination processor.
101 virtual void send(int pe, const void *buffer, int size, int tag) const = 0; // Blocking send
102 virtual void recv(int pe, void *buffer, int size, int tag) const = 0; // Blocking receive
103
104 // Broadcast methods: must be called on all processors simultaneously
105 virtual void broadcast(void *buffer, int size, int pe_source) const = 0;
106
107 // All-to-all methods
108 virtual void all_to_all(const void *src_buffer, void *dest_buffer, int data_size) const = 0;
109 virtual void all_gather(const void *src_buffer, void *dest_buffer, int data_size) const = 0;
110 virtual void gather(const void *src_buffer, void *dest_buffer, int data_size, int root) const = 0;
111 virtual void all_gatherv(const void *src_buffer, void *dest_buffer, int send_size, const int* recv_size, const int* displs) const = 0;
112
113 static void set_check_enabled(int flag);
114protected:
115 Comm_Group(const Comm_Group&); // forbidden!
116 const Comm_Group& operator=(const Comm_Group&); // forbidden!
117 virtual void init_group(const ArrOfInt& pe_list);
118 void init_group_node(int nproc, int loc_rank, int glob_rank);
119 void init_group_trio(int nproc, int rank);
120 friend class PE_Groups;
121
122 // ToDo gather that in a derived Comm_Group_MPI_Node class ?
123 // id of my node among all the other nodes
124 int node_id_ = -1;
125 // total number of nodes
126 int nb_nodes_ = -1;
127
128private:
129 static int check_enabled_;
130 static int static_group_number_;
131
132 // Rank of the local processor in the group, -1 if it is not in the group
133 int rank_ = -1;
134 // Number of processors in the group
135 int nproc_ = -1;
136 // For each PE in the full computation (array size = groupe_TRUST().nproc())
137 // index within the group if the PE is in it,
138 // -1 if the PE is not in the group
139 ArrOfInt local_ranks_;
140 // List of processors in the group (indices of processors in groupe_TRUST())
141 // (array size = nproc_)
142 ArrOfInt world_ranks_;
143
144 // My group number (equal to static_group_number_ at the time the group was created).
145 int group_number_ = -1;
146 // The group_communication_tag_ is incremented by this amount at each
147 // operation. It is a prime number, which allows different tags
148 // for each group for a long time (until the tag number exceeds MAXINT...).
149 int group_tag_increment_ = -1;
150 // The tag is incremented at each operation, allowing verification that processes are properly synchronized.
151 mutable int group_communication_tag_ = -1;
152};
153
155{
156 return check_enabled_;
157}
158
159/*! @brief Returns a new communication tag for the group.
160 *
161 * Side effect: increments the group_communication_tag_ member.
162 *
163 */
164inline int Comm_Group::get_new_tag() const
165{
166 // B.M. This feature is ultimately of little practical use
167 // and when the counter exceeds a limit, MPI crashes. Disabling:
168 //group_communication_tag_ += group_tag_increment_;
169 return group_communication_tag_;
170}
171
172/*! @brief Returns the rank of the local processor in the group *this.
173 *
174 * or -1 if this processor is not in the group.
175 *
176 */
177inline int Comm_Group::rank() const
178{
179 return rank_;
180}
181
182/*! @brief Returns the number of processors in the group *this
183 *
184 */
185inline int Comm_Group::nproc() const
186{
187 assert(nproc_ >= 0);
188 return nproc_;
189}
190
191/*! @brief Retrieve ID of my numa node
192 *
193 */
194inline int Comm_Group::get_node_id() const
195{
196 return node_id_;
197}
198
200{
201 return nb_nodes_;
202}
203
204
205#endif
static int check_enabled()
Definition Comm_Group.h:154
@ COLL_PARTIAL_SUM
Definition Comm_Group.h:49
virtual void mp_collective_op(const double *x, double *resu, const Collective_Op *op, int n) const =0
virtual void all_gather(const void *src_buffer, void *dest_buffer, int data_size) const =0
static void set_check_enabled(int flag)
virtual void send(int pe, const void *buffer, int size, int tag) const =0
int get_node_id() const
Retrieve ID of my numa node.
Definition Comm_Group.h:194
virtual void send_recv_finish() const =0
int nproc() const
Returns the number of processors in the group *this.
Definition Comm_Group.h:185
virtual void mp_collective_op(const int *x, int *resu, const Collective_Op *op, int n) const =0
virtual void send_recv_start(const ArrOfInt &send_list, const ArrOfInt &send_size, const char *const *const send_buffers, const ArrOfInt &recv_list, const ArrOfInt &recv_size, char *const *const recv_buffers, TypeHint typehint=CHAR) const =0
int rank() const
Returns the rank of the local processor in the group *this.
Definition Comm_Group.h:177
friend class PE_Groups
Definition Comm_Group.h:120
virtual void all_gatherv(const void *src_buffer, void *dest_buffer, int send_size, const int *recv_size, const int *displs) const =0
const Comm_Group & operator=(const Comm_Group &)
Assignment is forbidden!
virtual void broadcast(void *buffer, int size, int pe_source) const =0
virtual void abort() const =0
virtual void mp_collective_op(const float *x, float *resu, const Collective_Op *op, int n) const =0
virtual void mp_collective_op(const float *x, float *resu, int n, Collective_Op op) const =0
virtual void mp_collective_op(const double *x, double *resu, int n, Collective_Op op) const =0
virtual void all_to_all(const void *src_buffer, void *dest_buffer, int data_size) const =0
virtual void barrier(int tag) const =0
void init_group_node(int nproc, int loc_rank, int glob_rank)
Initialize all the information relative to world sizes and ranks for node communicator.
virtual void init_group(const ArrOfInt &pe_list)
This function must be called simultaneously by all PEs of the current_group with the same parameters.
virtual void mp_collective_op(const int *x, int *resu, int n, Collective_Op op) const =0
virtual void recv(int pe, void *buffer, int size, int tag) const =0
int get_number_of_nodes() const
Definition Comm_Group.h:199
virtual void gather(const void *src_buffer, void *dest_buffer, int data_size, int root) const =0
~Comm_Group() override
Destructor (nothing to do for now).
void init_group_trio(int nproc, int rank)
Initializes groupe_TRUST().
int get_new_tag() const
Returns a new communication tag for the group.
Definition Comm_Group.h:164
Objet_U()
Default constructor: assigns a unique identifier to the object (object_id_) and registers the object ...
Definition Objet_U.cpp:54