Alien  1.3.0
User documentation
Loading...
Searching...
No Matches
LUSendRecvOp.h
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* LUSendRecvOp.h (C) 2000-2024 */
9/* */
10/*---------------------------------------------------------------------------*/
11/*---------------------------------------------------------------------------*/
12
13#pragma once
14
15#include <vector>
16#include <map>
17
18#include <alien/kernels/simple_csr/SimpleCSRPrecomp.h>
19#include <alien/utils/Precomp.h>
20#include <alien/utils/Trace.h>
21
22#include <arccore/message_passing/Messages.h>
23#include <arccore/message_passing/Request.h>
24
25#include <alien/handlers/scalar/CSRModifierViewT.h>
26#include <alien/kernels/simple_csr/SendRecvOp.h>
27
30
31namespace Alien
32{
34}
35
36namespace Alien::SimpleCSRInternal
37{
38
39template <typename MatrixT>
40class LUSendRecvOp
41{
42 public:
43 // clang-format off
44 typedef MatrixT MatrixType;
45 typedef typename MatrixType::ValueType ValueType;
46 // clang-format on
47
48 LUSendRecvOp(MatrixType& matrix,
49 MatrixDistribution& distribution,
50 std::vector<int>& work,
51 Arccore::ITraceMng* trace_mng = nullptr)
52 : m_matrix(matrix)
53 , m_distribution(distribution)
54 , m_work(work)
55 , m_send_info(matrix.getDistStructInfo().m_send_info)
56 , m_recv_info(matrix.getDistStructInfo().m_recv_info)
57 , m_parallel_mng(matrix.getParallelMng())
58 , m_trace(trace_mng)
59 {
60 initSendRecvConnectivity();
61 }
62
63 void initSendRecvConnectivity()
64 {
65
66 CSRConstViewT<MatrixT> view(m_matrix);
67 // clang-format off
68 auto nrows = view.nrows() ;
69 auto kcol = view.kcol() ;
70 //auto dcol = view.dcol() ;
71 auto cols = view.cols() ;
72 // clang-format on
73 auto& local_row_size = m_matrix.getDistStructInfo().m_local_row_size;
74
75 //int my_rank = m_parallel_mng->commRank();
76
77 m_mpi_ext_inv_ids.resize(m_recv_info.m_first_upper_neighb);
78 for (int ineighb = 0; ineighb < m_recv_info.m_first_upper_neighb; ++ineighb) {
79 std::map<int, int>& inv_ids = m_mpi_ext_inv_ids[ineighb];
80 for (int i = m_recv_info.m_ids_offset[ineighb]; i < m_recv_info.m_ids_offset[ineighb]; ++i) {
81 inv_ids[m_recv_info.m_uids[i]] = i;
82 }
83 }
84 std::size_t recv_uids_size = m_recv_info.m_uids.size();
85 std::vector<int> conn_size(recv_uids_size);
86 std::fill(conn_size.begin(), conn_size.end(), 0);
87 for (std::size_t irow = 0; irow < nrows; ++irow) {
88 for (int k = kcol[irow] + local_row_size[irow]; k < kcol[irow + 1]; ++k) {
89 ++conn_size[cols[k] - nrows];
90 }
91 }
92 m_recv_connectivity_ids_ptr.resize(recv_uids_size + 1);
93 m_recv_connectivity_ids_ptr[0] = 0;
94 for (std::size_t i = 0; i < recv_uids_size; ++i)
95 m_recv_connectivity_ids_ptr[i + 1] = m_recv_connectivity_ids_ptr[i] + conn_size[i];
96 std::size_t total_conn_size = m_recv_connectivity_ids_ptr[recv_uids_size];
97 m_recv_connectivity_ids.resize(total_conn_size);
98 m_recv_connectivity_krow.resize(total_conn_size);
99 std::fill(conn_size.begin(), conn_size.end(), 0);
100 for (std::size_t irow = 0; irow < nrows; ++irow) {
101 for (auto k = kcol[irow] + local_row_size[irow]; k < kcol[irow + 1]; ++k) {
102 int col = cols[k];
103 auto id = col - nrows;
104 m_recv_connectivity_ids[m_recv_connectivity_ids_ptr[id] + conn_size[id]] = (int) irow;
105 m_recv_connectivity_krow[m_recv_connectivity_ids_ptr[id] + conn_size[id]] = k;
106 ++conn_size[id];
107 }
108 }
109 }
110
111 void sendUpperNeighbLUData(ValueType* values)
112 {
113 CSRModifierViewT<MatrixType> modifier(m_matrix);
114 // clang-format off
115 auto nrows = modifier.nrows() ;
116 //auto nnz = modifier.nnz() ;
117 auto kcol = modifier.kcol() ;
118 auto dcol = modifier.dcol() ;
119 auto cols = modifier.cols() ;
120 //auto values = modifier.data() ;
121 // clang-format on
122
123 auto max_row_size = m_matrix.getProfile().getMaxRowSize();
124 auto& local_row_size = m_matrix.getDistStructInfo().m_local_row_size;
125
126 m_send_lu_ibuffer.resize(m_send_info.m_num_neighbours - m_send_info.m_first_upper_neighb);
127 m_send_lu_buffer.resize(m_send_info.m_num_neighbours - m_send_info.m_first_upper_neighb);
128 for (int ineighb = m_send_info.m_first_upper_neighb; ineighb < m_send_info.m_num_neighbours; ++ineighb) {
129 int neighb = m_send_info.m_ranks[ineighb];
130 auto& ibuffer = m_send_lu_ibuffer[ineighb - m_send_info.m_first_upper_neighb];
131 auto& buffer = m_send_lu_buffer[ineighb - m_send_info.m_first_upper_neighb];
132 int nb_send_rows = m_send_info.m_ids_offset[ineighb + 1] - m_send_info.m_ids_offset[ineighb];
133 buffer.clear();
134 buffer.reserve(nb_send_rows * max_row_size);
135 ibuffer.clear();
136 ibuffer.reserve(nb_send_rows * max_row_size);
137 for (int i = m_send_info.m_ids_offset[ineighb]; i < m_send_info.m_ids_offset[ineighb + 1]; ++i) {
138 int irow = m_send_info.m_ids[i];
139 int lrow_size = local_row_size[irow];
140 int int_row_size = kcol[irow] + lrow_size - dcol[irow];
141 int ext_row_size = kcol[irow + 1] - kcol[irow] - lrow_size;
142 ibuffer.add(int_row_size);
143 ibuffer.add(ext_row_size);
144 for (int k = dcol[irow]; k < kcol[irow] + lrow_size; ++k) {
145 buffer.add(values[k]);
146 ibuffer.add(cols[k]);
147 }
148 for (int k = kcol[irow] + lrow_size; k < kcol[irow + 1]; ++k) {
149 buffer.add(values[k]);
150 ibuffer.add(m_recv_info.m_uids[cols[k] - nrows]);
151 }
152 }
153 UniqueArray<int> counts(2);
154 counts[0] = ibuffer.size();
155 counts[1] = buffer.size();
156 Arccore::MessagePassing::mpSend(m_parallel_mng, counts, neighb);
157 Arccore::MessagePassing::mpSend(m_parallel_mng, ibuffer, neighb);
158 Arccore::MessagePassing::mpSend(m_parallel_mng, buffer, neighb);
159 }
160 }
161
162 void recvLowerNeighbLUData(ValueType* values)
163 {
164 CSRModifierViewT<MatrixT> modifier(m_matrix);
165 // clang-format off
166 auto nrows = modifier.nrows() ;
167 auto kcol = modifier.kcol() ;
168 auto cols = modifier.cols() ;
169 //auto values = modifier.data() ;
170 // clang-format on
171 auto& local_row_size = m_matrix.getDistStructInfo().m_local_row_size;
172 auto const& distribution = m_distribution.rowDistribution();
173
174 int my_rank = m_parallel_mng->commRank();
175 int my_domain_offset = distribution.offset(my_rank);
176
177 m_recv_lu_ibuffer.resize(m_recv_info.m_first_upper_neighb);
178 m_recv_lu_buffer.resize(m_recv_info.m_first_upper_neighb);
179 for (int ineighb = 0; ineighb < m_recv_info.m_first_upper_neighb; ++ineighb) {
180 int neighb = m_recv_info.m_ranks[ineighb];
181 UniqueArray<int> counts(2);
182 Arccore::MessagePassing::mpReceive(m_parallel_mng, counts, neighb);
183 auto& ibuffer = m_recv_lu_ibuffer[ineighb];
184 auto& buffer = m_recv_lu_buffer[ineighb];
185 ibuffer.resize(counts[0]);
186 buffer.resize(counts[1]);
187 Arccore::MessagePassing::mpReceive(m_parallel_mng, ibuffer, neighb);
188 Arccore::MessagePassing::mpReceive(m_parallel_mng, buffer, neighb);
189 int icount = 0;
190 int icount2 = 0;
191 for (auto i = m_recv_info.m_ids_offset[ineighb]; i < m_recv_info.m_ids_offset[ineighb + 1]; ++i) {
192 auto irow = i - nrows;
193 int int_row_size = ibuffer[icount++];
194 int ext_row_size = ibuffer[icount++];
195 for (int conn_k = m_recv_connectivity_ids_ptr[irow]; conn_k < m_recv_connectivity_ids_ptr[irow + 1]; ++conn_k) {
196 auto conn_row = m_recv_connectivity_ids[conn_k];
197 auto krow = m_recv_connectivity_krow[conn_k];
198 for (int k = krow + 1; k < kcol[conn_row + 1]; ++k) {
199 m_work[cols[k]] = k;
200 }
201 for (int k = kcol[conn_row]; k < kcol[conn_row] + local_row_size[conn_row]; ++k) {
202 m_work[cols[k]] = k;
203 }
204
205 std::map<int, int>& inv_ids = m_mpi_ext_inv_ids[ineighb];
206 ValueType aik = values[krow] / buffer[icount2]; // aik = aik/akk
207 //MatrixDataType aik = mpi_ext_values[krow] / buffer[icount2 ]; // aik = aik/akk
208 values[krow] = aik;
209 for (int k = 1; k < int_row_size; ++k) {
210 int uid = ibuffer[icount + k];
211 std::map<int, int>::iterator iter = inv_ids.find(uid);
212 if (iter != inv_ids.end()) {
213 int lid = iter->second;
214 int kj = m_work[lid];
215 if (kj != -1) {
216 values[kj] -= aik * buffer[icount2 + k]; // aij = aij - aik*akj
217 }
218 }
219 }
220 for (int k = 0; k < ext_row_size; ++k) {
221 int uid = ibuffer[icount + int_row_size + k];
222 int owner = distribution.owner(uid);
223 if (owner == my_rank) {
224 int lid = uid - my_domain_offset;
225 int kj = m_work[lid];
226 if (kj != -1) {
227 values[kj] -= aik * buffer[icount2 + int_row_size + k]; // aij = aij - aik*akj
228 }
229 }
230 else {
231 std::map<int, int>::iterator iter = inv_ids.find(uid);
232 if (iter != inv_ids.end()) {
233 int lid = iter->second;
234 int kj = m_work[lid];
235 if (kj != -1) {
236 values[kj] -= aik * buffer[icount2 + int_row_size + k]; // aij = aij - aik*akj
237 }
238 }
239 }
240 }
241
242 for (int k = krow + 1; k < kcol[conn_row + 1]; ++k) {
243 m_work[cols[k]] = -1;
244 }
245 for (int k = kcol[conn_row]; k < kcol[conn_row] + local_row_size[conn_row]; ++k) {
246 m_work[cols[k]] = -1;
247 }
248 }
249 icount += int_row_size + ext_row_size;
250 icount2 += int_row_size + ext_row_size;
251 }
252 }
253 }
254
255 private:
256 // clang-format off
257 MatrixType& m_matrix;
258 MatrixDistribution& m_distribution ;
259 std::vector< int >& m_work;
260 const CommInfo& m_send_info;
261 const CommInfo& m_recv_info;
262 UniqueArray<UniqueArray<ValueType>> m_send_lu_buffer;
263 UniqueArray<UniqueArray<ValueType>> m_recv_lu_buffer;
264 UniqueArray<UniqueArray<int>> m_send_lu_ibuffer;
265 UniqueArray<UniqueArray<int>> m_recv_lu_ibuffer;
266
267 UniqueArray< int > m_recv_connectivity_ids ;
268 UniqueArray< int > m_recv_connectivity_krow ;
269 UniqueArray< int > m_recv_connectivity_ids_ptr ;
270 UniqueArray< std::map<int, int> > m_mpi_ext_inv_ids ;
271
272 Arccore::MessagePassing::IMessagePassingMng* m_parallel_mng = nullptr;
273 Arccore::ITraceMng* m_trace = nullptr;
274 // clang-format on
275};
276
277} // namespace Alien::SimpleCSRInternal
MatrixDistribution.h.
VectorDistribution.h.
Computes a matrix distribution.
const VectorDistribution & rowDistribution() const
Get the row distribution.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Definition BackEnd.h:17