SIONlib  1.7.7
Scalable I/O library for parallel access to task-local files
sion_internal.c
Go to the documentation of this file.
1 /****************************************************************************
2 ** SIONLIB http://www.fz-juelich.de/jsc/sionlib **
3 *****************************************************************************
4 ** Copyright (c) 2008-2019 **
5 ** Forschungszentrum Juelich, Juelich Supercomputing Centre **
6 ** **
7 ** Copyright (c) 2019 **
8 ** DataDirect Networks **
9 ** **
10 ** See the file COPYRIGHT in the package base directory for details **
11 ****************************************************************************/
12 
17 #define _XOPEN_SOURCE 700
18 
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <stdarg.h>
22 #include <string.h>
23 #include <time.h>
24 
25 #include <sys/time.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <errno.h>
30 
31 #include <unistd.h>
32 
33 #if defined(_SION_BGQ)
34 #include <stdio_ext.h>
35 #endif
36 
37 #if defined(_SION_BGP)
38 #include <stdio_ext.h>
39 #endif
40 
41 #include "sion.h"
42 #include "sion_debug.h"
43 #include "sion_error_handler.h"
44 #include "sion_internal.h"
45 #include "sion_metadata.h"
46 #include "sion_filedesc.h"
47 #include "sion_tools.h"
48 #include "sion_fd.h"
49 #include "sion_file.h"
50 #include "sion_hints.h"
51 #include "sion_printts.h"
52 #include "sion_keyvalue.h"
53 #include "sion_buffer.h"
54 #include "sion_flags.h"
55 #include "sion_internal_startptr.h"
56 
57 /* INTERNAL */
58 
59 int _sion_open(const char *fname, const char *file_mode, int *ntasks, int *nfiles, sion_int64 **chunksizes, sion_int32 *fsblksize, int **globalranks, FILE **fileptr)
60 {
61 
62  int sid=SION_ID_UNDEF;
63  _sion_flags_store* flags_store = NULL;
64 
65  DPRINTFP((1, "_sion_open", 0, "enter open of file %s in %s mode\n", fname, file_mode));
66 
67  flags_store = _sion_parse_flags(file_mode);
68  if ( ! flags_store ) {
69  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_open: could not parse file mode in %s, aborting ...\n", file_mode));
70  }
71 
72  if (flags_store->mask&_SION_FMODE_WRITE) {
73  /* **************** WRITE mode **************** */
74 
75  sid=_sion_open_write(fname,flags_store->mask,ntasks,nfiles,chunksizes,fsblksize,globalranks,fileptr);
76 
77  } else {
78  /* **************** READ mode **************** */
79  sid=_sion_open_read(fname,flags_store->mask,_SION_READ_ALL_OF_MULTI_FILES,ntasks,nfiles,chunksizes,fsblksize,globalranks,fileptr);
80 
81  }
82 
83  _sion_flags_destroy_store(&flags_store);
84 
85  DPRINTFP((1, "_sion_open", 0, "leave open of file %s in %s mode sid=%d\n", fname, file_mode,sid));
86 
87  return sid;
88 
89 }
90 
106 int _sion_open_write(const char *fname, sion_int64 file_mode_flags, int *ntasks, int *nfiles, sion_int64 **chunksizes, sion_int32 *fsblksize, int **globalranks, FILE **fileptr)
107 {
108 
109  int i, sid;
110  _sion_filedesc *sion_filedesc;
111  sion_int64 new_fsblocksize, apiflag;
112  sion_int32 endianness = 0;
113  _sion_fileptr *sion_fileptr;
114 
115  /* check parameter */
116  if (*ntasks<0) {
117  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: wrong number of tasks specific: ntasks=%d (<0), returning ...\n", *ntasks));
118  }
119 
120  /* check parameter */
121  if ((chunksizes==NULL) || (*chunksizes==NULL)) {
122  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: chunksizes seems not to be a pointer to an array, returning ...\n"));
123  }
124 
125  /* check parameter */
126  if ((globalranks==NULL) || (*globalranks==NULL)) {
127  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: globalranks seems not to be a pointer to an array, returning ...\n"));
128  }
129 
130  /* check parameter */
131  if (*nfiles>1) {
132  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: write with nfiles > 1 currently not supported (nfiles=%d), returning ...\n",(int) *nfiles));
133  }
134 
135  /* allocate and initialise internal data structure with default values (NULL and -1) */
136  sion_filedesc = _sion_alloc_filedesc();
137  if (sion_filedesc == NULL) {
138  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: cannot allocate filedescriptor structure of size %lu (sion_filedesc), aborting ...\n", (unsigned long) sizeof(sion_filedesc)));
139  }
140  _sion_init_filedesc(sion_filedesc);
141  sion_filedesc->fname = strdup(fname); /* Set the filename */
142 
143  /* New sion file handle */
144  sid = _sion_newvcd(sion_filedesc, SION_FILEDESCRIPTOR);
145  sion_filedesc->sid=sid;
146 
147  /* Allocate memory for storing MAXCHUNKS chunksize infos in internal structure */
149 
150  /* determine endianness */
151  endianness = _sion_get_endianness_with_flags(file_mode_flags);
152 
153  DPRINTFP((1, "sion_open", 0, " it is a write operation #tasks=%d\n", *ntasks));
154 
155  sion_filedesc->state = SION_FILESTATE_SEROPEN; /* Serial state */
156  sion_filedesc->mode = SION_FILEMODE_WRITE; /* Write mode */
157  sion_filedesc->endianness = endianness; /* Endianness */
158  sion_filedesc->swapbytes = 0; /* Endianness, swapping bytes */
159  sion_filedesc->fsblksize = *fsblksize; /* Filesystem block size */
160  sion_filedesc->ntasks = *ntasks; /* Number of tasks using this file */
161  sion_filedesc->nfiles = 1;
162  sion_filedesc->filenumber = 1;
163  sion_filedesc->prefix = strdup(fname);
164 
165  if (file_mode_flags&_SION_FMODE_POSIX) apiflag=SION_FILE_FLAG_POSIX;
166 #if defined(_SION_SIONFWD)
167  else if (file_mode_flags&_SION_FMODE_SIONFWD) apiflag=SION_FILE_FLAG_SIONFWD;
168 #endif
169 #ifdef _SION_IME_NATIVE
170  else if (file_mode_flags&_SION_FMODE_IME_NATIVE) apiflag=SION_FILE_FLAG_IME_NATIVE;
171 #endif
172  else apiflag=SION_FILE_FLAG_ANSI;
173 
174  /* memory allocation for internal fields */
175  _sion_alloc_filedesc_arrays(sion_filedesc);
176 
177  /* open file */
178  sion_fileptr = _sion_file_open(fname,apiflag|SION_FILE_FLAG_WRITE|SION_FILE_FLAG_CREATE,0);
179  if (!sion_fileptr) {
180  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: cannot open %s for reading, aborting ...\n", fname));
181  }
182  sion_filedesc->fileptr = sion_fileptr;
183 
184  /* check fsblksize with fstat fsblksize */
185  if(*fsblksize<=0) {
186  new_fsblocksize=(sion_int64) _sion_file_get_opt_blksize(sion_fileptr);
187  if((new_fsblocksize<0) || (new_fsblocksize>SION_MAX_FSBLOCKSIZE)) new_fsblocksize=SION_DEFAULT_FSBLOCKSIZE;
188  *fsblksize = new_fsblocksize;
189  sion_filedesc->fsblksize = *fsblksize;
190  DPRINTFP((32, "_sion_paropen_multi_generic", 0, "setting fsblksize to %lld\n", new_fsblocksize));
191  }
192 
193  /* initialize chunksizes and partnums */
194  for (i = 0; i < *ntasks; i++) {
195  sion_filedesc->all_chunksizes[i] = (sion_int64) (*chunksizes)[i];
196  sion_filedesc->all_globalranks[i] = (sion_int64) (*globalranks)[i];
197  }
198 
199  /* check for keyval parameter, needed at this point to set flag before writing header (flag1) */
200  _sion_keyval_check_env(sion_filedesc, file_mode_flags);
201  if(sion_filedesc->keyvalmode!=SION_KEYVAL_NONE) {
202  _sion_alloc_filedesc_all_keyvalptr(sion_filedesc);
203  }
204 
205  _sion_calculate_startpointers(sion_filedesc);
206 
207  /* write header */
208  _sion_write_header(sion_filedesc);
209 
210  /* needed for writing pointer to var part of metadata at the end of the file */
211  sion_filedesc->end_of_header = _sion_file_get_position(sion_fileptr);
212  sion_filedesc->start_of_data = sion_filedesc->all_startpointers[0];
213 
214  /* initalize current positions */
215  _sion_alloc_filedesc_block_arrays(sion_filedesc);
216  for (i = 0; i < *ntasks; i++) {
217  sion_filedesc->all_blockcount[i] = 1;
218  sion_filedesc->all_currentpos[i] = sion_filedesc->all_startpointers[i];
219  sion_filedesc->all_currentblocknr[i] = 0;
220  sion_filedesc->all_blocksizes[0 * *ntasks + i] = 0;
221  }
222 
223  /* set position to first block of rank 0 */
224  sion_filedesc->rank = 0;
225  sion_filedesc->chunksize = sion_filedesc->all_chunksizes[0];
226  sion_filedesc->startpos = sion_filedesc->all_startpointers[0];
227  sion_filedesc->currentpos = sion_filedesc->startpos;
228  sion_filedesc->lastchunknr = 0;
229  sion_filedesc->currentblocknr = 0;
230  _sion_file_purge(sion_fileptr);
231  _sion_file_set_position(sion_fileptr, sion_filedesc->currentpos);
232 
233  if(fileptr!=NULL) {
234  if(sion_filedesc->fileptr->flags&&SION_FILE_FLAG_ANSI) {
235  *fileptr=sion_filedesc->fileptr->fileptr;
236  sion_filedesc->fileptr_exported=1;
237  } else {
238  *fileptr=NULL;
239  sion_filedesc->fileptr_exported=0;
240  }
241  }
242 
243  _sion_print_filedesc(sion_filedesc, 512, "_sion_open_write", 1);
244 
245  return(sid);
246 }
247 
248 
266 int _sion_open_read(const char *fname, sion_int64 file_mode_flags, int read_all, int *ntasks, int *nfiles, sion_int64 **chunksizes, sion_int32 *fsblksize, int **globalranks, FILE **fileptr)
267 {
268 
269  int rc, sid;
270  _sion_filedesc *sion_filedesc;
271  _sion_fileptr *sion_fileptr;
272  sion_int64 apiflag;
273 
274  /* allocate and initialise internal data structure with default values (NULL and -1) */
275  sion_filedesc = _sion_alloc_filedesc();
276  if (sion_filedesc == NULL) {
277  return(_sion_errorprint(SION_ID_UNDEF,SION_ID_UNDEF,"sion_open: cannot allocate filedescriptor structure of size %lu (sion_filedesc), aborting ...\n", (unsigned long) sizeof(sion_filedesc)));
278  }
279  _sion_init_filedesc(sion_filedesc);
280  sion_filedesc->fname = strdup(fname); /* Set the filename */
281 
282  /* New sion file handle */
283  sid = _sion_newvcd(sion_filedesc, SION_FILEDESCRIPTOR);
284  sion_filedesc->sid=sid;
285 
286  if (file_mode_flags&_SION_FMODE_POSIX) apiflag=SION_FILE_FLAG_POSIX;
287 #if defined(_SION_SIONFWD)
288  else if (file_mode_flags&_SION_FMODE_SIONFWD) apiflag=SION_FILE_FLAG_SIONFWD;
289 #endif
290 #ifdef _SION_IME_NATIVE
291  else if (file_mode_flags&_SION_FMODE_IME_NATIVE) apiflag=SION_FILE_FLAG_IME_NATIVE;
292 #endif
293  else apiflag=SION_FILE_FLAG_ANSI;
294 
295  DPRINTFP((1, "sion_open", 0, " it is a read operation\n"));
296 
297  /* open file */
298  sion_fileptr = _sion_file_open(fname,apiflag|SION_FILE_FLAG_READ,0);
299  if (!sion_fileptr) {
300  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: cannot open %s for reading, aborting ...\n", fname));
301  }
302  sion_filedesc->fileptr = sion_fileptr;
303 
304  /* read part of header which does not depend on ntasks */
305  rc = _sion_read_header_fix_part(sion_filedesc);
306  if (rc!=SION_SUCCESS) {
307  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: cannot read header from file %s, aborting ...\n", fname));
308  }
309  sion_filedesc->rank = 0;
310  sion_filedesc->state = SION_FILESTATE_SEROPEN;
311  sion_filedesc->mode = SION_FILEMODE_READ;
312 
313  /* memory allocation for internal fields */
314  _sion_alloc_filedesc_arrays(sion_filedesc);
315 
316  /* read part of header which depends on ntasks */
317  rc = _sion_read_header_var_part(sion_filedesc);
318  if (rc!=SION_SUCCESS) {
319  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: cannot read header (var part) from file %s, aborting ...\n", fname));
320  }
321 
322  /* set up internal data */
323  _sion_calculate_startpointers(sion_filedesc);
324 
325  /* allocate memory and read all blocksizes of all tasks from meta data 2 */
326  _sion_alloc_filedesc_block_arrays(sion_filedesc);
327  rc = _sion_read_header_var_part_blocksizes(sion_filedesc);
328  if (rc!=SION_SUCCESS) {
329  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: cannot read header (var part block sizes) from file %s, aborting ...\n", fname));
330  }
331 
332  /* check for keyval parameter */
333  _sion_keyval_check_env(sion_filedesc, file_mode_flags);
334  if(sion_filedesc->keyvalmode!=SION_KEYVAL_NONE) {
335  _sion_alloc_filedesc_all_keyvalptr(sion_filedesc);
336  }
337 
338  /* read complete mapping */
339  if((sion_filedesc->nfiles>1) && (sion_filedesc->filenumber==0)) {
340 
341  if(read_all==_SION_READ_ALL_OF_MULTI_FILES) {
342  sid=_sion_open_read_master(fname,file_mode_flags,ntasks,nfiles,chunksizes,fsblksize,globalranks,fileptr,sion_filedesc);
343  } else {
344  sid=_sion_open_read_single(fname,file_mode_flags,ntasks,nfiles,chunksizes,fsblksize,globalranks,fileptr,sion_filedesc);
345  /* read mapping file, will be moved later to master file */
346  _sion_read_header_var_part_mapping(sion_filedesc);
347  { int rank;
348  for (rank = 0; rank < sion_filedesc->mapping_size; rank++) {
349  DPRINTFP((2048, "sion_open", 0, " mapping[%d] = %d , %d \n", rank,sion_filedesc->mapping[rank*2+0],sion_filedesc->mapping[rank*2+1]));
350  }
351  }
352  }
353 
354 
355  } else { /* not opened on master file */
356  sid=_sion_open_read_single(fname,file_mode_flags,ntasks,nfiles,chunksizes,fsblksize,globalranks,fileptr,sion_filedesc);
357 
358  } /* end single file */
359 
360 
361  return(sid);
362 }
363 
364 int _sion_open_read_single(const char *fname, sion_int64 file_mode_flags, int *ntasks, int *nfiles, sion_int64 **chunksizes, sion_int32 *fsblksize, int **globalranks, FILE **fileptr, _sion_filedesc *sion_filedesc)
365 {
366 
367  int i, sid, blknum;
368 
369  /* set info for current rank and position */
370  sid=sion_filedesc->sid;
371  sion_filedesc->chunksize = sion_filedesc->all_chunksizes[sion_filedesc->rank];
372  sion_filedesc->startpos = sion_filedesc->all_startpointers[sion_filedesc->rank];
373  sion_filedesc->currentpos = sion_filedesc->startpos;
374  sion_filedesc->currentblocknr = 0;
375  sion_filedesc->lastchunknr = sion_filedesc->all_blockcount[sion_filedesc->rank]-1;
376  for (blknum = 0; blknum <= sion_filedesc->lastchunknr; blknum++) {
377  sion_filedesc->blocksizes[blknum] = sion_filedesc->all_blocksizes[sion_filedesc->ntasks * blknum + sion_filedesc->rank];
378  }
379  _sion_file_flush(sion_filedesc->fileptr);
380  _sion_file_set_position(sion_filedesc->fileptr, sion_filedesc->currentpos);
381 
382  /* initalize current positions */
383  for (i = 0; i < sion_filedesc->ntasks; i++) {
384  sion_filedesc->all_currentpos[i] = sion_filedesc->all_startpointers[i];
385  sion_filedesc->all_currentblocknr[i] = 0;
386  }
387 
388 
389  /* OUTPUT parameters: set parameter chunksizes and globalranks */
390  *ntasks = sion_filedesc->ntasks;
391  *nfiles = sion_filedesc->nfiles;
392  *fsblksize = sion_filedesc->fsblksize;
393 
394  if (chunksizes != NULL) {
395  sion_int64 *helpptr = NULL;
396  if ((*chunksizes) == NULL) {
397  helpptr = (sion_int64 *) malloc(*ntasks * sizeof(sion_int64));
398  if (helpptr == NULL) {
399  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"cannot allocate filedescriptor structure of size %lu (chunksizes), aborting ...\n", (unsigned long) sizeof(sion_int64)));
400  }
401  *chunksizes = helpptr;
402  } else {
403  helpptr = *chunksizes;
404  }
405  for (i = 0; i < *ntasks; i++) {
406  helpptr[i] = sion_filedesc->all_chunksizes[i];
407  }
408  }
409  if (globalranks != NULL) {
410  int *helpptr = NULL;
411  if ((*globalranks) == NULL) {
412  helpptr = (int *) malloc(*ntasks * sizeof(int));
413  if (helpptr == NULL) {
414  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: cannot allocate memory of size %lu (globalranks), aborting ...\n", (unsigned long) (*ntasks) * sizeof(int)));
415  }
416  *globalranks = helpptr;
417  } else {
418  helpptr = *globalranks;
419  }
420  for (i = 0; i < (*ntasks); i++) {
421  helpptr[i] = (int) sion_filedesc->all_globalranks[i];
422  }
423  }
424 
425  if(fileptr!=NULL) {
426  if(sion_filedesc->fileptr->flags&&SION_FILE_FLAG_ANSI) {
427  *fileptr=sion_filedesc->fileptr->fileptr;
428  sion_filedesc->fileptr_exported=1;
429  } else {
430  *fileptr=NULL;
431  sion_filedesc->fileptr_exported=0;
432  }
433  }
434 
435  _sion_print_filedesc(sion_filedesc, 512, "_sion_open_read_single", 1);
436 
437  return(sid);
438 }
439 
440 
441 int _sion_open_read_master(const char *fname, sion_int64 file_mode_flags, int *ntasks, int *nfiles, sion_int64 **chunksizes, sion_int32 *fsblksize, int **globalranks, FILE **fileptr, _sion_filedesc *sion_filedesc)
442 {
443 
444  int i, sid, blknum;
445  int sid_master, subsid, lfile, lrank, filenr;
446  _sion_filedesc *sion_filedesc_master,*sion_filedesc_sub;
447 
448  /* set info for current rank and position */
449  sion_filedesc->chunksize = sion_filedesc->all_chunksizes[sion_filedesc->rank];
450  sion_filedesc->startpos = sion_filedesc->all_startpointers[sion_filedesc->rank];
451  sion_filedesc->currentpos = sion_filedesc->startpos;
452  sion_filedesc->currentblocknr = 0;
453  sion_filedesc->lastchunknr = sion_filedesc->all_blockcount[sion_filedesc->rank]-1;
454  for (blknum = 0; blknum <= sion_filedesc->lastchunknr; blknum++) {
455  sion_filedesc->blocksizes[blknum] = sion_filedesc->all_blocksizes[sion_filedesc->ntasks * blknum + sion_filedesc->rank];
456  }
457  _sion_file_flush(sion_filedesc->fileptr);
458  _sion_file_set_position(sion_filedesc->fileptr, sion_filedesc->currentpos);
459 
460  /* initalize current positions */
461  for (i = 0; i < sion_filedesc->ntasks; i++) {
462  sion_filedesc->all_currentpos[i] = sion_filedesc->all_startpointers[i];
463  sion_filedesc->all_currentblocknr[i] = 0;
464  }
465 
466  /* read mapping file, will be moved later to master file */
467  _sion_read_header_var_part_mapping(sion_filedesc);
468  { int rank;
469  for (rank = 0; rank < sion_filedesc->mapping_size; rank++) {
470  DPRINTFP((32, "sion_open", 0, " mapping[%d] = %d , %d \n", rank,sion_filedesc->mapping[rank*2+0],sion_filedesc->mapping[rank*2+1]));
471  }
472  }
473 
474  /* create a master datastructure */
475  sion_filedesc_master = _sion_alloc_filedesc();
476  if (sion_filedesc_master == NULL) {
477  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: cannot allocate filedescriptor structure of size %lu (sion_filedesc_master), aborting ...\n",
478  (unsigned long) sizeof(sion_filedesc_master)));
479  }
480  _sion_init_filedesc(sion_filedesc_master);
481  sion_filedesc_master->fname = strdup(fname); /* Set the filename */
482  sion_filedesc_master->state = SION_FILESTATE_SEROPENMASTER;
483  sion_filedesc_master->mode = SION_FILEMODE_READ;
484 
485  /* New sion file handle */
486  sid_master = _sion_newvcd(sion_filedesc_master, SION_FILEDESCRIPTOR);
487  sion_filedesc_master->sid=sid_master;
488 
489  /* allocate vector for all datastructures */
490  sion_filedesc_master->multifiles = (_sion_filedesc **) malloc(sion_filedesc->nfiles * sizeof(_sion_filedesc*));
491  if (sion_filedesc_master->multifiles == NULL) {
492  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"cannot allocate filedescriptor structure vector of size %lu (sion_filedesc), aborting ...\n",
493  (unsigned long) sion_filedesc->nfiles * sizeof(_sion_filedesc*)));
494  }
495 
496 
497  /* first file is already opened */
498  sion_filedesc_master->multifiles[0]=sion_filedesc;
499 
500  for(filenr=1;filenr<sion_filedesc->nfiles;filenr++) {
501  int sub_ntasts, sub_nfiles;
502  sion_int32 sub_chunksize;
503  FILE *sub_fileptr;
504  char *multi_fname;
505  multi_fname = _sion_get_multi_filename(fname, filenr);
506  DPRINTFP((32, "sion_open", 0, "open now sub file = %d %s\n", filenr, multi_fname));
507  subsid=_sion_open_read(multi_fname,
508  file_mode_flags, _SION_READ_ALL_OF_MULTI_FILES, &sub_ntasts, &sub_nfiles, NULL, &sub_chunksize, NULL, &sub_fileptr);
509  sion_filedesc_sub=_sion_get_filedesc(subsid);
510  sion_filedesc_master->multifiles[filenr]=sion_filedesc_sub;
511  DPRINTFP((32, "sion_open", 0, "sub file = %d %s opened\n", filenr, multi_fname));
512  free(multi_fname);
513  }
514 
515  /* move mapping to master */
516  sion_filedesc_master->mapping_size=sion_filedesc->mapping_size;sion_filedesc->mapping_size=-1;
517  sion_filedesc_master->mapping=sion_filedesc->mapping;sion_filedesc->mapping=NULL;
518 
519  /* set rest of master data */
520  sion_filedesc_master->rank = 0;
521 
522  /* lookup file which contains current rank */
523  lfile=sion_filedesc_master->mapping[sion_filedesc_master->rank*2+0];
524  lrank=sion_filedesc_master->mapping[sion_filedesc_master->rank*2+1];
525  sion_filedesc_sub=sion_filedesc_master->multifiles[lfile];
526 
527  sion_filedesc_master->ntasks = sion_filedesc_master->mapping_size;
528  sion_filedesc_master->endianness = sion_filedesc_sub->endianness;
529  sion_filedesc_master->swapbytes = sion_filedesc_sub->swapbytes;
530  sion_filedesc_master->fileversion = sion_filedesc_sub->fileversion;
531  sion_filedesc_master->filesionversion = sion_filedesc_sub->filesionversion;
532  sion_filedesc_master->filesionpatchlevel = sion_filedesc_sub->filesionpatchlevel;
533  sion_filedesc_master->fsblksize = sion_filedesc_sub->fsblksize;
534  sion_filedesc_master->swapbytes = sion_filedesc_sub->swapbytes;
535  sion_filedesc_master->nfiles = sion_filedesc_sub->nfiles;
536  sion_filedesc_master->flag1 = sion_filedesc_sub->flag1;
537  sion_filedesc_master->flag2 = sion_filedesc_sub->flag2;
538  sion_filedesc_master->keyvalmode = sion_filedesc_sub->keyvalmode;
539  sion_filedesc_master->prefix = strdup(sion_filedesc->prefix);
540  sion_filedesc_master->filenumber = 0;
541 
542  /* set info for current rank and position */
543  sion_filedesc_master->chunksize = sion_filedesc_sub->all_chunksizes[lrank];
544  sion_filedesc_master->startpos = sion_filedesc_sub->all_startpointers[lrank];
545  sion_filedesc_master->currentpos = sion_filedesc_master->startpos;
546  sion_filedesc_master->globalskip = sion_filedesc_sub->globalskip;
547 
548  sion_filedesc_master->currentblocknr = 0;
549  sion_filedesc_master->lastchunknr = sion_filedesc_sub->all_blockcount[lrank]-1;
550  sion_filedesc_master->start_of_varheader = sion_filedesc_sub->start_of_varheader;
551 
552  /* set maxusedchunks */
553  sion_filedesc_master->maxusedchunks = sion_filedesc->maxusedchunks;
554  for(filenr=1;filenr<sion_filedesc->nfiles;filenr++)
555  if (sion_filedesc_master->maxusedchunks < sion_filedesc_master->multifiles[filenr]->maxusedchunks)
556  sion_filedesc_master->maxusedchunks = sion_filedesc_master->multifiles[filenr]->maxusedchunks;
557 
558  _sion_realloc_filedesc_blocklist(sion_filedesc_master, sion_filedesc_master->maxusedchunks);
559  for (blknum = 0; blknum < sion_filedesc_sub->all_blockcount[lrank]; blknum++) {
560  sion_filedesc_master->blocksizes[blknum] = sion_filedesc_sub->all_blocksizes[sion_filedesc_sub->ntasks * blknum + lrank];
561  }
562 
563  /* set file pointer */
564  sion_filedesc_master->fileptr = sion_filedesc_master->multifiles[lfile]->fileptr;
565 
566  /* switch to master */
567  sion_filedesc = sion_filedesc_master;
568  sid = sid_master;
569 
570  /* set position */
571  _sion_file_flush(sion_filedesc->fileptr);
572  _sion_file_set_position(sion_filedesc->fileptr, sion_filedesc->currentpos);
573 
574  /* OUTPUT parameters: set parameter chunksizes and globalranks */
575  *ntasks = sion_filedesc->ntasks;
576  *nfiles = sion_filedesc->nfiles;
577  *fsblksize = sion_filedesc->fsblksize;
578  if (chunksizes != NULL) {
579  sion_int64 *helpptr = NULL;
580  if ((*chunksizes) == NULL) {
581  helpptr = (sion_int64 *) malloc(*ntasks * sizeof(sion_int64));
582  if (helpptr == NULL) {
583  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"cannot allocate filedescriptor structure of size %lu (chunksizes), aborting ...\n", (unsigned long) sizeof(sion_int64)));
584  }
585  *chunksizes = helpptr;
586  } else {
587  helpptr = *chunksizes;
588  }
589  for (i = 0; i < *ntasks; i++) {
590  lfile=sion_filedesc_master->mapping[i*2+0]; lrank=sion_filedesc_master->mapping[i*2+1];
591  helpptr[i] = sion_filedesc_master->multifiles[lfile]->all_chunksizes[lrank];
592  }
593  }
594  if (globalranks != NULL) {
595  int *helpptr = NULL;
596  if ((*globalranks) == NULL) {
597  helpptr = (int *) malloc(*ntasks * sizeof(int));
598  if (helpptr == NULL) {
599  return(_sion_errorprint(SION_ID_UNDEF,_SION_ERROR_RETURN,"sion_open: cannot allocate memory of size %lu (globalranks), aborting ...\n", (unsigned long) (*ntasks) * sizeof(int)));
600  }
601  *globalranks = helpptr;
602  }
603  else {
604  helpptr = *globalranks;
605  }
606  for (i = 0; i < (*ntasks); i++) {
607  lfile=sion_filedesc_master->mapping[i*2+0]; lrank=sion_filedesc_master->mapping[i*2+1];
608  helpptr[i] = sion_filedesc_master->multifiles[lfile]->all_globalranks[lrank];
609  }
610  }
611 
612  if(fileptr!=NULL) {
613  if(sion_filedesc->fileptr->flags&&SION_FILE_FLAG_ANSI) {
614  *fileptr=sion_filedesc->fileptr->fileptr;
615  sion_filedesc->fileptr_exported=1;
616  } else {
617  *fileptr=NULL;
618  sion_filedesc->fileptr_exported=0;
619  }
620  }
621 
622  _sion_print_filedesc(sion_filedesc, 512, "_sion_open_read_master", 1);
623 
624  return(sid);
625 }
626 
627 int _sion_open_rank(const char *fname, const char *file_mode, sion_int64 *chunksize, sion_int32 *fsblksize, int *rank, FILE **fileptr)
628 {
629 
630  int rc=SION_NOT_SUCCESS, sid=SION_ID_UNDEF;
631  int mapping_filenr, mapping_lrank;
632  char prefix = '\0';
633  sion_int64 apiflag;
634  _sion_filedesc *sion_filedesc;
635  _sion_fileptr *sion_fileptr;
636  _sion_flags_store* flags_store = NULL;
637 
638  /* */ DPRINTFTS(*rank, "before open rank");
639  DPRINTFP((1, "_sion_open_rank", *rank, "enter open of file %s in %s mode\n", fname, file_mode));
640 
641  /* allocate and initialise internal data structure with default values (NULL and -1) */
642  sion_filedesc = _sion_alloc_filedesc();
643  if (sion_filedesc == NULL) {
644  return(_sion_errorprint_on_rank(SION_ID_UNDEF,_SION_ERROR_RETURN,*rank,"_sion_open_rank: cannot allocate filedescriptor structure of size %lu (sion_filedesc), aborting ...", (unsigned long) sizeof(sion_filedesc)));
645  }
646  _sion_init_filedesc(sion_filedesc);
647  sion_filedesc->fname = strdup(fname); /* Set the filename */
648 
649  /* New sion file handle */
650  sid = _sion_newvcd(sion_filedesc, SION_FILEDESCRIPTOR);
651  sion_filedesc->sid=sid;
652 
653  flags_store = _sion_parse_flags(file_mode);
654  if ( ! flags_store ) {
655  return(_sion_errorprint_on_rank(SION_ID_UNDEF,_SION_ERROR_RETURN,*rank,"sion_paropen_mpi: could not parse file mode in %s, aborting ...", file_mode));
656  }
657 
658  if (flags_store->mask&_SION_FMODE_POSIX) apiflag=SION_FILE_FLAG_POSIX;
659 #if defined(_SION_SIONFWD)
660  else if (flags_store->mask&_SION_FMODE_SIONFWD) apiflag=SION_FILE_FLAG_SIONFWD;
661 #endif
662 #ifdef _SION_IME_NATIVE
663  else if (flags_store->mask&_SION_FMODE_IME_NATIVE) apiflag=SION_FILE_FLAG_IME_NATIVE;
664 #endif
665  else apiflag=SION_FILE_FLAG_ANSI;
666 
667  if (flags_store->mask&_SION_FMODE_WRITE) {
668  /* **************** WRITE mode **************** */
669 
670  DPRINTFP((1, "_sion_open_rank", *rank, " it is a write operation\n"));
671 
672  _sion_flags_destroy_store(&flags_store);
673  return(_sion_errorprint_on_rank(SION_ID_UNDEF,_SION_ERROR_RETURN,*rank,"_sion_open_rank: %s for writing currently not supported, aborting ...", fname));
674 
675  }
676  _sion_flags_destroy_store(&flags_store);
677 
678  /* **************** READ mode **************** */
679 /* */ DPRINTFTS(*rank, "start open read");
680  DPRINTFP((1, "_sion_open_rank", *rank, " it is a read operation rank=%d\n",*rank));
681 
682  /* open file */
683  sion_fileptr = _sion_file_open(fname,apiflag|SION_FILE_FLAG_READ,0);
684  if (!sion_fileptr) {
685  return(_sion_errorprint_on_rank(SION_ID_UNDEF,_SION_ERROR_RETURN,*rank,"_sion_open_rank: cannot open %s for reading, aborting ...", fname));
686  }
687  sion_filedesc->fileptr = sion_fileptr;
688  /* */ DPRINTFTS(*rank, "start after open file 1");
689  rc = _sion_read_header_fix_part(sion_filedesc);
690  /* */ DPRINTFTS(*rank, "start after read header fix part 1");
691  if (rc==SION_NOT_SUCCESS) {
692  return(_sion_errorprint_on_rank(SION_ID_UNDEF,_SION_ERROR_RETURN,*rank,"_sion_open_rank: cannot read header from file %s, aborting ...", fname));
693  }
694  sion_filedesc->rank = *rank;
695  sion_filedesc->state = SION_FILESTATE_SEROPENRANK;
696  sion_filedesc->mode = SION_FILEMODE_READ;
697 
698  /* memory allocation for internal fields */
699  _sion_alloc_filedesc_arrays(sion_filedesc);
700 
701  /* read part of header which depends on ntasks */
702  rc = _sion_read_header_var_part(sion_filedesc);
703  /* */ DPRINTFTS(*rank, "start after read header var part 1");
704  if (rc==SION_NOT_SUCCESS) {
705  return(_sion_errorprint_on_rank(SION_ID_UNDEF,_SION_ERROR_RETURN,*rank,"_sion_open_rank: cannot read var part header from file %s, aborting ...", fname));
706  }
707 
708  DPRINTFP((1, "_sion_open_rank", *rank, "found number of files %d in %s rank=%d\n", sion_filedesc->nfiles,sion_filedesc->fname,*rank));
709  if(sion_filedesc->nfiles>1) {
710  /* read mapping for rank */
711  rc=_sion_read_header_var_part_mapping_rank(sion_filedesc);
712  /* */ DPRINTFTS(*rank, "start after read mapping rank 1");
713  if (rc==SION_NOT_SUCCESS) {
714  return(_sion_errorprint_on_rank(SION_ID_UNDEF,_SION_ERROR_RETURN,*rank,"cannot read var part mapping header from file %s, aborting ...", fname));
715  }
716  mapping_filenr = sion_filedesc->mapping[0];
717  mapping_lrank = sion_filedesc->mapping[1];
718  DPRINTFP((1, "_sion_open_rank", *rank, "data for rank %d is in file %d (lrank=%d)\n", *rank, mapping_filenr,mapping_lrank));
719  /* */ DPRINTFTS(*rank, "start after read mapping 1");
720 
721  /* reopen one of other multi files if necessary */
722  if(mapping_filenr>0) {
723 
724  /* close current file */
725  _sion_free_filedesc_arrays(sion_filedesc);
726  _sion_file_close(sion_filedesc->fileptr);
727  sion_filedesc->fileptr=NULL;
728  /* */ DPRINTFTS(*rank, "start after close file 1");
729 
730  /* and open again the correct one */
731  sion_filedesc->fname=_sion_get_multi_filename(fname,mapping_filenr);
732 
733  DPRINTFP((1, "_sion_open_rank", *rank, "open file sion_filedesc->fname=%s fname=%s rank=%d\n", sion_filedesc->fname,fname,*rank));
734 
735  sion_fileptr = _sion_file_open(sion_filedesc->fname,apiflag|SION_FILE_FLAG_READ,0);
736  if (!sion_fileptr) {
737  return(_sion_errorprint_on_rank(SION_ID_UNDEF,_SION_ERROR_RETURN,*rank,"_sion_open_rank: cannot open %s for reading, aborting ...", fname));
738  }
739  sion_filedesc->fileptr = sion_fileptr;
740  /* */ DPRINTFTS(*rank, "start after open file i");
741 
742  rc = _sion_read_header_fix_part(sion_filedesc);
743  if (rc==SION_NOT_SUCCESS) {
744  return(_sion_errorprint_on_rank(SION_ID_UNDEF,_SION_ERROR_RETURN,*rank,"sion_open: cannot read header from file %s, aborting ...", fname));
745  }
746  /* */ DPRINTFTS(*rank, "start after read header fix part i");
747  _sion_alloc_filedesc_arrays(sion_filedesc);
748  rc = _sion_read_header_var_part(sion_filedesc);
749  if (rc==SION_NOT_SUCCESS) {
750  return(_sion_errorprint_on_rank(SION_ID_UNDEF,_SION_ERROR_RETURN,*rank,"cannot var mapping data from file %s, aborting ...", fname));
751  }
752  /* */ DPRINTFTS(*rank, "start after read header var part i");
753 
754  } else {
755  sion_filedesc->fname = strdup(fname);
756  }
757  } else {
758  mapping_lrank=*rank;
759  }
760 
761  DPRINTFP((1, "_sion_open_rank", *rank, "max blocks=%d\n", sion_filedesc->maxusedchunks));
762  _sion_realloc_filedesc_blocklist(sion_filedesc, sion_filedesc->maxusedchunks);
763 
764  sion_filedesc->prefix = strdup(&prefix);
765 
766  _sion_calculate_startpointers(sion_filedesc);
767 
768  sion_filedesc->rank = mapping_lrank;
769 
770  rc = _sion_read_header_var_part_blocksizes_rank(sion_filedesc);
771  if (rc==SION_NOT_SUCCESS) {
772  return(_sion_errorprint_on_rank(SION_ID_UNDEF,_SION_ERROR_RETURN,sion_filedesc->rank,"cannot read header from file %s, aborting ...", fname));
773  }
774  /* */ DPRINTFTS(*rank, "start after read header blocksizes i");
775 
776  /* set info for current rank and position */
777  sion_filedesc->chunksize = sion_filedesc->all_chunksizes[sion_filedesc->rank];
778  sion_filedesc->startpos = sion_filedesc->all_startpointers[sion_filedesc->rank];
779  sion_filedesc->currentpos = sion_filedesc->startpos;
780  sion_filedesc->currentblocknr = 0;
781 
782  /* set file pointer */
783  _sion_file_purge(sion_filedesc->fileptr);
784  _sion_file_set_position(sion_filedesc->fileptr, sion_filedesc->currentpos);
785 
786  /* set output parameter */
787  *chunksize=sion_filedesc->chunksize;
788  *fsblksize=sion_filedesc->fsblksize;
789 
790  if(fileptr!=NULL) {
791  if(sion_filedesc->fileptr->flags&SION_FILE_FLAG_ANSI) {
792  *fileptr=sion_filedesc->fileptr->fileptr;
793  sion_filedesc->fileptr_exported=1;
794  } else {
795  *fileptr=NULL;
796  sion_filedesc->fileptr_exported=0;
797  }
798  }
799 
800  _sion_print_filedesc(sion_filedesc, 512, "_sion_open_rank", 1);
801 
802  DPRINTFP((1, "_sion_open_rank", 0, "leave open of file %s in %s mode\n", fname, file_mode));
803  /* */ DPRINTFTS(*rank, "after open rank");
804 
805  return (sid);
806 
807 }
808 
809 /* sion_filedesc has to be freed by calling function */
810 int _sion_close(_sion_filedesc *sion_filedesc)
811 {
812 
813  int rc = SION_SUCCESS;
814  int blknum, rank, currentrank, mapping_size;
815 #ifdef SION_SERIAL_MASTER
816  int filenr;
817 #endif
818 
819 
820 
821  DPRINTFP((1, "_sion_close", -1, "enter close sid=%d currentpos=%15lld\n", sion_filedesc->sid, sion_filedesc->currentpos));
822  _sion_print_filedesc(sion_filedesc, 512, "_sion_close", 1);
823 
824 
825  if ((sion_filedesc->state != SION_FILESTATE_SEROPEN)
826  && (sion_filedesc->state != SION_FILESTATE_SEROPENRANK)
827  && (sion_filedesc->state != SION_FILESTATE_SEROPENMASTER)
828  ) {
829  return(_sion_errorprint_on_rank(SION_NOT_SUCCESS,_SION_ERROR_RETURN,sion_filedesc->rank,"_sion_close: invalid file open state (!SEROPEN), aborting %d ...", sion_filedesc->sid));
830  }
831 
832  if (sion_filedesc->mode == SION_FILEMODE_WRITE) {
833  /* write rest of metadata in headers */
834 
835  DPRINTFP((1, "_sion_close", -1, " file was opened in write mode sid=%d setpos to %lld\n", sion_filedesc->sid, sion_filedesc->end_of_header));
836 
837  /* update meta data of current rank */
838  _sion_flush_block(sion_filedesc);
839  DPRINTFP((1, "_sion_close", -1, " after flush block sid=%d fileptr is at position %14lld\n", sion_filedesc->sid, _sion_file_get_position(sion_filedesc->fileptr)));
840 
841  if (sion_filedesc->usebuffer) {
842  _sion_buffer_flush(sion_filedesc);
843  }
844 
845  /* store data of current rank */
846  currentrank = sion_filedesc->rank;
847  sion_filedesc->all_currentpos[currentrank] = sion_filedesc->startpos + sion_filedesc->blocksizes[sion_filedesc->lastchunknr];
848  sion_filedesc->all_currentblocknr[currentrank] = sion_filedesc->lastchunknr;
849  sion_filedesc->all_blockcount[currentrank] = sion_filedesc->lastchunknr + 1;
850  for (blknum = 0; blknum <= sion_filedesc->lastchunknr; blknum++) {
851  sion_filedesc->all_blocksizes[sion_filedesc->ntasks * blknum + currentrank] = sion_filedesc->blocksizes[blknum];
852  }
853 
854  /* search and set maxusedchunks */
855  sion_filedesc->maxusedchunks = -1;
856  for (blknum = 0; blknum < sion_filedesc->ntasks; blknum++)
857  if (sion_filedesc->all_blockcount[blknum] > sion_filedesc->maxusedchunks)
858  sion_filedesc->maxusedchunks = (int) sion_filedesc->all_blockcount[blknum];
859 
860  /* calculate and set start_of_varheader */
861  sion_filedesc->start_of_varheader = sion_filedesc->start_of_data + sion_filedesc->maxusedchunks * sion_filedesc->globalskip;
862 
863  /* write rest of first meta data block */
864  _sion_write_header_var_info(sion_filedesc);
865 
866  /* set blocksizes of all not used chunks to zero */
867  for (blknum = 0; blknum < sion_filedesc->maxusedchunks; blknum++) {
868  for (rank = 0; rank < sion_filedesc->ntasks; rank++) {
869  if (blknum >= sion_filedesc->all_blockcount[rank]) {
870  sion_filedesc->all_blocksizes[sion_filedesc->ntasks * blknum + rank] = 0;
871  } else {
872  DPRINTFP((1, "_sion_close", -1,
873  " blocksize rank %2d blk %2d -> %lld\n",
874  rank, blknum, sion_filedesc->all_blocksizes[sion_filedesc->ntasks * blknum + rank]));
875  }
876  }
877  }
878 
879  /* write blockinfo to second meta data block */
881 
882  /* write mapping info to second meta data block */
883  mapping_size = 0;
884  _sion_write_header_var_part_mapping(sion_filedesc,mapping_size,NULL);
885 
886  _sion_print_filedesc(sion_filedesc, 512, "_sion_close", 1);
887 
888  /* close file and free data structure */
889  _sion_file_close(sion_filedesc->fileptr);
890  sion_filedesc->fileptr=NULL;
891 
892  } else {
893  /* read */
894 
895 #ifdef SION_SERIAL_MASTER
896  /* close all files if multi file */
897  ;
898  if(sion_filedesc->state == SION_FILESTATE_SEROPENMASTER) {
899  for(filenr=1;filenr<sion_filedesc->nfiles;filenr++) {
900  _sion_close(sion_filedesc->multifiles[filenr]);
901  _sion_freevcd(sion_filedesc->multifiles[filenr]->sid);
902  _sion_free_filedesc(sion_filedesc->multifiles[filenr]);
903  sion_filedesc->multifiles[filenr]=NULL;
904  }
905  } else {
906 #endif
907 
908  /* close file and free data structure */
909  _sion_file_close(sion_filedesc->fileptr);
910  sion_filedesc->fileptr=NULL;
911 
912 #ifdef SION_SERIAL_MASTER
913  }
914 #endif
915  }
916 
917  DPRINTFP((1, "_sion_close", -1, "leave close sid=%d\n", sion_filedesc->sid));
918 
919  return (rc);
920 }
921 
929 char * _sion_get_multi_filename(const char *fname, int filenumber)
930 {
931  char *newfname;
932 
933  newfname = malloc(SION_FILENAME_LENGTH);
934  if (newfname == NULL) {
935  _sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_get_multi_filename: Cannot allocate string newfname\n");
936  return(NULL);
937  }
938  if(filenumber>0) {
939  if(strlen(fname)<SION_FILENAME_LENGTH-7) {
940  sprintf(newfname, "%s.%06d", fname, filenumber);
941  } else {
942  _sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_get_multi_filename: filename too long\n");
943  free(newfname);
944  return(NULL);
945  }
946  } else {
947  strcpy(newfname, fname);
948  }
949 
950  return(newfname);
951 }
952 
953 
960 int _sion_flush_file(int sid)
961 {
962  int rc = SION_SUCCESS;
963  _sion_filedesc *sion_filedesc;
964 
965  if ((_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
966  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_flush_file: invalid sion_filedesc, aborting %d ...\n", sid));
967  }
968  DPRINTFP((32, "_sion_flush_file", sion_filedesc->rank, "flush sid=%d\n", sid));
969 
970  _sion_file_flush(sion_filedesc->fileptr);
971  return (rc);
972 }
973 
974 
985 {
986  int rc = SION_SUCCESS;
987 
988  DPRINTFP((2, "_sion_update_fileposition", sion_filedesc->rank, "enter\n"));
989  /* only neccesary to get file position directly from system file pointer,
990  if fileptr was exported to application */
991  if(sion_filedesc->fileptr_exported) {
992 
993 #ifdef OLD
994  /* if fileptr is exported, it will be used in collective mode only from the collector tasks */
995  if( (!sion_filedesc->usecoll) || (sion_filedesc->collector==sion_filedesc->rank) ) {
996  _sion_file_flush(sion_filedesc->fileptr);
997  sion_filedesc->currentpos = _sion_file_get_position(sion_filedesc->fileptr);
998  }
999 #endif
1000  /* file position is possible be changed by external (non-sion) file read/write operation,
1001  therefore the sion internal file position must be updated */
1002  _sion_file_flush(sion_filedesc->fileptr);
1003  sion_filedesc->currentpos = _sion_file_get_position(sion_filedesc->fileptr);
1004  }
1005 
1006  DPRINTFP((2, "_sion_update_fileposition", sion_filedesc->rank, "leave pos=%lld usecoll=%d collector=%d rank\n",
1007  (long long) sion_filedesc->currentpos, sion_filedesc->usecoll,sion_filedesc->collector,sion_filedesc->rank));
1008  return (rc);
1009 }
1010 
1018  int rc = SION_SUCCESS;
1019 
1020  /* don't check if collective merge */
1021  /* branch to merge mode if enabled */
1022  if(sion_filedesc->collmergemode) {
1023  return(rc);
1024  }
1025 
1026 
1027  /* this functions checks in non-collective call after a collective one was called
1028  this function ensures that buffer are flushed accordantly */
1029  /* if(sion_filedesc->fileptr_exported) { */
1030  if(sion_filedesc->usecoll) {
1031  sion_filedesc->usecoll=0;
1032  if((!sion_filedesc->collector) && (sion_filedesc->collcmdused)) {
1033  _sion_file_flush(sion_filedesc->fileptr);
1034  _sion_file_set_position(sion_filedesc->fileptr,sion_filedesc->currentpos);;
1035  }
1036  return(rc);
1037  /* return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_WARN,"_sion_check_on_collective_mode: individual SION read/write function call in collective mode, switching back to no-collective mode")); */
1038  }
1039  /* } */
1040  return(rc);
1041 }
1042 
1043 
1050 int _sion_flush_block( _sion_filedesc *sion_filedesc )
1051 {
1052  int rc = SION_SUCCESS;
1053  sion_int64 byteswritten;
1054 
1055  DPRINTFP((2, "_sion_flush_block", sion_filedesc->rank, "enter fileposition=%lld\n", sion_filedesc->currentpos));
1056 
1057  _sion_update_fileposition(sion_filedesc);
1058 
1059  DPRINTFP((2, "_sion_flush_block", sion_filedesc->rank, "after update fileposition=%lld\n", sion_filedesc->currentpos));
1060 
1061  byteswritten = sion_filedesc->currentpos
1062  - ( sion_filedesc->startpos
1063  + sion_filedesc->currentblocknr * sion_filedesc->globalskip);
1064 
1065  if (byteswritten > 0) {
1066  sion_filedesc->blocksizes[sion_filedesc->currentblocknr] = byteswritten;
1067 
1068  DPRINTFP((2, "_sion_flush_block", sion_filedesc->rank,
1069  "flushed lastchunknr->%d currentblocknr=%d byteswritten=%lld fileposition=%lld startpos=%lld (%lld)\n",
1070  sion_filedesc->lastchunknr, sion_filedesc->currentblocknr,
1071  byteswritten, sion_filedesc->currentpos, sion_filedesc->startpos, sion_filedesc->blocksizes[sion_filedesc->currentblocknr]));
1072  } else {
1073  rc = SION_NOT_SUCCESS;
1074  DPRINTFP((2, "_sion_flush_block", sion_filedesc->rank, "not flushed lastchunknr->%d byteswritten=%lld fileposition=%lld startpos=%lld (%lld)\n",
1075  sion_filedesc->lastchunknr, byteswritten, sion_filedesc->currentpos, sion_filedesc->startpos, sion_filedesc->blocksizes[sion_filedesc->currentblocknr]));
1076  }
1077 
1078  DPRINTFP((2, "_sion_flush_block", sion_filedesc->rank, "leave\n"));
1079 
1080  return (rc);
1081 }
1082 
1090 {
1091  int rc = SION_SUCCESS;
1092 
1093  DPRINTFP((2, "_sion_create_new_block", _SION_DEFAULT_RANK, "enter alloc \n"));
1094 
1095  if(sion_filedesc->currentblocknr<sion_filedesc->lastchunknr) {
1096  /* in-between write, skip to next block and overwrite it */
1097 
1098  /* flush current block */
1099  _sion_flush_block(sion_filedesc);
1100 
1101  /* apply hint for freeing current chunk */
1102  _sion_apply_hints(sion_filedesc,SION_HINTS_FREE_TYPE_CHUNK);
1103 
1104  sion_filedesc->currentblocknr++;
1105  sion_filedesc->currentpos = sion_filedesc->startpos + sion_filedesc->currentblocknr * sion_filedesc->globalskip;
1106 
1107  /* apply hint for access current (new) chunk */
1108  rc = _sion_apply_hints(sion_filedesc,SION_HINTS_ACCESS_TYPE_CHUNK);
1109 
1110  /* advance fp to next block */
1111  if(sion_filedesc->fileptr) {
1112  _sion_file_flush(sion_filedesc->fileptr);
1113  rc = _sion_file_set_position(sion_filedesc->fileptr, sion_filedesc->currentpos);
1114  }
1115 
1116  DPRINTFP((2, "_sion_create_new_block", _SION_DEFAULT_RANK, "skip to next already allocated block currentblocknr=%d lastchunknr->%d currentpos=%lld\n",
1117  sion_filedesc->currentblocknr, sion_filedesc->lastchunknr, sion_filedesc->currentpos));
1118 
1119  } else {
1120  /* at-end write, skip to next block and overwrite it */
1121 
1122  /* flush current block */
1123  _sion_flush_block(sion_filedesc);
1124 
1125  /* adjust arraysize if necessary */
1126  if ((sion_filedesc->lastchunknr + 1) >= sion_filedesc->maxchunks) {
1127  _sion_realloc_filedesc_blocklist(sion_filedesc, sion_filedesc->maxchunks + MAXCHUNKS);
1128  }
1129 
1130  /* apply hint for freeing current chunk */
1131  _sion_apply_hints(sion_filedesc,SION_HINTS_FREE_TYPE_CHUNK);
1132 
1133  sion_filedesc->lastchunknr++;
1134  sion_filedesc->currentblocknr++;
1135  sion_filedesc->currentpos = sion_filedesc->startpos + sion_filedesc->currentblocknr * sion_filedesc->globalskip;
1136  if(sion_filedesc->lastchunknr+1>sion_filedesc->maxusedchunks) sion_filedesc->maxusedchunks=sion_filedesc->lastchunknr+1;
1137 
1138  /* apply hint for access current (new) chunk */
1139  rc = _sion_apply_hints(sion_filedesc,SION_HINTS_ACCESS_TYPE_CHUNK);
1140 
1141  /* advance fp to next block */
1142  if(sion_filedesc->fileptr) {
1143  _sion_file_flush(sion_filedesc->fileptr);
1144  rc = _sion_file_set_position(sion_filedesc->fileptr, sion_filedesc->currentpos);
1145  }
1146  DPRINTFP((2, "_sion_create_new_block", _SION_DEFAULT_RANK, "skip to new allocated block currentblocknr=%d lastchunknr->%d currentpos=%lld\n",
1147  sion_filedesc->currentblocknr, sion_filedesc->lastchunknr, sion_filedesc->currentpos));
1148 
1149  }
1150 
1151  return (rc);
1152 }
1153 
1158 sion_int32 _sion_get_endianness_with_flags(sion_int64 flags) {
1159  sion_int32 endianness = 0;
1160 
1161  DPRINTFP((2, "_sion_get_endianness_flags", -1, "enter with flags 0x%x\n", flags));
1162 
1163  /* determine endianness */
1164  endianness = sion_get_endianness();
1165  /* make value symmetric (first byte = last byte) -> endianness independent */
1166  endianness |= endianness << 24;
1167  if (flags & _SION_FMODE_ENDIANNESS_SET) {
1168  /* manually set endianness on middle bytes */
1169  if (flags & _SION_FMODE_ENDIANNESS_BIG) {
1170  endianness |= 0x0101 << 8;
1171  }
1172  }
1173  else if (endianness & 1) {
1174  /* no manual setting of endianness: set middle bytes matching the out ones */
1175  endianness |= 0x0101 << 8;
1176  }
1177 
1178  DPRINTFP((2, "_sion_get_endianness_flags", -1, "leave with endianness 0x%x\n", endianness));
1179 
1180  return endianness;
1181 }
1182 
1183 #define DFUNCTION "_sion_getenv"
1187 char *_sion_getenv(const char *name) {
1188  char *name_with_prefix = NULL;
1189  char *getenv_result = NULL;
1190  const int full_len = strlen(name) + strlen(SION_LVERSION_PREFIX) + 1;
1191 
1192  DPRINTFP((2, DFUNCTION, -1, "enter: name = %s\n", name));
1193 
1194  name_with_prefix = (char *)malloc(full_len);
1195  sprintf(name_with_prefix, "%s%s", SION_LVERSION_PREFIX, name);
1196 
1197  getenv_result = getenv(name_with_prefix);
1198  free(name_with_prefix);
1199 
1200  DPRINTFP((2, DFUNCTION, -1, "leave: getenv_result = %s\n", getenv_result));
1201 
1202  return getenv_result;
1203 }
1204 #undef DFUNCTION
1205 
1212  sion_io_stat_t *p=NULL;
1213  int i;
1214 
1215  /* allocate data structure */
1216  p = (sion_io_stat_t *) malloc(sizeof(sion_io_stat_t));
1217  if (p == NULL) {
1218  _sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_alloc_io_info: cannot allocate memory of size %lu (p_fn), aborting ...\n",
1219  (unsigned long) sizeof(sion_io_stat_t));
1220  return(NULL);
1221  }
1222 
1223  p->nfiles=p_nf;
1224 
1225  /* allocate vectors */
1226  p->names = (const char **) malloc(p_nf * sizeof(char *));
1227  if (p->names == NULL) {
1228  _sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_alloc_io_info: cannot allocate memory of size %lu (names), aborting ...\n",
1229  (unsigned long) p_nf * sizeof(char *));
1230  free(p);
1231  return(NULL);
1232  }
1233 
1234  p->sizes = (size_t *) malloc(p_nf * sizeof(size_t));
1235  if (p->sizes == NULL) {
1236  _sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_alloc_io_info: cannot allocate memory of size %lu (sizes), aborting ...\n",
1237  (unsigned long) p_nf * sizeof(size_t));
1238  free(p->names);
1239  free(p);
1240  return(NULL);
1241  }
1242 
1243  p->roles = (int *) malloc(p_nf * sizeof(int));
1244  if (p->roles == NULL) {
1245  _sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_alloc_io_info: cannot allocate memory of size %lu (roles), aborting ...\n",
1246  (unsigned long) p_nf * sizeof(int));
1247  free(p->names);
1248  free(p->sizes);
1249  free(p);
1250  return(NULL);
1251  }
1252  /* init fields */
1253  for(i=0;i<p_nf;i++) {
1254  p->names[i]=NULL;
1255  p->sizes[i]=0;
1256  p->roles[i]=SION_ROLE_NONE;
1257  }
1258 
1259  return(p);
1260 }
1261 
1268  int rc=SION_SUCCESS;
1269 
1270  if(p->names!=NULL) free(p->names);
1271  if(p->sizes!=NULL) free(p->sizes);
1272  if(p->roles!=NULL) free(p->roles);
1273 
1274  free(p);
1275 
1276  return(rc);
1277 }
int _sion_buffer_flush(_sion_filedesc *sion_filedesc)
Flush buffer.
Definition: sion_buffer.c:177
#define MAXCHUNKS
Definition: sion_common.h:35
int sion_get_endianness(void)
Return endianness.
Definition: sion_tools.c:32
#define SION_KEYVAL_NONE
Definition: sion_const.h:80
void * _sion_vcdtovcon(int sid)
Definition: sion_fd.c:53
int _sion_vcdtype(int sid)
Definition: sion_fd.c:58
int _sion_newvcd(void *data, int type)
Definition: sion_fd.c:43
int _sion_freevcd(int sid)
Definition: sion_fd.c:48
#define SION_FILEDESCRIPTOR
Definition: sion_fd.h:17
long _sion_file_get_opt_blksize(_sion_fileptr *sion_fileptr)
Get optional file system block size for a file.
Definition: sion_file.c:289
int _sion_file_flush(_sion_fileptr *sion_fileptr)
Flush data to file.
Definition: sion_file.c:434
int _sion_file_close(_sion_fileptr *sion_fileptr)
Close file and destroys fileptr structure.
Definition: sion_file.c:178
sion_int64 _sion_file_set_position(_sion_fileptr *sion_fileptr, sion_int64 startpointer)
Set new position in file.
Definition: sion_file.c:367
int _sion_file_purge(_sion_fileptr *sion_fileptr)
Purge data to file.
Definition: sion_file.c:467
sion_int64 _sion_file_get_position(_sion_fileptr *sion_fileptr)
Get new position in file.
Definition: sion_file.c:401
_sion_fileptr * _sion_file_open(const char *fname, unsigned int flags, unsigned int addflags)
Create and open a new file for writing.
Definition: sion_file.c:53
#define SION_FILE_FLAG_READ
Definition: sion_file.h:30
#define SION_FILE_FLAG_CREATE
Definition: sion_file.h:28
#define SION_FILE_FLAG_ANSI
Definition: sion_file.h:25
#define SION_FILE_FLAG_WRITE
Definition: sion_file.h:29
#define SION_FILE_FLAG_POSIX
Definition: sion_file.h:27
int _sion_init_filedesc(_sion_filedesc *sion_filedesc)
Initialize the sion file description.
Definition: sion_filedesc.c:37
int _sion_realloc_filedesc_blocklist(_sion_filedesc *sion_filedesc, sion_int32 maxchunks)
Increase the memory used by the internal sion structure for the blocklist.
int _sion_alloc_filedesc_arrays(_sion_filedesc *sion_filedesc)
Allocate memory for the internal sion arrays.
int _sion_print_filedesc(_sion_filedesc *sion_filedesc, int level, char *desc, int flag)
Print the initialized sion file description.
int _sion_free_filedesc_arrays(_sion_filedesc *sion_filedesc)
free memory for the internal sion arrays
_sion_filedesc * _sion_alloc_filedesc(void)
Allocates memory for internal sion structure.
int _sion_alloc_filedesc_block_arrays(_sion_filedesc *sion_filedesc)
Allocate memory for the internal sion structure, fields for all chunksizes of all tasks.
#define SION_FILEMODE_WRITE
Definition: sion_filedesc.h:38
#define SION_FILEMODE_READ
Definition: sion_filedesc.h:37
#define SION_FILESTATE_SEROPENRANK
Definition: sion_filedesc.h:30
#define SION_FILESTATE_SEROPENMASTER
Definition: sion_filedesc.h:31
#define SION_FILESTATE_SEROPEN
Definition: sion_filedesc.h:29
_sion_flags_store * _sion_parse_flags(const char *flags)
Parse flags and return a flags store with key value pairs.
Definition: sion_flags.c:326
int _sion_create_new_block(_sion_filedesc *sion_filedesc)
Create a new block for the internal data structure.
int _sion_open_write(const char *fname, sion_int64 file_mode_flags, int *ntasks, int *nfiles, sion_int64 **chunksizes, sion_int32 *fsblksize, int **globalranks, FILE **fileptr)
internal sion serial open function for writing on one file
char * _sion_getenv(const char *name)
int _sion_free_io_info(sion_io_stat_t *p)
frees an io_info data structure
char * _sion_get_multi_filename(const char *fname, int filenumber)
generates the multi filename
int _sion_flush_block(_sion_filedesc *sion_filedesc)
Update the internal data structure.
int _sion_check_on_collective_mode(_sion_filedesc *sion_filedesc)
check if a collective operation are already called,
sion_int32 _sion_get_endianness_with_flags(sion_int64 flags)
Return endianness including possible choice via flags.
sion_io_stat_t * _sion_alloc_io_info(int p_nf)
allocates an io_info data structure for nfiles files
int _sion_open_read(const char *fname, sion_int64 file_mode_flags, int read_all, int *ntasks, int *nfiles, sion_int64 **chunksizes, sion_int32 *fsblksize, int **globalranks, FILE **fileptr)
internal sion serial open function for reading on one or more files
int _sion_update_fileposition(_sion_filedesc *sion_filedesc)
Update the internal data structure (check fileposition)
int _sion_flush_file(int sid)
Flush the data to the disk for the current task.
int _sion_read_header_var_part(_sion_filedesc *sion_filedesc)
Read the second part of SION Meta Block 1.
int _sion_read_header_var_part_blocksizes_rank(_sion_filedesc *sion_filedesc)
Read the SION Meta Block 2.
int _sion_read_header_var_part_mapping_rank(_sion_filedesc *sion_filedesc)
Read the mapping data at end of SION Meta Block 2.
int _sion_write_header_var_info(_sion_filedesc *sion_filedesc)
Write the SION Meta Block 1.
int _sion_write_header_var_part_blocksizes(_sion_filedesc *sion_filedesc)
Write the SION Meta Block 2.
int _sion_write_header(_sion_filedesc *sion_filedesc)
Write the SION Meta Block 1.
Definition: sion_metadata.c:38
int _sion_read_header_var_part_blocksizes(_sion_filedesc *sion_filedesc)
Read the SION Meta Block 2.
int _sion_read_header_fix_part(_sion_filedesc *sion_filedesc)
Read part of the SION Meta Block 1.
int _sion_write_header_var_part_mapping(_sion_filedesc *sion_filedesc, sion_int32 mapping_size, sion_int32 *mapping)
Write mapping into the SION Meta Block 2.
int _sion_read_header_var_part_mapping(_sion_filedesc *sion_filedesc)
Read the mapping data at end of SION Meta Block 2.
Sion Time Stamp Header.
Sion File Descriptor Structure.
Definition: sion_filedesc.h:79
sion_int64 * all_blocksizes
sion_int32 filesionversion
sion_int64 start_of_varheader
sion_int32 filesionpatchlevel
sion_int64 * all_chunksizes
sion_int64 * all_currentpos
sion_int64 * blocksizes
sion_int64 * all_currentblocknr
sion_int32 fileptr_exported
_sion_filedesc ** multifiles
sion_int64 * all_globalranks
sion_int32 currentblocknr
Definition: sion_filedesc.h:97
_sion_fileptr * fileptr
Definition: sion_filedesc.h:82
sion_int64 * all_startpointers
sion_int64 * all_blockcount