src/base/cs_io.h Source File

| programmer's documentation

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cs_io.h
Go to the documentation of this file.
1 #ifndef __CS_IO_H__
2 #define __CS_IO_H__
3
4 /*============================================================================
5 * Low level file I/O utility functions for Preprocessor and restart files
6 *============================================================================*/
7
8 /*
9 This file is part of Code_Saturne, a general-purpose CFD tool.
10
11 Copyright (C) 1998-2013 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 "cs_base.h"
37 #include "cs_file.h"
38
39 /*----------------------------------------------------------------------------*/
40
41 BEGIN_C_DECLS
42
43 /*=============================================================================
44 * Local Macro Definitions
45 *============================================================================*/
46
47 #define CS_IO_NAME_LEN 32 /* Section header name length */
48
49 #define CS_IO_ECHO_NONE -2 /* No verbosity at all */
50 #define CS_IO_ECHO_OPEN_CLOSE -1 /* Echo open or close operations */
51 #define CS_IO_ECHO_HEADERS 0 /* Echo headers */
52
53 /*============================================================================
54 * Type definitions
55 *============================================================================*/
56
57 /* Input or output mode */
58
59 typedef enum {
60
61 CS_IO_MODE_READ,
62 CS_IO_MODE_WRITE
63
64 } cs_io_mode_t;
65
66 /* Structure associated with opaque pre-processing structure object */
67
68 typedef struct _cs_io_t cs_io_t;
69
70 /* Structure used to save section header data, so as to simplify
71 passing this data to various functions */
72
73 typedef struct {
74
75 const char *sec_name; /* Pointer to section name */
76 cs_file_off_t n_vals; /* Number of associated values */
77 size_t location_id; /* Id of associated location, or 0 */
78 size_t index_id; /* Id of associated index, or 0 */
79 size_t n_location_vals; /* Number of values per location */
80 cs_datatype_t elt_type; /* Type if n_elts > 0 */
81 cs_datatype_t type_read; /* Type in file */
82
83 } cs_io_sec_header_t;
84
85 /*=============================================================================
86 * Global variables
87 *============================================================================*/
88
89 /* Default hints for files using this API (for MPI-IO) */
90
91 extern int cs_glob_io_hints;
92
93 /*============================================================================
94 * Public function prototypes
95 *============================================================================*/
96
97 /*----------------------------------------------------------------------------
98 * Initialize a kernel IO file structure.
99 *
100 * The magic string may be NULL only in read mode;
101 *
102 * If the position of section bodies is already known (after initial
103 * analysis for example), the file may be opened for reading section bodies
104 * only by using "seek_read_section_bodies_only" as a magic string. This may
105 * be used to map another type of file to kernel io files, if header data is
106 * different but body data is similar (binary, using the same datatypes).
107 *
108 * parameters:
109 * name <-- file name
110 * magic_string <-- magic string associated with file type
111 * mode <-- read or write
112 * method <-- file access method
113 * echo <-- echo on main output (< 0 if none, header if 0,
114 * n first and last elements if n > 0)
115 * hints <-- associated hints for MPI-IO, or MPI_INFO_NULL
116 * block_comm <-- handle to MPI communicator used for distributed file
117 * block access (may be a subset of comm if some ranks do
118 * not directly access distributed data blocks)
119 * comm <-- handle to main MPI communicator
120 *
121 * returns:
122 * pointer to kernel IO structure
123 *----------------------------------------------------------------------------*/
124
125 #if defined(HAVE_MPI)
126
127 cs_io_t *
128 cs_io_initialize(const char *file_name,
129 const char *magic_string,
130 cs_io_mode_t mode,
131 cs_file_access_t method,
132 long echo,
133 MPI_Info hints,
134 MPI_Comm block_comm,
135 MPI_Comm comm);
136
137 #else
138
139 cs_io_t *
140 cs_io_initialize(const char *file_name,
141 const char *magic_string,
142 cs_io_mode_t mode,
143 cs_file_access_t method,
144 long echo);
145
146 #endif /* HAVE_MPI */
147
148 /*----------------------------------------------------------------------------
149 * Initialize a kernel IO file structure in read mode, building an index.
150 *
151 * The magic string may be NULL, if we choose to ignore it.
152 *
153 * parameters:
154 * name <-- file name
155 * magic_string <-- magic string associated with file type
156 * method <-- file access method
157 * echo <-- echo on main output (< 0 if none, header if 0,
158 * n first and last elements if n > 0)
159 * hints <-- associated hints for MPI-IO, or MPI_INFO_NULL
160 * block_comm <-- handle to MPI communicator used for distributed file
161 * block access (may be a subset of comm if some ranks do
162 * not directly access distributed data blocks)
163 * comm <-- handle to main MPI communicator
164
165 * returns:
166 * pointer to kernel IO structure
167 *----------------------------------------------------------------------------*/
168
169 #if defined(HAVE_MPI)
170
171 cs_io_t *
172 cs_io_initialize_with_index(const char *file_name,
173 const char *magic_string,
174 cs_file_access_t method,
175 long echo,
176 MPI_Info hints,
177 MPI_Comm block_comm,
178 MPI_Comm comm);
179 #else
180
181 cs_io_t *
182 cs_io_initialize_with_index(const char *file_name,
183 const char *magic_string,
184 cs_file_access_t method,
185 long echo);
186
187 #endif /* HAVE_MPI */
188
189 /*----------------------------------------------------------------------------
190 * Free a preprocessor output file structure, closing the associated file.
191 *
192 * parameters:
193 * pp_io <-> kernel IO structure
194 *----------------------------------------------------------------------------*/
195
196 void
197 cs_io_finalize(cs_io_t **pp_io);
198
199 /*----------------------------------------------------------------------------
200 * Return a pointer to a preprocessor IO structure's name.
201 *
202 * parameters:
203 * pp_io <-- kernel IO structure
204 *----------------------------------------------------------------------------*/
205
206 const char *
207 cs_io_get_name(const cs_io_t *pp_io);
208
209 /*----------------------------------------------------------------------------
210 * Return the number of indexed entries in a kernel IO structure.
211 *
212 * parameters:
213 * inp <-- input kernel IO structure
214 *
215 * returns:
216 * size of index if present, 0 otherwise,
217 *----------------------------------------------------------------------------*/
218
219 size_t
220 cs_io_get_index_size(const cs_io_t *inp);
221
222 /*----------------------------------------------------------------------------
223 * Return the name of an indexed section in a kernel IO structure.
224 *
225 * parameters:
226 * inp <-- input kernel IO structure
227 * id <-- id of section in index (0 to n-1 numbering)
228 *
229 * returns:
230 * pointer to section name if id in index range, NULL otherwise
231 *----------------------------------------------------------------------------*/
232
233 const char *
234 cs_io_get_indexed_sec_name(const cs_io_t *inp,
235 size_t id);
236
237 /*----------------------------------------------------------------------------
238 * Return header data for an indexed section in a kernel IO structure.
239 *
240 * parameters:
241 * inp <-- input kernel IO structure
242 * id <-- id of section in index (0 to n-1 numbering)
243 *
244 * returns:
245 * section header data (if id not in index range, fields set to zero)
246 *----------------------------------------------------------------------------*/
247
248 cs_io_sec_header_t
249 cs_io_get_indexed_sec_header(const cs_io_t *inp,
250 size_t id);
251
252 /*----------------------------------------------------------------------------
253 * Return a kernel IO structure's echo (verbosity) level.
254 *
255 * parameters:
256 * pp_io <-- kernel IO structure
257 *----------------------------------------------------------------------------*/
258
259 size_t
260 cs_io_get_echo(const cs_io_t *pp_io);
261
262 /*----------------------------------------------------------------------------
263 * Read a message header.
264 *
265 * parameters:
266 * pp_io <-- kernel IO structure
267 * header --> header structure
268 *
269 * returns:
270 * 0 if a header was read, 1 in case of error or end-of-file
271 *----------------------------------------------------------------------------*/
272
273 int
274 cs_io_read_header(cs_io_t *inp,
275 cs_io_sec_header_t *header);
276
277 /*----------------------------------------------------------------------------
278 * Set a kernel IO's state so as to be ready to read an indexed section.
279 *
280 * The header values and position in the file are set so as to be equivalent
281 * to those they would have if the corresponding header had just been read.
282 *
283 * parameters:
284 * inp <-> input kernel IO structure
285 * header --> associated header
286 * id <-- id of section in index (0 to n-1 numbering)
287 *
288 * returns:
289 * 0 in case of success, 1 in case of error
290 *----------------------------------------------------------------------------*/
291
292 int
293 cs_io_set_indexed_position(cs_io_t *inp,
294 cs_io_sec_header_t *header,
295 size_t id);
296
297 /*----------------------------------------------------------------------------
298 * Set a message's final data type to cs_lnum_t.
299 *
300 * It the datatype is not compatible, throw an error.
301 *
302 * parameters:
303 * header <-- header structure
304 * pp_io --> kernel IO structure
305 *----------------------------------------------------------------------------*/
306
307 void
308 cs_io_set_cs_lnum(cs_io_sec_header_t *header,
309 const cs_io_t *pp_io);
310
311 /*----------------------------------------------------------------------------
312 * Set a message's final data type to cs_gnum_t.
313 *
314 * It the datatype is not compatible, throw an error.
315 *
316 * parameters:
317 * header <-> header structure
318 * pp_io <-- kernel IO structure
319 *----------------------------------------------------------------------------*/
320
321 void
322 cs_io_set_cs_gnum(cs_io_sec_header_t *header,
323 const cs_io_t *pp_io);
324
325 /*----------------------------------------------------------------------------
326 * Check that a message's final data type corresponds to cs_real_t.
327 *
328 * parameters:
329 * header <-- header structure
330 * pp_io <-- kernel IO structure
331 *----------------------------------------------------------------------------*/
332
333 void
334 cs_io_assert_cs_real(const cs_io_sec_header_t *header,
335 const cs_io_t *pp_io);
336
337 /*----------------------------------------------------------------------------
338 * Read a message body and replicate it to all processors.
339 *
340 * If the array intended to receive the data already exists, we pass an
341 * "elt" pointer to this array; this same pointer is then returned.
342 * Otherwise, if this pointer is passed as NULL, memory is allocated
343 * by this function, and the corresponding pointer is returned. It is
344 * the caller's responsibility to free this array.
345 *
346 * parameters:
347 * header <-- header structure
348 * elts <-> pointer to data array, or NULL
349 * pp_io --> kernel IO structure
350 *
351 * returns:
352 * elts if non NULL, or pointer to allocated array otherwise
353 *----------------------------------------------------------------------------*/
354
355 void *
356 cs_io_read_global(const cs_io_sec_header_t *header,
357 void *elts,
358 cs_io_t *pp_io);
359
360 /*----------------------------------------------------------------------------
361 * Read a message body, assigning a different block to each processor.
362 *
363 * If location_id > 0 and header->n_location_vals > 1, then
364 * global_num_start and global_num_end will be based on location element
365 * numbers, so the total number of values read equals
366 * (global_num_end - global_num_start) * header->n_location_vals.
367 *
368 * If the array intended to receive the data already exists, we pass an
369 * "elt" pointer to this array; this same pointer is then returned.
370 * Otherwise, if this pointer is passed as NULL, memory is allocated
371 * by this function, and the corresponding pointer is returned. It is
372 * the caller's responsibility to free this array.
373 *
374 * parameters:
375 * header <-- header structure
376 * global_num_start <-- global number of first block item (1 to n numbering)
377 * global_num_end <-- global number of past-the end block item
378 * (1 to n numbering)
379 * elts <-> pointer to data array, or NULL
380 * pp_io --> kernel IO structure
381 *
382 * returns:
383 * elts if non NULL, or pointer to allocated array otherwise
384 *----------------------------------------------------------------------------*/
385
386 void *
387 cs_io_read_block(const cs_io_sec_header_t *header,
388 cs_gnum_t global_num_start,
389 cs_gnum_t global_num_end,
390 void *elts,
391 cs_io_t *pp_io);
392
393 /*----------------------------------------------------------------------------
394 * Read a message body, assigning a different block to each processor,
395 * when the body corresponds to an index.
396 *
397 * In serial mode, this function behaves just like cs_io_read_block(),
398 * except that it allows only unsigned integer values (cs_gnum_t).
399 *
400 * In parallel mode, global_num_end should be set to the past-the-end value
401 * of the base data block, the same as for regular data (and not increased
402 * by 1 for the last rank, as this will be handled internally).
403 * On each rank, the buffer size should be:
404 * global_num_end - global_num_start + 1, as the past-the end index
405 * for the local block is added automatically.
406 *
407 * If the array intended to receive the data already exists, we pass an
408 * "elt" pointer to this array; this same pointer is then returned.
409 * Otherwise, if this pointer is passed as NULL, memory is allocated
410 * by this function, and the corresponding pointer is returned. It is
411 * the caller's responsibility to free this array.
412 *
413 * parameters:
414 * header <-- header structure
415 * global_num_start <-- global number of first block item (1 to n numbering)
416 * global_num_end <-- global number of past-the end block item
417 * (1 to n numbering)
418 * elts <-> pointer to data array, or NULL
419 * pp_io --> kernel IO structure
420 *
421 * returns:
422 * elts if non NULL, or pointer to allocated array otherwise
423 *----------------------------------------------------------------------------*/
424
425 void *
426 cs_io_read_index_block(cs_io_sec_header_t *header,
427 cs_gnum_t global_num_start,
428 cs_gnum_t global_num_end,
429 cs_gnum_t *elts,
430 cs_io_t *pp_io);
431
432 /*----------------------------------------------------------------------------
433 * Write a global section.
434 *
435 * Under MPI, data is only written by the associated communicator's root
436 * rank. The section data on other ranks is ignored, though the file offset
437 * is updated (i.e. the call to this function is collective).
438 *
439 * parameters:
440 * section_name <-- section name
441 * n_vals <-- total number of values
442 * location_id <-- id of associated location, or 0
443 * index_id <-- id of associated index, or 0
444 * n_location_vals <-- number of values per location
445 * elt_type <-- element type
446 * elts <-- pointer to element data
447 * outp <-> output kernel IO structure
448 *----------------------------------------------------------------------------*/
449
450 void
451 cs_io_write_global(const char *sec_name,
452 cs_gnum_t n_vals,
453 size_t location_id,
454 size_t index_id,
455 size_t n_location_vals,
456 cs_datatype_t elt_type,
457 const void *elts,
458 cs_io_t *outp);
459
460 /*----------------------------------------------------------------------------
461 * Write a section to file, each associated process providing a contiguous
462 * of the section's body.
463 *
464 * Each process should provide a (possibly empty) block of the body,
465 * and we should have:
466 * global_num_start at rank 0 = 1
467 * global_num_start at rank i+1 = global_num_end at rank i.
468 * Otherwise, behavior (especially positioning for future reads) is undefined.
469 *
470 * If location_id > 0 and n_location_vals > 1, then global_num_start
471 * and global_num_end will be based on location element numbers, so the
472 * total number of values read equals
473 * (global_num_end - global_num_start) * header->n_location_vals.
474 *
475 * This function does not modify the values in its input buffer (notably,
476 * a copy is used to convert from little-endian to big-endian or vice-versa
477 * if necessary).
478 *
479 * parameters:
480 * section_name <-- section name
481 * n_g_elts <-- number of global elements (locations)
482 * global_num_start <-- global number of first block item (1 to n numbering)
483 * global_num_end <-- global number of past-the end block item
484 * location_id <-- id of associated location, or 0
485 * index_id <-- id of associated index, or 0
486 * n_location_vals <-- number of values per location
487 * elt_type <-- element type
488 * (1 to n numbering)
489 * elts <-- pointer to element data
490 * outp <-> output kernel IO structure
491 *----------------------------------------------------------------------------*/
492
493 void
494 cs_io_write_block(const char *sec_name,
495 cs_gnum_t n_g_elts,
496 cs_gnum_t global_num_start,
497 cs_gnum_t global_num_end,
498 size_t location_id,
499 size_t index_id,
500 size_t n_location_vals,
501 cs_datatype_t elt_type,
502 const void *elts,
503 cs_io_t *outp);
504
505 /*----------------------------------------------------------------------------
506 * Write a section to file, each associated process providing a contiguous
507 * of the section's body.
508 *
509 * Each process should provide a (possibly empty) block of the body,
510 * and we should have:
511 * global_num_start at rank 0 = 1
512 * global_num_start at rank i+1 = global_num_end at rank i.
513 * Otherwise, behavior (especially positioning for future reads) is undefined.
514 *
515 * If location_id > 0 and n_location_vals > 1, then global_num_start
516 * and global_num_end will be based on location element numbers, so the
517 * total number of values read equals
518 * (global_num_end - global_num_start) * header->n_location_vals.
519 *
520 * This function is intended to be used mainly on data that is already of
521 * copy of original data (such as data that has been redistributed across
522 * processors just for the sake of output), or that is to be deleted after
523 * writing, so it may modify the values in its input buffer (notably to
524 * convert from little-endian to big-endian or vice-versa if necessary).
525 *
526 * parameters:
527 * section_name <-- section name
528 * n_g_elts <-- number of global elements (locations)
529 * global_num_start <-- global number of first block item (1 to n numbering)
530 * global_num_end <-- global number of past-the end block item
531 * location_id <-- id of associated location, or 0
532 * index_id <-- id of associated index, or 0
533 * n_location_vals <-- number of values per location
534 * elt_type <-- element type
535 * (1 to n numbering)
536 * elts <-- pointer to element data
537 * outp <-> output kernel IO structure
538 *----------------------------------------------------------------------------*/
539
540 void
541 cs_io_write_block_buffer(const char *sec_name,
542 cs_gnum_t n_g_elts,
543 cs_gnum_t global_num_start,
544 cs_gnum_t global_num_end,
545 size_t location_id,
546 size_t index_id,
547 size_t n_location_vals,
548 cs_datatype_t elt_type,
549 void *elts,
550 cs_io_t *outp);
551
552 /*----------------------------------------------------------------------------
553 * Skip a message.
554 *
555 * parameters:
556 * header <-- header structure
557 * pp_io --> kernel IO structure
558 *----------------------------------------------------------------------------*/
559
560 void
561 cs_io_skip(const cs_io_sec_header_t *header,
562 cs_io_t *pp_io);
563
564 /*----------------------------------------------------------------------------
565 * Return the position of the file pointer for an open kernel IO file.
566 *
567 * parameters:
568 * inp <-- input kernel IO structure
569 *
570 * returns:
571 * offset in file
572 *----------------------------------------------------------------------------*/
573
574 cs_file_off_t
575 cs_io_get_offset(cs_io_t *inp);
576
577 /*----------------------------------------------------------------------------
578 * Set the position of the file pointer for an open kernel IO file.
579 *
580 * parameters:
581 * inp <-- input kernel IO structure
582 * offset <-- offset in file
583 *----------------------------------------------------------------------------*/
584
585 void
586 cs_io_set_offset(cs_io_t *inp,
587 cs_file_off_t offset);
588
589 /*----------------------------------------------------------------------------
590 * Initialize performance logging for cs_io_t structures.
591 *----------------------------------------------------------------------------*/
592
593 void
594 cs_io_log_initialize(void);
595
596 /*----------------------------------------------------------------------------
597 * Finalize performance logging for cs_io_t structures.
598 *----------------------------------------------------------------------------*/
599
600 void
601 cs_io_log_finalize(void);
602
603 /*----------------------------------------------------------------------------
604 * Dump a kernel IO file handle's metadata.
605 *
606 * parameters:
607 * cs_io <-- kernel IO structure
608 *----------------------------------------------------------------------------*/
609
610 void
611 cs_io_dump(const cs_io_t *cs_io);
612
613 /*----------------------------------------------------------------------------*/
614
615 END_C_DECLS
616
617 #endif /* __CS_IO_H__ */