Alien  1.3.0
Developer documentation
Loading...
Searching...
No Matches
DoKDistributorComm.cc
1/*
2
3Copyright 2020 IFPEN-CEA
4
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16*/
17
18#include "DoKDistributorComm.h"
19
20#include <alien/kernels/redistributor/RedistributorCommPlan.h>
21
22namespace Alien
23{
24using namespace Arccore;
25
27: m_comm_plan(commPlan)
28, m_pm_super(m_comm_plan->superParallelMng())
29, m_pm_dst(m_comm_plan->tgtParallelMng().get())
30{}
31
32void DoKDistributorComm::computeCommPlan(const Arccore::Span<Int32> base)
33{
34 Int32 super_comm_size = m_pm_super->commSize();
35
36 // This array will contain the target distribution, relative to the super communication
37 // manager.
38 ConstArrayView<Int32> tgt_dist = m_comm_plan->tgtDist();
39
40 // Now, all processors know the target data distribution.
41 auto size = base.size();
42
43 Int32 p = 0;
44 // I prefer to pass p and rowid in an explicit way !
45 auto is_mine = [&](Int32 p, Int32 rowid) {
46 return (tgt_dist[p] <= rowid) && (rowid < tgt_dist[p + 1]);
47 };
48
49 m_snd_offset.resize(super_comm_size + 1);
50 m_snd_offset.fill(-1);
51 m_snd_offset[0] = 0;
52 int i = 0;
53 for (auto row_id : base) {
54 while (p < super_comm_size // Check if p is valid
55 && (!is_mine(p, row_id))) {
56 p++;
57 m_snd_offset[p] = i;
58 }
59 i++;
60 }
61 for (int p2 = p; p2 < super_comm_size; p2++) {
62 m_snd_offset[p2 + 1] = size;
63 }
64
65 UniqueArray<Int32> snd_count(super_comm_size);
66 Alien::RedistributionTools::computeCounts(m_snd_offset.constView(), snd_count.view());
67 m_rcv_offset.resize(super_comm_size + 1);
68 UniqueArray<Int32> rcv_count(super_comm_size);
69
70 Arccore::MessagePassing::mpAllToAll(m_pm_super, snd_count, rcv_count, 1);
71
72 m_rcv_offset[0] = 0;
73 for (p = 0; p < super_comm_size; ++p) {
74 m_rcv_offset[p + 1] = m_rcv_offset[p] + rcv_count[p];
75 }
76}
77
78void DoKDistributorComm::computeCommPlan(IReverseIndexer* rev_index)
79{
80 // Now, all processors know the target data distribution.
81 Int32 size = 0;
82 if (rev_index) {
83 size = rev_index->size();
84 }
85
86 // Prepare communication buffer
87 UniqueArray<Int32> snd_rows(size, 0);
88 UniqueArray<Int32> snd_cols(size, 0);
89
90 for (IReverseIndexer::Offset offset = 0; offset < size; ++offset) {
91 auto ij = (*rev_index)[offset].value();
92 snd_rows[offset] = ij.first;
93 snd_cols[offset] = ij.second;
94 }
95
96 this->computeCommPlan(snd_rows);
97
98 // Arccore is not smart enough to resize reception buffers...
99 m_rcv_rows.resize(m_rcv_offset[m_pm_super->commSize()]);
100 m_rcv_cols.resize(m_rcv_offset[m_pm_super->commSize()]);
101
102 Alien::RedistributionTools::exchange(m_pm_super, snd_rows.constView(),
103 m_snd_offset.constView(), m_rcv_rows.view(), m_rcv_offset.constView());
104 Alien::RedistributionTools::exchange(m_pm_super, snd_cols.constView(),
105 m_snd_offset.constView(), m_rcv_cols.view(), m_rcv_offset.constView());
106}
107
108} // namespace Alien
DoKDistributorComm(const RedistributorCommPlan *commPlan)
Construct a DoKDistributorComm object over parallelMng:
Reverse indexer: associates an Index (i,j) to an offset.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17