TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
MD_Vector_std.cpp
1/****************************************************************************
2* Copyright (c) 2024, 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#include <MD_Vector_std.h>
17#include <Param.h>
18#include <Array_tools.h>
19
20Implemente_instanciable(MD_Vector_std,"MD_Vector_std",MD_Vector_mono);
21
22
23/*! @brief Stupid ctor.
24 *
25 * Everything set to n.
26 */
28{
29 nb_items_tot_ = n;
33 blocs_items_to_sum_.resize_array(2, RESIZE_OPTIONS::NOCOPY_NOINIT);
36 blocs_items_to_compute_.resize_array(2, RESIZE_OPTIONS::NOCOPY_NOINIT);
39}
40
41/*! @brief Constructor.
42 *
43 * If nb_items_reels >= 0, items_to_compute will contain a block with the real items,
44 * otherwise, items_to_compute will cover all items (up to nb_items_tot).
45 *
46 * @param (nb_items_tot) value assigned to nb_items_tot_ (must be >= 0)
47 * @param (nb_items_reels) value assigned to nb_items_reels_ (must be >= -1; -1 means there are no "real" items grouped at the start of the array)
48 * @param (pe_voisins) list of neighbouring processors, sorted in ascending order (ArrsOfInt arrays must have the same size). This list is not taken as-is: processors for which all three item lists are empty are removed.
49 * @param (items_to_send) for each pe_voisin, list of items to send (shared and virtual). count_items_to_send_to_items_ is computed via communication from items_to_recv.
50 * @param (items_to_recv) list of individual items to receive from the different procs (often shared items but not necessarily, e.g. front-tracking)
51 * @param (blocs_to_recv) list of blocks of items to receive (see MD_Vector_std::blocs_to_recv_) (often the virtual items...)
52 */
53MD_Vector_std::MD_Vector_std(int nb_items_tot, int nb_items_reels, const ArrOfInt& pe_voisins,
54 const ArrsOfInt& items_to_send, const ArrsOfInt& items_to_recv, const ArrsOfInt& blocs_to_recv)
55{
56 assert(nb_items_tot >= 0);
57 assert(nb_items_reels >= -1 && nb_items_reels <= nb_items_tot);
58 nb_items_tot_ = nb_items_tot;
59 nb_items_reels_ = nb_items_reels;
60 const int nb_voisins = pe_voisins.size_array();
61 assert(items_to_send.size() == nb_voisins);
62 assert(items_to_recv.size() == nb_voisins);
63 assert(blocs_to_recv.size() == nb_voisins);
64
65 // selection: list of indices of processors to keep in pe_voisins
66 // (procs with whom data is actually exchanged)
67 ArrOfInt tmp, selection;
68
69
70 int i;
71 for (i = 0; i < nb_voisins; i++)
72 if (items_to_send[i].size_array() > 0 || items_to_recv[i].size_array() > 0 || blocs_to_recv[i].size_array() > 0)
73 {
75 selection.append_array(i);
76 }
77 const int nb_voisins2 = tmp.size_array();
78 // ** pe_voisins_ **
79 pe_voisins_ = tmp;
80
81 {
82 ArrsOfInt tmpbis(nb_voisins2);
83
84 for (i = 0; i < nb_voisins2; i++)
85 tmpbis[i] = items_to_send[selection[i]];
86 items_to_send_.set(tmpbis);
87
88 for (i = 0; i < nb_voisins2; i++)
89 tmpbis[i] = items_to_recv[selection[i]];
90 items_to_recv_.set(tmpbis);
91
92 for (i = 0; i < nb_voisins2; i++)
93 tmpbis[i] = blocs_to_recv[selection[i]];
94 blocs_to_recv_.set(tmpbis);
95 }
96
97 // Compute nb_items_to_items_
98 {
99 nb_items_to_items_.resize_array(nb_voisins2, RESIZE_OPTIONS::NOCOPY_NOINIT);
100 tmp.resize_array(nproc(), RESIZE_OPTIONS::NOCOPY_NOINIT);
101 tmp = 0;
102 for (i = 0; i < nb_voisins2; i++)
103 tmp[pe_voisins_[i]] = items_to_recv[selection[i]].size_array();
104 ;
105 envoyer_all_to_all(tmp, tmp);
106 for (i = 0; i < nb_voisins2; i++)
107 {
108 int n = tmp[pe_voisins_[i]];
109 assert(n <= items_to_send_.get_list_size(i));
110 nb_items_to_items_[i] = n;
111 }
112 }
113 // Compute blocs_items_count_
114 {
115 blocs_items_count_.resize_array(nb_voisins2, RESIZE_OPTIONS::NOCOPY_NOINIT);
116 for (i = 0; i < nb_voisins2; i++)
117 {
118 const int nblocs = blocs_to_recv_.get_list_size(i) / 2;
119 int count = 0;
120 for (int j = 0; j < nblocs; j++)
121 {
122 int deb = blocs_to_recv_(i, j * 2);
123 int fin = blocs_to_recv_(i, j * 2 + 1);
124 assert(deb >= 0 && fin > deb && fin <= nb_items_tot_);
125 count += fin - deb;
126 }
127 blocs_items_count_[i] = count;
128 }
129 }
130 // Compute the blocks of sequential items (items not received from another proc)
131 tmp.resize_array(nb_items_tot, RESIZE_OPTIONS::NOCOPY_NOINIT);
132 {
133 // Mark received items as zero
134 tmp = 1;
135 const ArrOfInt& items = items_to_recv_.get_data();
136 int n = items.size_array();
137 for (i = 0; i < n; i++)
138 {
139 assert(tmp[items[i]] == 1); // otherwise the same item is received twice
140 tmp[items[i]] = 0;
141 }
142 const ArrOfInt& items2 = blocs_to_recv_.get_data();
143 assert(items2.size_array() % 2 == 0);
144 n = items2.size_array() / 2;
145 for (i = 0; i < n; i++)
146 {
147 const int start = items2[i * 2];
148 const int end = items2[i * 2 + 1];
149 for (int j = start; j < end; j++)
150 {
151 assert(tmp[j] == 1); // otherwise, the same item is received twice
152 tmp[j] = 0;
153 }
154 }
155
156 // Build a list of sequential item blocks (those that remained 1)
157 ArrOfInt blocs;
158
159 int nb_seq = 0;
160 for (i = 0; i < nb_items_tot; i++)
161 {
162 if (tmp[i])
163 {
164 if (nb_items_reels >= 0 && i >= nb_items_reels)
165 {
166 // On a un item non recu parmi les items virtuels !
167 Cerr << "Error in MD_Vector_std::MD_Vector_std(...) [pe " << me() << "]\n "
168 "an item i(" << i << ") > nb_items_reels(" << nb_items_reels << ") is not received from any other processor" << finl;
170 }
171 append_item_to_blocs(blocs, i);
172 nb_seq++;
173 }
174 }
175 blocs_items_to_sum_ = blocs;
176 nb_items_seq_local_ = nb_seq;
177 nb_items_seq_tot_ = mp_sum(nb_seq);
178 }
179
180 // Bloc items to compute:
181 // Default: a single block
182 if (nb_items_reels_ >= 0)
183 {
184 // Array operators compute all real items
185 blocs_items_to_compute_.resize(2, RESIZE_OPTIONS::NOCOPY_NOINIT);
188 }
189 else
190 {
191 // Array operators compute everything
192 blocs_items_to_compute_.resize(2, RESIZE_OPTIONS::NOCOPY_NOINIT);
195 }
196}
197
198/*! @brief method used to dump/restore a descriptor in a file Each process writes a different descriptor.
199 *
200 * See MD_Vector_tools::restore_vector_with_md()
201 *
202 */
204{
206 Param p(que_suis_je());
207 ArrOfInt items_send_index, items_send_data, items_index, items_data, blocs_index, blocs_data;
208 p.ajouter("pe_voisins", &pe_voisins_);
209 p.ajouter("items_to_send_index", &items_send_index);
210 p.ajouter("items_to_send_data", &items_send_data);
211 p.ajouter("nb_items_to_items", &nb_items_to_items_);
212 p.ajouter("items_to_recv_index", &items_index);
213 p.ajouter("items_to_recv_data", &items_data);
214 p.ajouter("blocs_to_recv_index", &blocs_index);
215 p.ajouter("blocs_to_recv_data", &blocs_data);
216 p.ajouter("blocs_items_count", &blocs_items_count_);
217 p.lire_avec_accolades(is);
218 if (items_send_data.size_array())
219 items_to_send_.set_index_data(items_send_index, items_send_data);
220 if (items_data.size_array())
221 items_to_recv_.set_index_data(items_index, items_data);
222 if (blocs_data.size_array())
223 blocs_to_recv_.set_index_data(blocs_index, blocs_data);
224 return is;
225}
226
227/*! @brief method used to dump/restore a descriptor in a file Each process writes a different descriptor.
228 *
229 * See MD_Vector_tools::dump_vector_with_md()
230 *
231 */
233{
235 os << "{" << finl;
236 os << "pe_voisins" << tspace << pe_voisins_ << finl;
237 os << "items_to_send_index" << tspace << items_to_send_.get_index() << finl;
238 os << "items_to_send_data" << tspace << items_to_send_.get_data() << finl;
239 os << "nb_items_to_items" << tspace << nb_items_to_items_ << finl;
240 os << "items_to_recv_index" << tspace << items_to_recv_.get_index();
241 os << "items_to_recv_data" << tspace << items_to_recv_.get_data();
242 os << "blocs_to_recv_index" << tspace << blocs_to_recv_.get_index() << finl;
243 os << "blocs_to_recv_data" << tspace << blocs_to_recv_.get_data();
244 os << "blocs_items_count" << tspace << blocs_items_count_ << finl;
245 os << "}" << finl;
246 return os;
247}
248
249namespace // Anonymous namespace
250{
251
252/*! @brief returns i such that a[i]==x, or -1 if x is not found
253 */
254int find_in_array(const ArrOfInt& a, int x)
255{
256 int n;
257 for (n = a.size_array() - 1; n >= 0; n--)
258 if (a[n] == x)
259 break;
260 return n;
261}
262
263/*! @brief Returns the number of extracted items (not the number of blocks).
264 */
265int extract_blocs(const ArrOfInt src, const ArrOfInt& renum, ArrOfInt& dest)
266{
267 const int nblocs_src = src.size_array() / 2;
268
269 dest.resize_array(0);
270 int end_last_bloc = -1;
271 int count = 0;
272 for (int i = 0; i < nblocs_src; i++)
273 {
274 const int deb = src[i*2];
275 const int fin = src[i*2+1];
276 for (int j = deb; j < fin; j++)
277 {
278 const int rj = renum[j];
279 if (rj >= 0)
280 {
281 count++;
282 // Blocs construction assumes that renum is ordered
283 assert(rj >= end_last_bloc);
284 if (rj == end_last_bloc)
285 {
286 // item is contiguous to last bloc in destination array, increase bloc size:
287 end_last_bloc++;
288 dest[dest.size_array()-1] = end_last_bloc;
289 }
290 else
291 {
292 // non contiguous item, create new bloc
293 end_last_bloc = rj;
294 dest.append_array(end_last_bloc);
295 end_last_bloc++;
296 dest.append_array(end_last_bloc);
297 }
298 }
299 }
300 }
301 return count;
302}
303
304} // end anonymous NS
305
306
307/*! Append all items in "src" to "this", duplicating src items "multiplier" times
308 * and adding the "offset" to item indexes. Also merge pe_voisins_ lists.
309 */
310void MD_Vector_std::append_from_other_std(const MD_Vector_std& src, int offset, int multiplier)
311{
312 // List sizes for items_to_send_, items_to_recv_ and blocs_to_recv_ of new descriptor
313 ArrOfInt x_sz, y_sz, z_sz;
314 // Data of these lists:
315 ArrOfInt x_data, y_data, z_data;
316 ArrOfInt new_blocs_items_count, new_nb_items_to_items;
317 ArrOfInt tmp;
318 ArrOfInt pe_list(pe_voisins_);
319
320 append_blocs(pe_list, src.pe_voisins_);
321 array_trier_retirer_doublons(pe_list);
322 const int np = pe_list.size_array();
323
324 new_blocs_items_count.resize_array(np);
325 new_nb_items_to_items.resize_array(np);
326
327 for (int i = 0; i < np; i++)
328 {
329 // Number of items to recv, send and blocs to recv for this processor:
330 int nx = 0, ny = 0, nz = 0;
331 int blocs_count = 0;
332 // Is processor pe_list[i] in initial "dest" descriptor ?
333 int j;
334
335 for (j = pe_voisins_.size_array()-1; j >= 0; j--)
336 if (pe_voisins_[j] == pe_list[i])
337 break;
338 const int pe = pe_list[i];
339
340 // Insert items to send and items to recv from dest
341 j = ::find_in_array(pe_voisins_, pe);
342 if (j >= 0)
343 {
344 const int count_items_single = nb_items_to_items_[j];
345 nx += count_items_single;
346 // take only single items to send
347 tmp.resize_array(0);
348 tmp.resize_array(count_items_single);
349 for (int k = 0; k < count_items_single; k++)
350 tmp[k] = items_to_send_(j, k);
351 append_blocs(x_data, tmp);
352
353 ny += items_to_recv_.get_list_size(j);
354 items_to_recv_.copy_list_to_array(j, tmp);
355 append_blocs(y_data, tmp);
356 }
357
358 // Insert items to send and items to recv from src, with multiplier
359 j = find_in_array(src.pe_voisins_, pe);
360 if (j >= 0)
361 {
362 const int count_items_single = src.nb_items_to_items_[j];
363 nx += count_items_single * multiplier;
364 // take only single items to send
365 tmp.resize_array(0);
366 tmp.resize_array(count_items_single);
367 for (int k = 0; k < count_items_single; k++)
368 tmp[k] = src.items_to_send_(j, k);
369 append_items(x_data, tmp, offset, multiplier);
370
371 ny += src.items_to_recv_.get_list_size(j) * multiplier;
373 append_items(y_data, tmp, offset, multiplier);
374 }
375 const int single_items_count = nx;
376 // Insert blocs to send and blocs to recv from dest
377 j = ::find_in_array(pe_voisins_, pe);
378 if (j >= 0)
379 {
380 const int count_items_tot = items_to_send_.get_list_size(j);
381 const int count_items_single = nb_items_to_items_[j];
382 nx += count_items_tot - count_items_single;
383 tmp.resize_array(0);
384 tmp.resize_array(count_items_tot - count_items_single);
385 for (int k = count_items_single; k < count_items_tot; k++)
386 tmp[k - count_items_single] = items_to_send_(j, k);
387 append_blocs(x_data, tmp);
388
389 nz += blocs_to_recv_.get_list_size(j);
390 blocs_to_recv_.copy_list_to_array(j, tmp);
391 append_blocs(z_data, tmp);
392
393 blocs_count += blocs_items_count_[j];
394 }
395 // Insert blocs to send and blocs to recv from src, with multiplier
396 j = find_in_array(src.pe_voisins_, pe);
397 if (j >= 0)
398 {
399 const int count_items_tot = src.items_to_send_.get_list_size(j);
400 const int count_items_single = src.nb_items_to_items_[j];
401 nx += (count_items_tot - count_items_single) * multiplier;
402 tmp.resize_array(0);
403 tmp.resize_array(count_items_tot - count_items_single);
404 for (int k = count_items_single; k < count_items_tot; k++)
405 tmp[k - count_items_single] = src.items_to_send_(j, k);
406 append_items(x_data, tmp, offset, multiplier);
407
408 nz += src.blocs_to_recv_.get_list_size(j);
410 append_blocs(z_data, tmp, offset, multiplier);
411
412 blocs_count += src.blocs_items_count_[j] * multiplier;
413 }
414
415 x_sz.append_array(nx);
416 y_sz.append_array(ny);
417 z_sz.append_array(nz);
418 new_blocs_items_count[i] = blocs_count;
419 new_nb_items_to_items[i] = single_items_count;
420 }
421
422 items_to_send_.set_list_sizes(x_sz);
423 items_to_send_.set_data(x_data);
424 items_to_recv_.set_list_sizes(y_sz);
425 items_to_recv_.set_data(y_data);
426 blocs_to_recv_.set_list_sizes(z_sz);
427 blocs_to_recv_.set_data(z_data);
428 pe_voisins_ = pe_list;
429 blocs_items_count_ = new_blocs_items_count;
430 nb_items_to_items_ = new_nb_items_to_items;
431}
432
433void MD_Vector_std::fill_md_vect_renum(const IntVect& renum, MD_Vector& md_vect) const
434{
435 MD_Vector_std dest;
436
437 // Compute nb_items_tot_ and nb_items_reels_
438 // nb_items_tot_ is the number of items for which renum[i] >= 0
439 // Real items are those that were real in the original array and are to be kept
440 {
441 const int src_size = get_nb_items_tot();
442 const int src_size_r = get_nb_items_reels();
443 dest.nb_items_tot_ = 0;
444 dest.nb_items_reels_ = 0;
445 for (int i = 0; i < src_size; i++)
446 {
447 if (renum[i] >= 0)
448 {
449 dest.nb_items_tot_++;
450 if (i < src_size_r)
451 dest.nb_items_reels_++;
452 }
453 }
454 // If the nb_items_reels_ attribute is invalid in the source vector, it is also invalid in the
455 // result vector:
456 if (src_size_r < 0)
457 dest.nb_items_reels_ = -1;
458 }
459 // Fill blocs_items_to_sum_ and blocs_items_to_compute_
460 // These are the items for which renum[i] >= 0 and which are in the blocs_items_to_sum_
461 // and blocs_items_to_compute_ of the source descriptor.
462 ::extract_blocs(blocs_items_to_sum_, renum, dest.blocs_items_to_sum_);
463 dest.nb_items_seq_local_ = ::extract_blocs(blocs_items_to_compute_, renum, dest.blocs_items_to_compute_);
465
466 // ********************************************************
467 // Compute items to receive: these are items for which renum[i] >= 0 and which were to be
468 // received in the source descriptor.
469 // Each time a received item is found, the neighbouring processor that owns it must be notified
470 // that this item needs to be sent (using schema_comm). To identify these items, their rank
471 // in the array of items to send in the source descriptor is used (variable item_rank).
472 //
473 const int nb_pe_voisins = pe_voisins_.size_array();
474 Schema_Comm schema_comm;
476 schema_comm.begin_comm();
477 // Compute the items_to_recv lists
478 // index+data form the two arrays of a StaticIntLists.
479 // We first build as many lists as there are neighbouring processors in the source descriptor.
480 // Processors that do not exchange data will be removed at the end.
481 ArrOfInt dest_items_recv_index;
482 ArrOfInt dest_items_recv_data;
483 ArrOfInt dest_blocs_recv_index;
484 ArrOfInt dest_blocs_recv_data;
485
486 ArrOfInt tmp;
487
488 {
489 dest_items_recv_index.resize_array(nb_pe_voisins + 1, RESIZE_OPTIONS::NOCOPY_NOINIT);
490 dest_items_recv_index[0] = 0;
491 dest_blocs_recv_index.resize_array(nb_pe_voisins + 1, RESIZE_OPTIONS::NOCOPY_NOINIT);
492 dest_blocs_recv_index[0] = 0;
493 dest.blocs_items_count_.resize_array(nb_pe_voisins, RESIZE_OPTIONS::NOCOPY_NOINIT);
494 dest.nb_items_to_items_.resize_array(nb_pe_voisins, RESIZE_OPTIONS::NOCOPY_NOINIT);
495 // Pre-allocate to maximum size
496 dest_items_recv_data.resize_array(items_to_recv_.get_data().size_array(), RESIZE_OPTIONS::NOCOPY_NOINIT);
497
498 dest_items_recv_data.resize_array(0);
499 // The number of blocks cannot be predicted; there can be more than in the source
500
501 for (int i_pe = 0; i_pe < nb_pe_voisins; i_pe++)
502 {
503 tmp.resize_array(0);
504 int item_rank = 0; // Counter of received items in the source descriptor
505 // 1) Extract individual items
506 // (fill dest_items_recv_index, dest_items_recv_data and tmp)
507 const int n = items_to_recv_.get_list_size(i_pe);
508 for (int i = 0; i < n; i++)
509 {
510 const int j = items_to_recv_(i_pe, i);
511 const int rj = renum[j];
512 if (rj >= 0)
513 {
514 // Add this item
515 dest_items_recv_data.append_array(rj);
516 // Request that the neighbouring processor sends this item
517 tmp.append_array(item_rank);
518 }
519 item_rank++;
520 }
521 // Set the list size for items of this processor:
522 dest_items_recv_index[i_pe+1] = dest_items_recv_data.size_array();
523
524 // 2) Extract blocks of items received from this processor
525 // (fill dest_blocs_recv_index, dest_blocs_recv_data, dest.blocs_items_count_ and tmp)
526 const int nblocs = blocs_to_recv_.get_list_size(i_pe) / 2;
527 int received_count = 0; // number of items received from this processor
528 for (int ibloc = 0; ibloc < nblocs; ibloc++)
529 {
530 const int jdeb = blocs_to_recv_(i_pe, ibloc * 2);
531 const int jfin = blocs_to_recv_(i_pe, ibloc * 2 + 1);
532 int last_added = -2; // can never equal rj-1
533 // For each item in the block, if it is to be kept, report it in the blocks to receive:
534 for (int j = jdeb; j < jfin; j++)
535 {
536 const int rj = renum[j];
537 if (rj >= 0)
538 {
539 if (rj <= last_added)
540 {
541 // Items in the receive blocks must be sorted in ascending order
542 // (otherwise this algorithm does not work; a different one is needed to
543 // build the blocks, and furthermore counting the real items may no longer make sense)
544 Cerr << "Error in creer_md_vect_renum: renum array is not sorted: cannot extract blocs to recv" << finl;
546 }
547 // Is this item contiguous with the previous one?
548 if (last_added == rj-1)
549 {
550 // Yes, extend the last block
551 const int k = dest_blocs_recv_data.size_array();
552 // end of block = index of last + 1
553 dest_blocs_recv_data[k-1] = rj+1;
554 }
555 else
556 {
557 // No, create a new block
558 dest_blocs_recv_data.append_array(rj);
559 dest_blocs_recv_data.append_array(rj+1);
560 }
561 last_added = rj;
562 // Request that the neighbouring processor sends this item
563 tmp.append_array(item_rank);
564 received_count++;
565 }
566 item_rank++;
567 }
568 }
569 // Set the list size for blocks of this processor:
570 dest_blocs_recv_index[i_pe+1] = dest_blocs_recv_data.size_array();
571 // Number of items received from this processor
572 dest.blocs_items_count_[i_pe] = received_count;
573 // Send the tmp array to the neighbouring processor:
574 schema_comm.send_buffer(pe_voisins_[i_pe]) << tmp;
575 }
576 }
577
578 schema_comm.echange_taille_et_messages();
579
580 // ********************************************************
581 // Build dest.items_to_send with the received information
582 //
583 ArrOfInt dest_items_send_index;
584 dest_items_send_index.resize_array(nb_pe_voisins + 1, RESIZE_OPTIONS::NOCOPY_NOINIT);
585 ArrOfInt dest_items_send_data;
586 ArrOfInt nb_items_to_items(nb_pe_voisins); // Initialized to zero
587
588 // Allocate to upper-bound size:
589 dest_items_send_data.resize_array(items_to_send_.get_data().size_array(), RESIZE_OPTIONS::NOCOPY_NOINIT);
590 dest_items_send_index[0] = 0;
591 {
592 int count = 0;
593 int error = 0;
594 for (int i_pe = 0; i_pe < nb_pe_voisins; i_pe++)
595 {
596 // nb_item_received_single is the number of items in items_to_send_ that will be received
597 // by items_to_recv_. The subsequent ones are received in blocs_to_recv_.
598 schema_comm.recv_buffer(pe_voisins_[i_pe]) >> tmp;
599 const int n = tmp.size_array();
600 for (int i = 0; i < n; i++)
601 {
602 // tmp contains indices pointing into items_to_send_
603 int j = tmp[i];
604 // k is the index in the old array of the item to send
605 int k = items_to_send_(i_pe, j);
606 int renum_k = renum[k];
607 // A possible error here: a processor needs a virtual item and the
608 // real item has been removed on the source processor. A different algorithm
609 // must then be used to change the owner of the item...
610 if (renum_k < 0)
611 error = 1;
612 dest_items_send_data[count++] = renum_k;
613 }
614 dest_items_send_index[i_pe+1] = count;
615 }
616 if (error)
617 {
618 Cerr << "Internal error in MD_Vector_tools::creer_md_vect_renum:\n"
619 << " processor " << Process::me()
620 << " received a request for distant items that are not in the new vector" << finl;
622 }
623 // Adjust to the final size
624
625 dest_items_send_data.resize_array(count);
626 }
627 schema_comm.end_comm();
628
629 /* new nb_items_to_items */
630 schema_comm.begin_comm();
631 for (int i_pe = 0; i_pe < nb_pe_voisins; i_pe++)
632 schema_comm.send_buffer(pe_voisins_[i_pe]) << dest_items_recv_index(i_pe + 1) - dest_items_recv_index(i_pe);
633 schema_comm.echange_taille_et_messages();
634 for (int i_pe = 0; i_pe < nb_pe_voisins; i_pe++)
635 schema_comm.recv_buffer(pe_voisins_[i_pe]) >> nb_items_to_items[i_pe];
636 schema_comm.end_comm();
637
638 // Build the list of neighbouring processors for dest
639 // (processors with whom data is exchanged)
640 // And compress the StaticIntLists indexes to remove the
641 // deleted processors.
642 {
643 int pe_count = 0;
644 dest.pe_voisins_.resize_array(nb_pe_voisins, RESIZE_OPTIONS::NOCOPY_NOINIT);
645 for (int i_pe = 0; i_pe < nb_pe_voisins; i_pe++)
646 {
647 int flag = 0;
648 if (dest_items_recv_index[i_pe+1] - dest_items_recv_index[i_pe] > 0)
649 flag = 1;
650 if (dest_blocs_recv_index[i_pe+1] - dest_blocs_recv_index[i_pe] > 0)
651 flag = 1;
652 if (dest_items_send_index[i_pe+1] - dest_items_send_index[i_pe] > 0)
653 flag = 1;
654
655 if (flag)
656 {
657 dest_items_recv_index[pe_count+1] = dest_items_recv_index[i_pe+1];
658 dest_blocs_recv_index[pe_count+1] = dest_blocs_recv_index[i_pe+1];
659 dest_items_send_index[pe_count+1] = dest_items_send_index[i_pe+1];
660 dest.blocs_items_count_[pe_count] = dest.blocs_items_count_[i_pe];
661 dest.pe_voisins_[pe_count] = pe_voisins_[i_pe];
662 dest.nb_items_to_items_[pe_count] = nb_items_to_items[i_pe];
663 pe_count++;
664 }
665 }
666
667 dest_items_recv_index.resize_array(pe_count+1);
668
669 dest_blocs_recv_index.resize_array(pe_count+1);
670
671 dest_items_send_index.resize_array(pe_count+1);
672
673 dest.pe_voisins_.resize_array(pe_count);
674
675 dest.blocs_items_count_.resize_array(pe_count);
676
677 dest.nb_items_to_items_.resize_array(pe_count);
678 }
679 dest.items_to_send_.set_index_data(dest_items_send_index, dest_items_send_data);
680 dest.items_to_recv_.set_index_data(dest_items_recv_index, dest_items_recv_data);
681 dest.blocs_to_recv_.set_index_data(dest_blocs_recv_index, dest_blocs_recv_data);
682
683 md_vect.copy(dest);
684}
685
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
friend class MD_Vector
static void append_blocs(ArrOfInt &dest, const ArrOfInt &src, int offset=0, int multiplier=1)
trustIdType nb_items_seq_tot_
static void append_items(ArrOfInt &dest, const ArrOfInt &src, int offset=0, int multiplier=1)
virtual int get_nb_items_tot() const
virtual int get_nb_items_reels() const
static void append_item_to_blocs(ArrOfInt &blocs, int item)
Helper method to append an item to a "blocs"-type array containing series of blocks.
Generic class for all mono-block MD_Vectors (i.e. non compoosite).
ArrOfInt blocs_items_to_sum_
ArrOfInt blocs_items_to_compute_
This is the simplest descriptor, used for arrays of values at vertices, elements, faces,...
Static_Int_Lists items_to_send_
ArrOfInt blocs_items_count_
const Static_Int_Lists & items_to_recv() const
ArrOfInt pe_voisins_
void fill_md_vect_renum(const IntVect &renum, MD_Vector &md_vect) const override
const ArrOfInt & pe_voisins() const
Static_Int_Lists items_to_recv_
MD_Vector_std(int n)
Stupid ctor.
const Static_Int_Lists & items_to_send() const
const Static_Int_Lists & blocs_to_recv() const
void append_from_other_std(const MD_Vector_std &src, int offset, int multiplier) override
Static_Int_Lists blocs_to_recv_
ArrOfInt nb_items_to_items_
void copy(const MD_Vector_base &)
Constructs an MD_Vector object by copying an existing object.
Definition MD_Vector.cpp:26
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
static int nproc()
Returns the number of processors in the current group. See Comm_Group::nproc() and PE_Groups::current...
Definition Process.cpp:102
static double mp_sum(double)
Computes the sum of x over all processors in the current group.
Definition Process.cpp:145
static int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
Definition Process.cpp:122
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
void echange_taille_et_messages() const
Launches the data exchange between all processors.
Sortie & send_buffer(int num_PE) const
Returns the buffer corresponding to processor num_PE to stack data to send.
void end_comm() const
Clears the buffers and releases resources: reading of received data from buffers is complete.
Entree & recv_buffer(int num_PE) const
Returns the buffer corresponding to processor num_PE to read received data.
void begin_comm() const
Reserves communication buffers for a new communication.
void set_send_recv_pe_list(const ArrOfInt &send_pe_list, const ArrOfInt &recv_pe_list, const int me_to_me=0)
Defines the list of processors to send data to and receive data from.
Base class for output streams.
Definition Sortie.h:52
void copy_list_to_array(int_t i_liste, ArrOfInt_t &array) const
Copies the i-th list into the provided array. The array must be resizable.
void set_index_data(const ArrOfInt_t &index, const ArrOfInt_t &data)
Replaces index and data arrays.
int_t get_list_size(int_t i_liste) const
Returns the number of elements in list i.
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)