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