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