9.2
general documentation
cs_redistribute.h
Go to the documentation of this file.
1#ifndef CS_REDISTRIBUTE_H
2#define CS_REDISTRIBUTE_H
3
4/*============================================================================
5 * Redistribution of mesh and field data.
6 *============================================================================*/
7
8/*
9 This file is part of code_saturne, a general-purpose CFD tool.
10
11 Copyright (C) 1998-2026 EDF S.A.
12
13 This program is free software; you can redistribute it and/or modify it under
14 the terms of the GNU General Public License as published by the Free Software
15 Foundation; either version 2 of the License, or (at your option) any later
16 version.
17
18 This program is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
21 details.
22
23 You should have received a copy of the GNU General Public License along with
24 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
25 Street, Fifth Floor, Boston, MA 02110-1301, USA.
26*/
27
28/*----------------------------------------------------------------------------*/
29
30/*----------------------------------------------------------------------------
31 * Local headers
32 *----------------------------------------------------------------------------*/
33
34#include "base/cs_all_to_all.h"
35#include "base/cs_algorithm.h"
36
37/*============================================================================
38 * Type definitions
39 *============================================================================*/
40
41#if defined(HAVE_MPI)
42
51};
52
53#endif
54
55/*============================================================================
56 * Public function definitions
57 *============================================================================*/
58
59#if defined(HAVE_MPI)
60
61/*----------------------------------------------------------------------------*/
71/*----------------------------------------------------------------------------*/
72
73template <typename T>
74void
76 const int stride,
77 T *buffer[])
78{
79 if (buffer == nullptr || db == nullptr)
80 return;
81
82 T *_buffer = nullptr;
83
84 if (db->send_list) {
85
86 T *send_data = nullptr;
87 CS_MALLOC(send_data, stride * db->n_send, T);
88
89 _buffer = *buffer;
90
91 for (cs_lnum_t i = 0; i < db->n_send; i++) {
92 cs_lnum_t id = db->send_list[i];
93 for (int j = 0; j < stride; j++)
94 send_data[stride*i+j] = _buffer[stride*id+j];
95 }
96
97 CS_FREE(*buffer);
98 *buffer = send_data;
99
100 }
101
102 T *recv_data = cs_all_to_all_copy_array(db->d,
103 stride,
104 false,
105 *buffer);
106
107 CS_REALLOC(*buffer, db->n_uniq * stride, T);
108 _buffer = *buffer;
109
110 for (cs_lnum_t i = 0; i < db->n_recv; i++) {
111 cs_lnum_t ordered = db->recv_order[i];
112 cs_lnum_t local = db->ordered_to_local[ordered];
113 if (local == -1) continue;
114
115 for (int j = 0; j < stride; j++)
116 _buffer[stride*local+j] = recv_data[stride*ordered+j];
117 }
118
119 CS_FREE(recv_data);
120}
121
122/*----------------------------------------------------------------------------*/
136/*----------------------------------------------------------------------------*/
137
138template <typename T>
139void
141 const int stride,
142 const T send_buf[],
143 T recv_buf[])
144{
145 if (recv_buf == nullptr || db == nullptr)
146 return;
147
148 T *_send_buf = nullptr;
149
150 if (db->send_list) {
151
152 CS_MALLOC(_send_buf, stride * db->n_send, T);
153
154 for (cs_lnum_t i = 0; i < db->n_send; i++) {
155 cs_lnum_t id = db->send_list[i];
156 for (int j = 0; j < stride; j++)
157 _send_buf[stride*i+j] = send_buf[stride*id+j];
158 }
159
160 send_buf = _send_buf;
161
162 }
163
164 T *_recv_buf = cs_all_to_all_copy_array(db->d,
165 stride,
166 false,
167 send_buf);
168
169 CS_FREE(_send_buf);
170
171 for (cs_lnum_t i = 0; i < db->n_recv; i++) {
172 cs_lnum_t ordered = db->recv_order[i];
173 cs_lnum_t local = db->ordered_to_local[ordered];
174 if (local == -1) continue;
175
176 for (int j = 0; j < stride; j++)
177 recv_buf[stride*local+j] = _recv_buf[stride*ordered+j];
178 }
179
180 CS_FREE(_recv_buf);
181}
182
183/*----------------------------------------------------------------------------*/
194/*----------------------------------------------------------------------------*/
195
196template <typename T>
197void
199 cs_lnum_t *idx[],
200 T *buffer[])
201{
202 T *_buffer = nullptr;
203
204 cs_lnum_t *idx_s = nullptr;
205 CS_MALLOC(idx_s, db->n_send+1, cs_lnum_t);
206
207 cs_lnum_t *_idx = *idx;
208
209 for (cs_lnum_t i = 0; i < db->n_send; i++) {
210 cs_lnum_t id = db->send_list ? db->send_list[i] : i;
211 idx_s[i] = _idx[id+1] - _idx[id];
212 }
213
214 cs_lnum_t *idx_r = nullptr;
215 CS_MALLOC(idx_r, db->n_recv+1, cs_lnum_t);
216
218 1,
219 false,
220 idx_s,
221 idx_r);
222
223 // Build the buffer to send.
224
226 ctx.set_use_gpu(false);
227
228 cs::algorithm::count_to_index(ctx, db->n_send, idx_s);
229
230 if (db->send_list) {
231
232 T* send_data = nullptr;
233 CS_MALLOC(send_data, idx_s[db->n_send], T);
234
235 T* _send_data = send_data;
236 _buffer = *buffer;
237
238 for (cs_lnum_t i = 0; i < db->n_send; i++) {
239 cs_lnum_t id = db->send_list[i];
240 for (cs_lnum_t j = _idx[id]; j < _idx[id+1]; j++)
241 *_send_data++ = _buffer[j];
242 }
243
244 assert(_send_data - send_data == idx_s[db->n_send]);
245
246 CS_FREE(*buffer);
247 CS_FREE(*idx);
248
249 *buffer = send_data;
250 }
251
252 // Build the correct idx.
253
254 CS_REALLOC(*idx, db->n_uniq+1, cs_lnum_t);
255 _idx = *idx;
256
257 for (cs_lnum_t i = 0; i < db->n_recv; i++) {
258 cs_lnum_t ordered = db->recv_order[i];
259 cs_lnum_t local = db->ordered_to_local[ordered];
260 if (local == -1) continue;
261
262 _idx[local] = idx_r[ordered];
263 }
264
266
267 // Exchange buffer.
268
269 cs::algorithm::count_to_index(ctx, db->n_recv, idx_r);
270
271 T *_recv_data = cs_all_to_all_copy_indexed(db->d,
272 false,
273 idx_s,
274 *buffer,
275 idx_r);
276
277 CS_FREE(idx_s);
278
279 // Build the unique buffer.
280
281 CS_REALLOC(*buffer, _idx[db->n_uniq], T);
282 _buffer = *buffer;
283
284 for (cs_lnum_t i = 0; i < db->n_recv; i++) {
285 cs_lnum_t ordered = db->recv_order[i];
286 cs_lnum_t local = db->ordered_to_local[ordered];
287 if (local == -1) continue;
288
289 T *dst = _buffer + _idx[local];
290
291 for (cs_lnum_t j = idx_r[ordered]; j < idx_r[ordered+1]; j++)
292 *dst++ = _recv_data[j];
293 }
294
295 CS_FREE(_recv_data);
296 CS_FREE(idx_r);
297}
298
299void
301
302void
303cs_redistribute(const int cell_dest_rank[],
304 cs_distributor_t **cd,
305 cs_distributor_t **ifd,
306 cs_distributor_t **bfd,
307 cs_distributor_t **vd);
308
309#endif // defined(HAVE_MPI)
310
311/*----------------------------------------------------------------------------*/
312
313#endif /* CS_REDISTRIBUTE_H */
Definition: cs_dispatch.h:2288
void * cs_all_to_all_copy_array(cs_all_to_all_t *d, cs_datatype_t datatype, int stride, bool reverse, const void *src_data, void *dest_data)
Communicate array data using all-to-all distributor.
Definition: cs_all_to_all.cpp:2786
void * cs_all_to_all_copy_indexed(cs_all_to_all_t *d, cs_datatype_t datatype, bool reverse, const cs_lnum_t *src_index, const void *src_data, const cs_lnum_t *dest_index, void *dest_data)
Communicate local index using all-to-all distributor.
Definition: cs_all_to_all.cpp:3159
struct _cs_all_to_all_t cs_all_to_all_t
Definition: cs_all_to_all.h:77
int cs_lnum_t
local mesh entity id
Definition: cs_defs.h:325
#define CS_FREE(_ptr)
Definition: cs_mem.h:151
#define CS_REALLOC(_ptr, _ni, _type)
Reallocate memory for _ni elements of type _type.
Definition: cs_mem.h:111
#define CS_MALLOC(_ptr, _ni, _type)
Allocate memory for _ni elements of type _type.
Definition: cs_mem.h:75
void cs_distributor_destroy(cs_distributor_t **db)
Destroy a distributor structure.
Definition: cs_redistribute.cpp:729
void cs_distribute_buffer_indexed(const cs_distributor_t *db, cs_lnum_t *idx[], T *buffer[])
Distribute an indexed array and its corresponding index array using the distributor structure.
Definition: cs_redistribute.h:198
void cs_distribute_buffer(const cs_distributor_t *db, const int stride, T *buffer[])
Distribute a buffer using the distributor structure.
Definition: cs_redistribute.h:75
void cs_redistribute(const int cell_dest_rank[], cs_distributor_t **cd, cs_distributor_t **ifd, cs_distributor_t **bfd, cs_distributor_t **vd)
Redistribute mesh and field data based on a cell destination rank map.
Definition: cs_redistribute.cpp:770
void cs_distribute_buffer_allocated(const cs_distributor_t *db, const int stride, const T send_buf[], T recv_buf[])
Distribute a buffer using the distributor structure.
Definition: cs_redistribute.h:140
void count_to_index(cs_dispatch_context &ctx, cs_lnum_t n, cs_lnum_t a[], size_t tmp_size=0, void *tmp_storage=nullptr)
Definition: cs_redistribute.h:43
cs_lnum_t * ordered_to_local
Definition: cs_redistribute.h:50
cs_lnum_t n_send
Definition: cs_redistribute.h:45
cs_lnum_t * recv_order
Definition: cs_redistribute.h:49
cs_all_to_all_t * d
Definition: cs_redistribute.h:44
cs_lnum_t * send_list
Definition: cs_redistribute.h:48
cs_lnum_t n_uniq
Definition: cs_redistribute.h:47
cs_lnum_t n_recv
Definition: cs_redistribute.h:46