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