TrioCFD 1.9.8
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 : Cette classe decrit un groupe de processeurs sur lesquels
24 *
25 * une portion de code s'execute simultanement. Elle fournit
26 * toutes les methodes permettant d'echanger des donnees entre
27 * les processeurs du groupe (mpsum, send, recv, ...),
28 * et de synchroniser les processeurs (barrier).
29 * Elle est specialisee selon le support reseau (MPI, PVM, ...)
30 * Attention, ces methodes sont reservees a des operations de bas niveau
31 * (noyau TRUST).
32 * Dans le code courant, il faut utiliser les methodes classes de communications
33 * de haut niveau :
34 * (envoyer(), envoyer_broadcast(), class Schema_Comm, class Process, etc)
35 * Pour creer un nouveau groupe et l'utiliser, voir class PE_Groups
36 * Pour la procedure d'initialisation, voir PE_Groups::Initialize()
37 *
38 */
39class Comm_Group : public Objet_U
40{
41 Declare_base_sans_constructeur_ni_destructeur(Comm_Group);
42public:
43 Comm_Group();
44 ~Comm_Group() override;
45 virtual void abort() const = 0;
46
47 // COLL_SUM: somme sur tous les procs
48 // COLL_MIN: minimum
49 // COLL_MAX: max
50 // COLL_PARTIAL_SUM calcule la somme partielle des valeurs sur les processeurs de rang
51 // strictement inferieurs a me() (le resultat vaut toujours 0 sur le processeur 0).
53 virtual void mp_collective_op(const double *x, double *resu, int n, Collective_Op op) const = 0;
54 virtual void mp_collective_op(const double *x, double *resu, const Collective_Op *op, int n) const = 0;
55 virtual void mp_collective_op(const float *x, float *resu, int n, Collective_Op op) const = 0;
56 virtual void mp_collective_op(const float *x, float *resu, const Collective_Op *op, int n) const = 0;
57 virtual void mp_collective_op(const int *x, int *resu, int n, Collective_Op op) const = 0;
58 virtual void mp_collective_op(const int *x, int *resu, const Collective_Op *op, int n) const = 0;
59#if INT_is_64_ == 2
60 virtual void mp_collective_op(const trustIdType *x, trustIdType *resu, int n, Collective_Op op) const = 0;
61 virtual void mp_collective_op(const trustIdType *x, trustIdType *resu, const Collective_Op *op, int n) const = 0;
62#endif
63
64 virtual void barrier(int tag) const = 0;
65
66 // Calcule un nouveau tag de communication qui permet d'identifier les
67 // echanges de facon unique pour l'ensemble des groupes.
68 inline int get_new_tag() const;
69
70 inline int rank() const;
71 inline int nproc() const;
72
73 inline int get_node_id() const;
74 inline int get_number_of_nodes() const;
75
76
77 // Veut-on faire des verifications supplementaires sur les communications ?
78 // Ces verifications impliquent des communications en plus, ce qui modifie
79 // le deroulement du programme. C'est donc un mecanisme separe des "assert".
80 inline static int check_enabled();
81
83 // Demarre l'echange des buffers.
84 // send_list / recv_list = liste de PEs (rangs dans le groupe courant)
85 // send_size / recv_size = taille des messages en bytes
86 // send_buffers / recv_buffers = adresse des buffers
87 // Les buffers en reception doivent avoir une taille suffisante.
88 // Note au sujet des const :
89 // send_buffers est completement const, on n'a le droit de rien modifier
90 // recv_buffers est const, recv_buffers[i] est const mais *(recv_buffers[i])
91 // n'est pas const car on y stocke les donnees recues.
92 virtual void send_recv_start(const ArrOfInt& send_list,
93 const ArrOfInt& send_size,
94 const char * const * const send_buffers,
95 const ArrOfInt& recv_list,
96 const ArrOfInt& recv_size,
97 char * const * const recv_buffers,
98 TypeHint typehint = CHAR) const = 0;
99 // Attend que les communications lancees par send_recv soient terminees.
100 virtual void send_recv_finish() const = 0;
101
102 // Methodes d'envoi / reception blocantes: a chaque send doit correpondre
103 // simultanement un recv sur le processeur destination.
104 virtual void send(int pe, const void *buffer, int size, int tag) const = 0; // Envoi bloquant
105 virtual void recv(int pe, void *buffer, int size, int tag) const = 0; // Reception bloquante
106
107 // Methodes de broadcast : a appeler sur tous les processeurs en meme temps
108 virtual void broadcast(void *buffer, int size, int pe_source) const = 0;
109
110 // Methodes all_to_all
111 virtual void all_to_all(const void *src_buffer, void *dest_buffer, int data_size) const = 0;
112 virtual void all_gather(const void *src_buffer, void *dest_buffer, int data_size) const = 0;
113 virtual void gather(const void *src_buffer, void *dest_buffer, int data_size, int root) const = 0;
114 virtual void all_gatherv(const void *src_buffer, void *dest_buffer, int send_size, const int* recv_size, const int* displs) const = 0;
115
116 static void set_check_enabled(int flag);
117protected:
118 Comm_Group(const Comm_Group&); // interdit !
119 const Comm_Group& operator=(const Comm_Group&); // interdit !
120 virtual void init_group(const ArrOfInt& pe_list);
121 void init_group_node(int nproc, int loc_rank, int glob_rank);
122 void init_group_trio(int nproc, int rank);
123 friend class PE_Groups;
124
125 // ToDo gather that in a derived Comm_Group_MPI_Node class ?
126 // id of my node among all the other nodes
127 int node_id_ = -1;
128 // total number of nodes
129 int nb_nodes_ = -1;
130
131private:
132 static int check_enabled_;
133 static int static_group_number_;
134
135 // Rang du processeur local dans le groupe, -1 s'il n'est pas dans le groupe
136 int rank_ = -1;
137 // Nombre de processeurs dans le groupe
138 int nproc_ = -1;
139 // Pour chaque pe du calcul complet (taille du tableau = groupe_TRUST().nproc())
140 // indice au sein du groupe si le pe est dedans,
141 // -1 si le pe n'est pas dans le groupe
142 ArrOfInt local_ranks_;
143 // Liste des processeurs du groupes (indices des processeurs dans groupe_TRUST())
144 // (taille du tableau = nproc_)
145 ArrOfInt world_ranks_;
146
147 // Mon numero de groupe (egal au static_group_number_ au moment de la
148 // creation du groupe).
149 int group_number_ = -1;
150 // On incremente le group_communication_tag_ de cette quantite a chaque
151 // operation. C'est un nombre premier, ce qui permet d'avoir des tags
152 // differents pour chaque groupe pendant un bon bout de temps (jusqu'a ce
153 // que le numero de tag depasse MAXINT...)
154 int group_tag_increment_ = -1;
155 // On incremente le tag a chaque operation, ce qui permet de verifier que les processus sont bien synchronises.
156 mutable int group_communication_tag_ = -1;
157};
158
160{
161 return check_enabled_;
162}
163
164/*! @brief Cette fonction renvoie un nouveau tag de communication pour le groupe.
165 *
166 * Effet de bord : incremente le membre group_communication_tag_.
167 *
168 */
169inline int Comm_Group::get_new_tag() const
170{
171 // B.M. Cette fonctionnalite est finalement tres peu utile en pratique
172 // et quand le compteur depasse une limite ca plante mpi. Je desactive:
173 //group_communication_tag_ += group_tag_increment_;
174 return group_communication_tag_;
175}
176
177/*! @brief Renvoie le rang du processeur local dans le groupe *this.
178 *
179 * ou -1 si je ne suis pas dans le groupe.
180 *
181 */
182inline int Comm_Group::rank() const
183{
184 return rank_;
185}
186
187/*! @brief Renvoie le nombre de processeurs dans le groupe *this
188 *
189 */
190inline int Comm_Group::nproc() const
191{
192 assert(nproc_ >= 0);
193 return nproc_;
194}
195
196/*! @brief Retrieve ID of my numa node
197 *
198 */
199inline int Comm_Group::get_node_id() const
200{
201 return node_id_;
202}
203
205{
206 return nb_nodes_;
207}
208
209
210#endif
static int check_enabled()
Definition Comm_Group.h:159
@ COLL_PARTIAL_SUM
Definition Comm_Group.h:52
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:199
virtual void send_recv_finish() const =0
int nproc() const
Renvoie le nombre de processeurs dans le groupe *this.
Definition Comm_Group.h:190
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
Renvoie le rang du processeur local dans le groupe *this.
Definition Comm_Group.h:182
friend class PE_Groups
Definition Comm_Group.h:123
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 &)
La copie est interdite !
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)
Cette fonction doit etre appelee simultanement par tous les PEs du groupe current_group avec les meme...
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:204
virtual void gather(const void *src_buffer, void *dest_buffer, int data_size, int root) const =0
~Comm_Group() override
Destructeur (pour l'instant, rien a faire).
void init_group_trio(int nproc, int rank)
Initialise le groupe_TRUST().
int get_new_tag() const
Cette fonction renvoie un nouveau tag de communication pour le groupe.
Definition Comm_Group.h:169
Objet_U()
Constructeur par defaut : attribue un numero d'identifiant unique a l'objet (object_id_),...
Definition Objet_U.cpp:55