SIONlib  1.6.1
Scalable I/O library for parallel access to task-local files
sion_common.c
Go to the documentation of this file.
1 /****************************************************************************
2 ** SIONLIB http://www.fz-juelich.de/jsc/sionlib **
3 *****************************************************************************
4 ** Copyright (c) 2008-2015 **
5 ** Forschungszentrum Juelich, Juelich Supercomputing Centre **
6 ** **
7 ** See the file COPYRIGHT in the package base directory for details **
8 ****************************************************************************/
9 
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <time.h>
20 #include <assert.h>
21 
22 #if defined(_BGL)
23 #include <rts.h>
24 #ifndef __USE_FILE_OFFSET64
25 #define __USE_FILE_OFFSET64
26 #endif
27 #endif
28 
29 #include <sys/time.h>
30 
31 
32 #include "sion.h"
33 #include "sion_debug.h"
34 #include "sion_filedesc.h"
35 #include "sion_tools.h"
36 #include "sion_fd.h"
37 #include "sion_file.h"
38 #include "sion_metadata.h"
39 #include "sion_internal.h"
40 #include "sion_internal_seek.h"
41 #include "sion_hints.h"
42 #include "sion_printts.h"
43 #include "sion_buffer.h"
44 #include "sion_dup.h"
45 #include "sion_lock.h"
46 
80 int sion_get_locations(int sid,
81  int *ntasks,
82  int *maxchunks,
83  sion_int64 *globalskip,
84  sion_int64 *start_of_varheader,
85  sion_int64 **sion_chunksizes,
86  sion_int64 **sion_globalranks,
87  sion_int64 **sion_blockcount,
88  sion_int64 **sion_blocksizes ) {
89  int rc = SION_SUCCESS;
90  _sion_filedesc *sion_filedesc;
91 #ifdef SION_SERIAL_MASTER
92  _sion_filedesc *help;
93  int i, lfile, lrank, blknum;
94 #endif
95 
96  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
97  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
98  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
99  }
100  DPRINTFP((1, "sion_get_locations", -1, "enter\n"));
101 
102 #ifdef SION_SERIAL_MASTER
103  if((sion_filedesc->state == SION_FILESTATE_SEROPENMASTER) &&
104  (sion_filedesc->all_blockcount==NULL) ) {
105 
106  /* collect info from sub files */
107  _sion_alloc_filedesc_arrays(sion_filedesc);
108  _sion_alloc_filedesc_block_arrays_only(sion_filedesc);
109 
110  for (i = 0; i < sion_filedesc->ntasks; i++) {
111  lfile=sion_filedesc->mapping[i*2+0]; lrank=sion_filedesc->mapping[i*2+1];
112  sion_filedesc->all_chunksizes[i] = sion_filedesc->multifiles[lfile]->all_chunksizes[lrank];
113  sion_filedesc->all_globalranks[i] = sion_filedesc->multifiles[lfile]->all_globalranks[lrank];
114  sion_filedesc->all_blockcount[i] = sion_filedesc->multifiles[lfile]->all_blockcount[lrank];
115  }
116  for (i = 0; i < sion_filedesc->ntasks; i++) {
117  lfile=sion_filedesc->mapping[i*2+0]; lrank=sion_filedesc->mapping[i*2+1];
118  help=sion_filedesc->multifiles[lfile];
119  for (blknum = 0; blknum < sion_filedesc->all_blockcount[i]; blknum++) {
120  sion_filedesc->all_blocksizes[sion_filedesc->ntasks * blknum + i] =
121  help->all_blocksizes[help->ntasks * blknum + lrank];
122  }
123  }
124  }
125 #endif
126 
127  *ntasks = sion_filedesc->ntasks;
128  *maxchunks = sion_filedesc->maxusedchunks;
129  *sion_chunksizes = sion_filedesc->all_chunksizes;
130  *sion_globalranks = sion_filedesc->all_globalranks;
131  *sion_blockcount = sion_filedesc->all_blockcount;
132  *sion_blocksizes = sion_filedesc->all_blocksizes;
133  *globalskip = sion_filedesc->globalskip;
134  *start_of_varheader = sion_filedesc->start_of_varheader;
135 
136  DPRINTFP((1, "sion_get_locations", -1, "leave\n"));
137 
138  return (rc);
139 }
140 
141 int _sion_close_sid(int sid)
142 {
143  int rc = SION_SUCCESS;
144  _sion_filedesc *sion_filedesc;
145 
146  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
147  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
148  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_close: invalid sion_filedesc, aborting %d ...\n", sid));
149  }
150  rc=_sion_close(sion_filedesc);
151 
152  if(rc==SION_SUCCESS) {
153  _sion_freevcd(sid);
154  _sion_free_filedesc(sion_filedesc);
155  }
156 
157  return(rc);
158 
159 }
160 
178 int sion_get_current_location(int sid, int *currentchunknr, sion_int64 *currentpos, int *maxchunks, sion_int64 **chunksizes)
179 {
180  int rc = SION_SUCCESS;
181  _sion_filedesc *sion_filedesc;
182 
183  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
184  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
185  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
186  }
187  DPRINTFP((1, "sion_get_current_location", -1, "enter\n"));
188 
189  *currentchunknr = sion_filedesc->currentblocknr;
190  *currentpos = sion_filedesc->currentpos - (sion_filedesc->startpos + sion_filedesc->currentblocknr * sion_filedesc->globalskip);
191  *maxchunks = sion_filedesc->lastchunknr+1;
192  *chunksizes = sion_filedesc->blocksizes;
193 
194  DPRINTFP((1, "sion_get_current_location", -1, "leave\n"));
195  return (rc);
196 }
197 
212 int sion_get_mapping(int sid,
213  int *mapping_size,
214  sion_int32 **mapping,
215  int *numfiles ) {
216  int rc = SION_SUCCESS;
217  _sion_filedesc *sion_filedesc;
218 
219  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
220  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
221  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
222  }
223  DPRINTFP((1, "sion_get_mapping", -1, "enter\n"));
224 
225  if(sion_filedesc->mapping_size>0) {
226  *mapping_size=sion_filedesc->mapping_size;
227  *mapping=sion_filedesc->mapping;
228  } else {
229  *mapping_size=-1;
230  }
231  *numfiles=sion_filedesc->nfiles;
232 
233  DPRINTFP((1, "sion_get_mapping", -1, "leave (mapping_size=%d)\n",*mapping_size));
234 
235  return (rc);
236 }
237 
247 {
248  _sion_filedesc *sion_filedesc;
249 
250  DPRINTFP((1, "sion_get_file_endianness", -1, "enter (sid=%d)\n",sid));
251 
252  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
253  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
254  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
255  }
256 
257  DPRINTFP((1, "sion_get_file_endianness", -1, "leave (sid=%d)\n",sid));
258  /* return endianness of user data */
259  return ((sion_filedesc->endianness >> 8) & 1);
260 }
261 
271 {
272  int swap_needed = 0;
273 
274  DPRINTFP((1, "sion_endianness_swap_needed", -1, "enter (sid=%d)\n",sid));
275 
276  swap_needed = (sion_get_file_endianness(sid) != sion_get_endianness());
277 
278  DPRINTFP((1, "sion_endianness_swap_needed", -1, "leave (swap_needed=%d)\n",
279  swap_needed));
280 
281  return swap_needed;
282 }
283 
301  int *ntasks,
302  sion_int64 **sion_currentpos,
303  sion_int64 **sion_currentblocknr)
304 {
305  int rc = SION_SUCCESS;
306  _sion_filedesc *sion_filedesc;
307 
308  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
309  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
310  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
311  }
312  DPRINTFP((1, "sion_get_current_locations", -1, "enter\n"));
313 
314  *ntasks = sion_filedesc->ntasks;
315  *sion_currentpos = sion_filedesc->all_currentpos;
316  *sion_currentblocknr = sion_filedesc->all_currentblocknr;
317 
318  DPRINTFP((1, "sion_get_current_locations", -1, "leave\n"));
319  return (rc);
320 }
321 
322 int sion_get_number_of_files(int sid)
323 {
324  _sion_filedesc *sion_filedesc;
325 
326  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
327  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
328  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
329  }
330 
331  return (sion_filedesc->nfiles);
332 }
333 
334 int sion_get_filenumber(int sid)
335 {
336  _sion_filedesc *sion_filedesc;
337 
338  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
339  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
340  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
341  }
342 
343  return (sion_filedesc->filenumber);
344 }
345 
346 int sion_is_serial_opened(int sid)
347 {
348  _sion_filedesc *sion_filedesc;
349 
350  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
351  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
352  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
353  }
354 
355  return (sion_filedesc->state == SION_FILESTATE_SEROPEN
356  || sion_filedesc->state == SION_FILESTATE_SEROPENRANK
357  || sion_filedesc->state == SION_FILESTATE_SEROPENMASTER);
358 }
359 
360 int sion_using_hints(int sid)
361 {
362  _sion_filedesc *sion_filedesc;
363 
364  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
365  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
366  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
367  }
368 
369  return (sion_filedesc->usehints);
370 }
371 
372 sion_int64 sion_get_bytes_written(int sid)
373 {
374  _sion_filedesc *sion_filedesc;
375  sion_int64 bytes=SION_SIZE_NOT_VALID;
376  int i;
377 
378  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
379  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
380  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
381  }
382 
383  if (sion_filedesc->mode == SION_FILEMODE_WRITE) {
384  if (sion_filedesc->usebuffer) {
385  _sion_buffer_flush(sion_filedesc);
386  }
387  _sion_flush_block(sion_filedesc);
388  bytes=0;
389  for(i=0;i<=sion_filedesc->lastchunknr;i++) bytes+=sion_filedesc->blocksizes[i];
390  }
391 
392  return (bytes);
393 }
394 
395 sion_int64 sion_get_bytes_read(int sid)
396 {
397  _sion_filedesc *sion_filedesc;
398  sion_int64 bytes=SION_SIZE_NOT_VALID;
399  int i;
400 
401  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
402  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
403  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
404  }
405 
406  if (sion_filedesc->mode == SION_FILEMODE_READ) {
407  _sion_file_purge(sion_filedesc->fileptr);
408  sion_filedesc->currentpos = _sion_file_get_position(sion_filedesc->fileptr);
409 
410  bytes=0;
411  for(i=0;i<sion_filedesc->currentblocknr;i++) bytes+=sion_filedesc->blocksizes[i];
412  /* current chunk */
413  bytes+=sion_filedesc->currentpos - (sion_filedesc->startpos + sion_filedesc->currentblocknr * sion_filedesc->globalskip);
414  }
415 
416  return (bytes);
417 }
418 
432 size_t sion_fwrite(const void *data, size_t size, size_t nitems, int sid)
433 {
434  sion_int64 bytes_buffered, bytes_to_write, bbytes, bytes_left;
435  _sion_filedesc *sion_filedesc;
436  size_t rc=0, frc;
437  char *data_ptr;
438  void *bdata;
439 
440  DPRINTFP((1, "sion_fwrite", -1, "enter size=%ld nitems=%ld\n",(long) size, (long) nitems));
441 
442  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
443  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
444  return(_sion_errorprint(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
445  }
446 
447  _sion_check_on_collective_mode(sion_filedesc);
448 
449  bytes_to_write=size*nitems;
450 
451  /* buffering? */
452  if(sion_filedesc->usebuffer) {
453 
454  /* create a new block if needed and check size of input */
455  if(!sion_ensure_free_space(sid,bytes_to_write)) {
456  return(_sion_errorprint_on_rank(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,sion_filedesc->rank,
457  "could not ensure free space for this buffered block of size %d, returning sid=%d ...",
458  (int) bytes_to_write, sid));
459  }
460 
461  data_ptr=(void *) data;
462  bytes_left = sion_filedesc->chunksize -
463  sion_filedesc->blocksizes[sion_filedesc->currentblocknr];
464  bbytes = sion_filedesc->buffer_ptr;
465 
466  /* check for enough space in current block */
467  if (bbytes + bytes_to_write > bytes_left) {
468  /* not enough space for buffer + bytes_to_write => flush first */
469  _sion_buffer_get_data_ptr(sion_filedesc,&bdata,&bbytes);
470  if(sion_ensure_free_space(sid,bbytes)) {
471  frc = _sion_file_write(bdata, bbytes, sion_filedesc->fileptr);
472  if(frc != bbytes) {
473  return(_sion_errorprint_on_rank(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,sion_filedesc->rank,
474  "could not write data (%d bytes) to file (sid=%d) ...", (int) bbytes, sid));
475  }
476  } else {
477  return(_sion_errorprint_on_rank(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,sion_filedesc->rank,
478  "could not ensure free space for this buffered block of size %d, returning sid=%d ...",
479  (int) bbytes, sid));
480  }
481  /* increase current position */
482  sion_filedesc->currentpos+=bbytes;
483  }
484  /* buffer data */
485  bytes_buffered=_sion_buffer_push(sion_filedesc,data_ptr,bytes_to_write);
486  bytes_to_write-=bytes_buffered;
487  data_ptr+=bytes_buffered;
488 
489  while(bytes_to_write>0) {
490  /* flush filled buffer to file, not all data could be stored */
491  _sion_buffer_get_data_ptr(sion_filedesc,&bdata,&bbytes);
492  if(sion_ensure_free_space(sid,bbytes)) {
493  frc = _sion_file_write(bdata, bbytes, sion_filedesc->fileptr);
494  if(frc != bbytes) {
495  return(_sion_errorprint_on_rank(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,sion_filedesc->rank,
496  "could not write data (%d bytes) to file (sid=%d) ...", (int) bbytes, sid));
497  }
498  } else {
499  return(_sion_errorprint_on_rank(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,sion_filedesc->rank,
500  "could not ensure free space for this buffered block of size %d, returning sid=%d ...",
501  (int) bbytes, sid));
502  }
503  /* increase current position */
504  sion_filedesc->currentpos+=bbytes;
505 
506  /* next try to push data into buffer */
507  bytes_buffered=_sion_buffer_push(sion_filedesc,data_ptr,bytes_to_write);
508  bytes_to_write-=bytes_buffered;
509  data_ptr+=bytes_buffered;
510  }
511  /* reset value since it will be used later */
512  bytes_to_write=size*nitems;
513  /* return code: bytes stored */
514  rc=(size_t) (size ? bytes_to_write / size : 0);
515 
516  } else {
517  /* normal write */
518  if(sion_ensure_free_space(sid,bytes_to_write)) {
519  frc = _sion_file_write(data, bytes_to_write, sion_filedesc->fileptr);
520  if(frc != bytes_to_write) {
521  return(_sion_errorprint_on_rank(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,sion_filedesc->rank,
522  "could not write data (%d bytes) to file (frc=%d sid=%d) ...", (int) bytes_to_write, (int) frc, sid));
523  }
524 
525  rc=(size_t) (size ? bytes_to_write / size : 0);
526 
527  } else {
528  return(_sion_errorprint_on_rank(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,sion_filedesc->rank,"could not ensure free space for this block, returning %d ...", sid));
529  }
530  /* increase current position */
531  sion_filedesc->currentpos+=bytes_to_write;
532  }
533 
534  DPRINTFP((1, "sion_fwrite", -1, "leave rc=%ld\n",(long) rc));
535  return(rc);
536 }
537 
552 size_t sion_fread( void *data, size_t size, size_t nitems, int sid) {
553  _sion_filedesc *sion_filedesc;
554  sion_int64 bytes, bread, bytes_left;
555 
556  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
557  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
558  return(_sion_errorprint(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,"invalid sion_filedesc, aborting %d ...\n", sid));
559  }
560  if (!data) {
561  /* FIXME: replace SION_ANSI_SIZE_NOT_VALID? */
562  return(_sion_errorprint(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,"invalid pointer, aborting %d ...\n", data));
563  }
564 
565  /* check and update current position */
566  _sion_update_fileposition(sion_filedesc);
567 
568  bytes_left = sion_filedesc->startpos +
569  sion_filedesc->currentblocknr * sion_filedesc->globalskip +
570  sion_filedesc->blocksizes[sion_filedesc->currentblocknr] -
571  sion_filedesc->currentpos;
572 
573  DPRINTFP((1, "sion_fread", -1, "enter\n"));
574  DPRINTFP((4, "sion_fread", -1, " parameter size=%ld nitems=%ld\n",(long) size,(long) nitems));
575 
576  _sion_check_on_collective_mode(sion_filedesc);
577 
578  bread=0;
579  bytes=size*nitems;
580 
581  /* Check size. bytes_left == 0 is handled by sion_feof */
582  if((sion_filedesc->chunksize < bytes) || ((bytes_left < bytes) &&
583  (bytes_left != 0))) {
584  /* FIXME: replace SION_ANSI_SIZE_NOT_VALID? */
585  return(_sion_errorprint(SION_ANSI_SIZE_NOT_VALID,_SION_ERROR_RETURN,"not enough bytes left in chunk, aborting (%ld < %ld) ...\n", bytes_left, bytes));
586  }
587 
588  if(!sion_feof(sid)) {
589  bread=_sion_file_read(data,bytes,sion_filedesc->fileptr);
590  DPRINTFP((256, "sion_fread", -1, " _sion_file_read returns %ld\n",(long) bread));
591  }
592  if(bread!=bytes) {
593  return (size_t) (size ? bread / size : 0);
594  }
595 
596  bread = size ? bread / size : 0;
597 
598  /* increase current position */
599  sion_filedesc->currentpos+=bytes;
600 
601  DPRINTFP((4, "sion_fread", -1, " return value %ld\n",(long) bread));
602  DPRINTFP((1, "sion_fread", -1, "leave\n"));
603  return(bread);
604 }
605 
620 int sion_seek(int sid, int rank, int currentblocknr, sion_int64 posinblk)
621 {
622  FILE *fileptr;
623  int rc=SION_SUCCESS;
624  /* TBD: check if not sion_open and multi file */
625  rc=sion_seek_fp(sid,rank,currentblocknr,posinblk,&fileptr);
626  return(rc);
627 
628 }
629 
643 int sion_seek_fp(int sid, int rank, int currentblocknr, sion_int64 posinblk, FILE **fileptr)
644 {
645  int rc = SION_SUCCESS;
646  _sion_filedesc *sion_filedesc;
647 
648  DPRINTFP((1, "sion_seek_fp", -1, " enter seek with sid=%d\n", sid));
649  assert((_sion_vcdtype(sid) == SION_FILEDESCRIPTOR));
650 
651  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
652  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
653  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"sion_seek: invalid sion_filedesc, aborting %d ...\n", sid));
654  }
655 
656  /* check state */
657  if ((sion_filedesc->mode != SION_FILEMODE_READ) && (sion_filedesc->mode != SION_FILEMODE_WRITE)) {
658  return(_sion_errorprint_on_rank(SION_NOT_SUCCESS,_SION_ERROR_RETURN,sion_filedesc->rank,"sion_seek_fp: unknown file open state !(READ|WRITE), aborting %d ...", sid));
659  }
660  if (sion_filedesc->usebuffer) {
661  _sion_buffer_flush(sion_filedesc);
662  }
663  if ( (sion_filedesc->state != SION_FILESTATE_PAROPEN)
664  && (sion_filedesc->state != SION_FILESTATE_SEROPEN)
665  && (sion_filedesc->state != SION_FILESTATE_SEROPENMASTER)
666  && (sion_filedesc->state != SION_FILESTATE_SEROPENRANK)
667  && (sion_filedesc->state != SION_FILESTATE_PAROPENMAPPEDMASTER)
668  ) {
669  return(_sion_errorprint_on_rank(SION_NOT_SUCCESS,_SION_ERROR_RETURN,sion_filedesc->rank,"sion_seek_fp: unknown file open state !(PAR|SER|SERRANK|MAPPED), aborting %d ...", sid));
670  }
671 
672 
673  if (sion_filedesc->mode == SION_FILEMODE_READ) { /* READ */
674 
675  if (sion_filedesc->state == SION_FILESTATE_SEROPEN) {
676  rc = _sion_seek_on_all_ranks_read(sion_filedesc, rank, currentblocknr, posinblk);
677  }
678  else if (sion_filedesc->state == SION_FILESTATE_SEROPENMASTER) {
679  rc = _sion_seek_on_all_ranks_read_master(sion_filedesc, rank, currentblocknr, posinblk);
680  }
681  else if ((sion_filedesc->state == SION_FILESTATE_SEROPENRANK) ||
682  (sion_filedesc->state == SION_FILESTATE_PAROPEN)) {
683  rc = _sion_seek_on_current_rank_read(sion_filedesc, rank, currentblocknr, posinblk);
684  }
685  else if (sion_filedesc->state == SION_FILESTATE_PAROPENMAPPEDMASTER) {
686  rc = _sion_seek_on_all_ranks_read_mapped(sion_filedesc, rank, currentblocknr, posinblk);
687  }
688  } else { /* WRITE */
689  if (sion_filedesc->state == SION_FILESTATE_SEROPEN) {
690  rc = _sion_seek_on_all_ranks_write(sion_filedesc, rank, currentblocknr, posinblk);
691  }
692  else if (sion_filedesc->state == SION_FILESTATE_SEROPENRANK) {
693  return _sion_errorprint_on_rank(SION_NOT_SUCCESS, _SION_ERROR_RETURN, sion_filedesc->rank, "sion_seek_fp: seek not supported for this type (write, sion_open_rank), aborting ...");
694  }
695  else if (sion_filedesc->state == SION_FILESTATE_PAROPEN) {
696  rc = _sion_seek_on_current_rank_write(sion_filedesc, rank, currentblocknr, posinblk);
697  }
698  else if (sion_filedesc->state == SION_FILESTATE_PAROPENMAPPEDMASTER) {
699  rc = _sion_seek_on_all_ranks_write_mapped(sion_filedesc, rank, currentblocknr, posinblk);
700  }
701 
702  }
703 
704  /* TBD: implement sion_open and sion_seek_fp for multi-files */
705  if(fileptr!=NULL) {
706  if(sion_filedesc->fileptr->flags&SION_FILE_FLAG_ANSI) {
707  *fileptr=sion_filedesc->fileptr->fileptr;
708  sion_filedesc->fileptr_exported=1;
709 
710  } else {
711  *fileptr=NULL;
712  sion_filedesc->fileptr_exported=0;
713  }
714  }
715 
716  DPRINTFP((1, "sion_seek_fp", -1, "leave seek rc=%d\n",rc));
717 
718  return (rc);
719 }
720 
731 int sion_feof(int sid)
732 {
733  int rc = SION_NOT_SUCCESS;
734  sion_int64 maxpos;
735 
736  _sion_filedesc *sion_filedesc;
737  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
738  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
739  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"sion_feof: invalid sion_filedesc, aborting %d ...\n", sid));
740  }
741 
742  DPRINTFP((8, "sion_feof", -1, "enter feof sid=%d currentpos=%15lld\n", sid, sion_filedesc->currentpos));
743 
744  /* check and update current position */
745  _sion_update_fileposition(sion_filedesc);
746 
747  maxpos = sion_filedesc->startpos
748  + sion_filedesc->currentblocknr * sion_filedesc->globalskip + sion_filedesc->blocksizes[sion_filedesc->currentblocknr];
749 
750  DPRINTFP((16, "sion_feof", -1,
751  " after flush sid=%d currentpos=%15lld maxpos= %lld startpos=%lld curblknr=%d\n",
752  sid, sion_filedesc->currentpos, maxpos, sion_filedesc->startpos, sion_filedesc->currentblocknr));
753 
754  if (sion_filedesc->currentpos < maxpos) {
755  /* end of current block not reached */
756  rc = 0;
757  DPRINTFP((16, "sion_feof", -1, " end of current block %d not reached sid=%d\n",
758  sion_filedesc->currentblocknr, sid));
759  } else {
760  if (sion_filedesc->currentblocknr < sion_filedesc->lastchunknr) {
761 
762  /* apply hint for freeing current chunk */
763  rc = _sion_apply_hints(sion_filedesc,SION_HINTS_FREE_TYPE_CHUNK);
764 
765  /* end of current block reached, skip to next block */
766  sion_filedesc->currentblocknr++;
767  sion_filedesc->currentpos = sion_filedesc->startpos + sion_filedesc->currentblocknr * sion_filedesc->globalskip;
768 
769  /* apply hint for access current (new) chunk */
770  rc = _sion_apply_hints(sion_filedesc,SION_HINTS_ACCESS_TYPE_CHUNK);
771 
772  _sion_file_purge(sion_filedesc->fileptr);
773  _sion_file_set_position(sion_filedesc->fileptr, sion_filedesc->currentpos);
774  rc = SION_NOT_SUCCESS;
775  DPRINTFP((8, "sion_feof", -1,
776  " end of block %d reached, skipping to next %lld -> %lld position=%lld gs=%lld sid=%d\n",
777  sion_filedesc->currentblocknr - 1,
778  sion_filedesc->currentpos, _sion_file_get_position(sion_filedesc->fileptr), sion_filedesc->currentpos, sion_filedesc->globalskip, sid));
779  }
780  else {
781  /* end of last block reached */
782  DPRINTFP((8, "sion_feof", -1, " end of last block %d reached sid=%d\n", sion_filedesc->currentblocknr, sid));
783  rc = SION_SUCCESS;
784  }
785  }
786 
787  DPRINTFP((8, "sion_feof", -1, "leave feof sid=%d currentpos=%15lld rc=%d\n", sid, sion_filedesc->currentpos, rc));
788 
789  return (rc);
790 }
791 
801 sion_int64 sion_bytes_avail_in_block(int sid)
802 {
803  return(sion_bytes_avail_in_chunk(sid));
804 }
805 
816 sion_int64 sion_bytes_avail_in_chunk(int sid)
817 {
818  sion_int64 maxpos;
819  sion_int64 bytes_avail=SION_SIZE_NOT_VALID;
820  _sion_filedesc *sion_filedesc;
821 
822  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
823  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
824  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"sion_bytes_avail_in_chunk: invalid sion_filedesc, aborting %d ...\n", sid));
825  }
826 
827 
828  _sion_update_fileposition(sion_filedesc);
829 
830  maxpos = sion_filedesc->startpos
831  + sion_filedesc->currentblocknr * sion_filedesc->globalskip + sion_filedesc->blocksizes[sion_filedesc->currentblocknr];
832 
833  bytes_avail = maxpos - sion_filedesc->currentpos;
834 
835  DPRINTFP((8, "sion_bytes_avail_in_chunk", -1,
836  "leave sid=%d rank=%4d currentpos=%lld maxpos= %lld -> bytes to read %lld\n",
837  sid, sion_filedesc->rank, sion_filedesc->currentpos, maxpos, bytes_avail));
838 
839  return (bytes_avail);
840 }
841 
852 sion_int64 sion_get_position(int sid)
853 {
854  _sion_filedesc *sion_filedesc;
855 
856  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
857  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
858  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"sion_get_position: invalid sion_filedesc, aborting %d ...\n", sid));
859  }
860 
861 
862  _sion_file_flush(sion_filedesc->fileptr);
863 
864  return (_sion_file_get_position(sion_filedesc->fileptr));
865 
866 }
867 
868 int sion_set_fp_closed(int sid)
869 {
870  int rc = SION_SUCCESS;
871  _sion_filedesc *sion_filedesc;
872 
873  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
874  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
875  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"sion_set_fp_closed: invalid sion_filedesc, aborting %d ...\n", sid));
876  }
877  sion_filedesc->state = SION_FILESTATE_CLOSE;
878  return (rc);
879 }
880 
881 int sion_set_second_fp(int sid, FILE *secondfd)
882 {
883  int rc = SION_SUCCESS;
884  _sion_filedesc *sion_filedesc;
885 
886 
887  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
888  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
889  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"sion_set_second_fp: invalid sion_filedesc, aborting %d ...\n", sid));
890  }
891 
892  if(!(sion_filedesc->fileptr->flags&SION_FILE_FLAG_ANSI)) {
893  return(_sion_errorprint_on_rank(SION_NOT_SUCCESS,_SION_ERROR_RETURN,sion_filedesc->rank,"sion_set_second_fp: file was not opened in ANSI mode, aborting %d ...", sid));
894  }
895 
896  _sion_file_set_second_fileptr(sion_filedesc->fileptr,secondfd);
897 
898  _sion_print_filedesc(sion_filedesc, 512, "sion_set_second_fd", 1);
899  /*
900  if (sion_filedesc->mode == SION_FILEMODE_READ) {
901  sion_seek(sid, SION_CURRENT_RANK, 0, 0);
902  }
903  */
904  return (rc);
905 }
906 
907 int sion_unset_second_fp(int sid)
908 {
909  int rc = SION_SUCCESS;
910  _sion_filedesc *sion_filedesc;
911 
912  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
913  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
914  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"sion_unset_second_fp: invalid sion_filedesc, aborting %d ...\n", sid));
915  }
916 
917  if(!(sion_filedesc->fileptr->flags&SION_FILE_FLAG_ANSI)) {
918  return(_sion_errorprint_on_rank(SION_NOT_SUCCESS,_SION_ERROR_RETURN,sion_filedesc->rank,"sion_unset_second_fp: file was not opened in ANSI mode, aborting %d ...", sid));
919  }
920 
921  _sion_file_unset_second_fileptr(sion_filedesc->fileptr);
922  return (rc);
923 }
924 
925 int sion_optimize_fp_buffer(int sid)
926 {
927  int rc = SION_SUCCESS;
928  _sion_filedesc *sion_filedesc;
929 
930  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
931  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
932  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"sion_set_second_fp: invalid sion_filedesc, aborting %d ...\n", sid));
933  }
934 
935  sion_filedesc->fpbuffer = (char *) malloc(sion_filedesc->fsblksize);
936  if (sion_filedesc->fpbuffer == NULL) {
937  return(_sion_errorprint_on_rank(SION_NOT_SUCCESS,_SION_ERROR_RETURN,sion_filedesc->rank,"sion_optimize_fp_buffer: cannot allocate internal buffer of size %lu , aborting ...", (unsigned long) sion_filedesc->fsblksize));
938  }
939  sion_filedesc->fpbuffer_size = sion_filedesc->fsblksize;
940 
941  rc=_sion_file_set_buffer(sion_filedesc->fileptr, sion_filedesc->fpbuffer, sion_filedesc->fpbuffer_size);
942  return (rc);
943 }
944 
952 int sion_flush(int sid)
953 {
954  int rc = SION_SUCCESS;
955  _sion_filedesc *sion_filedesc;
956 
957  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
958  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
959  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"sion_unset_second_fp: invalid sion_filedesc, aborting %d ...\n", sid));
960  }
961  rc = _sion_flush_block(sion_filedesc);
962  return (rc);
963 }
964 
975 int sion_ensure_free_space(int sid, sion_int64 bytes)
976 {
977  _sion_filedesc *sion_filedesc;
978  sion_int64 byteswritten;
979  int rc = SION_SUCCESS;
980 
981  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
982  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
983  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"sion_ensure_free_space: invalid sion_filedesc, returning %d ...\n", sid));
984  }
985 
986  DPRINTFP((8, "_sion_ensure_free_space", -1, "enter ensure_free sid=%d bytes=%lld\n", sid, bytes));
987 
988  if (sion_filedesc->mode != SION_FILEMODE_WRITE) {
989  DPRINTFP((8, "_sion_ensure_free_space", -1, "invalid opened\n"));
990  return(_sion_errorprint_on_rank(SION_NOT_SUCCESS,_SION_ERROR_RETURN,sion_filedesc->rank,"sion_ensure_free_space[%2d]: file is opened invalid sion_mode, returning ...", sion_filedesc->rank));
991  }
992  if (sion_filedesc->fileptr == NULL) {
993  DPRINTFP((8, "_sion_ensure_free_space", -1, "file not opened\n"));
994  return(_sion_errorprint_on_rank(SION_NOT_SUCCESS,_SION_ERROR_RETURN,sion_filedesc->rank,"sion_ensure_free_space[%2d]: file is not open, returning ...", sion_filedesc->rank));
995  }
996 
997  if (bytes > sion_filedesc->chunksize) {
998  DPRINTFP((8, "_sion_ensure_free_space", -1, "could not write %lld bytes, chunksize=%lld\n", bytes, sion_filedesc->chunksize));
999  return(_sion_errorprint_on_rank(SION_NOT_SUCCESS,_SION_ERROR_RETURN,sion_filedesc->rank,"sion_ensure_free_space[%2d]: could not write %lld bytes, chunksize=%lld, returning ...",sion_filedesc->rank, bytes, sion_filedesc->chunksize));
1000  }
1001 
1002  _sion_flush_block(sion_filedesc);
1003 
1004  DPRINTFP((16, "_sion_ensure_free_space", -1,
1005  " after getpos sid=%d fileposition is %lld bytes=%lld\n", sid, sion_filedesc->currentpos, bytes));
1006 
1007  byteswritten = sion_filedesc->blocksizes[sion_filedesc->currentblocknr];
1008 
1009  DPRINTFP((16, "_sion_ensure_free_space", -1,
1010  " sid=%d byteswritten(%lld) + new bytes (%lld) = %lld\n", sid, byteswritten, bytes, byteswritten + bytes));
1011 
1012  if ((byteswritten + bytes) > sion_filedesc->chunksize) {
1013  /* not enough space for writing next data */
1014  _sion_create_new_block(sion_filedesc);
1015  }
1016 
1017  DPRINTFP((8, "_sion_ensure_free_space", -1,
1018  "leave ensure_free sid=%d fileposition is %lld bw+bytes=%lld <= chunksize=%lld (fsblksize=%d)\n",
1019  sid, sion_filedesc->currentpos, byteswritten + bytes, sion_filedesc->chunksize, sion_filedesc->fsblksize));
1020 
1021 
1022  return (rc);
1023 
1024 }
1025 
1026 int sion_is_thread_safe() {
1027 #ifdef SION_PTHREADS
1028  return(SION_SUCCESS);
1029 #else
1030  return(SION_NOT_SUCCESS);
1031 #endif
1032 }
1033 
1043 int sion_get_sizeof(int sid, int *numbytes, int *numfds) {
1044  _sion_filedesc *sion_filedesc;
1045  int rc=SION_NOT_SUCCESS;
1046 
1047  *numbytes=SION_SIZE_NOT_VALID;
1048  *numfds=SION_SIZE_NOT_VALID;
1049 
1050  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
1051  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
1052  return(_sion_errorprint(SION_SIZE_NOT_VALID,_SION_ERROR_RETURN,"sion_get_sizeof: invalid sion_filedesc, returning %d ...\n", sid));
1053  }
1054  DPRINTFP((2, "sion_get_sizeof", -1, "enter sid=%d\n", sid));
1055 
1056  rc=_sion_get_size_of_filedesc(sion_filedesc,numbytes,numfds);
1057 
1058  DPRINTFP((2, "sion_get_sizeof", -1, "leave sid=%d numbytes=%d numfds=%d\n", sid, *numbytes, *numfds));
1059 
1060  return (rc);
1061 
1062 }
1063 
1064 
1065 #define DFUNCTION "sion_dup"
1066 
1081 int sion_dup(int sid, int mode, int rank, uint64_t key)
1082 {
1083  int new_sid = SION_ID_NOT_VALID;
1084  _sion_filedesc *sion_filedesc;
1085 
1086  if ((sid<0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR)
1087  || !(sion_filedesc = _sion_vcdtovcon(sid))) {
1088  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"sion_dup: invalid sion_filedesc, returning %d ...\n", sid));
1089  }
1090  DPRINTFP((8, DFUNCTION, -1, "enter sid=%d\n", sid));
1091 
1092  if (sion_filedesc->mode != SION_FILEMODE_READ) {
1093  DPRINTFP((8, DFUNCTION, -1, "invalid opened\n"));
1094  return(_sion_errorprint_on_rank(SION_ID_NOT_VALID,_SION_ERROR_RETURN,sion_filedesc->rank, DFUNCTION "[%2d]: file is not opened in read mode, returning ...", sion_filedesc->rank));
1095  }
1096 
1097  new_sid=_sion_dup(sid, mode, rank, key);
1098 
1099  DPRINTFP((8, DFUNCTION, -1, "leave sid=%d new_sid=%d\n", sid, new_sid));
1100 
1101  return (new_sid);
1102 
1103 }
1104 #undef DFUNCTION
1105 
1106 #define DFUNCTION "sion_dedup"
1107 
1115 int sion_dedup(int sid)
1116 {
1117  int rc = SION_SUCCESS;
1118  DPRINTFP((8, DFUNCTION, -1, "enter sid=%d\n", sid));
1119 
1120  rc=_sion_dedup(sid);
1121 
1122  DPRINTFP((8, DFUNCTION, -1, "leave sid=%d rc=%d\n", sid, rc));
1123 
1124  return (rc);
1125 
1126 }
1127 #undef DFUNCTION
1128 
1129 #define DFUNCTION "sion_lock_register_lock_callbacks"
1130 
1140 int sion_lock_register_lock_callbacks(int lock(void *), int unlock(void *), void *lock_data)
1141 {
1142  int rc = SION_SUCCESS;
1143  DPRINTFP((8, DFUNCTION, -1, "enter\n"));
1144 
1145  rc=_sion_lock_register_lock_callbacks(lock,unlock,lock_data);
1146 
1147  DPRINTFP((8, DFUNCTION, -1, "leave rc=%d\n", rc));
1148 
1149  return (rc);
1150 }
1151 #undef DFUNCTION
1152 
1153 #define DFUNCTION "sion_lock_user_callbacks_defined"
1154 
1160 {
1161  int rc = SION_SUCCESS;
1162  DPRINTFP((8, DFUNCTION, -1, "enter\n"));
1163 
1164  rc=_sion_lock_user_callbacks_defined();
1165 
1166  DPRINTFP((8, DFUNCTION, -1, "leave rc=%d\n", rc));
1167 
1168  return (rc);
1169 }
1170 #undef DFUNCTION
int sion_feof(int sid)
Function that indicates whether the end of file is reached for this task.
Definition: sion_common.c:731
int sion_dup(int sid, int mode, int rank, uint64_t key)
Function which duplicates a sion file descriptor.
Definition: sion_common.c:1081
sion_int64 sion_bytes_avail_in_block(int sid)
Return the number of bytes available in the current chunk.
Definition: sion_common.c:801
sion_int64 sion_bytes_avail_in_chunk(int sid)
Function that returns the number of bytes available in the current chunk.
Definition: sion_common.c:816
Sion File Descriptor Structure.
Definition: sion_filedesc.h:72
int sion_get_endianness(void)
Return endianness.
Definition: sion_tools.c:26
int sion_ensure_free_space(int sid, sion_int64 bytes)
Funtion to ensure that enough space is available for writing.
Definition: sion_common.c:975
sion_int64 * all_blockcount
sion_int64 sion_get_position(int sid)
Function that returns the current file position.
Definition: sion_common.c:852
int sion_get_file_endianness(int sid)
Returns edianness of data in file sid.
Definition: sion_common.c:246
sion_int64 * all_currentpos
sion_int64 * all_globalranks
int sion_lock_register_lock_callbacks(int lock(void *), int unlock(void *), void *lock_data)
Function which registers callback funtions for lock and unlock internal access to shared data structu...
Definition: sion_common.c:1140
sion_int64 * all_currentblocknr
int sion_get_current_locations(int sid, int *ntasks, sion_int64 **sion_currentpos, sion_int64 **sion_currentblocknr)
Returns current position in file and pointer fiels containing chunk sizes.
Definition: sion_common.c:300
sion_int32 fileptr_exported
int sion_get_locations(int sid, int *ntasks, int *maxchunks, sion_int64 *globalskip, sion_int64 *start_of_varheader, sion_int64 **sion_chunksizes, sion_int64 **sion_globalranks, sion_int64 **sion_blockcount, sion_int64 **sion_blocksizes)
Returns pointers to internal fields.
Definition: sion_common.c:80
int sion_get_mapping(int sid, int *mapping_size, sion_int32 **mapping, int *numfiles)
Returns pointers to the internal field mapping.
Definition: sion_common.c:212
size_t sion_fwrite(const void *data, size_t size, size_t nitems, int sid)
Write data to sion file.
Definition: sion_common.c:432
int sion_endianness_swap_needed(int sid)
Returns whether or not byte swapping is needed for sid.
Definition: sion_common.c:270
int sion_seek(int sid, int rank, int currentblocknr, sion_int64 posinblk)
Function to set the file pointer to a new position.
Definition: sion_common.c:620
int sion_lock_user_callbacks_defined()
Function which return flag, if user callback for locking are registered.
Definition: sion_common.c:1159
int sion_get_sizeof(int sid, int *numbytes, int *numfds)
Function returns size of internal data structure for sid.
Definition: sion_common.c:1043
sion_int32 fpbuffer_size
Definition: sion_filedesc.h:81
sion_int64 * blocksizes
Definition: sion_filedesc.h:93
sion_int32 currentblocknr
Definition: sion_filedesc.h:90
sion_int64 * all_chunksizes
size_t sion_fread(void *data, size_t size, size_t nitems, int sid)
Read data from sion file.
Definition: sion_common.c:552
Sion Time Stamp Header.
int sion_dedup(int sid)
Function which destroy a duplicated sion file descriptor.
Definition: sion_common.c:1115
sion_int64 start_of_varheader
sion_int64 * all_blocksizes
int sion_get_current_location(int sid, int *currentchunknr, sion_int64 *currentpos, int *maxchunks, sion_int64 **chunksizes)
Returns current position in file and pointer fiels containing chunk sizes.
Definition: sion_common.c:178
_sion_filedesc ** multifiles
_sion_fileptr * fileptr
Definition: sion_filedesc.h:75
int sion_seek_fp(int sid, int rank, int currentblocknr, sion_int64 posinblk, FILE **fileptr)
Deprecated. Use sion_seek() instead.
Definition: sion_common.c:643
int sion_flush(int sid)
Flushed sion file.
Definition: sion_common.c:952