Code_Saturne
CFD tool
fvm_gather.h
Go to the documentation of this file.
1 #ifndef __FVM_GATHER_H__
2 #define __FVM_GATHER_H__
3 
4 /*============================================================================
5  * Base functions for parallelism
6  *============================================================================*/
7 
8 /*
9  This file is part of Code_Saturne, a general-purpose CFD tool.
10 
11  Copyright (C) 1998-2012 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 #if defined(HAVE_MPI)
31 #include <mpi.h>
32 #endif
33 
34 /*----------------------------------------------------------------------------
35  * Local headers
36  *----------------------------------------------------------------------------*/
37 
38 #include "fvm_defs.h"
39 #include "fvm_io_num.h"
40 
41 /*----------------------------------------------------------------------------*/
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #if 0
46 } /* Fake brace to force back Emacs auto-indentation back to column 0 */
47 #endif
48 #endif /* __cplusplus */
49 
50 /*=============================================================================
51  * Macro definitions
52  *============================================================================*/
53 
54 /*============================================================================
55  * Type definitions
56  *============================================================================*/
57 
58 /*----------------------------------------------------------------------------
59  * Structure defining an I/O numbering scheme
60  *----------------------------------------------------------------------------*/
61 
62 #if defined(HAVE_MPI)
63 
64 /*
65  Pointer to structure keeping track of the status of a series of
66  fvm_gather_...() operations by slices of element global I/O number
67  intervals. The structure itself is private, and is defined in fvm_gather.c
68 */
69 
70 typedef struct _fvm_gather_slice_t fvm_gather_slice_t;
71 
72 #endif /* defined(HAVE_MPI) */
73 
74 /*=============================================================================
75  * Static global variables
76  *============================================================================*/
77 
78 /*=============================================================================
79  * Public function prototypes
80  *============================================================================*/
81 
82 #if defined(HAVE_MPI)
83 
84 /*----------------------------------------------------------------------------
85  * Create a fvm_gather_slice_t structure.
86  *
87  * parameters:
88  * entity_io_num <-- I/O numbering structure associated with slice entity
89  * slice_size <-- reference slice size
90  * comm <-- associated MPI communicator
91  *----------------------------------------------------------------------------*/
92 
93 fvm_gather_slice_t *
94 fvm_gather_slice_create(const fvm_io_num_t *entity_io_num,
95  const cs_gnum_t slice_size,
96  MPI_Comm comm);
97 
98 /*----------------------------------------------------------------------------
99  * Destroy a fvm_gather_slice_t structure.
100  *
101  * parameters:
102  * this_slice <-- pointer to structure that should be destroyed
103  *
104  * returns:
105  * NULL pointer
106  *----------------------------------------------------------------------------*/
107 
108 fvm_gather_slice_t *
109 fvm_gather_slice_destroy(fvm_gather_slice_t * this_slice);
110 
111 /*----------------------------------------------------------------------------
112  * Advance a fvm_gather_slice_t structure to the next start and end values.
113  *
114  * Elements within this slice will be those for whose global number
115  * is >= global_num_start and < global_num_end.
116  *
117  * parameters:
118  * this_slice <-- pointer to structure that should be advanced
119  * global_num_start --> new current global slice start number
120  * global_num_end --> new current global slice past the end number
121  *
122  * returns:
123  * 0 if the end of the slice has not been reached before this call,
124  * 1 if we have already attained the end of the slice.
125  *----------------------------------------------------------------------------*/
126 
127 int
128 fvm_gather_slice_advance(fvm_gather_slice_t *this_slice,
129  cs_gnum_t *global_num_start,
130  cs_gnum_t *global_num_end);
131 
132 /*----------------------------------------------------------------------------
133  * Reset a fvm_gather_slice_t structure to its initial state.
134  *
135  * parameters:
136  * this_slice <-- pointer to structure that should be reinitialized
137  *----------------------------------------------------------------------------*/
138 
139 void
140 fvm_gather_slice_reinitialize(fvm_gather_slice_t *this_slice);
141 
142 /*----------------------------------------------------------------------------
143  * Limit an fvm_gather_slice_t structure's end value.
144  *
145  * This allows setting a lower global_num_end value than that previously
146  * defined (which may be necessary when buffer size limits require it).
147  *
148  * parameters:
149  * this_slice <-- pointer to structure that should be advanced
150  * global_num_end --> new current global slice past the end number
151  *----------------------------------------------------------------------------*/
152 
153 void
154 fvm_gather_slice_limit(fvm_gather_slice_t *this_slice,
155  cs_gnum_t *global_num_end);
156 
157 /*----------------------------------------------------------------------------
158  * Build a slice index (0 to n-1 numbering) on rank 0 from local index arrays.
159  *
160  * This is done by computing the local block lengths from the local
161  * index, gathering those lengths to rank 0, and rebuilding a 0 to n-1
162  * numbered slice index on rank 0.
163  *
164  * This function is intended to be used within a loop on subsets of the global
165  * lengths array (so as to enable writing to file or sending to an
166  * external process without requiring the full array to reside in the process
167  * directly handling I/O's memory). As such, it avoids allocating its own
168  * working arrays (buffers), so that they may be allocated outside the loop
169  * and reused for each call (avoiding the overhead associated with memory
170  * allocation).
171  *
172  * All or most elements in a given portion may belong to a same process rank
173  * (depending on mesh numbering and domain splitting). To account for
174  * this, for each process rank, the slice_index[] arrays must be large
175  * enough to contain (slice_size * stride) values, even though most processes
176  * will require less.
177  *
178  * parameters:
179  * local_index <-- local index array
180  * slice_index --> global slice index section for elements
181  * slice global_num_start to global_num_end
182  * (output for rank 0, working array only for others)
183  * element_io_num <-- I/O numbering structure associated with elements
184  * comm <-- MPI communicator for structures considered
185  * this_slice <-> structure for management of slice status
186  *----------------------------------------------------------------------------*/
187 
188 void
189 fvm_gather_slice_index(const cs_lnum_t local_index[],
190  cs_gnum_t slice_index[],
191  const fvm_io_num_t *element_io_num,
192  MPI_Comm comm,
193  fvm_gather_slice_t *this_slice);
194 
195 /*----------------------------------------------------------------------------
196  * Recompute maximum value of global_num_end and slice connectivity size for
197  * an indexed connectivity slice.
198  *
199  * Given an initial global connectivity buffer size associated with the
200  * slice (global_connect_s_size), this function verifies that the connectivity
201  * associated with the slice from global_num_start to global_num_end may fit
202  * in this buffer. If this is not the case, global_num_end is reduced to the
203  * largest value such that the associated indexed connectivity or values may
204  * fit in the indicated buffer size.
205  *
206  * In any case, slice size will neither be increased above the current
207  * slice size, nor be reduced to less than
208  * than min(n_g_elements, n_elements_s_min) if initially larger than this.
209  * If necessary, global_connect_s_size is increased so that this minimal
210  * slice may fit in a buffer of this same size.
211  *
212  * parameters:
213  * n_elements_s_min <-- minimum number of elements per slice desired
214  * global_num_end --> new current global slice past the end number
215  * global_connect_s_size <-> pointer to global connectivity slice size
216  * comm <-- associated MPI communicator
217  * slice_index <-- index of blocks corresponding to a given
218  * element in the global_connect_s array
219  * (required for rank 0 only)
220  * this_slice <-> structure for management of slice status
221  *----------------------------------------------------------------------------*/
222 
223 void
224 fvm_gather_resize_indexed_slice(const cs_gnum_t n_elements_s_min,
225  cs_gnum_t *global_num_end,
226  cs_gnum_t *global_connect_s_size,
227  MPI_Comm comm,
228  const cs_gnum_t slice_index[],
229  fvm_gather_slice_t *this_slice);
230 
231 /*----------------------------------------------------------------------------
232  * Gather a given portion of an array to rank 0.
233  *
234  * This function is intended to be used within a loop on subsets of the global
235  * array (so as to enable writing to file or sending to an external process
236  * without requiring the full array to reside in the process directly
237  * handling I/O's memory). As such, it avoids allocating its own working arrays
238  * (buffers), so that they may be allocated outside the loop and reused for
239  * each call (avoiding the overhead associated with memory allocation).
240  *
241  * All or most elements in a given portion may belong to a same process rank
242  * (depending on mesh numbering and domain splitting). To account for
243  * this, for each process rank, the global_array_s[] array must be large
244  * enough to contain (slice_size * stride) values, even though most processes
245  * will require less.
246  *
247  * parameters:
248  * local_array <-- local array (size n_local_elements * stride)
249  * global_array_s --> global array section for elements
250  * slice global_num_start to global_num_end
251  * (output for rank 0, working array only for others)
252  * datatype <-- MPI datatype of each value
253  * stride <-- number of (interlaced) values per element
254  * element_io_num <-- I/O numbering structure associated with elements
255  * comm <-- MPI communicator for structures considered
256  * this_slice <-> structure for management of slice status
257  *----------------------------------------------------------------------------*/
258 
259 void
260 fvm_gather_array(const void *local_array,
261  void *global_array_s,
262  MPI_Datatype datatype,
263  size_t stride,
264  const fvm_io_num_t *element_io_num,
265  MPI_Comm comm,
266  fvm_gather_slice_t *this_slice);
267 
268 /*----------------------------------------------------------------------------
269  * Gather a given portion of an indexed array of to rank 0.
270  *
271  * A slice_index[] array indicating the index (0 to n-1) of blocks in
272  * the slice is required for rank 0. This implies that the block sizes in
273  * the slice have already been gathered through the use of
274  * fvm_gather_slice_index() or some similar method, and used to build this
275  * slice index.
276  *
277  * This function is intended to be used within a loop on subsets of the global
278  * lengths array (so as to enable writing to file or sending to an
279  * external process without requiring the full array to reside in the process
280  * directly handling I/O's memory). As such, it avoids allocating its own
281  * working arrays (buffers), so that they may be allocated outside the loop
282  * and reused for each call (avoiding the overhead associated with memory
283  * allocation).
284  *
285  * All or most elements in a given portion may belong to a same process rank
286  * (depending on mesh numbering and domain splitting). To account for
287  * this, for each process rank, the global_lengths_s[] arrays must be large
288  * enough to contain (slice_index[current_slice_size] - 1) values, even
289  * though most processes will require less.
290  * Use fvm_gather_resize_indexed_slice() to adjust current_slice_size.
291  *
292  * parameters:
293  * local_array <-- local array
294  * (size: local_index[n_local_elements] * stride)
295  * global_array_s --> global array section for elements
296  * slice global_num_start to global_num_end
297  * (output for rank 0, working array only for others)
298  * datatype <-- MPI datatype of each value
299  * local_index <-- local index array
300  * element_io_num <-- I/O numbering structure associated with elements
301  * comm <-- MPI communicator for structures considered
302  * slice_index <-- index of blocks corresponding to a given
303  * element in the global_numbers_s array
304  * (required for rank 0 only)
305  * this_slice <-> structure for management of slice status
306  *----------------------------------------------------------------------------*/
307 
308 void
309 fvm_gather_indexed(const void *local_array,
310  void *global_array_s,
311  const MPI_Datatype datatype,
312  const cs_lnum_t local_index[],
313  const fvm_io_num_t *element_io_num,
314  MPI_Comm comm,
315  const cs_gnum_t slice_index[],
316  fvm_gather_slice_t *this_slice);
317 
318 /*----------------------------------------------------------------------------
319  * Gather a given portion of a strided (i.e. regular) connectivity array
320  * to rank 0. Connectivity values are converted from local to global values
321  * (both with 1 to n type numbering).
322  *
323  * This function is intended to be used within a loop on subsets of the global
324  * connectivity array (so as to enable writing to file or sending to an
325  * external process without requiring the full array to reside in the process
326  * directly handling I/O's memory). As such, it avoids allocating its own
327  * working arrays (buffers), so that they may be allocated outside the loop
328  * and reused for each call (avoiding the overhead associated with memory
329  * allocation).
330  *
331  * All or most elements in a given portion may belong to a same process rank
332  * (depending on mesh numbering and domain splitting). To account for
333  * this, for each process rank, the global_connect_s[] array must be large
334  * enough to contain (slice_size * stride) values, even though most processes
335  * will require less.
336  *
337  * parameters:
338  * local_connect <-- local connectivity array (1 to n numbering)
339  * global_connect_s --> global connectivity array section for elements
340  * slice global_num_start to global_num_end
341  * (output for rank 0, working array only for others)
342  * stride <-- number of connected entities (i.e. vertices in
343  * a nodal connectivity) per element
344  * connected_io_num <-- I/O numbering structure associated with "connected"
345  * entities (i.e. vertices in a nodal connectivity)
346  * element_io_num <-- I/O numbering structure associated with elements
347  * comm <-- MPI communicator for structures considered
348  * this_slice <-> structure for management of slice status
349  *----------------------------------------------------------------------------*/
350 
351 void
352 fvm_gather_strided_connect(const cs_lnum_t local_connect[],
353  cs_gnum_t global_connect_s[],
354  const int stride,
355  const fvm_io_num_t *connected_io_num,
356  const fvm_io_num_t *element_io_num,
357  MPI_Comm comm,
358  fvm_gather_slice_t *this_slice);
359 
360 /*----------------------------------------------------------------------------
361  * Gather a given portion of an indexed array of numbers to rank 0.
362  * If the connected_io_num argument is non-NULL, these numbers
363  * are assumed to represent connectivity values, and are converted from
364  * local to global values (both with 1 to n type numbering).
365  * Otherwise, they are considered to represent any other type of positive
366  * integer (such as the number of vertices for each of a polyhedron's faces).
367  *
368  * A slice_index[] array indicating the index (0 to n-1) of blocks in
369  * the slice is required for rank 0. This implies that the block sizes in
370  * the slice have already been gathered through the use of
371  * fvm_gather_slice_index() or some similar method, and used to build this
372  * slice index.
373  *
374  * This function is intended to be used within a loop on subsets of the global
375  * lengths array (so as to enable writing to file or sending to an
376  * external process without requiring the full array to reside in the process
377  * directly handling I/O's memory). As such, it avoids allocating its own
378  * working arrays (buffers), so that they may be allocated outside the loop
379  * and reused for each call (avoiding the overhead associated with memory
380  * allocation).
381  *
382  * All or most elements in a given portion may belong to a same process rank
383  * (depending on mesh numbering and domain splitting). To account for
384  * this, for each process rank, the global_lengths_s[] arrays must be large
385  * enough to contain (slice_index[slice_size] - 1) values, even though most
386  * processes will require less.
387  * Use fvm_gather_resize_indexed_slice() to adjust current_slice_size.
388  *
389  * parameters:
390  * local_index <-- local index array
391  * local_numbers <-- local numbers array
392  * global_numbers_s --> global numbers array section for elements
393  * slice global_num_start to global_num_end
394  * (output for rank 0, working array only for others)
395  * connected_io_num <-- I/O numbering structure associated with "connected"
396  * entities (i.e. vertices in a nodal connectivity)
397  * element_io_num <-- I/O numbering structure associated with elements
398  * comm <-- MPI communicator for structures considered
399  * slice_index <-- index of blocks corresponding to a given
400  * element in the global_numbers_s array
401  * (required for rank 0 only)
402  * this_slice <-> structure for management of slice status
403  *----------------------------------------------------------------------------*/
404 
405 void
406 fvm_gather_indexed_numbers(const cs_lnum_t local_index[],
407  const cs_lnum_t local_numbers[],
408  cs_gnum_t global_numbers_s[],
409  const fvm_io_num_t *connected_io_num,
410  const fvm_io_num_t *element_io_num,
411  MPI_Comm comm,
412  const cs_gnum_t slice_index[],
413  fvm_gather_slice_t *this_slice);
414 
415 #endif /* defined(HAVE_MPI) */
416 
417 /*----------------------------------------------------------------------------*/
418 
419 #ifdef __cplusplus
420 }
421 #endif /* __cplusplus */
422 
423 #endif /* __FVM_GATHER_H__ */
Definition: fvm_io_num.c:120
int cs_lnum_t
Definition: cs_defs.h:260
unsigned cs_gnum_t
Definition: cs_defs.h:255