10 #define _XOPEN_SOURCE 700 
   18 #include "sion_buffer.h" 
   19 #include "sion_common.h" 
   20 #include "sion_const.h" 
   21 #include "sion_debug.h" 
   23 #include "sion_error_handler.h" 
   25 #include "sion_file.h" 
   26 #include "sion_filedesc.h" 
   27 #include "sion_hints.h" 
   28 #include "sion_internal.h" 
   29 #include "sion_internal_positioning.h" 
   30 #include "sion_internal_seek.h" 
   31 #include "sion_lock.h" 
   33 sion_io_stat_t *sion_get_io_info_buddy(
int sid, 
int roles, 
int flag);
 
   35 int sion_get_locations(
int sid, 
int *ntasks, 
int *maxchunks, int64_t *globalskip, int64_t *start_of_varheader,
 
   36   int64_t **sion_chunksizes, int64_t **sion_globalranks, int64_t **sion_blockcount, int64_t **sion_blocksizes)
 
   38   int rc = SION_SUCCESS;
 
   39   _sion_filedesc *sion_filedesc;
 
   40 #ifdef SION_SERIAL_MASTER 
   44   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
   45     return _sion_errorprint(SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
   47   DPRINTFP((1, 
"sion_get_locations", -1, 
"enter\n"));
 
   49 #ifdef SION_SERIAL_MASTER 
   50   if ((sion_filedesc->state == SION_FILESTATE_SEROPENMASTER) && (sion_filedesc->all_blockcount == NULL)) {
 
   54     _sion_alloc_filedesc_arrays(sion_filedesc);
 
   55     _sion_alloc_filedesc_block_arrays_only(sion_filedesc);
 
   57     for (i = 0; i < sion_filedesc->ntasks; i++) {
 
   58       int lfile = sion_filedesc->mapping[i * 2 + 0];
 
   59       int lrank = sion_filedesc->mapping[i * 2 + 1];
 
   60       sion_filedesc->all_chunksizes[i] = sion_filedesc->multifiles[lfile]->all_chunksizes[lrank];
 
   61       sion_filedesc->all_globalranks[i] = sion_filedesc->multifiles[lfile]->all_globalranks[lrank];
 
   62       sion_filedesc->all_blockcount[i] = sion_filedesc->multifiles[lfile]->all_blockcount[lrank];
 
   64     for (i = 0; i < sion_filedesc->ntasks; i++) {
 
   65       int lfile = sion_filedesc->mapping[i * 2 + 0];
 
   66       int lrank = sion_filedesc->mapping[i * 2 + 1];
 
   68       help = sion_filedesc->multifiles[lfile];
 
   69       for (blknum = 0; blknum < sion_filedesc->all_blockcount[i]; blknum++) {
 
   70         sion_filedesc->all_blocksizes[sion_filedesc->ntasks * blknum + i] = help->all_blocksizes[help->ntasks * blknum + lrank];
 
   76   *ntasks = sion_filedesc->ntasks;
 
   77   *maxchunks = sion_filedesc->maxusedchunks;
 
   78   *sion_chunksizes = sion_filedesc->all_chunksizes;
 
   79   *sion_globalranks = sion_filedesc->all_globalranks;
 
   80   *sion_blockcount = sion_filedesc->all_blockcount;
 
   81   *sion_blocksizes = sion_filedesc->all_blocksizes;
 
   82   *globalskip = sion_filedesc->globalskip;
 
   83   *start_of_varheader = sion_filedesc->start_of_varheader;
 
   85   DPRINTFP((1, 
"sion_get_locations", -1, 
"leave\n"));
 
   92   int rc = SION_SUCCESS;
 
   93   _sion_filedesc *sion_filedesc;
 
   95   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
   96     return _sion_errorprint(SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
   98   DPRINTFP((1, 
"sion_get_current_location", -1, 
"enter\n"));
 
  100   *currentchunknr = sion_filedesc->currentblocknr;
 
  101   *currentpos = sion_filedesc->currentpos - (sion_filedesc->startpos + sion_filedesc->currentblocknr * sion_filedesc->globalskip);
 
  102   *maxchunks = sion_filedesc->lastchunknr + 1;
 
  103   *chunksizes = sion_filedesc->blocksizes;
 
  105   DPRINTFP((1, 
"sion_get_current_location", -1, 
"leave\n"));
 
  111   int rc = SION_SUCCESS;
 
  112   _sion_filedesc *sion_filedesc;
 
  114   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  115     return _sion_errorprint(SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
  117   DPRINTFP((1, 
"sion_get_mapping", -1, 
"enter\n"));
 
  119   if (sion_filedesc->state == SION_FILESTATE_PAROPENMAPPEDMASTER) {
 
  121     for (
int filenr = 0; filenr < sion_filedesc->nfiles; filenr++) {
 
  122       *mapping_size += sion_filedesc->multifiles[filenr]->nlocaltasksinfile;
 
  124     *numfiles = sion_filedesc->nfiles;
 
  125     *mapping = malloc(2 * 
sizeof(int32_t) * *mapping_size);
 
  128       for (
int filenr = 0; filenr < sion_filedesc->nfiles; filenr++) {
 
  129         _sion_filedesc *filedesc_sub = sion_filedesc->multifiles[filenr];
 
  130         for (
int ltask = 0; ltask < filedesc_sub->nlocaltasksinfile; ltask++) {
 
  131           (*mapping)[2 * task] = filenr;
 
  132           (*mapping)[2 * task + 1] = filedesc_sub->all_localranks[ltask];
 
  136       assert(task == *mapping_size);
 
  139     if (sion_filedesc->mapping_size > 0) {
 
  140       *mapping_size = sion_filedesc->mapping_size;
 
  141       *mapping = sion_filedesc->mapping;
 
  145     *numfiles = sion_filedesc->nfiles;
 
  148   DPRINTFP((1, 
"sion_get_mapping", -1, 
"leave (mapping_size=%d)\n", *mapping_size));
 
  155   _sion_filedesc *sion_filedesc;
 
  157   DPRINTFP((1, 
"sion_get_file_endianness", -1, 
"enter (sid=%d)\n", sid));
 
  159   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  160     return _sion_errorprint(SION_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
  163   DPRINTFP((1, 
"sion_get_file_endianness", -1, 
"leave (sid=%d)\n", sid));
 
  165   return (sion_filedesc->endianness >> 8) & 1;
 
  172   DPRINTFP((1, 
"sion_endianness_swap_needed", -1, 
"enter (sid=%d)\n", sid));
 
  176   DPRINTFP((1, 
"sion_endianness_swap_needed", -1, 
"leave (swap_needed=%d)\n", swap_needed));
 
  183   int rc = SION_SUCCESS;
 
  184   _sion_filedesc *sion_filedesc;
 
  186   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  187     return _sion_errorprint(SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
  189   DPRINTFP((1, 
"sion_get_current_locations", -1, 
"enter\n"));
 
  191   *ntasks = sion_filedesc->ntasks;
 
  192   *sion_currentpos = sion_filedesc->all_currentpos;
 
  193   *sion_currentblocknr = sion_filedesc->all_currentblocknr;
 
  195   DPRINTFP((1, 
"sion_get_current_locations", -1, 
"leave\n"));
 
  199 int sion_get_number_of_files(
int sid)
 
  201   _sion_filedesc *sion_filedesc;
 
  203   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  204     return _sion_errorprint(SION_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
  207   return sion_filedesc->nfiles;
 
  210 int sion_get_filenumber(
int sid)
 
  212   _sion_filedesc *sion_filedesc;
 
  214   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  215     return _sion_errorprint(SION_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
  218   return sion_filedesc->filenumber;
 
  221 int sion_is_serial_opened(
int sid)
 
  223   _sion_filedesc *sion_filedesc;
 
  225   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  226     return _sion_errorprint(SION_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
  229   return sion_filedesc->state == SION_FILESTATE_SEROPEN || sion_filedesc->state == SION_FILESTATE_SEROPENRANK
 
  230     || sion_filedesc->state == SION_FILESTATE_SEROPENMASTER;
 
  233 int sion_using_hints(
int sid)
 
  235   _sion_filedesc *sion_filedesc;
 
  237   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  238     return _sion_errorprint(SION_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
  241   return sion_filedesc->usehints;
 
  244 int64_t sion_get_bytes_written(
int sid)
 
  246   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  247   if (filedesc == NULL) {
 
  248     return _sion_errorprint(SION_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
  251   if (filedesc->mode == SION_FILEMODE_WRITE) {
 
  252     if (filedesc->usebuffer) {
 
  253       _sion_buffer_flush(filedesc);
 
  255     return filedesc->size;
 
  257     return SION_SIZE_NOT_VALID;
 
  261 int64_t sion_get_bytes_read(
int sid)
 
  263   _sion_filedesc *sion_filedesc;
 
  264   int64_t bytes = SION_SIZE_NOT_VALID;
 
  266   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  267     return _sion_errorprint(SION_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
  270   if (sion_filedesc->mode == SION_FILEMODE_READ) {
 
  272     sion_filedesc->currentpos = _sion_file_get_position(sion_filedesc->fileptr);
 
  275     for (i = 0; i < sion_filedesc->currentblocknr; i++) {
 
  276       bytes += sion_filedesc->blocksizes[i];
 
  279     bytes += sion_filedesc->currentpos - (sion_filedesc->startpos + sion_filedesc->currentblocknr * sion_filedesc->globalskip);
 
  288   return sion_get_io_info_by_spec(sid, SION_ROLE_COLLECTOR | SION_ROLE_WRITER | SION_ROLE_NOWRITER, SION_GET_IO_INFO_FLAG_NONE);
 
  292 sion_io_stat_t *sion_get_io_info_by_spec(
int sid, 
int roles, 
int flag)
 
  294   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  295   if (filedesc == NULL) {
 
  296     _sion_errorprint(0, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
  301   if (filedesc->usebuddy) {
 
  302     return sion_get_io_info_buddy(sid, roles, flag);
 
  310   return _sion_free_io_info(p);
 
  313 size_t sion_write(
const void *data, 
size_t size, 
size_t nitems, 
int sid)
 
  315   int64_t bytes_to_write, bbytes;
 
  316   _sion_filedesc *sion_filedesc;
 
  320   DPRINTFP((1, __func__, -1, 
"enter size=%ld nitems=%ld\n", (
long)size, (
long)nitems));
 
  322   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  323     return _sion_errorprint(SION_ANSI_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
  326   _sion_check_on_collective_mode(sion_filedesc);
 
  328   bytes_to_write = size * nitems;
 
  331   if (sion_filedesc->usebuffer) {
 
  332     const char *data_ptr = data;
 
  334     int64_t bytes_buffered = _sion_buffer_push(sion_filedesc, data_ptr, bytes_to_write);
 
  335     bytes_to_write -= bytes_buffered;
 
  336     data_ptr += bytes_buffered;
 
  338     while (bytes_to_write > 0) {
 
  340       _sion_buffer_get_data_ptr(sion_filedesc, &bdata, &bbytes);
 
  341       frc = _sion_write_multi_chunk(sion_filedesc, bdata, bbytes);
 
  343         return _sion_errorprint_on_rank(SION_ANSI_SIZE_NOT_VALID, _SION_ERROR_RETURN, sion_filedesc->rank,
 
  344           "could not write data (%d bytes) to file (sid=%d) ...", (
int)bbytes, sid);
 
  348       bytes_buffered = _sion_buffer_push(sion_filedesc, data_ptr, bytes_to_write);
 
  349       bytes_to_write -= bytes_buffered;
 
  350       data_ptr += bytes_buffered;
 
  353     rc = size ? nitems : 0;
 
  357     frc = _sion_write_multi_chunk(sion_filedesc, data, bytes_to_write);
 
  358     if (frc != bytes_to_write) {
 
  359       return _sion_errorprint_on_rank(SION_ANSI_SIZE_NOT_VALID, _SION_ERROR_RETURN, sion_filedesc->rank,
 
  360         "could not write data (%d bytes) to file (frc=%d sid=%d) ...", (
int)bytes_to_write, (
int)frc, sid);
 
  362     rc = size ? nitems : 0;
 
  365   DPRINTFP((1, __func__, -1, 
"leave rc=%ld\n", (
long)rc));
 
  369 size_t sion_fwrite(
const void *data, 
size_t size, 
size_t nitems, 
int sid)
 
  374 size_t sion_read(
void *data, 
size_t size, 
size_t nitems, 
int sid)
 
  376   _sion_filedesc *sion_filedesc;
 
  379   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  380     return _sion_errorprint(SION_ANSI_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"invalid sion_filedesc, aborting %d ...\n", sid);
 
  384     return _sion_errorprint(SION_ANSI_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"invalid pointer, aborting %d ...\n", data);
 
  387   DPRINTFP((1, __func__, -1, 
"enter\n"));
 
  388   DPRINTFP((4, __func__, -1, 
" parameter size=%zu nitems=%zu\n", size, nitems));
 
  390   _sion_check_on_collective_mode(sion_filedesc);
 
  393     bread = _sion_read_multi_chunk(sion_filedesc, data, size * nitems);
 
  394     DPRINTFP((256, __func__, -1, 
"  _sion_file_read returns %zu\n", bread));
 
  397   bread = size ? bread / size : 0;
 
  399   DPRINTFP((4, __func__, -1, 
" return value  %zu\n", bread));
 
  400   DPRINTFP((1, __func__, -1, 
"leave\n"));
 
  405 size_t sion_fread(
void *data, 
size_t size, 
size_t nitems, 
int sid)
 
  407   return sion_read(data, size, nitems, sid);
 
  415   DPRINTFP((1, __func__, -1, 
" enter seek with sid=%d\n", sid));
 
  417   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  418   if (filedesc == NULL) {
 
  419     return _sion_errorprint(SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"sion_seek: invalid sion_filedesc, aborting %d ...\n", sid);
 
  423   if ((filedesc->mode != SION_FILEMODE_READ) && (filedesc->mode != SION_FILEMODE_WRITE)) {
 
  424     return _sion_errorprint_on_rank(SION_NOT_SUCCESS, _SION_ERROR_RETURN, filedesc->rank,
 
  425       "sion_seek: unknown file open state !(READ|WRITE), aborting %d ...", sid);
 
  427   if (filedesc->usebuffer) {
 
  428     _sion_buffer_flush(filedesc);
 
  430   if ((filedesc->state != SION_FILESTATE_PAROPEN) && (filedesc->state != SION_FILESTATE_SEROPEN)
 
  431     && (filedesc->state != SION_FILESTATE_SEROPENMASTER) && (filedesc->state != SION_FILESTATE_SEROPENRANK)
 
  432     && (filedesc->state != SION_FILESTATE_PAROPENMAPPEDMASTER)) {
 
  433     return _sion_errorprint_on_rank(SION_NOT_SUCCESS, _SION_ERROR_RETURN, filedesc->rank,
 
  434       "sion_seek: unknown file open state !(PAR|SER|SERRANK|MAPPED), aborting %d ...", sid);
 
  438   if (filedesc->mode == SION_FILEMODE_READ) { 
 
  439     rc = _sion_seek_on_current_rank_read(filedesc, offset, whence);
 
  441     if (filedesc->state == SION_FILESTATE_SEROPENRANK) {
 
  442       return _sion_errorprint_on_rank(SION_NOT_SUCCESS, _SION_ERROR_RETURN, filedesc->rank,
 
  443         "sion_seek: seek not supported for this type (write, sion_open_rank), aborting ...");
 
  445       rc = _sion_seek_on_current_rank_write(filedesc, offset, whence);
 
  449   DPRINTFP((1, __func__, -1, 
"leave seek rc=%d\n", rc));
 
  455   DPRINTFP((1, __func__, -1, 
" enter seek with sid=%d\n", sid));
 
  457   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  458   if (filedesc == NULL) {
 
  459     return _sion_errorprint(
 
  460       SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"sion_seek_chunk: invalid sion_filedesc, aborting %d ...\n", sid);
 
  466     new_blocknr = offset;
 
  469     new_blocknr = _sion_get_current_chunk_number(filedesc) + offset;
 
  472     new_blocknr = filedesc->lastchunknr + offset;
 
  475     return _sion_errorprint(SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"sion_seek_block: seek mode not supported, aborting ...\n");
 
  478   if (new_blocknr < 0) {
 
  479     return _sion_errorprint(
 
  480       SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"sion_seek_chunk: cannot seek before first block, aborting ...\n");
 
  482   if (filedesc->mode == SION_FILEMODE_READ && new_blocknr > filedesc->lastchunknr) {
 
  483     return _sion_errorprint(
 
  484       SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"sion_seek_chunk: cannot seek past last block in read mode, aborting ...\n");
 
  487   _sion_apply_hints(filedesc, SION_HINTS_FREE_TYPE_CHUNK);
 
  488   _sion_chunk_sequence sequence = _sion_chunk_sequence_from_filedesc(filedesc);
 
  489   _sion_range chunk = _sion_chunk_sequence_chunk_from_number(&sequence, new_blocknr);
 
  490   filedesc->currentpos = chunk.start;
 
  491   filedesc->currentblocknr = new_blocknr;
 
  492   _sion_apply_hints(filedesc, SION_HINTS_ACCESS_TYPE_CHUNK);
 
  494   _sion_file_set_position(filedesc->fileptr, filedesc->currentpos);
 
  496   DPRINTFP((1, __func__, -1, 
"leave seek rc=%d\n", SION_SUCCESS));
 
  502   DPRINTFP((1, __func__, -1, 
" enter switch_logical_file with sid=%d\n", sid));
 
  504   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  505   if (filedesc == NULL) {
 
  506     return _sion_errorprint(
 
  507       SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"sion_seek_chunk: invalid sion_filedesc, aborting %d ...\n", sid);
 
  511   if (filedesc->mode == SION_FILEMODE_READ) {
 
  512     if (filedesc->state == SION_FILESTATE_SEROPEN) {
 
  513       rc = _sion_switch_logical_file_read(filedesc, file_number);
 
  514     } 
else if (filedesc->state == SION_FILESTATE_SEROPENMASTER) {
 
  515       rc = _sion_switch_logical_file_read_master(filedesc, file_number);
 
  516     } 
else if (filedesc->state == SION_FILESTATE_PAROPENMAPPEDMASTER) {
 
  517       rc = _sion_switch_logical_file_read_mapped(filedesc, file_number);
 
  518     } 
else if ((filedesc->state == SION_FILESTATE_SEROPENRANK) || (filedesc->state == SION_FILESTATE_PAROPEN)) {
 
  519       return _sion_errorprint_on_rank(SION_NOT_SUCCESS, _SION_ERROR_RETURN, filedesc->rank,
 
  520         "sion_switch_logical_file: switching logical file not supported for this type (sion_open_rank, sion_paropen_...), " 
  523       return _sion_errorprint_on_rank(SION_NOT_SUCCESS, _SION_ERROR_RETURN, filedesc->rank,
 
  524         "sion_switch_logical_file: switching logical file not supported for unknown file state, aborting ...\n");
 
  527     if (filedesc->state == SION_FILESTATE_SEROPEN) {
 
  528       rc = _sion_switch_logical_file_write(filedesc, file_number);
 
  529     } 
else if (filedesc->state == SION_FILESTATE_PAROPENMAPPEDMASTER) {
 
  530       rc = _sion_switch_logical_file_write_mapped(filedesc, file_number);
 
  531     } 
else if ((filedesc->state == SION_FILESTATE_SEROPENRANK) || (filedesc->state == SION_FILESTATE_PAROPEN)) {
 
  532       return _sion_errorprint_on_rank(SION_NOT_SUCCESS, _SION_ERROR_RETURN, filedesc->rank,
 
  533         "sion_switch_logical_file: switching logical file not supported for this type (sion_open_rank, sion_paropen_...), " 
  536       return _sion_errorprint_on_rank(SION_NOT_SUCCESS, _SION_ERROR_RETURN, filedesc->rank,
 
  537         "sion_switch_logical_file: switching logical file not supported for unknown file state, aborting ...\n");
 
  541   DPRINTFP((1, __func__, -1, 
"leave switch_logical_file rc=%d\n", rc));
 
  547   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  548   if (filedesc == NULL) {
 
  549     return _sion_errorprint(-1, _SION_ERROR_RETURN, 
"%s: invalid file descriptor (%d)\n", __func__, sid);
 
  552   return _sion_get_logical_position(filedesc);
 
  557   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  558   DPRINTFP((8, __func__, -1, 
"enter eof   sid=%d\n", sid));
 
  560     return _sion_errorprint(SION_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"sion_eof: invalid filedesc, aborting %d ...\n", sid);
 
  564   if (filedesc->mode == SION_FILEMODE_WRITE) {
 
  565     DPRINTFP((64, __func__, -1, 
"file opened for writing, no eof\n"));
 
  566     eof = SION_NOT_SUCCESS;
 
  568     _sion_limited_chunk_sequence sequence = _sion_limited_chunk_sequence_from_filedesc(filedesc);
 
  569     DPRINTFP((64, __func__, -1, 
"  current position: %" PRId64 
", eof: %" PRId64 
"\n", filedesc->currentpos, sequence.ubound));
 
  570     eof = (_sion_limited_chunk_sequence_position_oob(&sequence, filedesc->currentpos)) ? SION_SUCCESS : SION_NOT_SUCCESS;
 
  572   DPRINTFP((8, __func__, -1, 
"leave feof   sid=%d rc=%d\n", sid, eof));
 
  588   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  589   if (filedesc == NULL) {
 
  590     return _sion_errorprint(
 
  591       SION_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"sion_bytes_avail_in_chunk: invalid filedesc, aborting %d ...\n", sid);
 
  594   assert(filedesc->mode == SION_FILEMODE_READ);
 
  596   _sion_limited_chunk_sequence sequence = _sion_limited_chunk_sequence_from_filedesc(filedesc);
 
  598   if (_sion_limited_chunk_sequence_position_oob(&sequence, filedesc->currentpos)) {
 
  601     _sion_range chunk = _sion_limited_chunk_sequence_chunk_from_physical_position(&sequence, filedesc->currentpos);
 
  602     bytes_avail = chunk.length;
 
  605   DPRINTFP((8, __func__, -1, 
"leave sid=%d rank=%4d  currentpos=%lld  maxpos= %lld -> bytes to read %lld\n", sid, filedesc->rank,
 
  606     filedesc->currentpos, bytes_avail));
 
  613   _sion_filedesc *sion_filedesc;
 
  615   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  616     return _sion_errorprint(
 
  617       SION_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"sion_get_position: invalid sion_filedesc, aborting %d ...\n", sid);
 
  620   return _sion_file_get_position(sion_filedesc->fileptr);
 
  623 int sion_optimize_fp_buffer(
int sid)
 
  625   int rc = SION_SUCCESS;
 
  626   _sion_filedesc *sion_filedesc;
 
  628   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  629     return _sion_errorprint(
 
  630       SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"sion_optimize_fp_buffer: invalid sion_filedesc, aborting %d ...\n", sid);
 
  633   sion_filedesc->fpbuffer = malloc(sion_filedesc->fsblksize);
 
  634   if (sion_filedesc->fpbuffer == NULL) {
 
  635     return _sion_errorprint_on_rank(SION_NOT_SUCCESS, _SION_ERROR_RETURN, sion_filedesc->rank,
 
  636       "sion_optimize_fp_buffer: cannot allocate internal buffer of size %lu , aborting ...",
 
  637       (
unsigned long)sion_filedesc->fsblksize);
 
  639   sion_filedesc->fpbuffer_size = sion_filedesc->fsblksize;
 
  641   rc = _sion_file_set_buffer(sion_filedesc->fileptr, sion_filedesc->fpbuffer, sion_filedesc->fpbuffer_size);
 
  647   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  648   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(filedesc = _sion_vcdtovcon(sid))) {
 
  649     return _sion_errorprint(SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"sion_flush: invalid sion_filedesc, aborting %d ...\n", sid);
 
  657   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  660     return _sion_errorprint(
 
  661       SION_NOT_SUCCESS, _SION_ERROR_RETURN, 
"sion_ensure_free_space: invalid filedesc, returning %d ...\n", sid);
 
  664   DPRINTFP((8, 
"_sion_ensure_free_space", -1, 
"enter ensure_free   sid=%d bytes=%lld\n", sid, bytes));
 
  666   if (filedesc->mode != SION_FILEMODE_WRITE) {
 
  667     DPRINTFP((8, 
"_sion_ensure_free_space", -1, 
"invalid opened\n"));
 
  668     return _sion_errorprint_on_rank(SION_NOT_SUCCESS, _SION_ERROR_RETURN, filedesc->rank,
 
  669       "sion_ensure_free_space[%2d]: file is opened invalid sion_mode, returning ...", filedesc->rank);
 
  671   if (!filedesc->usecoll) {
 
  672     if (filedesc->fileptr == NULL) {
 
  673       DPRINTFP((8, 
"_sion_ensure_free_space", -1, 
"file not opened\n"));
 
  674       return _sion_errorprint_on_rank(SION_NOT_SUCCESS, _SION_ERROR_RETURN, filedesc->rank,
 
  675         "sion_ensure_free_space[%2d]: file is not open, returning ...", filedesc->rank);
 
  679   DPRINTFP((16, 
"_sion_ensure_free_space", -1, 
"  after getpos sid=%d fileposition is %lld bytes=%lld\n", sid,
 
  680     filedesc->currentpos, bytes));
 
  682   int64_t byteswritten = filedesc->blocksizes[filedesc->currentblocknr];
 
  684   DPRINTFP((16, 
"_sion_ensure_free_space", -1, 
" sid=%d byteswritten(%lld) + new bytes (%lld) = %lld\n", sid, byteswritten, bytes,
 
  685     byteswritten + bytes));
 
  687   DPRINTFP((8, 
"_sion_ensure_free_space", -1,
 
  688     "leave ensure_free   sid=%d fileposition is %lld bw+bytes=%lld <= chunksize=%lld (fsblksize=%d)\n", sid, filedesc->currentpos,
 
  689     byteswritten + bytes, filedesc->chunksize, filedesc->fsblksize));
 
  694 int sion_is_thread_safe()
 
  699   return SION_NOT_SUCCESS;
 
  705   _sion_filedesc *sion_filedesc;
 
  706   int rc = SION_NOT_SUCCESS;
 
  708   *numbytes = SION_SIZE_NOT_VALID;
 
  709   *numfds = SION_SIZE_NOT_VALID;
 
  711   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  712     return _sion_errorprint(
 
  713       SION_SIZE_NOT_VALID, _SION_ERROR_RETURN, 
"sion_get_sizeof: invalid sion_filedesc, returning %d ...\n", sid);
 
  715   DPRINTFP((2, 
"sion_get_sizeof", -1, 
"enter sid=%d\n", sid));
 
  717   rc = _sion_get_size_of_filedesc(sion_filedesc, numbytes, numfds);
 
  719   DPRINTFP((2, 
"sion_get_sizeof", -1, 
"leave sid=%d numbytes=%d numfds=%d\n", sid, *numbytes, *numfds));
 
  724 #define DFUNCTION "sion_dup" 
  725 int sion_dup(
int sid, 
int mode, 
int rank, uint64_t key)
 
  727   int new_sid = SION_ID_NOT_VALID;
 
  728   _sion_filedesc *sion_filedesc;
 
  730   if ((sid < 0) || (_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc = _sion_vcdtovcon(sid))) {
 
  731     return _sion_errorprint(SION_ID_NOT_VALID, _SION_ERROR_RETURN, 
"sion_dup: invalid sion_filedesc, returning %d ...\n", sid);
 
  733   DPRINTFP((8, DFUNCTION, -1, 
"enter sid=%d\n", sid));
 
  735   if (sion_filedesc->mode != SION_FILEMODE_READ) {
 
  736     DPRINTFP((8, DFUNCTION, -1, 
"invalid opened\n"));
 
  737     return _sion_errorprint_on_rank(SION_ID_NOT_VALID, _SION_ERROR_RETURN, sion_filedesc->rank,
 
  738       DFUNCTION 
"[%2d]: file is not opened in read mode, returning ...", sion_filedesc->rank);
 
  741   new_sid = _sion_dup(sid, mode, rank, key);
 
  743   DPRINTFP((8, DFUNCTION, -1, 
"leave sid=%d new_sid=%d\n", sid, new_sid));
 
  749 #define DFUNCTION "sion_dedup" 
  753   DPRINTFP((8, DFUNCTION, -1, 
"enter sid=%d\n", sid));
 
  755   rc = _sion_dedup(sid);
 
  757   DPRINTFP((8, DFUNCTION, -1, 
"leave sid=%d rc=%d\n", sid, rc));
 
  763 #define DFUNCTION "sion_lock_register_lock_callbacks" 
  767   DPRINTFP((8, DFUNCTION, -1, 
"enter\n"));
 
  769   rc = _sion_lock_register_lock_callbacks(lock, unlock, lock_data);
 
  771   DPRINTFP((8, DFUNCTION, -1, 
"leave rc=%d\n", rc));
 
  777 #define DFUNCTION "sion_lock_user_callbacks_defined" 
  781   DPRINTFP((8, DFUNCTION, -1, 
"enter\n"));
 
  783   rc = _sion_lock_user_callbacks_defined();
 
  785   DPRINTFP((8, DFUNCTION, -1, 
"leave rc=%d\n", rc));
 
  791 char *sion_get_fname(
int sid)
 
  793   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  795   return filedesc->fname;
 
  798 int64_t sion_get_chunksize(
int sid)
 
  800   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  802   return filedesc->chunksize;
 
  805 int32_t sion_get_globalrank(
int sid)
 
  807   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  809   return filedesc->globalrank;
 
  812 int32_t *sion_get_globalranks(
int sid)
 
  814   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  816   if (filedesc->state == SION_FILESTATE_PAROPENMAPPEDMASTER) {
 
  818     for (
int filenr = 0; filenr < filedesc->nfiles; filenr++) {
 
  819       ntasks += filedesc->multifiles[filenr]->nlocaltasksinfile;
 
  821     int32_t *globalranks = malloc(
sizeof(int32_t) * ntasks);
 
  824       for (
int filenr = 0; filenr < filedesc->nfiles; filenr++) {
 
  825         _sion_filedesc *filedesc_sub = filedesc->multifiles[filenr];
 
  826         for (
int ltask = 0; ltask < filedesc_sub->nlocaltasksinfile; ltask++) {
 
  827           globalranks[task] = filedesc_sub->all_globalranks[ltask];
 
  831       assert(ntasks == task);
 
  839 int sion_get_number_of_logical_files(
int sid)
 
  841   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  843   return filedesc->ntasks;
 
  846 int64_t *sion_get_chunksizes(
int sid)
 
  848   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  850   if (filedesc->state == SION_FILESTATE_PAROPENMAPPEDMASTER) {
 
  852     for (
int filenr = 0; filenr < filedesc->nfiles; filenr++) {
 
  853       ntasks += filedesc->multifiles[filenr]->nlocaltasksinfile;
 
  855     int64_t *chunksizes = malloc(
sizeof(int64_t) * ntasks);
 
  858       for (
int filenr = 0; filenr < filedesc->nfiles; filenr++) {
 
  859         _sion_filedesc *filedesc_sub = filedesc->multifiles[filenr];
 
  860         for (
int ltask = 0; ltask < filedesc_sub->nlocaltasksinfile; ltask++) {
 
  861           chunksizes[task] = filedesc_sub->all_chunksizes[ltask];
 
  865       assert(ntasks == task);
 
  869     return filedesc->all_chunksizes;
 
  873 int32_t sion_get_fsblksize(
int sid)
 
  875   _sion_filedesc *filedesc = _sion_get_filedesc(sid);
 
  877   return filedesc->fsblksize;
 
  885     char c[
sizeof(long)];
 
  889   return u.c[
sizeof(long) - 1] == 1;
 
  892 int sion_get_version(
int *major_version, 
int *minor_version, 
int *patch_level, 
int *fileformat_version)
 
  894   *major_version = SION_VERSION_MAJOR;
 
  895   *minor_version = SION_VERSION_MINOR;
 
  896   *patch_level = SION_VERSION_PATCH;
 
  897   *fileformat_version = SION_FILEFORMAT_VERSION;
 
int sion_switch_logical_file(int sid, int file_number)
moves the file pointer to a different logical file
size_t sion_write(const void *data, size_t size, size_t nitems, int sid)
Write data to a SIONlib file.
size_t sion_read(void *data, size_t size, size_t nitems, int sid)
Read data from SIONlib file.
int sion_get_mapping(int sid, int *mapping_size, int32_t **mapping, int *numfiles)
Returns pointers to the internal field mapping.
int sion_get_locations(int sid, int *ntasks, int *maxchunks, int64_t *globalskip, int64_t *start_of_varheader, int64_t **sion_chunksizes, int64_t **sion_globalranks, int64_t **sion_blockcount, int64_t **sion_blocksizes)
Returns pointers to internal fields.
int sion_flush(int sid)
Flushed sion file.
int sion_get_current_locations(int sid, int *ntasks, int64_t **sion_currentpos, int64_t **sion_currentblocknr)
Returns current position in file and pointer fiels containing chunk sizes.
int sion_feof(int sid)
Function that indicates whether the end of this logical file has been reached.
int sion_get_version(int *major_version, int *minor_version, int *patch_level, int *fileformat_version)
Return version numbers.
size_t sion_fread(void *data, size_t size, size_t nitems, int sid)
Read data from a SIONlib file.
int sion_get_endianness(void)
Return endianness.
int sion_get_file_endianness(int sid)
Returns edianness of data in file sid.
int sion_ensure_free_space(int sid, int64_t bytes)
Function to ensure that enough space is available for writing.
int64_t sion_bytes_avail_in_chunk(int sid)
Function that returns the number of bytes available in the current chunk.
int sion_eof(int sid)
Function that indicates whether the end of this logical file has been reached.
int sion_get_current_location(int sid, int *currentchunknr, int64_t *currentpos, int *maxchunks, int64_t **chunksizes)
Returns current position in file and pointer fiels containing chunk sizes.
int sion_endianness_swap_needed(int sid)
Returns whether or not byte swapping is needed for sid.
int sion_seek(int sid, int64_t offset, sion_seek_mode whence)
moves the file pointer inside a logical file
int64_t sion_tell(int sid)
Inspect position of file pointer in logical file.
int sion_dup(int sid, int mode, int rank, uint64_t key)
Function which duplicates a sion file descriptor.
int64_t sion_bytes_avail_in_block(int sid)
Return the number of bytes available in the current chunk.
int sion_seek_chunk(int sid, int32_t offset, sion_seek_mode whence)
moves the file pointer by increments of entire chunks inside the logical file
int64_t sion_get_position(int sid)
Function that returns the current file position.
int sion_lock_user_callbacks_defined()
Function which return flag, if user callback for locking are registered.
int sion_get_sizeof(int sid, int *numbytes, int *numfds)
Function returns size of internal data structure for sid.
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...
int sion_dedup(int sid)
Function which destroy a duplicated sion file descriptor.
size_t sion_fwrite(const void *data, size_t size, size_t nitems, int sid)
Write data to a SIONlib file.
sion_seek_mode
determines how offsets are interpreted for seek operations
@ SION_SEEK_END
interpret the offset relative to the end of the file
@ SION_SEEK_CURRENT
interpret the offset relative to the current position in the file
@ SION_SEEK_BEGINNING
interpret the offset relative to the beginning of the file