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