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