Code_Saturne
CFD tool
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros 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-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 #include "cs_defs.h"
31 
32 /*----------------------------------------------------------------------------
33  * Local headers
34  *----------------------------------------------------------------------------*/
35 
36 #include "cs_base.h"
37 #include "cs_file.h"
38 
39 /*----------------------------------------------------------------------------*/
40 
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 
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 
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, or NULL
111  * mode <-- read or write
112  * hints <-- optional flags for file access method (see cs_file.h)
113  * echo <-- echo on main output (< 0 if none, header if 0,
114  * n first and last elements if n > 0)
115  * comm <-- associated MPI communicator
116  *
117  * returns:
118  * pointer to kernel IO structure
119  *----------------------------------------------------------------------------*/
120 
121 #if defined(HAVE_MPI)
122 
123 cs_io_t *
124 cs_io_initialize(const char *file_name,
125  const char *magic_string,
126  cs_io_mode_t mode,
127  int hints,
128  long echo,
129  MPI_Comm comm);
130 
131 #else
132 
133 cs_io_t *
134 cs_io_initialize(const char *file_name,
135  const char *magic_string,
136  cs_io_mode_t mode,
137  int hints,
138  long echo);
139 
140 #endif /* HAVE_MPI */
141 
142 /*----------------------------------------------------------------------------
143  * Initialize a kernel IO file structure in read mode, building an index.
144  *
145  * The magic string may be NULL, if we choose to ignore it.
146  *
147  * parameters:
148  * name <-- file name
149  * magic_string <-- magic string associated with file type
150  * hints <-- optional flags for file access method (see cs_file.h)
151  * echo <-- echo on main output (< 0 if none, header if 0,
152  * n first and last elements if n > 0)
153  * comm <-- associated MPI communicator
154  *
155  * returns:
156  * pointer to kernel IO structure
157  *----------------------------------------------------------------------------*/
158 
159 #if defined(HAVE_MPI)
160 
161 cs_io_t *
162 cs_io_initialize_with_index(const char *file_name,
163  const char *magic_string,
164  int hints,
165  long echo,
166  MPI_Comm comm);
167 
168 #else
169 
170 cs_io_t *
171 cs_io_initialize_with_index(const char *file_name,
172  const char *magic_string,
173  int hints,
174  long echo);
175 
176 #endif /* HAVE_MPI */
177 
178 /*----------------------------------------------------------------------------
179  * Free a preprocessor output file structure, closing the associated file.
180  *
181  * parameters:
182  * pp_io <-> kernel IO structure
183  *----------------------------------------------------------------------------*/
184 
185 void
186 cs_io_finalize(cs_io_t **pp_io);
187 
188 /*----------------------------------------------------------------------------
189  * Return a pointer to a preprocessor IO structure's name.
190  *
191  * parameters:
192  * pp_io <-- kernel IO structure
193  *----------------------------------------------------------------------------*/
194 
195 const char *
196 cs_io_get_name(const cs_io_t *pp_io);
197 
198 /*----------------------------------------------------------------------------
199  * Return the number of indexed entries in a kernel IO structure.
200  *
201  * parameters:
202  * inp <-- input kernel IO structure
203  *
204  * returns:
205  * size of index if present, 0 otherwise,
206  *----------------------------------------------------------------------------*/
207 
208 size_t
209 cs_io_get_index_size(const cs_io_t *inp);
210 
211 /*----------------------------------------------------------------------------
212  * Return the name of an indexed section in a kernel IO structure.
213  *
214  * parameters:
215  * inp <-- input kernel IO structure
216  * id <-- id of section in index (0 to n-1 numbering)
217  *
218  * returns:
219  * pointer to section name if id in index range, NULL otherwise
220  *----------------------------------------------------------------------------*/
221 
222 const char *
224  size_t id);
225 
226 /*----------------------------------------------------------------------------
227  * Return header data for an indexed section in a kernel IO structure.
228  *
229  * parameters:
230  * inp <-- input kernel IO structure
231  * id <-- id of section in index (0 to n-1 numbering)
232  *
233  * returns:
234  * section header data (if id not in index range, fields set to zero)
235  *----------------------------------------------------------------------------*/
236 
239  size_t id);
240 
241 /*----------------------------------------------------------------------------
242  * Return a kernel IO structure's echo (verbosity) level.
243  *
244  * parameters:
245  * pp_io <-- kernel IO structure
246  *----------------------------------------------------------------------------*/
247 
248 size_t
249 cs_io_get_echo(const cs_io_t *pp_io);
250 
251 /*----------------------------------------------------------------------------
252  * Read a message header.
253  *
254  * parameters:
255  * pp_io <-- kernel IO structure
256  * header --> header structure
257  *
258  * returns:
259  * 0 if a header was read, 1 in case of error or end-of-file
260  *----------------------------------------------------------------------------*/
261 
262 int
264  cs_io_sec_header_t *header);
265 
266 /*----------------------------------------------------------------------------
267  * Set a kernel IO's state so as to be ready to read an indexed section.
268  *
269  * The header values and position in the file are set so as to be equivalent
270  * to those they would have if the corresponding header had just been read.
271  *
272  * parameters:
273  * inp <-> input kernel IO structure
274  * header --> associated header
275  * id <-- id of section in index (0 to n-1 numbering)
276  *
277  * returns:
278  * 0 in case of success, 1 in case of error
279  *----------------------------------------------------------------------------*/
280 
281 int
283  cs_io_sec_header_t *header,
284  size_t id);
285 
286 /*----------------------------------------------------------------------------
287  * Set a message's final data type to cs_lnum_t.
288  *
289  * It the datatype is not compatible, throw an error.
290  *
291  * parameters:
292  * header <-- header structure
293  * pp_io --> kernel IO structure
294  *----------------------------------------------------------------------------*/
295 
296 void
298  const cs_io_t *pp_io);
299 
300 /*----------------------------------------------------------------------------
301  * Set a message's final data type to cs_gnum_t.
302  *
303  * It the datatype is not compatible, throw an error.
304  *
305  * parameters:
306  * header <-> header structure
307  * pp_io <-- kernel IO structure
308  *----------------------------------------------------------------------------*/
309 
310 void
312  const cs_io_t *pp_io);
313 
314 /*----------------------------------------------------------------------------
315  * Check that a message's final data type corresponds to cs_real_t.
316  *
317  * parameters:
318  * header <-- header structure
319  * pp_io <-- kernel IO structure
320  *----------------------------------------------------------------------------*/
321 
322 void
324  const cs_io_t *pp_io);
325 
326 /*----------------------------------------------------------------------------
327  * Read a message body and replicate it to all processors.
328  *
329  * If the array intended to receive the data already exists, we pass an
330  * "elt" pointer to this array; this same pointer is then returned.
331  * Otherwise, if this pointer is passed as NULL, memory is allocated
332  * by this function, and the corresponding pointer is returned. It is
333  * the caller's responsibility to free this array.
334  *
335  * parameters:
336  * header <-- header structure
337  * elts <-> pointer to data array, or NULL
338  * pp_io --> kernel IO structure
339  *
340  * returns:
341  * elts if non NULL, or pointer to allocated array otherwise
342  *----------------------------------------------------------------------------*/
343 
344 void *
346  void *elts,
347  cs_io_t *pp_io);
348 
349 /*----------------------------------------------------------------------------
350  * Read a message body, assigning a different block to each processor.
351  *
352  * If location_id > 0 and header->n_location_vals > 1, then
353  * global_num_start and global_num_end will be based on location element
354  * numbers, so the total number of values read equals
355  * (global_num_end - global_num_start) * header->n_location_vals.
356  *
357  * If the array intended to receive the data already exists, we pass an
358  * "elt" pointer to this array; this same pointer is then returned.
359  * Otherwise, if this pointer is passed as NULL, memory is allocated
360  * by this function, and the corresponding pointer is returned. It is
361  * the caller's responsibility to free this array.
362  *
363  * parameters:
364  * header <-- header structure
365  * global_num_start <-- global number of first block item (1 to n numbering)
366  * global_num_end <-- global number of past-the end block item
367  * (1 to n numbering)
368  * elts <-> pointer to data array, or NULL
369  * pp_io --> kernel IO structure
370  *
371  * returns:
372  * elts if non NULL, or pointer to allocated array otherwise
373  *----------------------------------------------------------------------------*/
374 
375 void *
377  cs_gnum_t global_num_start,
378  cs_gnum_t global_num_end,
379  void *elts,
380  cs_io_t *pp_io);
381 
382 /*----------------------------------------------------------------------------
383  * Read a message body, assigning a different block to each processor,
384  * when the body corresponds to an index.
385  *
386  * In serial mode, this function behaves just like cs_io_read_block(),
387  * except that it allows only unsigned integer values (cs_gnum_t).
388  *
389  * In parallel mode, global_num_end should be set to the past-the-end value
390  * of the base data block, the same as for regular data (and not increased
391  * by 1 for the last rank, as this will be handled internally).
392  * On each rank, the buffer size should be:
393  * global_num_end - global_num_start + 1, as the past-the end index
394  * for the local block is added automatically.
395  *
396  * If the array intended to receive the data already exists, we pass an
397  * "elt" pointer to this array; this same pointer is then returned.
398  * Otherwise, if this pointer is passed as NULL, memory is allocated
399  * by this function, and the corresponding pointer is returned. It is
400  * the caller's responsibility to free this array.
401  *
402  * parameters:
403  * header <-- header structure
404  * global_num_start <-- global number of first block item (1 to n numbering)
405  * global_num_end <-- global number of past-the end block item
406  * (1 to n numbering)
407  * elts <-> pointer to data array, or NULL
408  * pp_io --> kernel IO structure
409  *
410  * returns:
411  * elts if non NULL, or pointer to allocated array otherwise
412  *----------------------------------------------------------------------------*/
413 
414 void *
416  cs_gnum_t global_num_start,
417  cs_gnum_t global_num_end,
418  cs_gnum_t *elts,
419  cs_io_t *pp_io);
420 
421 /*----------------------------------------------------------------------------
422  * Write a global section.
423  *
424  * Under MPI, data is only written by the associated communicator's root
425  * rank. The section data on other ranks is ignored, though the file offset
426  * is updated (i.e. the call to this function is collective).
427  *
428  * parameters:
429  * section_name <-- section name
430  * n_vals <-- total number of values
431  * location_id <-- id of associated location, or 0
432  * index_id <-- id of associated index, or 0
433  * n_location_vals <-- number of values per location
434  * elt_type <-- element type
435  * elts <-- pointer to element data
436  * outp <-> output kernel IO structure
437  *----------------------------------------------------------------------------*/
438 
439 void
440 cs_io_write_global(const char *sec_name,
441  cs_gnum_t n_vals,
442  size_t location_id,
443  size_t index_id,
444  size_t n_location_vals,
445  cs_datatype_t elt_type,
446  const void *elts,
447  cs_io_t *outp);
448 
449 /*----------------------------------------------------------------------------
450  * Write a section to file, each associated process providing a contiguous
451  * of the section's body.
452  *
453  * Each process should provide a (possibly empty) block of the body,
454  * and we should have:
455  * global_num_start at rank 0 = 1
456  * global_num_start at rank i+1 = global_num_end at rank i.
457  * Otherwise, behavior (especially positioning for future reads) is undefined.
458  *
459  * If location_id > 0 and n_location_vals > 1, then global_num_start
460  * and global_num_end will be based on location element numbers, so the
461  * total number of values read equals
462  * (global_num_end - global_num_start) * header->n_location_vals.
463  *
464  * This function does not modify the values in its input buffer (notably,
465  * a copy is used to convert from little-endian to big-endian or vice-versa
466  * if necessary).
467  *
468  * parameters:
469  * section_name <-- section name
470  * n_g_elts <-- number of global elements (locations)
471  * global_num_start <-- global number of first block item (1 to n numbering)
472  * global_num_end <-- global number of past-the end block item
473  * location_id <-- id of associated location, or 0
474  * index_id <-- id of associated index, or 0
475  * n_location_vals <-- number of values per location
476  * elt_type <-- element type
477  * (1 to n numbering)
478  * elts <-- pointer to element data
479  * outp <-> output kernel IO structure
480  *----------------------------------------------------------------------------*/
481 
482 void
483 cs_io_write_block(const char *sec_name,
484  cs_gnum_t n_g_elts,
485  cs_gnum_t global_num_start,
486  cs_gnum_t global_num_end,
487  size_t location_id,
488  size_t index_id,
489  size_t n_location_vals,
490  cs_datatype_t elt_type,
491  const void *elts,
492  cs_io_t *outp);
493 
494 /*----------------------------------------------------------------------------
495  * Write a section to file, each associated process providing a contiguous
496  * of the section's body.
497  *
498  * Each process should provide a (possibly empty) block of the body,
499  * and we should have:
500  * global_num_start at rank 0 = 1
501  * global_num_start at rank i+1 = global_num_end at rank i.
502  * Otherwise, behavior (especially positioning for future reads) is undefined.
503  *
504  * If location_id > 0 and n_location_vals > 1, then global_num_start
505  * and global_num_end will be based on location element numbers, so the
506  * total number of values read equals
507  * (global_num_end - global_num_start) * header->n_location_vals.
508  *
509  * This function is intended to be used mainly on data that is already of
510  * copy of original data (such as data that has been redistributed across
511  * processors just for the sake of output), or that is to be deleted after
512  * writing, so it may modify the values in its input buffer (notably to
513  * convert from little-endian to big-endian or vice-versa if necessary).
514  *
515  * parameters:
516  * section_name <-- section name
517  * n_g_elts <-- number of global elements (locations)
518  * global_num_start <-- global number of first block item (1 to n numbering)
519  * global_num_end <-- global number of past-the end block item
520  * location_id <-- id of associated location, or 0
521  * index_id <-- id of associated index, or 0
522  * n_location_vals <-- number of values per location
523  * elt_type <-- element type
524  * (1 to n numbering)
525  * elts <-- pointer to element data
526  * outp <-> output kernel IO structure
527  *----------------------------------------------------------------------------*/
528 
529 void
530 cs_io_write_block_buffer(const char *sec_name,
531  cs_gnum_t n_g_elts,
532  cs_gnum_t global_num_start,
533  cs_gnum_t global_num_end,
534  size_t location_id,
535  size_t index_id,
536  size_t n_location_vals,
537  cs_datatype_t elt_type,
538  void *elts,
539  cs_io_t *outp);
540 
541 /*----------------------------------------------------------------------------
542  * Return the position of the file pointer for an open kernel IO file.
543  *
544  * parameters:
545  * inp <-- input kernel IO structure
546  *
547  * returns:
548  * offset in file
549  *----------------------------------------------------------------------------*/
550 
553 
554 /*----------------------------------------------------------------------------
555  * Set the position of the file pointer for an open kernel IO file.
556  *
557  * parameters:
558  * inp <-- input kernel IO structure
559  * offset <-- offset in file
560  *----------------------------------------------------------------------------*/
561 
562 void
564  cs_file_off_t offset);
565 
566 /*----------------------------------------------------------------------------
567  * Print information on default options for file access.
568  *----------------------------------------------------------------------------*/
569 
570 void
571 cs_io_defaults_info(void);
572 
573 /*----------------------------------------------------------------------------
574  * Set the default semantics for file access.
575  *
576  * Allowed values for mpi_io_mode are:
577  * 0: no MPI-IO,
578  * 1: MPI-IO with explicit offsets,
579  * 2: MPI-IO with individual file pointers
580  *
581  * Invalid values (for example an MPI-IO mode with no MPI or MPI-IO
582  * support) are silently ignored.
583  *
584  * parameters:
585  * mpi_io_mode <-- mode for default semantics
586  *----------------------------------------------------------------------------*/
587 
588 void
589 cs_io_set_defaults(int mpi_io_mode);
590 
591 /*----------------------------------------------------------------------------
592  * Initialize performance logging for cs_io_t structures.
593  *----------------------------------------------------------------------------*/
594 
595 void
597 
598 /*----------------------------------------------------------------------------
599  * Finalize performance logging for cs_io_t structures.
600  *----------------------------------------------------------------------------*/
601 
602 void
603 cs_io_log_finalize(void);
604 
605 /*----------------------------------------------------------------------------
606  * Dump a kernel IO file handle's metadata.
607  *
608  * parameters:
609  * cs_io <-- kernel IO structure
610  *----------------------------------------------------------------------------*/
611 
612 void
613 cs_io_dump(const cs_io_t *cs_io);
614 
615 /*----------------------------------------------------------------------------*/
616 
618 
619 #endif /* __CS_IO_H__ */
cs_io_t * cs_io_initialize(const char *file_name, const char *magic_string, cs_io_mode_t mode, int hints, long echo)
Definition: cs_io.c:2206
const char * cs_io_get_indexed_sec_name(const cs_io_t *inp, size_t id)
Definition: cs_io.c:2399
cs_datatype_t
Definition: cs_defs.h:223
void cs_io_dump(const cs_io_t *cs_io)
Definition: cs_io.c:3606
cs_datatype_t elt_type
Definition: cs_io.h:80
cs_datatype_t type_read
Definition: cs_io.h:81
void cs_io_set_offset(cs_io_t *inp, cs_file_off_t offset)
Definition: cs_io.c:3408
int cs_glob_io_hints
Definition: cs_io.c:208
void * cs_io_read_global(const cs_io_sec_header_t *header, void *elts, cs_io_t *pp_io)
Definition: cs_io.c:2874
cs_io_mode_t
Definition: cs_io.h:59
const char * cs_io_get_name(const cs_io_t *pp_io)
Definition: cs_io.c:2359
void cs_io_assert_cs_real(const cs_io_sec_header_t *header, const cs_io_t *pp_io)
Definition: cs_io.c:2839
#define BEGIN_C_DECLS
Definition: cs_defs.h:365
size_t index_id
Definition: cs_io.h:78
cs_io_t * cs_io_initialize_with_index(const char *file_name, const char *magic_string, int hints, long echo)
Definition: cs_io.c:2262
size_t location_id
Definition: cs_io.h:77
const char * sec_name
Definition: cs_io.h:75
Definition: cs_io.h:62
void cs_io_log_initialize(void)
Definition: cs_io.c:3483
Definition: cs_io.h:61
void cs_io_set_defaults(int mpi_io_mode)
Definition: cs_io.c:3462
size_t n_location_vals
Definition: cs_io.h:79
void cs_io_write_block_buffer(const char *sec_name, cs_gnum_t n_g_elts, cs_gnum_t global_num_start, cs_gnum_t global_num_end, size_t location_id, size_t index_id, size_t n_location_vals, cs_datatype_t elt_type, void *elts, cs_io_t *outp)
Definition: cs_io.c:3313
cs_file_off_t n_vals
Definition: cs_io.h:76
size_t cs_io_get_echo(const cs_io_t *pp_io)
Definition: cs_io.c:2469
cs_file_off_t cs_io_get_offset(cs_io_t *inp)
Definition: cs_io.c:3391
cs_io_sec_header_t cs_io_get_indexed_sec_header(const cs_io_t *inp, size_t id)
Definition: cs_io.c:2426
void cs_io_set_cs_gnum(cs_io_sec_header_t *header, const cs_io_t *pp_io)
Definition: cs_io.c:2805
void * cs_io_read_index_block(cs_io_sec_header_t *header, cs_gnum_t global_num_start, cs_gnum_t global_num_end, cs_gnum_t *elts, cs_io_t *pp_io)
Definition: cs_io.c:2957
void cs_io_log_finalize(void)
Definition: cs_io.c:3500
int cs_io_set_indexed_position(cs_io_t *inp, cs_io_sec_header_t *header, size_t id)
Definition: cs_io.c:2702
unsigned cs_gnum_t
Definition: cs_defs.h:255
Definition: cs_io_dump.c:124
void cs_io_write_block(const char *sec_name, cs_gnum_t n_g_elts, cs_gnum_t global_num_start, cs_gnum_t global_num_end, size_t location_id, size_t index_id, size_t n_location_vals, cs_datatype_t elt_type, const void *elts, cs_io_t *outp)
Definition: cs_io.c:3210
void * cs_io_read_block(const cs_io_sec_header_t *header, cs_gnum_t global_num_start, cs_gnum_t global_num_end, void *elts, cs_io_t *pp_io)
Definition: cs_io.c:2908
void cs_io_set_cs_lnum(cs_io_sec_header_t *header, const cs_io_t *pp_io)
Definition: cs_io.c:2768
#define END_C_DECLS
Definition: cs_defs.h:366
void cs_io_write_global(const char *sec_name, cs_gnum_t n_vals, size_t location_id, size_t index_id, size_t n_location_vals, cs_datatype_t elt_type, const void *elts, cs_io_t *outp)
Definition: cs_io.c:3117
size_t cs_io_get_index_size(const cs_io_t *inp)
Definition: cs_io.c:2377
int cs_io_read_header(cs_io_t *inp, cs_io_sec_header_t *header)
Definition: cs_io.c:2491
long cs_file_off_t
Definition: cs_file.h:93
void cs_io_defaults_info(void)
Definition: cs_io.c:3424
Definition: cs_io.h:73
void cs_io_finalize(cs_io_t **pp_io)
Definition: cs_io.c:2321