Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
VectorDistribution.cc
Go to the documentation of this file.
1/*
2 * Copyright 2020 IFPEN-CEA
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 * SPDX-License-Identifier: Apache-2.0
17 */
18
23
24#include "VectorDistribution.h"
25
26#include <iostream>
27#include <numeric>
28
29#include <arccore/message_passing/Messages.h>
30
31#include <alien/data/Space.h>
32#include <alien/utils/Trace.h>
33
34/*---------------------------------------------------------------------------*/
35/*---------------------------------------------------------------------------*/
36
37namespace Alien
38{
39
40using namespace Arccore;
41using namespace Arccore::MessagePassing;
42
43/*---------------------------------------------------------------------------*/
44/*---------------------------------------------------------------------------*/
45
48{
50 Internal();
51
57 Internal(const ISpace& space, IMessagePassingMng* parallel_mng);
58
64 Internal(const ISpace& space, std::shared_ptr<IMessagePassingMng> parallel_mng);
65
71 Internal(Integer global_size, IMessagePassingMng* parallel_mng);
72
78 Internal(Integer global_size, std::shared_ptr<IMessagePassingMng> parallel_mng);
79
86 Internal(const ISpace& space, Integer local_size, IMessagePassingMng* parallel_mng);
87
94 Internal(const ISpace& space, Integer local_size,
95 std::shared_ptr<IMessagePassingMng> parallel_mng);
96
103 Internal(Integer global_size, Integer local_size, IMessagePassingMng* parallel_mng);
104
111 Internal(Integer global_size, Integer local_size,
112 std::shared_ptr<IMessagePassingMng> parallel_mng);
113
115 ~Internal() = default;
116
122 bool operator==(const Internal& dist) const;
123
128 bool isParallel() const;
129
135 Integer owner(Integer i) const;
136
138 std::shared_ptr<ISpace> m_space;
139
140 // Is shared_ptr necessary ?
142 std::shared_ptr<IMessagePassingMng> m_parallel_mng;
143
145 Integer m_rank;
151 Integer m_offset;
153 UniqueArray<Integer> m_offsets;
154};
155
156/*---------------------------------------------------------------------------*/
157/*---------------------------------------------------------------------------*/
158
160: m_parallel_mng(nullptr)
161, m_rank(0)
162, m_global_size(0)
163, m_local_size(0)
164, m_offset(0)
165, m_offsets(1, 0)
166{}
167
168/*---------------------------------------------------------------------------*/
169/*---------------------------------------------------------------------------*/
170
172const ISpace& space, IMessagePassingMng* parallel_mng)
174, m_parallel_mng(std::shared_ptr<IMessagePassingMng>(
175 parallel_mng, [](IMessagePassingMng*) {})) // Do not call delete.
176, m_rank(0)
177, m_global_size(m_space->size())
178, m_local_size(0)
179, m_offset(0)
180{
181 if (!parallel_mng)
182 return;
183 m_rank = m_parallel_mng->commRank();
184 Integer np = parallel_mng->commSize();
185 UniqueArray<Integer> lsize(np, m_global_size / np);
186 for (Integer i = 0; i < m_global_size % np; ++i)
187 lsize[i]++;
188 m_offsets.resize(np, 0);
189 for (Integer i = 1; i < np; ++i) {
190 m_offsets[i] = lsize[i - 1] + m_offsets[i - 1];
191 }
192 m_offsets.add(m_global_size);
193 m_offset = m_offsets[m_rank];
194 m_local_size = lsize[m_rank];
195}
196
197/*---------------------------------------------------------------------------*/
198/*---------------------------------------------------------------------------*/
199
201const ISpace& space, std::shared_ptr<IMessagePassingMng> parallel_mng)
203, m_parallel_mng(parallel_mng)
204, m_rank(0)
205, m_global_size(m_space->size())
206, m_local_size(0)
207, m_offset(0)
208{
209 if (m_parallel_mng == nullptr)
210 return;
211 m_rank = m_parallel_mng->commRank();
212 Integer np = parallel_mng->commSize();
213 UniqueArray<Integer> lsize(np, m_global_size / np);
214 for (Integer i = 0; i < m_global_size % np; ++i)
215 lsize[i]++;
216 m_offsets.resize(np, 0);
217 for (Integer i = 1; i < np; ++i) {
218 m_offsets[i] = lsize[i - 1] + m_offsets[i - 1];
219 }
222 m_local_size = lsize[m_rank];
223}
224
225/*---------------------------------------------------------------------------*/
226/*---------------------------------------------------------------------------*/
227
229Integer global_size, IMessagePassingMng* parallel_mng)
230: Internal(Space(global_size), parallel_mng)
231{}
232
233/*---------------------------------------------------------------------------*/
234/*---------------------------------------------------------------------------*/
235
237Integer global_size, std::shared_ptr<IMessagePassingMng> parallel_mng)
238: Internal(Space(global_size), parallel_mng)
239{}
240
241/*---------------------------------------------------------------------------*/
242/*---------------------------------------------------------------------------*/
243
245const ISpace& space, Integer local_size, IMessagePassingMng* parallel_mng)
247, m_parallel_mng(std::shared_ptr<IMessagePassingMng>(
248 parallel_mng, [](IMessagePassingMng*) {})) // Do not use delete
249, m_rank(0)
250, m_global_size(m_space->size())
251, m_local_size(local_size)
252, m_offset(0)
253{
254 if (!parallel_mng)
255 return;
256 m_rank = m_parallel_mng->commRank();
257 Integer np = parallel_mng->commSize();
258 UniqueArray<Integer> lsize(np, 0);
259 lsize[m_rank] = m_local_size;
260 Arccore::MessagePassing::mpAllReduce(
261 m_parallel_mng.get(), Arccore::MessagePassing::ReduceMax, lsize.view());
262 Integer gsize = std::accumulate(lsize.begin(), lsize.end(), 0);
263 if (gsize != m_global_size) {
264 alien_fatal([&] {
265 cout() << "error, expected global size (" << m_global_size
266 << ") is not equal to computed global size (" << gsize << ")";
267 });
268 }
269 m_offsets.resize(np, 0);
270 auto tmp = 0;
271 for (Integer i = 1; i < np; ++i) {
272 tmp += lsize[i - 1];
273 m_offsets[i] = tmp;
274 }
275 m_offsets.add(m_global_size);
276 m_offset = m_offsets[m_rank];
277}
278
279/*---------------------------------------------------------------------------*/
280/*---------------------------------------------------------------------------*/
281
283 std::shared_ptr<IMessagePassingMng> parallel_mng)
285, m_parallel_mng(parallel_mng)
286, m_rank(0)
287, m_global_size(m_space->size())
288, m_local_size(local_size)
289, m_offset(0)
290{
291 if (!parallel_mng)
292 return;
293 m_rank = m_parallel_mng->commRank();
294 Integer np = parallel_mng->commSize();
295 UniqueArray<Integer> lsize(np, 0);
296 lsize[m_rank] = m_local_size;
297 Arccore::MessagePassing::mpAllReduce(
298 m_parallel_mng.get(), Arccore::MessagePassing::ReduceMax, lsize.view());
299 Integer gsize = std::accumulate(lsize.begin(), lsize.end(), 0);
300 if (gsize != m_global_size) {
301 alien_fatal([&] {
302 cout() << "error, expected global size (" << m_global_size
303 << ") is not equal to computed global size (" << gsize << ")";
304 });
305 }
306 m_offsets.resize(np, 0);
307 auto tmp = 0;
308 for (Integer i = 1; i < np; ++i) {
309 tmp += lsize[i - 1];
310 m_offsets[i] = tmp;
311 }
314}
315
316/*---------------------------------------------------------------------------*/
317/*---------------------------------------------------------------------------*/
318
320Integer global_size, Integer local_size, IMessagePassingMng* parallel_mng)
321: Internal(Space(global_size), local_size, parallel_mng)
322{}
323
324/*---------------------------------------------------------------------------*/
325/*---------------------------------------------------------------------------*/
326
327VectorDistribution::Internal::Internal(Integer global_size, Integer local_size,
328 std::shared_ptr<IMessagePassingMng> parallel_mng)
329: Internal(Space(global_size), local_size, parallel_mng)
330{}
331
332/*---------------------------------------------------------------------------*/
333/*---------------------------------------------------------------------------*/
334
336{
337 return ((dist.m_parallel_mng == m_parallel_mng) && (dist.m_rank == m_rank) && (dist.m_global_size == m_global_size) && (dist.m_local_size == m_local_size) && (dist.m_offset == m_offset));
338}
339
340/*---------------------------------------------------------------------------*/
341/*---------------------------------------------------------------------------*/
342
344{
345 return (m_parallel_mng != nullptr) && (m_parallel_mng->commSize() > 1);
346}
347
348/*---------------------------------------------------------------------------*/
349/*---------------------------------------------------------------------------*/
350
351Integer
353{
354 // TODO: use a dichotomous search to accelerate search
355 // on the proc
356 if (i >= m_offset && i < m_offsets[m_rank + 1]) {
357 return m_rank;
358 }
359 // else on proc > rank
360 if (i < m_offset) {
361 for (int rk = m_rank - 1; rk > 0; --rk) {
362 if (i >= m_offsets[rk]) {
363 return rk;
364 }
365 }
366 return 0;
367 }
368 else { // or on proc < rank
369 Integer np = m_parallel_mng->commSize();
370 for (int rk = m_rank + 1; rk < np - 1; ++rk) {
371 if (i < m_offsets[rk + 1]) {
372 return rk;
373 }
374 }
375 return np - 1;
376 }
377}
378
379/*---------------------------------------------------------------------------*/
380/*---------------------------------------------------------------------------*/
381
383: m_internal(std::make_shared<Internal>())
384{
385 alien_debug([&] { cout() << "Create Empty VectorDistribution"; });
386}
387
388/*---------------------------------------------------------------------------*/
389/*---------------------------------------------------------------------------*/
390
392const ISpace& space, IMessagePassingMng* parallel_mng)
393: m_internal(std::make_shared<Internal>(space, parallel_mng))
394{
395 alien_debug(
396 [&] { cout() << "Create VectorDistribution(global=" << space.size() << ")"; });
397}
398
399/*---------------------------------------------------------------------------*/
400/*---------------------------------------------------------------------------*/
401
403const ISpace& space, std::shared_ptr<IMessagePassingMng> parallel_mng)
404: m_internal(std::make_shared<Internal>(space, parallel_mng))
405{
406 alien_debug(
407 [&] { cout() << "Create VectorDistribution(global=" << space.size() << ")"; });
408}
409
410/*---------------------------------------------------------------------------*/
411/*---------------------------------------------------------------------------*/
412
414Integer global_size, IMessagePassingMng* parallel_mng)
415: m_internal(std::make_shared<Internal>(global_size, parallel_mng))
416{
417 alien_debug(
418 [&] { cout() << "Create VectorDistribution(global=" << global_size << ")"; });
419}
420
421/*---------------------------------------------------------------------------*/
422/*---------------------------------------------------------------------------*/
423
425const ISpace& space, Integer local_size, IMessagePassingMng* parallel_mng)
426: m_internal(std::make_shared<Internal>(space, local_size, parallel_mng))
427{
428 alien_debug([&] {
429 cout() << "Create VectorDistribution(global=" << space.size()
430 << "local=" << local_size << ")";
431 });
432}
433
434/*---------------------------------------------------------------------------*/
435/*---------------------------------------------------------------------------*/
436
437VectorDistribution::VectorDistribution(const ISpace& space, Integer local_size,
438 std::shared_ptr<IMessagePassingMng> parallel_mng)
439: m_internal(std::make_shared<Internal>(space, local_size, parallel_mng))
440{
441 alien_debug([&] {
442 cout() << "Create VectorDistribution(global=" << space.size()
443 << "local=" << local_size << ")";
444 });
445}
446
447/*---------------------------------------------------------------------------*/
448/*---------------------------------------------------------------------------*/
449
451Integer global_size, Integer local_size, IMessagePassingMng* parallel_mng)
452: m_internal(std::make_shared<Internal>(global_size, local_size, parallel_mng))
453{
454 alien_debug([&] {
455 cout() << "Create VectorDistribution(global=" << global_size << "local=" << local_size
456 << ")";
457 });
458}
459
460/*---------------------------------------------------------------------------*/
461/*---------------------------------------------------------------------------*/
462
463VectorDistribution::VectorDistribution(Integer global_size, Integer local_size,
464 std::shared_ptr<IMessagePassingMng> parallel_mng)
465: m_internal(std::make_shared<Internal>(global_size, local_size, parallel_mng))
466{
467 alien_debug([&] {
468 cout() << "Create VectorDistribution(global=" << global_size << "local=" << local_size
469 << ")";
470 });
471}
472
473/*---------------------------------------------------------------------------*/
474/*---------------------------------------------------------------------------*/
475
479
480/*---------------------------------------------------------------------------*/
481/*---------------------------------------------------------------------------*/
482
486
487/*---------------------------------------------------------------------------*/
488/*---------------------------------------------------------------------------*/
489
491
492/*---------------------------------------------------------------------------*/
493/*---------------------------------------------------------------------------*/
494
495const ISpace&
497{
498 return *m_internal->m_space;
499}
500
501/*---------------------------------------------------------------------------*/
502/*---------------------------------------------------------------------------*/
503
506{
507 m_internal = dist.m_internal;
508 return *this;
509}
510
511/*---------------------------------------------------------------------------*/
512/*---------------------------------------------------------------------------*/
513
516{
517 m_internal = std::move(dist.m_internal);
518 return *this;
519}
520
521/*---------------------------------------------------------------------------*/
522/*---------------------------------------------------------------------------*/
523
525{
526 return *m_internal == *dist.m_internal;
527}
528
529/*---------------------------------------------------------------------------*/
530/*---------------------------------------------------------------------------*/
531
533{
534 return m_internal->isParallel();
535}
536
537/*---------------------------------------------------------------------------*/
538/*---------------------------------------------------------------------------*/
539
540Integer
542{
543 return m_internal->owner(i);
544}
545
546/*---------------------------------------------------------------------------*/
547/*---------------------------------------------------------------------------*/
548
549std::shared_ptr<IMessagePassingMng>
551{
552 return m_internal->m_parallel_mng;
553}
554
555/*---------------------------------------------------------------------------*/
556/*---------------------------------------------------------------------------*/
557
558IMessagePassingMng*
560{
561 return m_internal->m_parallel_mng.get();
562}
563
564/*---------------------------------------------------------------------------*/
565/*---------------------------------------------------------------------------*/
566
567Integer
569{
570 return m_internal->m_local_size;
571}
572
573/*---------------------------------------------------------------------------*/
574/*---------------------------------------------------------------------------*/
575
576Integer
578{
579 return m_internal->m_global_size;
580}
581
582/*---------------------------------------------------------------------------*/
583/*---------------------------------------------------------------------------*/
584
585Integer
587{
588 return m_internal->m_offset;
589}
590
591/*---------------------------------------------------------------------------*/
592/*---------------------------------------------------------------------------*/
593
594Integer
595VectorDistribution::offset(Integer p) const
596{
597 return m_internal->m_offsets[p];
598}
599
600/*---------------------------------------------------------------------------*/
601/*---------------------------------------------------------------------------*/
602
603ConstArrayView<Integer>
605{
606 return m_internal->m_offsets.constView();
607}
608
609/*---------------------------------------------------------------------------*/
610/*---------------------------------------------------------------------------*/
611
612std::shared_ptr<VectorDistribution>
614{
615 return std::make_shared<VectorDistribution>(*this);
616}
617
618/*---------------------------------------------------------------------------*/
619/*---------------------------------------------------------------------------*/
620
621Integer
623{
624 return i - m_internal->m_offset;
625}
626
627/*---------------------------------------------------------------------------*/
628/*---------------------------------------------------------------------------*/
629
630Integer
631VectorDistribution::globalToLocal(Integer i, Integer p) const
632{
633 return i - m_internal->m_offsets[p];
634}
635
636/*---------------------------------------------------------------------------*/
637/*---------------------------------------------------------------------------*/
638
639Integer
641{
642 return i + m_internal->m_offset;
643}
644
645/*---------------------------------------------------------------------------*/
646/*---------------------------------------------------------------------------*/
647
648Integer
649VectorDistribution::localToGlobal(Integer i, Integer p) const
650{
651 return i + m_internal->m_offsets[p];
652}
653
654/*---------------------------------------------------------------------------*/
655/*---------------------------------------------------------------------------*/
656
657std::ostream&
658operator<<(std::ostream& nout, const VectorDistribution& dist)
659{
660 nout << "1d distributed";
661 if (dist.isParallel()) {
662 nout << ", parallel";
663 }
664 nout << ", global size=" << dist.globalSize();
665 nout << ", local size=" << dist.localSize();
666 nout << ", offset=" << dist.offset();
667 return nout;
668}
669
670/*---------------------------------------------------------------------------*/
671/*---------------------------------------------------------------------------*/
672
673} // namespace Alien
674
675/*---------------------------------------------------------------------------*/
676/*---------------------------------------------------------------------------*/
Space.h.
VectorDistribution.h.
Interface for algebraic space objects.
Definition ISpace.h:44
virtual Arccore::Integer size() const =0
Get space size.
Implementation of an algebraic space.
Definition Space.h:47
Computes a vector distribution.
VectorDistribution & operator=(const VectorDistribution &dist)
Equal operator.
std::shared_ptr< VectorDistribution > clone() const
Clone the distribution.
bool operator==(const VectorDistribution &dist) const
Comparison operator.
std::shared_ptr< Arccore::MessagePassing::IMessagePassingMng > sharedParallelMng() const
Get the parallel manager.
Arccore::Integer offset() const
Get the offset.
Arccore::ConstArrayView< Integer > offsets() const
Get all the offsets.
const ISpace & space() const
Get the space.
Arccore::Integer owner(Arccore::Integer i) const
Get the owner of an entry.
Arccore::Integer localToGlobal(Arccore::Integer i) const
Get the global id of an elements with its local id.
Arccore::Integer globalToLocal(Arccore::Integer i) const
Get the local id of an elements with its global id.
Arccore::Integer localSize() const
Get the local size.
bool isParallel() const
Whether or not the run is parallel.
Arccore::Integer globalSize() const
Get the global size.
Arccore::MessagePassing::IMessagePassingMng * parallelMng() const
Get the parallel manager.
~VectorDistribution()
Free resources.
std::shared_ptr< Internal > m_internal
Internal implementation of the vector distribution.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17
std::ostream & operator<<(std::ostream &nout, const MatrixDistribution &dist)
Print the distribution.
Internal implementation of the vector distribution.
~Internal()=default
Free resources.
Integer owner(Integer i) const
Get the owner of an entry.
std::shared_ptr< IMessagePassingMng > m_parallel_mng
The parallel manager.
UniqueArray< Integer > m_offsets
The array of offsets for all proc.
bool operator==(const Internal &dist) const
Comparison operator.
std::shared_ptr< ISpace > m_space
The space.
bool isParallel() const
Whether or not the run is parallel.