TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Schema_Comm.cpp
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#include <Schema_Comm.h>
16#include <PE_Groups.h>
17#include <InOutCommBuffers.h>
18#include <Comm_Group.h>
19#include <communications.h>
20#include <Comm_Group_MPI.h>
21
22// ====================================================================
23// class Schema_Comm
24// ====================================================================
25
27InOutCommBuffers Schema_Comm::buffers_;
28int Schema_Comm::n_buffers_ = 0;
29
30/*! @brief Accesseur a un membre du tableau obuffers_ (avec verification)
31 *
32 */
34{
35 assert(pe >= 0 && pe < n_buffers_);
36 return buffers_.obuffers_[pe];
37}
38
39/*! @brief Accesseur a un membre du tableau ebuffers_ (avec verification)
40 *
41 */
43{
44 assert(pe >= 0 && pe < n_buffers_);
45 return buffers_.ebuffers_[pe];
46}
47
48//static const int SET_GROUP_TAG = 0;
49static const int BEGIN_COMM_TAG = 1;
50static const int ECHANGE_MESSAGES_COMM_TAG = 2;
51static const int END_COMM_TAG = 3;
52static const int COPY_OPERATOR_TAG = 4;
53//static const int CHECK_SEND_RCV_TAG = 5;
54
55/*! @brief Construction d'un nouveau schema de communication.
56 *
57 */
59{
60
61
62 me_to_me_ = 0;
64 // Pour verifier plus tard qu'on est toujours dans le bon groupe,
65 // on conserve une ref au groupe courant.
66 ref_group_ = PE_Groups::current_group();
68 {
69 n_buffers_ = Process::nproc();
70 buffers_.obuffers_ = new OutputCommBuffer[n_buffers_];
71 buffers_.ebuffers_ = new InputCommBuffer[n_buffers_];
72 status_ = RESET;
73 }
74}
75
76/*! @brief Destruction d'un schema de communication.
77 *
78 */
82
83/*! @brief Constructeur par copie (nouveau schema place en mode RESET).
84 *
85 * Attention : tous les membres du Comm_Group doivent executer
86 * cette fonction simultanement.
87 *
88 */
90{
91
92
93 operator= (schema);
94}
95
96/*! @brief Operateur copie : on copie la liste des processeurs qui communiquent.
97 *
98 * Le nouveau schema est place dans l'etat RESET.
99 * Attention : tous les membres du Comm_Group doivent executer
100 * cette fonction simultanement.
101 *
102 */
104{
105 assert(status_ == RESET);
106 ref_group_ = schema.ref_group_;
107 assert(&(ref_group_.valeur()) == &PE_Groups::current_group());
110 me_to_me_ = schema.me_to_me_;
112 const Comm_Group& group = ref_group_.valeur();
113 if (group.check_enabled()) group.barrier(COPY_OPERATOR_TAG);
114 return *this;
115}
116
117/*! @brief Methode obsolete, le groupe associe au schema est le groupe courant au moment ou on cree le schema.
118 *
119 * L'appel a cette methode
120 * n'est valide qu'avec le meme groupe que le groupe d'origine.
121 * La methode ne fait rien.
122 *
123 */
125{
126 assert(&group == &(ref_group_.valeur()));
127 assert(&group == &PE_Groups::current_group());
128}
129
130/*! @brief Renvoie le groupe auquel est associe le schema.
131 *
132 */
134{
135 assert(ref_group_);
136 return ref_group_.valeur();
137}
138
139/*! @brief Definit la liste des processeurs a qui on va envoyer et de qui on va recevoir des donnees.
140 *
141 * Si me_to_me est non nul, on autorise l'envoi des messages a soi-meme,
142 * sinon non (argument optionnel : par defaut, me_to_me=0)
143 *
144 */
145void Schema_Comm::set_send_recv_pe_list(const ArrOfInt& send_pe_list,
146 const ArrOfInt& recv_pe_list,
147 const int me_to_me)
148{
149 assert(status_ == RESET);
150 send_pe_list_ = send_pe_list;
151 recv_pe_list_ = recv_pe_list;
152 me_to_me_ = me_to_me;
153 // Verification du principe "tu m'ecoutes quand je te parle"
154 const Comm_Group& group = ref_group_.valeur();
155 assert(&group == &PE_Groups::current_group());
157}
158
159/*! @brief Reserve les buffers de comm pour une nouvelle communication.
160 *
161 * Le schema passe de RESET a WRITING, on a maintenant le droit
162 * d'appeler send_buffer(). Interdiction d'appeler a nouveau begin_comm
163 * sur tous les objets de comm avant d'avoir fini cette communication
164 * avec end_comm().
165 *
166 */
168{
169 // On verifie qu'une autre communication n'est pas en cours.
170 assert (status_ == RESET && ref_group_);
172 // On verifie que tous les membres du groupe executent ceci.
173 // Si ca plante ici, c'est que tous les membres declares ne sont
174 // pas en train de faire la barriere.
175 const Comm_Group& group = ref_group_.valeur();
176 assert(&group == &PE_Groups::current_group());
177 if (group.check_enabled()) group.barrier(BEGIN_COMM_TAG);
178}
179
180static void exchange_data(const ArrOfInt& send_list,
181 const ArrOfInt& send_size,
182 const char * const * const send_buffers,
183 const ArrOfInt& recv_list,
184 const ArrOfInt& recv_size,
185 char * const * const recv_buffers,
186 const Comm_Group& group,
187 bool use_all_to_all)
188{
189// GF je rajoute le ifdef pour les versions sans MPI comm_group_mpi n'existep pas
190#ifdef MPI_
191 if (!use_all_to_all || !sub_type(Comm_Group_MPI, group))
192#else
193 //if (!use_all_to_all || !sub_type(Comm_Group_MPI, group))
194 // on n utilise pas le all_to_all car n'exsite pas sans MPI
195 if (1)
196#endif
197 {
198 group.send_recv_start(send_list, send_size, send_buffers,
199 recv_list, recv_size, recv_buffers);
200 group.send_recv_finish();
201 }
202 else
203 {
204#ifdef MPI_
205 const int n = group.nproc();
206 const int nsend = send_list.size_array();
207 const int nrecv = recv_list.size_array();
208 // Pack all send data in a single buffer:
209 ArrOfInt a_send_size(n);
210 ArrOfInt a_send_offset(n);
211 ArrOfInt a_recv_size(n);
212 ArrOfInt a_recv_offset(n);
213 int i, offset;
214 // Compute send_size array
215 for (i = 0; i < nsend; i++)
216 a_send_size[send_list[i]] = send_size[i];
217 // Compute send_offset
218 for (i = 0, offset = 0; i < n; i++)
219 {
220 a_send_offset[i] = offset;
221 offset += a_send_size[i];
222 }
223 const int buf_size_send = offset;
224 // Compute recv_size array
225 for (i = 0; i < nrecv; i++)
226 a_recv_size[recv_list[i]] = recv_size[i];
227 // Compute recv_offset
228 for (i = 0, offset = 0; i < n; i++)
229 {
230 a_recv_offset[i] = offset;
231 offset += a_recv_size[i];
232 }
233 const int buf_size_recv = offset;
234 // Allocate contiguous send and recv buffer:
235 char *send_buffer = (char *) malloc(buf_size_send);
236 char *recv_buffer = (char *) malloc(buf_size_recv);
237 // Copy send data to send buffer
238 for (i = 0; i < nsend; i++)
239 memcpy(send_buffer + a_send_offset[send_list[i]], // dest
240 send_buffers[i], // source
241 send_size[i]); // size
242 // Exchange data
243 ref_cast(Comm_Group_MPI, group).all_to_allv(send_buffer, a_send_size.addr(), a_send_offset.addr(),
244 recv_buffer, a_recv_size.addr(), a_recv_offset.addr());
245 // Copy recv data to recv_buffers
246 for (i = 0; i < nrecv; i++)
247 memcpy(recv_buffers[i], // dest
248 recv_buffer + a_recv_offset[recv_list[i]], // source
249 recv_size[i]); // size
250 // [ABN] arrruhhhhhmmmmmm:
251 free(send_buffer);
252 free(recv_buffer);
253#endif
254 }
255}
256
257/*! @brief Transmet la taille des messages a envoyer aux processeurs qui vont les recevoir.
258 *
259 * La taille est le nombre de bytes des obuffers.
260 * send_pe_list et recv_pe_list doivent etre initialises.
261 * Le schema doit etre dans l'etat WRITING.
262 *
263 */
264void Schema_Comm::echange_taille(const ArrOfInt& send_size,
265 ArrOfInt& recv_size) const
266{
267 static ArrOfInt send_sz;
268 static ArrOfInt recv_sz;
269
270
271
272 assert(status_ == WRITING && ref_group_);
273 const Comm_Group& group = ref_group_.valeur();
274 assert(&group == &PE_Groups::current_group());
275
276 // On verifie que tous les membres du groupe executent ceci.
277 // Si ca plante ici, c'est que tous les membres declares ne sont
278 // pas en train de faire la barriere.
279 if (group.check_enabled()) group.barrier(ECHANGE_MESSAGES_COMM_TAG);
280
281 const int n_send = send_pe_list_.size_array();
282 const int n_recv = recv_pe_list_.size_array();
283
284 recv_size.resize_array(n_recv);
285
286 const char ** send_buffers = new const char* [n_send];
287 char ** recv_buffers = new char* [n_recv];
288
289 send_sz.resize_array(n_send); // Taille d'un int (on echange une taille)
290 send_sz = sizeof(int);
291 int i;
292 for (i = 0; i < n_send; i++)
293 send_buffers[i] = (char*) (& send_size[i]);
294
295 recv_sz.resize_array(n_recv);
296 recv_sz = sizeof(int);
297 recv_size.resize_array(n_recv);
298 for (i = 0; i < n_recv; i++)
299 recv_buffers[i] = (char*) (& recv_size[i]);
300
301 exchange_data(send_pe_list_, send_sz, send_buffers,
302 recv_pe_list_, recv_sz, recv_buffers,
303 group,
305
306 delete[] recv_buffers;
307 delete[] send_buffers;
308}
309
310/*! @brief Cette methode lance l'echange de donnees entre tous les processeurs.
311 *
312 * La taille des messages recus doit etre deja connue.
313 * Le schema passe de WRITING a EXCHANGED.
314 *
315 */
316void Schema_Comm::echange_messages(const ArrOfInt& send_size,
317 const ArrOfInt& recv_size) const
318{
319 assert(status_ == WRITING && ref_group_);
320 const Comm_Group& group = ref_group_.valeur();
321 assert(&group == &PE_Groups::current_group());
322
323 // On verifie que tous les membres du groupe executent ceci.
324 // Si ca plante ici, c'est que tous les membres declares ne sont
325 // pas en train de faire la barriere.
326 if (group.check_enabled()) group.barrier(ECHANGE_MESSAGES_COMM_TAG);
327
328 const int n_send = send_pe_list_.size_array();
329 const int n_recv = recv_pe_list_.size_array();
330 const char ** send_buffers = new const char* [n_send];
331 char ** recv_buffers = new char* [n_recv];
332
333 int i;
334 for (i = 0; i < n_recv; i++)
335 {
336 int pe = recv_pe_list_[i];
337 int size = recv_size[i];
338 InputCommBuffer& buf = ebuffer(pe);
339 recv_buffers[i] = buf.reserve_buffer(size);
340 }
341 for (i = 0; i < n_send; i++)
342 {
343 int pe = send_pe_list_[i];
344 OutputCommBuffer& buf = obuffer(pe);
345 // On verifie que la taille des messages en emission est la meme que
346 // celle enregistree dans send_size_, ce qui garantit que la taille
347 // en reception est juste elle-aussi.
348 assert(send_size[i] == buf.get_buffer_size());
349 send_buffers[i] = buf.get_buffer();
350 }
351
352 exchange_data(send_pe_list_, send_size, send_buffers,
353 recv_pe_list_, recv_size, recv_buffers,
354 group,
356
357 delete[] recv_buffers;
358 delete[] send_buffers;
359
360 // Creation des input streams a partir des buffers recus
361 for (i = 0; i < n_recv; i++)
362 {
363 int pe = recv_pe_list_[i];
364 InputCommBuffer& buf = ebuffer(pe);
365 buf.create_stream();
366 }
367
368 // Cas particulier des messages envoyes a moi-meme:
369 if (me_to_me_)
370 {
371 int pe = Process::me();
372 InputCommBuffer& buf = ebuffer(pe);
373 OutputCommBuffer& obuf = obuffer(pe);
374 buf.create_stream_from_output_stream(obuf);
375 }
376
378}
379
380/*! @brief Cette methode lance l'echange de donnees entre tous les processeurs.
381 *
382 * La taille des messages recus n'a pas besoin d'etre connue a priori,
383 * on la transmet.
384 * Le schema passe de WRITING a EXCHANGED.
385 *
386 */
388{
389 static ArrOfInt send_size;
390 static ArrOfInt recv_size;
391 const int n_send = send_pe_list_.size_array();
392 send_size.resize_array(n_send);
393 int i;
394 for (i = 0; i < n_send; i++)
395 {
396 int pe = send_pe_list_[i];
397 send_size[i] = obuffer(pe).get_buffer_size();
398 }
399
400 // Methode non optimale: en MPI on pourrait utiliser MPI_Probe mais
401 // cette methode me parait peu sure.
402 echange_taille(send_size, recv_size);
403 echange_messages(send_size, recv_size);
404}
405
406/*! @brief Cette methode lance l'echange de donnees.
407 *
408 * On fournit la taille en octets des messages recus dans recv_size (tableau de la meme taille que recv_pe_list)
409 * En mode check_enabled, on verifie que la taille est correcte
410 *
411 */
412void Schema_Comm::echange_messages(const ArrOfInt& recv_size) const
413{
414 const int n_send = send_pe_list_.size_array();
415 ArrOfInt send_size(n_send);
416 int i;
417 for (i = 0; i < n_send; i++)
418 {
419 int pe = send_pe_list_[i];
420 send_size[i] = obuffer(pe).get_buffer_size();
421 }
422 if (PE_Groups::current_group().check_enabled())
423 {
424 ArrOfInt check_recv_size;
425 echange_taille(send_size, check_recv_size);
426 if (!(check_recv_size == recv_size))
427 {
428 Cerr << "Error in Schema_Comm::echange_messages : bad recv_size" << finl;
430 }
431 }
432 echange_messages(send_size, recv_size);
433}
434
435/*! @brief Vide les buffers et libere les ressources: on a fini de lire les donnees recues dans les buffers.
436 *
437 * Le schema passe de EXCHANGED a RESET
438 *
439 */
441{
442 assert(status_ == EXCHANGED && ref_group_);
443 const Comm_Group& group = ref_group_.valeur();
444 assert(&group == &PE_Groups::current_group());
445
446 // On verifie que tous les membres du groupe executent ceci.
447 // Si ca plante ici, c'est que tous les membres declares ne sont
448 // pas en train de faire la barriere.
449 if (group.check_enabled()) group.barrier(END_COMM_TAG);
450
451 int i, n;
452 n = send_pe_list_.size_array();
453 for (i = 0; i < n; i++)
454 {
455 int pe = send_pe_list_[i];
456 obuffer(pe).clear();
457 }
458 n = recv_pe_list_.size_array();
459 for (i = 0; i < n; i++)
460 {
461 int pe = recv_pe_list_[i];
462 ebuffer(pe).clear();
463 }
464
465 if (me_to_me_)
466 {
467 int pe = Process::me();
468 obuffer(pe).clear();
469 ebuffer(pe).clear();
470 }
471
472 status_ = RESET;
473}
474
475#ifndef NDEBUG
476static int check_PE_in_list(int num_pe, const ArrOfInt& list)
477{
478 int i;
479 int n = list.size_array();
480 for (i = 0; i < n && list[i] != num_pe; i++);
481 return (i < n);
482}
483#endif
484
485/*! @brief renvoie le buffer correspondant au processeur num_PE pour y entasser des donnees a envoyer.
486 *
487 * Le schema doit etre dans l'etat WRITING.
488 *
489 */
491{
492 // Si l'assert suivant plante, c'est qu'on essaie de
493 // mettre des donnees dans le buffer en dehors du bloc
494 // begin_comm();
495 // ...
496 /// echange_xxx();
497 assert(status_ == WRITING && ref_group_);
498
499 // On verifie que le PE demande est bien dans la liste
500 // des PEs declares en envoi.
501 assert((me_to_me_&&num_PE==Process::me()) || check_PE_in_list(num_PE, send_pe_list_));
502 return obuffer(num_PE);
503}
504
505/*! @brief renvoie le buffer correspondant au processeur num_PE pour y lire les donnees recues.
506 *
507 * Le schema doit etre dans l'etat EXCHANGED.
508 *
509 */
511{
512 // Si l'assert suivant plante, c'est qu'on essaie de
513 // lire des donnees dans les buffers en dehors du bloc
514 // echange_xxx();
515 // ...
516 // end_comm();
517 assert(status_ == EXCHANGED && ref_group_);
518 // On verifie que le PE demande est bien dans la liste
519 // des PEs declares en reception.
520 assert((me_to_me_&&num_PE==Process::me()) || check_PE_in_list(num_PE, recv_pe_list_));
521 return ebuffer(num_PE);
522}
523
524const ArrOfInt& Schema_Comm::get_send_pe_list() const
525{
526 assert(ref_group_);
527 return send_pe_list_;
528}
529
530const ArrOfInt& Schema_Comm::get_recv_pe_list() const
531{
532 assert(ref_group_);
533 return recv_pe_list_;
534}
535
536/*! @brief renvoie une reference a un tableau qui contient, pour chaque processeur de send_pe_list_, la taille en bytes des donnees
537 *
538 * a envoyer.
539 * A FINIR !!!!
540 *
541 */
543{
544 assert(0);
545 assert(status_ == EXCHANGED);
546 return send_size_;
547}
548
549/*! @brief renvoie une reference a un tableau qui contient, pour chaque processeur de send_pe_list_, la taille en bytes des donnees
550 *
551 * a recues.
552 * A FINIR !!!!
553 *
554 */
556{
557 assert(0);
558 assert(status_ == EXCHANGED);
559 return recv_size_;
560}
561
562/*! @brief Verifie que les send/recv_pe_list verifient la propriete "tu m'ecoutes quand je te parle"
563 *
564 */
566{
567 assert(status_ == RESET);
568 // On verifie que les indices de processeurs sont dans le groupe
569 int fail1 = 0;
570 const int np = Process::nproc();
571 const int n1 = send_pe_list_.size_array();
572 int i;
573 for (i = 0; i < n1; i++)
574 if (send_pe_list_[i] < 0 || send_pe_list_[i] >= np)
575 fail1 = 1;
576 const int n2 = recv_pe_list_.size_array();
577 for (i = 0; i < n2; i++)
578 if (recv_pe_list_[i] < 0 || recv_pe_list_[i] >= np)
579 fail1 = 1;
580 int fail2 = 0;
581 ArrOfInt recv_list;
582 if (!fail1)
583 {
584 reverse_send_recv_pe_list(send_pe_list_, recv_list);
585 // Le tableau recv_pe_list_ n'est pas forcement trie alors que recv_list l'est toujours
586 // On trie avant de comparer
587 ArrOfInt copie(recv_pe_list_);
588 copie.ordonne_array();
589 fail2 = !(recv_list == copie);
590 }
591 if (Process::mp_sum(fail1+fail2))
592 {
594 Cerr << "Error in Schema_Comm::check_send_recv_pe_list(), see .log files" << finl;
595 Process::Journal() << "Error in Schema_Comm::check_send_recv_pe_list() :\n"
596 << "send_list:\n" << send_pe_list_
597 << "recv_list:\n" << recv_pe_list_;
598 if (fail1)
599 Process::Journal() << "processor ranks not in current group: current group size = " << np;
600 else if (fail2)
601 Process::Journal() << "recv_list should be this one:\n" << recv_list << finl;
602 else
603 Process::Journal() << "OK on this processor" << finl;
606 }
607}
: Classe Comm_Group_MPI, derivee de la classe abstraite Comm_Group.
: Cette classe decrit un groupe de processeurs sur lesquels
Definition Comm_Group.h:40
static int check_enabled()
Definition Comm_Group.h:159
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 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
virtual void barrier(int tag) const =0
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
: Classe outil utilisee exclusivement par Schema_Comm.
: Classe outil utilisee exclusivement par Schema_Comm.
static const Comm_Group & current_group()
renvoie une reference au groupe de processeurs actif courant
Definition PE_Groups.h:65
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
Definition Process.cpp:588
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
Definition Process.cpp:104
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
static void barrier()
Synchronise tous les processeurs du groupe courant (attend que tous les processeurs soient arrives a ...
Definition Process.cpp:136
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
const ArrOfInt & get_send_size() const
renvoie une reference a un tableau qui contient, pour chaque processeur de send_pe_list_,...
const ArrOfInt & get_recv_size() const
renvoie une reference a un tableau qui contient, pour chaque processeur de send_pe_list_,...
void echange_messages(const ArrOfInt &recv_size) const
Cette methode lance l'echange de donnees.
static InputCommBuffer & ebuffer(int pe)
Accesseur a un membre du tableau ebuffers_ (avec verification).
const Schema_Comm & operator=(const Schema_Comm &)
Operateur copie : on copie la liste des processeurs qui communiquent.
ArrOfInt recv_pe_list_
void set_group(const Comm_Group &group)
Methode obsolete, le groupe associe au schema est le groupe courant au moment ou on cree le schema.
const Comm_Group & get_group() const
Renvoie le groupe auquel est associe le schema.
void echange_taille_et_messages() const
Cette methode lance l'echange de donnees entre tous les processeurs.
~Schema_Comm()
Destruction d'un schema de communication.
Sortie & send_buffer(int num_PE) const
renvoie le buffer correspondant au processeur num_PE pour y entasser des donnees a envoyer.
static OutputCommBuffer & obuffer(int pe)
Accesseur a un membre du tableau obuffers_ (avec verification).
void end_comm() const
Vide les buffers et libere les ressources: on a fini de lire les donnees recues dans les buffers.
Entree & recv_buffer(int num_PE) const
renvoie le buffer correspondant au processeur num_PE pour y lire les donnees recues.
int use_all_to_allv_
void echange_taille(const ArrOfInt &send_size, ArrOfInt &recv_size) const
Transmet la taille des messages a envoyer aux processeurs qui vont les recevoir.
const ArrOfInt & get_recv_pe_list() const
ArrOfInt send_pe_list_
void begin_comm() const
Reserve les buffers de comm pour une nouvelle communication.
void check_send_recv_pe_list() const
Verifie que les send/recv_pe_list verifient la propriete "tu m'ecoutes quand je te parle".
const ArrOfInt & get_send_pe_list() const
void set_send_recv_pe_list(const ArrOfInt &send_pe_list, const ArrOfInt &recv_pe_list, const int me_to_me=0)
Definit la liste des processeurs a qui on va envoyer et de qui on va recevoir des donnees.
static Static_Status status_
Schema_Comm()
Construction d'un nouveau schema de communication.
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ size_array() const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void ordonne_array()