44 typedef MatrixT MatrixType;
45 typedef typename MatrixType::ValueType ValueType;
48 LUSendRecvOp(MatrixType& matrix,
50 std::vector<int>& work,
51 Arccore::ITraceMng* trace_mng =
nullptr)
53 , m_distribution(distribution)
55 , m_send_info(matrix.getDistStructInfo().m_send_info)
56 , m_recv_info(matrix.getDistStructInfo().m_recv_info)
57 , m_parallel_mng(matrix.getParallelMng())
60 initSendRecvConnectivity();
63 void initSendRecvConnectivity()
68 auto nrows = view.nrows() ;
69 auto kcol = view.kcol() ;
71 auto cols = view.cols() ;
73 auto& local_row_size = m_matrix.getDistStructInfo().m_local_row_size;
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;
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];
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) {
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;
111 void sendUpperNeighbLUData(ValueType* values)
115 auto nrows = modifier.nrows() ;
117 auto kcol = modifier.kcol() ;
118 auto dcol = modifier.dcol() ;
119 auto cols = modifier.cols() ;
123 auto max_row_size = m_matrix.getProfile().getMaxRowSize();
124 auto& local_row_size = m_matrix.getDistStructInfo().m_local_row_size;
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];
134 buffer.reserve(nb_send_rows * max_row_size);
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]);
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]);
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);
162 void recvLowerNeighbLUData(ValueType* values)
166 auto nrows = modifier.nrows() ;
167 auto kcol = modifier.kcol() ;
168 auto cols = modifier.cols() ;
171 auto& local_row_size = m_matrix.getDistStructInfo().m_local_row_size;
174 int my_rank = m_parallel_mng->commRank();
175 int my_domain_offset = distribution.offset(my_rank);
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);
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) {
201 for (
int k = kcol[conn_row]; k < kcol[conn_row] + local_row_size[conn_row]; ++k) {
205 std::map<int, int>& inv_ids = m_mpi_ext_inv_ids[ineighb];
206 ValueType aik = values[krow] / buffer[icount2];
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];
216 values[kj] -= aik * buffer[icount2 + k];
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];
227 values[kj] -= aik * buffer[icount2 + int_row_size + k];
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];
236 values[kj] -= aik * buffer[icount2 + int_row_size + k];
242 for (
int k = krow + 1; k < kcol[conn_row + 1]; ++k) {
243 m_work[cols[k]] = -1;
245 for (
int k = kcol[conn_row]; k < kcol[conn_row] + local_row_size[conn_row]; ++k) {
246 m_work[cols[k]] = -1;
249 icount += int_row_size + ext_row_size;
250 icount2 += int_row_size + ext_row_size;
257 MatrixType& m_matrix;
259 std::vector< int >& m_work;
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;
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 ;
272 Arccore::MessagePassing::IMessagePassingMng* m_parallel_mng =
nullptr;
273 Arccore::ITraceMng* m_trace =
nullptr;