SIONlib  1.7.4
Scalable I/O library for parallel access to task-local files
sion_generic_mapped.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 
15 #define _XOPEN_SOURCE 700
16 
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <unistd.h>
21 
22 #include "sion.h"
23 #include "sion_debug.h"
24 #include "sion_error_handler.h"
25 #include "sion_file.h"
26 #include "sion_filedesc.h"
27 #include "sion_fd.h"
28 #include "sion_metadata.h"
29 #include "sion_internal.h"
30 #include "sion_internal_startptr.h"
31 #include "sion_printts.h"
32 
33 #include "sion_buffer.h"
34 
35 #include "sion_filedesc.h"
36 #include "sion_keyvalue.h"
37 
38 #include "sion_generic_internal.h"
40 
41 #define _SION_CONST_MAX_INT32 2147483647
42 
67  int sid,
68  char *fname,
69  sion_int64 file_mode_flags,
70  char *prefix,
71  int *numFiles,
72  int *nlocaltasks,
73  int **globalranks,
74  sion_int64 **chunksizes,
75  int **mapping_filenrs,
76  int **mapping_lranks,
77  sion_int32 *fsblksize,
78  int rank,
79  int ntasks,
80  int flag,
81  FILE **fileptr,
82  _sion_generic_gendata *sion_gendata) {
83  int rc=SION_SUCCESS;
84  int filenr, root, task;
85 
86  _sion_filedesc *sion_filedesc_sub,*sion_filedesc_master;
87  _sion_fileptr *sion_fileptr = NULL;
88  sion_int64 helpint64, apiflag, new_fsblocksize, lstartpointer;
89  /* sion_int64 lchunksize, lstartpointer, lglobalrank, helpint64; */
90  sion_int32 *sion_count = NULL;
91  sion_int32 helpint32;
92  sion_int64 *sion_tmpintfield2 = NULL;
93  sion_int64 *sion_tmpintfield3 = NULL;
94 
95  /* for write */
96  int *lfilecounter,*lfilemanager, ltask, tmpsize, blknum;
97 
98  if (file_mode_flags&_SION_FMODE_POSIX) apiflag=SION_FILE_FLAG_POSIX;
99  else apiflag=SION_FILE_FLAG_ANSI;
100 
101  DPRINTFP((2, "_sion_paropen_mapped_generic", rank, "enter parallel open sid=%d\n", sid));
102 
103  sion_filedesc_master = _sion_alloc_filedesc();
104  if (sion_filedesc_master == NULL) {
105  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot allocate filedescriptor structure of size %lu (sion_filedesc_master), aborting ...\n",
106  (unsigned long) sizeof(sion_filedesc_master)));
107  }
108 
109  _sion_init_filedesc(sion_filedesc_master);
110  sion_filedesc_master->fname = strdup(fname); /* Set the filename */
111  sion_filedesc_master->state = SION_FILESTATE_PAROPENMAPPEDMASTER;
112 
113 
114  if (file_mode_flags&_SION_FMODE_WRITE) {
115  /* **************** WRITE mode **************** */
116 
117  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, " starting open for write #tasks=%d\n", ntasks));
118 
119 
120  for(ltask=0;ltask<*nlocaltasks;ltask++) {
121  DPRINTFP((128, "_sion_paropen_mapped_generic", rank, "input: %2d: f=%d gtask=%2d ltask=%d --> %d\n", ltask,
122  (int) (*mapping_filenrs)[ltask],
123  (int) (*globalranks)[ltask],
124  (int) (*mapping_lranks)[ltask],
125  (int) (*chunksizes)[ltask]
126  ));
127  }
128 
129 
130  /* init and allocate master filedesc */
131  sion_filedesc_master->mode = SION_FILEMODE_WRITE;
132  _sion_reassignvcd(sid,sion_filedesc_master, SION_FILEDESCRIPTOR);
133  sion_filedesc_master->sid=sid;
134  sion_filedesc_master->nfiles=*numFiles;
135 
136  sion_filedesc_master->multifiles = (_sion_filedesc **) malloc(sion_filedesc_master->nfiles * sizeof(_sion_filedesc*));
137  if (sion_filedesc_master->multifiles == NULL) {
138  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"cannot allocate filedescriptor structure vector of size %lu (chunksizes), aborting ...\n",
139  (unsigned long) sion_filedesc_master->nfiles * sizeof(_sion_filedesc*)));
140  }
141 
142  /* loop over all files:
143  - collect chunksizes, ... on task 0 of file
144  - calculate startpointers
145  - distribute info
146  */
147 
148  lfilecounter = (int *) malloc(*numFiles * sizeof(int));
149  if (lfilecounter == NULL) {
150  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot allocate temporary memory of size %lu (lfilecounter), aborting ...\n",
151  (unsigned long) *numFiles * sizeof(int)));
152  }
153  lfilemanager = (int *) malloc(*numFiles * sizeof(int));
154  if (lfilemanager == NULL) {
155  free(lfilecounter);
156  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot allocate temporary memory of size %lu (lfilemanager), aborting ...\n",
157  (unsigned long) *numFiles * sizeof(int)));
158  }
159 
160  sion_count = (sion_int32 *) malloc(ntasks * sizeof(sion_int32));
161  if (sion_count == NULL) {
162  free(lfilemanager);
163  free(lfilecounter);
164  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot allocate temporary memory of size %lu (sion_count), aborting ...\n",
165  (unsigned long) ntasks * sizeof(sion_int32)));
166  }
167 
168 
169  /* get number of local tasks writing to a physical file */
170  for(filenr=0;filenr<*numFiles;filenr++) lfilecounter[filenr]=lfilemanager[filenr]=0;
171  for(ltask=0;ltask<*nlocaltasks;ltask++) {
172  filenr=(*mapping_filenrs)[ltask];
173  if((filenr<0) || (filenr>=*numFiles)){
174  free(sion_count);
175  free(lfilemanager);
176  free(lfilecounter);
177  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: on task %d: wrong file number index (%d) in mapping for task %d, aborting ...\n",
178  rank,filenr,ltask));
179  }
180  lfilecounter[filenr]++;
181  if((*mapping_lranks)[ltask]==0) {
182  lfilemanager[filenr]=1;
183  }
184  }
185 
186  sion_filedesc_master->mapping_size=0;
187 
188  /* check for keyval parameter also on master */
189  _sion_keyval_check_env(sion_filedesc_master, file_mode_flags);
190 
191  /* LOOP over files */
192  for(filenr=0;filenr<*numFiles;filenr++) {
193 
194  DPRINTFP((4, "_sion_paropen_mapped_generic", rank, " starting init of SION #%d of %d (%d local tasks) \n", filenr,*numFiles,lfilecounter[filenr]));
195 
196  /* determine which task handle this file */
197  root=-1;
198  helpint32 = lfilemanager[filenr];
199  sion_gendata->apidesc->gatherr_cb(&helpint32, sion_count, sion_gendata->comm_data_global, _SION_INT32, 1, 0);
200  if (rank == 0) {
201  for(task=0;task<ntasks;task++) {
202  if(sion_count[task]==1) root=task;
203  }
204  helpint64=root;
205  }
206  sion_gendata->apidesc->bcastr_cb(&helpint64, sion_gendata->comm_data_global, _SION_INT64,1 , 0); root=helpint64;
207  if(root<0){
208  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: on task %d: local rank 0 of file number index (%d) will not used by any tasks, aborting ...\n",
209  rank,filenr));
210  }
211 
212  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, " file #%d will be managed by task %d \n", filenr,root));
213 
214  /* allocate and initialise internal data structure with default values (NULL and -1) */
215  sion_filedesc_sub = _sion_alloc_filedesc();
216  if (sion_filedesc_sub == NULL) {
217  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot allocate filedescriptor structure of size %lu (sion_filedesc), aborting ...\n",
218  (unsigned long) sizeof(sion_filedesc_sub)));
219  }
220  sion_filedesc_master->multifiles[filenr]=sion_filedesc_sub;
221 
222  _sion_init_filedesc(sion_filedesc_sub);
223 
224  sion_filedesc_sub->fname = (sion_gendata->apidesc->get_multi_filename_cb?sion_gendata->apidesc->get_multi_filename_cb:_sion_get_multi_filename)(fname, filenr); /* Set the filename */
225  if(rank == root ){
226  sion_filedesc_sub->state = SION_FILESTATE_PAROPENMAPPEDMANAGED;
227 
228  } else {
229  sion_filedesc_sub->state = SION_FILESTATE_PAROPENMAPPED;
230  }
231  sion_filedesc_sub->mode = SION_FILEMODE_WRITE;
232  sion_filedesc_sub->endianness = _sion_get_endianness_with_flags(file_mode_flags); /* Endianness */
233  sion_filedesc_sub->fsblksize = *fsblksize;
234  sion_filedesc_sub->swapbytes = 0; /* Endianness, swapping bytes */
235  sion_filedesc_sub->nfiles = *numFiles;
236  sion_filedesc_sub->filenumber = filenr;
237  sion_filedesc_sub->prefix = strdup(prefix);
238  sion_filedesc_sub->compress = file_mode_flags&_SION_FMODE_COMPRESS;
239  sion_filedesc_sub->usecoll = file_mode_flags&_SION_FMODE_COLLECTIVE;
240  sion_filedesc_sub->filemanagedbytask = root;
241 
242  /* check for keyval parameter */
243  _sion_keyval_check_env(sion_filedesc_sub, file_mode_flags);
244 
245  /* allocate memory for storing MAXCHUNKS chunksize infos in internal structure */
246  _sion_realloc_filedesc_blocklist(sion_filedesc_sub, MAXCHUNKS);
247 
248  /* the local datastructure for one sion file contains only info for a subset of tasks writing at all to this file.
249  All parameter of this local data structures all set set as if the file consists only of the local maintained
250  tasks of the file. The data structure element all_localranks contains a mapping from local rank number
251  to the overall rank in this file. The data structure element all_globalranks contains the corresponding globalrank
252  number of all tasks of all files.
253  */
254 
255  /* get number of tasks writing to this file */
256  helpint32 = lfilecounter[filenr];
257  sion_filedesc_sub->nlocaltasksinfile = helpint32;
258  sion_gendata->apidesc->gatherr_cb(&helpint32, sion_count, sion_gendata->comm_data_global, _SION_INT32, 1, root);
259  if (rank == root) {
260  helpint64=0;
261  for(task=0;task<ntasks;task++) helpint64 += sion_count[task];
262  }
263  sion_gendata->apidesc->bcastr_cb(&helpint64, sion_gendata->comm_data_global, _SION_INT64, 1, root);
264  sion_filedesc_sub->ntotaltasksinfile = helpint64;
265  sion_filedesc_master->mapping_size+=helpint64;
266  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, "mapping size increased to %d\n",sion_filedesc_master->mapping_size));
267 
268  /* root stores in sion_count the number of local task of this file for each task */
269 
270  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, " file #%d (%s) will store chunks from %d tasks (%d local) \n",
271  filenr,sion_filedesc_sub->fname,
272  sion_filedesc_sub->ntotaltasksinfile,sion_filedesc_sub->nlocaltasksinfile));
273 
274  /* check and distribute new fsblksize */
275  if(rank == root) {
276  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, " create file #%d (%s) \n", filenr,sion_filedesc_sub->fname));
277  sion_fileptr = _sion_file_open(sion_filedesc_sub->fname,apiflag|SION_FILE_FLAG_WRITE|SION_FILE_FLAG_CREATE,0);
278  if (!sion_fileptr) {
279  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"sion_paropen_generic: cannot open %s for writing, aborting ...\n", fname));
280  }
281  if(sion_filedesc_sub->fsblksize<=-1) {
282  /* check with fstat fsblksize */
283  new_fsblocksize=(sion_int64) _sion_file_get_opt_blksize(sion_fileptr);
284  if((new_fsblocksize<0) || (new_fsblocksize>SION_MAX_FSBLOCKSIZE)) new_fsblocksize=SION_DEFAULT_FSBLOCKSIZE;
285  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, " found new_fsblksize of %d\n", (int) new_fsblocksize));
286  }
287  if (sion_filedesc_sub->usebuffer) {
288  _sion_buffer_flush(sion_filedesc_sub);
289  }
290  _sion_file_close(sion_fileptr);
291  }
292  sion_gendata->apidesc->barrier_cb(sion_gendata->comm_data_global);
293  if(sion_filedesc_sub->fsblksize==-1) {
294  sion_gendata->apidesc->bcastr_cb(&new_fsblocksize, sion_gendata->comm_data_global, _SION_INT64, 1, root);
295  sion_filedesc_sub->fsblksize = new_fsblocksize;
296  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, " setting fsblksize to %d\n", (int) new_fsblocksize));
297  }
298 
299 
300 
301  /* collect local ranks/chunksizes */
302  tmpsize=3*sion_filedesc_sub->nlocaltasksinfile;
303  sion_tmpintfield2 = (sion_int64 *) malloc(tmpsize * sizeof(sion_int64));
304  if (sion_tmpintfield2 == NULL) {
305  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot allocate temporary memory of size %lu (sion_tmpintfield2), aborting ...\n",
306  (unsigned long) tmpsize * sizeof(sion_int64)));
307  }
308  if (rank == root) {
309  tmpsize=3*sion_filedesc_sub->ntotaltasksinfile;
310  sion_tmpintfield3 = (sion_int64 *) malloc(tmpsize * sizeof(sion_int64));
311  if (sion_tmpintfield3 == NULL) {
312  free(sion_tmpintfield2);
313  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot allocate temporary memory of size %lu (sion_tmpintfield3), aborting ...\n",
314  (unsigned long) tmpsize * sizeof(sion_int64)));
315  }
316  } else sion_tmpintfield3 = NULL;
317 
318  { int p,lfilenr;
319  p=0;
320  for(ltask=0;ltask<*nlocaltasks;ltask++) {
321  lfilenr=(int) (*mapping_filenrs)[ltask];
322  if(lfilenr==filenr) {
323  sion_tmpintfield2[p*3+0]=(sion_int64) (*mapping_lranks)[ltask];
324  sion_tmpintfield2[p*3+1]=(sion_int64) (*globalranks)[ltask];
325  sion_tmpintfield2[p*3+2]=(sion_int64) (*chunksizes)[ltask];
326  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " prepare %d --> lrank=%d %d %d\n", p,(int) sion_tmpintfield2[p*3+0],(int) sion_tmpintfield2[p*3+1],(int) sion_tmpintfield2[p*3+2]));
327 
328  p++;
329  }
330  }
331  }
332  /* for(ltask=0;ltask<3*sion_filedesc_sub->nlocaltasks;ltask++) {
333  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " debug in %d --> %d\n", ltask, (int) sion_tmpintfield2[ltask] ));
334  }*/
335  if (rank == root) for(task=0;task<ntasks;task++) sion_count[task]*=3;
336  sion_gendata->apidesc->gathervr_cb(sion_tmpintfield2, sion_tmpintfield3, sion_gendata->comm_data_global, _SION_INT64,sion_count,3*sion_filedesc_sub->nlocaltasksinfile, root);
337  if (rank == root) for(task=0;task<ntasks;task++) sion_count[task]/=3;
338  /* if (rank == root) {
339  for(ltask=0;ltask<3*sion_filedesc_sub->ntasks;ltask++) {
340  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " debug out %d --> %d\n", ltask, (int) sion_tmpintfield3[ltask] ));
341  }
342 
343  } */
344 
345  if (rank == root) {
346  int lrank;
347 
348  /* memory allocation for internal fields (large size) */
349  sion_filedesc_sub->ntasks=sion_filedesc_sub->ntotaltasksinfile;
350  _sion_alloc_filedesc_arrays(sion_filedesc_sub);
351 
352  /* sort data into filedesc vectors */
353  for(ltask=0;ltask<sion_filedesc_sub->ntotaltasksinfile;ltask++) {
354  lrank=(int) sion_tmpintfield3[ltask*3+0];
355  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " sort in ltask=%d --> lrank=%d\n", ltask,lrank));
356  sion_filedesc_sub->all_globalranks[lrank]=sion_tmpintfield3[ltask*3+1];
357  sion_filedesc_sub->all_chunksizes[lrank] =sion_tmpintfield3[ltask*3+2];
358  }
359 
360  /* calculate startpointers */
361  _sion_calculate_startpointers(sion_filedesc_sub);
362  _sion_print_filedesc(sion_filedesc_sub, 512, "start of paropen_mapped", 1);
363  }
364 
365  /* open file on all ranks */
366  /* */ DPRINTFTS(rank, "before open");
367  sion_fileptr = _sion_file_open(sion_filedesc_sub->fname,apiflag|SION_FILE_FLAG_WRITE,0);
368  if (!sion_fileptr) {
369  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"sion_paropen_generic: cannot open %s for reading, aborting ...\n", fname));
370  }
371  sion_gendata->apidesc->barrier_cb(sion_gendata->comm_data_global);
372  /* */ DPRINTFTS(rank, "after open");
373 
374  /* store data in static data structure (sid) */
375  sion_filedesc_sub->fileptr = sion_fileptr;
376 
377  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " store for file %s fileprt=%x\n",sion_filedesc_sub->fname, sion_fileptr ));
378 
379  /* write header */
380  if (rank == root) {
381 
382  /* */ DPRINTFTS(rank, "before writeh");
383  /* writes serial metadata, all_globalranks, all_chunksizes */
384  _sion_write_header(sion_filedesc_sub);
385  /* */ DPRINTFTS(rank, "after writeh");
386 
387  /* needed for writing pointer to var part of metadata at the end of the file */
388  sion_filedesc_sub->end_of_header = _sion_file_get_position(sion_filedesc_sub->fileptr);
389  sion_filedesc_sub->start_of_data = sion_filedesc_sub->all_startpointers[0];
390 
391  /*set file pointer to end of file (max. file size with one chunk) */
392  lstartpointer = sion_filedesc_sub->all_startpointers[sion_filedesc_sub->ntasks - 1]
393  + sion_filedesc_sub->all_chunksizes[sion_filedesc_sub->ntasks - 1];
394  /* */ DPRINTFTS(rank, "before setp(0)");
395  _sion_file_flush(sion_filedesc_sub->fileptr);
396  _sion_file_set_position(sion_filedesc_sub->fileptr, lstartpointer);
397  /* */ DPRINTFTS(rank, "after setp(0)");
398 
399  /* free on root some of the large fields */
400  _sion_free_filedesc_all_globalranks(sion_filedesc_sub);
401 
402  /* and realloc with less memory */
403  sion_filedesc_sub->ntasks=sion_filedesc_sub->nlocaltasksinfile;
404  _sion_alloc_filedesc_all_globalranks(sion_filedesc_sub);
405  _sion_alloc_filedesc_all_localranks(sion_filedesc_sub);
406 
407  }
408 
409  if(rank!=root) {
410  /* allocate internal arrays (small size) */
411  sion_filedesc_sub->ntasks=sion_filedesc_sub->nlocaltasksinfile;
412  _sion_alloc_filedesc_arrays(sion_filedesc_sub);
413  _sion_alloc_filedesc_all_localranks(sion_filedesc_sub);
414  }
415 
416  /* allocate memory for keyval if necessary (small size) */
417  if(sion_filedesc_sub->keyvalmode!=SION_KEYVAL_NONE) {
418  _sion_alloc_filedesc_all_keyvalptr(sion_filedesc_sub);
419  }
420 
421  /* store data in internal data structure (rank info) */
422  for(ltask=0;ltask<sion_filedesc_sub->nlocaltasksinfile;ltask++) {
423  sion_filedesc_sub->all_localranks[ltask] = sion_tmpintfield2[ltask*3+0];
424  sion_filedesc_sub->all_globalranks[ltask] = sion_tmpintfield2[ltask*3+1];
425  }
426 
427  /* distribute start_pointer and chunk sizes */
428  if (rank == root) {
429  int lrank;
430  /* get data out of filedesc vectors */
431  for(ltask=0;ltask<sion_filedesc_sub->ntotaltasksinfile;ltask++) {
432  lrank=(int) sion_tmpintfield3[ltask*3+0];
433  sion_tmpintfield3[ltask*3+1]=sion_filedesc_sub->all_startpointers[lrank];
434  sion_tmpintfield3[ltask*3+2]=sion_filedesc_sub->all_chunksizes[lrank]; /* possible changed by calculate_startpointers */
435  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " sort out ltask=%d --> lrank=%d startptr=%ld chunksize=%ld\n",
436  ltask,lrank,(long) sion_tmpintfield3[ltask*3+1],sion_tmpintfield3[ltask*3+2]));
437  }
438  }
439  if (rank == root) for(task=0;task<ntasks;task++) sion_count[task]*=3;
440  sion_gendata->apidesc->scattervr_cb(sion_tmpintfield2, sion_tmpintfield3, sion_gendata->comm_data_global, _SION_INT64,sion_count,3*sion_filedesc_sub->nlocaltasksinfile, root);
441  if (rank == root) for(task=0;task<ntasks;task++) sion_count[task]/=3;
442 
443  if (rank == root) {
444  /* free on root the last large fields */
445  _sion_free_filedesc_all_startpointers(sion_filedesc_sub);
446  _sion_free_filedesc_all_chunksizes(sion_filedesc_sub);
447  /* and realloc with less memory */
448  _sion_alloc_filedesc_all_startpointers(sion_filedesc_sub);
449  _sion_alloc_filedesc_all_chunksizes(sion_filedesc_sub);
450  }
451 
452  for(ltask=0;ltask<sion_filedesc_sub->nlocaltasksinfile;ltask++) {
453  sion_filedesc_sub->all_startpointers[ltask] = sion_tmpintfield2[ltask*3+1];
454  sion_filedesc_sub->all_chunksizes[ltask] = sion_tmpintfield2[ltask*3+2];
455  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " get startpointer[%d] --> %ld\n", ltask, sion_filedesc_sub->all_startpointers[ltask]));
456  }
457 
458  /* distribute globalskip */
459  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->globalskip, sion_gendata->comm_data_global, _SION_INT64, 1, root);
460 
461 
462  /* set filepointer on each task */
463  /* */ DPRINTFTS(rank, "before setp");
464  sion_gendata->apidesc->barrier_cb(sion_gendata->comm_data_global);
465 
466  /* initalize current positions */
467  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " allocating block arrays of size %d\n", sion_filedesc_sub->ntasks));
468  _sion_alloc_filedesc_block_arrays(sion_filedesc_sub);
469  for (ltask = 0; ltask < sion_filedesc_sub->nlocaltasksinfile; ltask++) {
470  sion_filedesc_sub->all_blockcount[ltask] = 1;
471  sion_filedesc_sub->all_currentpos[ltask] = sion_filedesc_sub->all_startpointers[ltask];
472  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " set all_currentpos[%d]=%d\n",ltask,sion_filedesc_sub->all_currentpos[ltask] ));
473  sion_filedesc_sub->all_currentblocknr[ltask] = 0;
474  sion_filedesc_sub->all_blocksizes[0 * sion_filedesc_sub->nlocaltasksinfile + ltask] = 0;
475  }
476 
477  /* set position to first block of rank 0 */
478  sion_filedesc_sub->rank = 0;
479  sion_filedesc_sub->globalrank = sion_filedesc_sub->all_globalranks[sion_filedesc_sub->rank];
480  sion_filedesc_sub->chunksize = sion_filedesc_sub->all_chunksizes[0];
481  sion_filedesc_sub->startpos = sion_filedesc_sub->all_startpointers[0];
482  sion_filedesc_sub->currentpos = sion_filedesc_sub->startpos;
483  sion_filedesc_sub->lastchunknr = 0;
484  sion_filedesc_sub->currentblocknr = 0;
485 
486  _sion_file_purge(sion_fileptr);
487  _sion_file_set_position(sion_fileptr, sion_filedesc_sub->currentpos);
488 
489  sion_gendata->apidesc->barrier_cb(sion_gendata->comm_data_global);
490 
491  if(sion_tmpintfield2) free(sion_tmpintfield2);
492  if(sion_tmpintfield3) free(sion_tmpintfield3);
493 
494  DPRINTFP((4, "_sion_paropen_mapped_generic", rank, " ending init of SION #%d of %d \n", filenr,*numFiles));
495 
496  } /* for each file */
497 
498 
499  /* set master to first file, first available rank */
500 
501 
502  /* lookup file which contains current rank and set master */
503  { int lfile=-1, lrank=-1, blknum;
504  sion_filedesc_sub=NULL;
505  for(filenr=0;filenr<*numFiles;filenr++) {
506  sion_filedesc_sub=sion_filedesc_master->multifiles[filenr];
507  lfile=filenr;
508  lrank=0;
509  if(sion_filedesc_sub->nlocaltasksinfile>0) {
510  lfile=filenr;
511  lrank=0;
512  break;
513  }
514  }
515 
516  if((sion_filedesc_sub) && (lrank>=0) && (lfile>=0)) {
517  _sion_realloc_filedesc_blocklist(sion_filedesc_master, MAXCHUNKS);
518 
519  sion_filedesc_master->ntotaltasksinfile = sion_filedesc_master->mapping_size;
520  sion_filedesc_master->globalrank = sion_filedesc_sub->all_globalranks[lrank];
521  sion_filedesc_master->rank = lrank;
522  sion_filedesc_master->fsblksize = sion_filedesc_sub->fsblksize;
523  sion_filedesc_master->swapbytes = sion_filedesc_sub->swapbytes;
524  sion_filedesc_master->keyvalmode = sion_filedesc_sub->keyvalmode;
525  sion_filedesc_master->filenumber = lfile;
526 
527  /* set info for current rank and position */
528  sion_filedesc_master->chunksize = sion_filedesc_sub->all_chunksizes[lrank];
529  sion_filedesc_master->startpos = sion_filedesc_sub->all_startpointers[lrank];
530  sion_filedesc_master->currentpos = sion_filedesc_master->startpos;
531  sion_filedesc_master->globalskip = sion_filedesc_sub->globalskip;
532 
533  sion_filedesc_master->currentblocknr = 0;
534  sion_filedesc_master->lastchunknr = sion_filedesc_sub->all_blockcount[lrank]-1;
535 
536  sion_filedesc_master->maxusedchunks = sion_filedesc_sub->maxusedchunks;
537 
538  for (blknum = 0; blknum < sion_filedesc_sub->all_blockcount[lrank]; blknum++) {
539  sion_filedesc_master->blocksizes[blknum] = sion_filedesc_sub->all_blocksizes[sion_filedesc_sub->nlocaltasksinfile * blknum + lrank];
540  }
541 
542  /* set file pointer */
543  sion_filedesc_master->fileptr = sion_filedesc_master->multifiles[lfile]->fileptr;
544 
545  /* set position */
546  _sion_file_flush(sion_filedesc_master->fileptr);
547 
548  DPRINTFP((32,"sion_paropen_mapped_generic:",rank,"set startpointer to %d\n",(int) sion_filedesc_master->currentpos));
549  _sion_file_set_position(sion_filedesc_master->fileptr, sion_filedesc_master->currentpos);
550 
551  if(fileptr!=NULL) {
552  if(sion_filedesc_master->fileptr->flags&&SION_FILE_FLAG_ANSI) {
553  *fileptr=sion_filedesc_master->fileptr->fileptr;
554  sion_filedesc_master->fileptr_exported=1;
555  } else {
556  *fileptr=NULL;
557  sion_filedesc_master->fileptr_exported=0;
558  }
559  }
560 
561  }
562  }
563  _sion_print_filedesc(sion_filedesc_master, 512, "_sion_paropen_mapped_generic", 1);
564 
565  if(sion_count) free(sion_count);
566 
567  if(lfilecounter) free(lfilecounter);
568  if(lfilemanager) free(lfilemanager);
569 
570  /* ******************** end of WRITE ************************* */
571 
572  } else if (file_mode_flags&_SION_FMODE_READ) {
573 
574  /* ******************** start of READ ************************* */
575  int mapping_size,mapsid=-1, rootcounter;
576  int lnfiles,lntasks;
577  sion_int32 lfsblksize;
578  FILE *lfileptr;
579  sion_int32 *mapping;
580 
581  DPRINTFP((1, "_sion_paropen_mapped_generic", rank, "read mode ntasks=%d\n",ntasks));
582 
583  for(ltask=0;ltask<*nlocaltasks;ltask++) {
584  DPRINTFP((128, "_sion_paropen_mapped_generic", rank, "input: %2d: gtask=%2d \n", ltask, (int) (*globalranks)[ltask]));
585  }
586 
587  /* init and allocate master filedesc */
588  sion_filedesc_master->mode = SION_FILEMODE_READ;
589  _sion_reassignvcd(sid,sion_filedesc_master, SION_FILEDESCRIPTOR);
590  sion_filedesc_master->sid=sid;
591 
592  /* allocate temp fields */
593  sion_count = (sion_int32 *) malloc(ntasks * sizeof(sion_int32));
594  if (sion_count == NULL) {
595  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot allocate temporary memory of size %lu (sion_count), aborting ...\n",
596  (unsigned long) ntasks * sizeof(sion_int32)));
597  }
598  lfilemanager=NULL;
599 
600  /* 1. Read mapping info from file */
601 
602  if(rank == 0) {
603  /* open and get mapping of sion file */
604  DPRINTFP((1, "_sion_paropen_mapped_generic", rank, "before open\n"));
605  mapsid=_sion_open_read(fname,_SION_FMODE_READ|_SION_FMODE_ANSI,_SION_READ_MASTER_ONLY_OF_MULTI_FILES,
606  &lntasks,&lnfiles,NULL,&lfsblksize,NULL,&lfileptr);
607  if(mapsid>=0) {
608  DPRINTFP((1, "_sion_paropen_mapped_generic", rank, "after open\n"));
609  rc=sion_get_mapping(mapsid,&mapping_size,&mapping,numFiles);
610  DPRINTFP((1, "_sion_paropen_mapped_generic", rank, "sion file %d files #tasks=%d rc=%d\n", *numFiles,mapping_size,rc));
611 
612  /* allocate vector to distribute info about which task is managing which file */
613  lfilemanager = (int *) malloc(*numFiles * sizeof(int));
614  if (lfilemanager == NULL) {
615  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot allocate temporary memory of size %lu (lfilemanager), aborting ...\n",
616  (unsigned long) *numFiles * sizeof(int)));
617  }
618 
619  sion_filedesc_master->keyvalmode=sion_get_keyval_mode(mapsid);
620 
621  if(*numFiles>1) {
622  /* 1a. search filemanager for files, granks with lrank=0 for each file in mapping (tasks reading first sion task of multi file) */
623  for(task=0;task<mapping_size;task++) {
624  if(mapping[task*2+1]==0) {
625  lfilemanager[mapping[task*2+0]]=task;
626  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, " manager of file %d is grank=%d\n",mapping[task*2+0],task));
627  }
628  }
629  sion_filedesc_master->mapping_size=mapping_size;
630 
631  } else {
632  /* only one file */
633  sion_filedesc_master->mapping_size=lntasks;
634  lfilemanager[0]=0;
635  }
636 
637  } else {
638  *numFiles=-1;
639  free(sion_count);
640  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot find file %s , aborting ...\n",fname));
641  }
642  }
643 
644  /* broadcast information about mapping (number of global sion tasks) */
645  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_master->mapping_size, sion_gendata->comm_data_global, _SION_INT32, 1, 0);
646  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, " mapping_size is=%d\n",sion_filedesc_master->mapping_size));
647 
648  /* and close file directly */
649  if(rank == 0) {
650  if (mapsid>=0) _sion_close_sid(mapsid); /* frees also mapping vector */
651  }
652 
653  if(*nlocaltasks<0) {
654  /* 2. If not globalranks parameter given */
655  /* 2.a. compute distribution */
656  /* --> simple blockwise distribution, later improvements with task-to-file relation */
657  int tasks_per_task = sion_filedesc_master->mapping_size / ntasks;
658  int startpos = rank*tasks_per_task;
659  int endpos = (rank+1)*tasks_per_task;
660  if(rank+1==ntasks) {
661  /* remaining tasks are added to last communicator */
662  if(endpos<sion_filedesc_master->mapping_size) endpos=sion_filedesc_master->mapping_size;
663  }
664  *nlocaltasks=endpos-startpos;
665  DPRINTFP((32,"sion_paropen_mapped_generic:",rank,"pre-compute distribution: startpos=%d endpos=%d nlocaltasks=%d\n",startpos, endpos, (int) *nlocaltasks ));
666 
667  if (globalranks == NULL) {
668  free(lfilemanager);
669  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"pre-compute distribution: cannot allocate globalranks, not pointer parameter given, aborting ...\n"));
670  }
671  if (mapping_filenrs == NULL) {
672  free(lfilemanager);
673  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"pre-compute distribution: cannot allocate mapping_filenrs, not pointer parameter given, aborting ...\n"));
674  }
675  if (mapping_lranks == NULL) {
676  free(lfilemanager);
677  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"pre-compute distribution: cannot allocate mapping_lranks, not pointer parameter given, aborting ...\n"));
678  }
679  if ((*globalranks) != NULL) {
680  free(lfilemanager);
681  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"pre-compute distribution: cannot allocate globalranks, memory allready allocated (unknown size), aborting ...\n"));
682  }
683  if ((*mapping_filenrs) != NULL) {
684  free(lfilemanager);
685  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"pre-compute distribution: cannot allocate mapping_filenrs, memory allready allocated (unknown size), aborting ...\n"));
686  }
687  if ((*mapping_lranks) != NULL) {
688  free(lfilemanager);
689  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"pre-compute distribution: cannot allocate mapping_lranks, memory allready allocated (unknown size), aborting ...\n"));
690  }
691 
692 
693  DPRINTFP((32,"sion_paropen_mapped_generic:",rank,"allocate globalranks field for parameter size=%d\n",(int) *nlocaltasks ));
694  *globalranks = (sion_int32 *) malloc(*nlocaltasks * sizeof(sion_int32));
695  if (*globalranks == NULL) {
696  free(lfilemanager);
697  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"cannot allocate memory of size %lu (globalranks), aborting ...\n", (unsigned long) sizeof(sion_int32)));
698  }
699  /* init globalranks vector */
700  ltask=0;
701  for(task=startpos;task<endpos;task++) {
702  (*globalranks)[ltask]=task;
703  DPRINTFP((32,"sion_paropen_mapped_generic:",rank,"set *globalranks[%d]=%d\n",(int) ltask,(*globalranks)[ltask]));
704  ltask++;
705  }
706 
707  }
708 
709  /* broadcast keyvalmode from file */
710  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_master->keyvalmode, sion_gendata->comm_data_global, _SION_INT32, 1, 0);
711  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, " keyvalmode is=%d\n",sion_filedesc_master->keyvalmode));
712 
713  /* check for keyval parameter also on master */
714  _sion_keyval_check_env(sion_filedesc_master, file_mode_flags);
715 
716  /* 4. bcast numfiles to all */
717  if (rank == 0) helpint64=*numFiles;
718  sion_gendata->apidesc->bcastr_cb(&helpint64, sion_gendata->comm_data_global, _SION_INT64, 1, 0); *numFiles=helpint64;
719  sion_filedesc_master->nfiles=*numFiles;
720 
721  /* allocate on each task filedesc structure for each multifile */
722  sion_filedesc_master->multifiles = (_sion_filedesc **) malloc(sion_filedesc_master->nfiles * sizeof(_sion_filedesc*));
723  if (sion_filedesc_master->multifiles == NULL) {
724  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"cannot allocate filedescriptor structure vector of size %lu (chunksizes), aborting ...\n",
725  (unsigned long) sion_filedesc_master->nfiles * sizeof(_sion_filedesc*)));
726  }
727 
728  /* 5. Loop over files */
729  rootcounter=0; /* for round robin */
730  for(filenr=0;filenr<sion_filedesc_master->nfiles;filenr++) {
731 
732  DPRINTFP((4, "_sion_paropen_mapped_generic", rank, " starting init of SION #%d of %d\n", filenr,*numFiles));
733 
734 #ifdef _SION_FIND_ROOT_LRANK_NULL_DO_NOT_USE
735  {
736  int grankroot;
737  /* WARNING: this algorithm has some problems if no rank reads lrank-0 from file */
738  /* bcast grank with lrank=0 for this file */
739  grankroot=-1;
740  if (rank == 0) {
741  helpint64=lfilemanager[filenr];
742  }
743  sion_gendata->apidesc->bcastr_cb(&helpint64, sion_gendata->comm_data_global, _SION_INT64, 1, 0);
744  grankroot=helpint64;
745 
746  /* search for grankroot in my globalranks */
747  helpint32=-1;
748  for(task=0;task<*nlocaltasks;task++) {
749  if((*globalranks)[task]==grankroot) helpint32=1;
750  }
751 
752  /* gather on task 0 vector containing -1 or ranknumber for each task to determine which task is handling this file */
753  sion_gendata->apidesc->gatherr_cb(&helpint32, sion_count, sion_gendata->comm_data_global, _SION_INT32, 1, 0);
754  if (rank == 0) {
755  for(task=0;task<ntasks;task++) {
756  if(sion_count[task]==1) {
757  root=task;
758  break;
759  }
760  }
761  helpint32=root;
762  }
763  }
764 #endif
765 
766  /* round robin distribution of master role for a multi-file */
767  rootcounter=( (rootcounter+1) % ntasks);
768  helpint64=rootcounter;
769 
770  /* bcast root number for this file */
771  sion_gendata->apidesc->bcastr_cb(&helpint64, sion_gendata->comm_data_global, _SION_INT64, 1, 0);
772  root=helpint64;
773  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, " manager of file %d is rank=%d\n",filenr,root));
774 
775  /* allocate and initialise internal data structure with default values (NULL and -1) */
776  sion_filedesc_sub = _sion_alloc_filedesc();
777  if (sion_filedesc_sub == NULL) {
778  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot allocate filedescriptor structure of size %lu (sion_filedesc), aborting ...\n",
779  (unsigned long) sizeof(sion_filedesc_sub)));
780  }
781  sion_filedesc_master->multifiles[filenr]=sion_filedesc_sub;
782  _sion_init_filedesc(sion_filedesc_sub);
783  sion_filedesc_sub->fname = (sion_gendata->apidesc->get_multi_filename_cb?sion_gendata->apidesc->get_multi_filename_cb:_sion_get_multi_filename)(fname, filenr); /* Set the filename */
784  if(rank == root ){
785  sion_filedesc_sub->state = SION_FILESTATE_PAROPENMAPPEDMANAGED;
786  } else {
787  sion_filedesc_sub->state = SION_FILESTATE_PAROPENMAPPED;
788  }
789  sion_filedesc_sub->mode = SION_FILEMODE_READ;
790 
791  /* open file on each task */
792  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, " starting open for read on file %s\n", sion_filedesc_sub->fname));
793  /* */ DPRINTFTS(rank, "before open");
794  sion_filedesc_sub->fileptr=NULL;
795  if (rank == root) {
796  sion_fileptr = _sion_file_open(sion_filedesc_sub->fname,apiflag|SION_FILE_FLAG_READ,0);
797  if (!sion_fileptr) {
798  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot open %s for reading, aborting ...\n", fname));
799  }
800  sion_filedesc_sub->fileptr = sion_fileptr;
801  }
802  sion_gendata->apidesc->barrier_cb(sion_gendata->comm_data_global);
803  /* */ DPRINTFTS(rank, "after open root");
804 
805  /* get meta data of file (1st Block ) on managing task */
806  if (rank == root) {
807  rc = _sion_read_header_fix_part(sion_filedesc_sub);
808  if (rc!=SION_SUCCESS) {
809  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot read header from file %s, aborting ...\n", fname));
810  }
811  DPRINTFP((32, "_sion_paropen_mapped_generic", rank,
812  " read, after read of fix header part endianness=0x%x blksize=%d ntasks=%d\n", sion_filedesc_sub->endianness, sion_filedesc_sub->fsblksize, sion_filedesc_sub->ntasks));
813 
814  /* */ DPRINTFTS(rank, "before alloc");
815  /* memory allocation (large fields, all sion tasks of file) */
816  _sion_alloc_filedesc_arrays(sion_filedesc_sub);
817  /* */ DPRINTFTS(rank, "after alloc");
818 
819  rc = _sion_read_header_var_part(sion_filedesc_sub);
820  if (rc != SION_SUCCESS) {
821  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot read header from file %s, aborting ...\n", fname));
822  }
823 
824  _sion_coll_check_env(sion_filedesc_sub);
825  if(sion_filedesc_sub->usecoll) _sion_alloc_filedesc_coll_arrays(sion_filedesc_sub);
826 
827  /* collective */
828  if (!sion_filedesc_sub->usecoll) _sion_calculate_startpointers(sion_filedesc_sub);
829  else _sion_calculate_startpointers_collective(sion_filedesc_sub);
830  /* */ DPRINTFTS(rank, "after calculate");
831 
832  /* check for keyval parameter */
833  _sion_keyval_check_env(sion_filedesc_sub, file_mode_flags);
834 
835  }
836 
837  /* distribute globalskip */
838  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->globalskip, sion_gendata->comm_data_global, _SION_INT64, 1, root);
839 
840  /* broadcast information read from file */
841  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->endianness, sion_gendata->comm_data_global, _SION_INT32, 1, root);
842  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->swapbytes, sion_gendata->comm_data_global, _SION_INT32, 1, root);
843  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->fsblksize, sion_gendata->comm_data_global, _SION_INT32, 1, root);
844  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->ntasks, sion_gendata->comm_data_global, _SION_INT32, 1, root);
845  sion_filedesc_sub->ntotaltasksinfile=sion_filedesc_sub->ntasks;
846  sion_filedesc_sub->nlocaltasksinfile=-1; /* has to be computed after distribution of globalranks */
847  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->fileversion, sion_gendata->comm_data_global, _SION_INT32, 1, root);
848  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->nfiles, sion_gendata->comm_data_global, _SION_INT32, 1, root);
849  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->filenumber, sion_gendata->comm_data_global, _SION_INT32, 1, root);
850  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->flag1, sion_gendata->comm_data_global, _SION_INT64, 1, root);
851  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->flag2, sion_gendata->comm_data_global, _SION_INT64, 1, root);
852  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->maxusedchunks, sion_gendata->comm_data_global, _SION_INT32, 1, root);
853  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->start_of_varheader, sion_gendata->comm_data_global, _SION_INT64, 1, root);
854  DPRINTFP((32, "_sion_paropen_mapped_generic", rank,
855  " read, after read of maxusedchunks=%d maxchunks=%d (%d) start_of_varheader=%d\n", sion_filedesc_sub->maxusedchunks,sion_filedesc_sub->maxchunks, MAXCHUNKS,(int) sion_filedesc_sub->start_of_varheader ));
856  if (sion_filedesc_sub->maxusedchunks > sion_filedesc_sub->maxchunks) _sion_realloc_filedesc_blocklist(sion_filedesc_sub, sion_filedesc_sub->maxusedchunks);
857  /* */ DPRINTFTS(rank, "after bcast");
858 
859  /* allocate temp field to receive data of all tasks in file; Data
860  distribution will be done by data sieving: meta data about all sion
861  tasks in file will be sent to all task and meta data about local sion
862  tasks will be selected from these fields */
863  tmpsize=sion_filedesc_sub->ntotaltasksinfile;
864  sion_tmpintfield2 = (sion_int64 *) malloc(tmpsize * sizeof(sion_int64));
865  if (sion_tmpintfield2 == NULL) {
866  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot allocate temporary memory of size %lu (sion_tmpintfield2), aborting ...\n",
867  (unsigned long) tmpsize * sizeof(sion_int64)));
868  }
869 
870  /* bcast GLOBALRANKS number in this file */
871  if(rank==root) for(task=0;task<sion_filedesc_sub->ntotaltasksinfile;task++) sion_tmpintfield2[task]=sion_filedesc_sub->all_globalranks[task];
872  sion_gendata->apidesc->bcastr_cb(sion_tmpintfield2, sion_gendata->comm_data_global, _SION_INT64, sion_filedesc_sub->ntotaltasksinfile, root);
873 
874  /* compare globalrank number list with list of globalrank to open on this task */
875  sion_filedesc_sub->nlocaltasksinfile=0;
876  for(task=0;task<sion_filedesc_sub->ntotaltasksinfile;task++) {
877  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " scan for gtask=%d\n", (int) sion_tmpintfield2[task]));
878  for(ltask=0;ltask<*nlocaltasks;ltask++) {
879  if( (int) sion_tmpintfield2[task]==(*globalranks)[ltask]) {
880  sion_tmpintfield2[task]=-1 * (sion_tmpintfield2[task] + 1); /* set mask (set to negative value) */
881  sion_filedesc_sub->nlocaltasksinfile++;
882  }
883  }
884  }
885  DPRINTFP((32, "_sion_paropen_mapped_generic", rank, " found %d globalranks for file %s\n", sion_filedesc_sub->nlocaltasksinfile, sion_filedesc_sub->fname));
886 
887  /* */ DPRINTFTS(rank, "before open non-root");
888  /* if really necessary (not needed when on this task no globalranks are stored in this file) */
889  if ( (rank != root) && (sion_filedesc_sub->nlocaltasksinfile>0) ) {
890  sion_fileptr = _sion_file_open(sion_filedesc_sub->fname,apiflag|SION_FILE_FLAG_READ,0);
891  if (!sion_fileptr) {
892  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot open %s for reading, aborting ...\n", fname));
893  }
894  sion_filedesc_sub->fileptr = sion_fileptr;
895  }
896  /* sion_gendata->apidesc->barrier_cb(sion_gendata->comm_data_global); */
897  /* */ DPRINTFTS(rank, "after open non-root");
898 
899 
900  /* allocate internal arrays (small size, only sion tasks needed by this task) */
901  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
902  /* free on root some of the large fields */
903  _sion_free_filedesc_all_globalranks(sion_filedesc_sub);
904  /* and realloc with less memory */
905  sion_filedesc_sub->ntasks=sion_filedesc_sub->nlocaltasksinfile;
906  _sion_alloc_filedesc_all_globalranks(sion_filedesc_sub);
907  _sion_alloc_filedesc_all_localranks(sion_filedesc_sub);
908  /* all_chunksizes will follow later */
909  } else {
910  sion_filedesc_sub->ntasks=sion_filedesc_sub->nlocaltasksinfile;
911  _sion_alloc_filedesc_arrays(sion_filedesc_sub);
912  _sion_alloc_filedesc_all_localranks(sion_filedesc_sub);
913  }
914 
915  /* store position of local tasks in this file */
916  ltask=0;
917  for(task=0;task<sion_filedesc_sub->ntotaltasksinfile;task++) {
918  if(sion_tmpintfield2[task]<0) {
919  sion_filedesc_sub->all_localranks[ltask]=task;
920  sion_filedesc_sub->all_globalranks[ltask]= (-1 * sion_tmpintfield2[task]) - 1;
921  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " all_globalranks[%d]=%d all_localranks[%d]=%d\n",
922  ltask,(int) sion_filedesc_sub->all_globalranks[ltask],ltask,(int) sion_filedesc_sub->all_localranks[ltask]));
923  ltask++;
924  }
925  }
926 
927  /* bcast CHUNKSIZES */
928  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
929  for(task=0;task<sion_filedesc_sub->ntotaltasksinfile;task++) sion_tmpintfield2[task]=sion_filedesc_sub->all_chunksizes[task];
930  }
931  sion_gendata->apidesc->bcastr_cb(sion_tmpintfield2, sion_gendata->comm_data_global, _SION_INT64, sion_filedesc_sub->ntotaltasksinfile, root);
932  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
933  _sion_free_filedesc_all_chunksizes(sion_filedesc_sub); /* free on root large field */
934  _sion_alloc_filedesc_all_chunksizes(sion_filedesc_sub); /* and realloc with less memory */
935  }
936  /* store in local field */
937  for(ltask=0;ltask<sion_filedesc_sub->nlocaltasksinfile;ltask++) {
938  task=sion_filedesc_sub->all_localranks[ltask];
939  sion_filedesc_sub->all_chunksizes[ltask]=sion_tmpintfield2[task];
940  }
941 
942  /* bcast STARTPOINTERS */
943  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
944  for(task=0;task<sion_filedesc_sub->ntotaltasksinfile;task++) sion_tmpintfield2[task]=sion_filedesc_sub->all_startpointers[task];
945  }
946  sion_gendata->apidesc->bcastr_cb(sion_tmpintfield2, sion_gendata->comm_data_global, _SION_INT64, sion_filedesc_sub->ntotaltasksinfile, root);
947  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
948  _sion_free_filedesc_all_startpointers(sion_filedesc_sub); /* free on root large field */
949  _sion_alloc_filedesc_all_startpointers(sion_filedesc_sub); /* and realloc with less memory */
950  }
951  /* store in local field */
952  for(ltask=0;ltask<sion_filedesc_sub->nlocaltasksinfile;ltask++) {
953  task=sion_filedesc_sub->all_localranks[ltask];
954  sion_filedesc_sub->all_startpointers[ltask]=sion_tmpintfield2[task];
955  }
956 
957  /* allocate memory for block info */
958  _sion_alloc_filedesc_block_arrays(sion_filedesc_sub);
959 
960  /* bcast BLOCKCOUNT */
961  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
962  sion_filedesc_sub->ntasks=sion_filedesc_sub->ntotaltasksinfile;
963  _sion_read_header_var_part_blockcount_to_field(sion_filedesc_sub, sion_filedesc_sub->ntotaltasksinfile, sion_tmpintfield2);
964  sion_filedesc_sub->ntasks=sion_filedesc_sub->nlocaltasksinfile;
965  for(task=0;task<sion_filedesc_sub->ntotaltasksinfile;task++)
966  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " got from file blockcount[%d]=%d\n",task,(int) sion_tmpintfield2[task]));
967  }
968  sion_gendata->apidesc->bcastr_cb(sion_tmpintfield2, sion_gendata->comm_data_global, _SION_INT64, sion_filedesc_sub->ntotaltasksinfile, root);
969  /* store in local field */
970  for(ltask=0;ltask<sion_filedesc_sub->nlocaltasksinfile;ltask++) {
971  task=sion_filedesc_sub->all_localranks[ltask];
972  sion_filedesc_sub->all_blockcount[ltask]=sion_tmpintfield2[task];
973  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " store blockcount task=%d -> ltask=%d cnt=%d\n",task,ltask,(int) sion_tmpintfield2[task]));
974 
975  }
976 
977  /* bcast BLOCKSIZES */
978  for (blknum = 0; blknum < sion_filedesc_sub->maxusedchunks; blknum++) {
979  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
980  sion_filedesc_sub->ntasks=sion_filedesc_sub->ntotaltasksinfile;
981  _sion_read_header_var_part_nextblocksizes_to_field(sion_filedesc_sub, sion_filedesc_sub->ntotaltasksinfile, sion_tmpintfield2);
982  sion_filedesc_sub->ntasks=sion_filedesc_sub->nlocaltasksinfile;
983  }
984  sion_gendata->apidesc->bcastr_cb(sion_tmpintfield2, sion_gendata->comm_data_global, _SION_INT64, sion_filedesc_sub->ntotaltasksinfile, root);
985  /* store in local field */
986  for(ltask=0;ltask<sion_filedesc_sub->nlocaltasksinfile;ltask++) {
987  task=sion_filedesc_sub->all_localranks[ltask];
988  sion_filedesc_sub->all_blocksizes[sion_filedesc_sub->nlocaltasksinfile * blknum + ltask]=sion_tmpintfield2[task];
989  }
990  }
991 
992  /* distribute keyval options */
993  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->keyvalmode, sion_gendata->comm_data_global, _SION_INT32, 1, root);
994 
995  /* distribute collective options */
996  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->usecoll, sion_gendata->comm_data_global, _SION_INT32, 1, root);
997  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->collsize, sion_gendata->comm_data_global, _SION_INT32, 1, root);
998 
999  if(sion_filedesc_sub->usecoll) {
1000 
1001  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
1002  for(task=0;task<sion_filedesc_sub->ntotaltasksinfile;task++)
1003  sion_tmpintfield2[task]= (sion_int64) (sion_filedesc_sub->all_coll_collector[task]*_SION_CONST_MAX_INT32) + sion_filedesc_sub->collsize;
1004  }
1005  sion_gendata->apidesc->bcastr_cb(sion_tmpintfield2, sion_gendata->comm_data_global, _SION_INT64, sion_filedesc_sub->ntotaltasksinfile, root);
1006  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
1007  _sion_free_filedesc_coll_arrays(sion_filedesc_sub); /* free on root large field */
1008  }
1009  _sion_alloc_filedesc_all_chunksizes(sion_filedesc_sub); /* and alloc with less memory on all tasks */
1010 
1011  /* store in local field */
1012  DPRINTFP((64, "_sion_paropen_mapped_generic", rank, " store collsize+collector for %d elements\n",sion_filedesc_sub->nlocaltasksinfile));
1013  for(ltask=0;ltask<sion_filedesc_sub->nlocaltasksinfile;ltask++) {
1014  task=sion_filedesc_sub->all_localranks[ltask];
1015  sion_filedesc_sub->all_coll_collsize[sion_filedesc_sub->nlocaltasksinfile * blknum + ltask]=(sion_int32) sion_tmpintfield2[task]%_SION_CONST_MAX_INT32;
1016  sion_filedesc_sub->all_coll_collector[sion_filedesc_sub->nlocaltasksinfile * blknum + ltask]= (sion_int32)
1017  (sion_tmpintfield2[task]-sion_filedesc_sub->all_coll_collsize[sion_filedesc_sub->nlocaltasksinfile * blknum + ltask])/_SION_CONST_MAX_INT32;
1018  }
1019  }
1020 
1021  /* init rest of data structure */
1022  if(sion_filedesc_sub->nlocaltasksinfile>0) {
1023  for (ltask = 0; ltask < sion_filedesc_sub->nlocaltasksinfile; ltask++) {
1024  sion_filedesc_sub->all_currentpos[ltask] = sion_filedesc_sub->all_startpointers[ltask];
1025  sion_filedesc_sub->all_currentblocknr[ltask] = 0;
1026  }
1027  sion_filedesc_sub->rank = 0;
1028  sion_filedesc_sub->globalrank = sion_filedesc_sub->all_globalranks[sion_filedesc_sub->rank];
1029  sion_filedesc_sub->chunksize = sion_filedesc_sub->all_chunksizes[0];
1030  sion_filedesc_sub->startpos = sion_filedesc_sub->all_startpointers[0];
1031  sion_filedesc_sub->currentpos = sion_filedesc_sub->startpos;
1032  sion_filedesc_sub->currentblocknr = 0;
1033  sion_filedesc_sub->lastchunknr = sion_filedesc_sub->all_blockcount[sion_filedesc_sub->rank]-1;
1034 
1035  /* allocate memory for keyval if necessary (small size) */
1036  if(sion_filedesc_sub->keyvalmode!=SION_KEYVAL_NONE) {
1037  _sion_alloc_filedesc_all_keyvalptr(sion_filedesc_sub);
1038  }
1039 
1040 
1041  _sion_file_purge(sion_fileptr);
1042  _sion_file_set_position(sion_fileptr, sion_filedesc_sub->currentpos);
1043  }
1044  if(sion_tmpintfield2) free(sion_tmpintfield2);
1045 
1046  } /* filenr */
1047 
1048  /* set master to first file, first available rank */
1049 
1050  /* lookup file which contains current rank and set master */
1051  {
1052  int lfile=-1,lrank=-1, blknum;
1053  sion_filedesc_sub=NULL;
1054  for(filenr=0;filenr<sion_filedesc_master->nfiles;filenr++) {
1055  sion_filedesc_sub=sion_filedesc_master->multifiles[filenr];
1056  if(sion_filedesc_sub->nlocaltasksinfile>0) {
1057  lfile=filenr;
1058  lrank=0;
1059  break;
1060  }
1061  }
1062 
1063  DPRINTFP((32,"sion_paropen_mapped_generic",rank,"init to first local rank in first file (%d, %d)\n",lfile,lrank));
1064 
1065  if((sion_filedesc_sub) && (lrank>=0) && (lfile>=0)) {
1066  DPRINTFP((32,"sion_paropen_mapped_generic",rank,"sion_filedesc_master->mapping_size=%d\n",sion_filedesc_master->mapping_size));
1067 
1068  sion_filedesc_master->ntotaltasksinfile = sion_filedesc_master->mapping_size;
1069  sion_filedesc_master->endianness = sion_filedesc_sub->endianness;
1070  sion_filedesc_master->swapbytes = sion_filedesc_sub->swapbytes;
1071  sion_filedesc_master->globalrank = sion_filedesc_sub->all_globalranks[lrank];
1072  sion_filedesc_master->fileversion = sion_filedesc_sub->fileversion;
1073  sion_filedesc_master->filesionversion = sion_filedesc_sub->filesionversion;
1074  sion_filedesc_master->filesionpatchlevel = sion_filedesc_sub->filesionpatchlevel;
1075  sion_filedesc_master->rank = lrank;
1076  sion_filedesc_master->fsblksize = sion_filedesc_sub->fsblksize;
1077  sion_filedesc_master->filenumber = lfile;
1078 
1079  /* set info for current rank and position */
1080  sion_filedesc_master->chunksize = sion_filedesc_sub->all_chunksizes[lrank];
1081  sion_filedesc_master->startpos = sion_filedesc_sub->all_startpointers[lrank];
1082  sion_filedesc_master->currentpos = sion_filedesc_master->startpos;
1083  sion_filedesc_master->globalskip = sion_filedesc_sub->globalskip;
1084 
1085  sion_filedesc_master->currentblocknr = 0;
1086  sion_filedesc_master->lastchunknr = sion_filedesc_sub->all_blockcount[lrank]-1;
1087 
1088  sion_filedesc_master->start_of_varheader = sion_filedesc_sub->start_of_varheader;
1089 
1090 
1091  /* set maxusedchunks to maxusedchunks of all files */
1092  sion_filedesc_master->maxusedchunks = sion_filedesc_sub->maxusedchunks;
1093  for(filenr=0;filenr<sion_filedesc_sub->nfiles;filenr++) {
1094  if (sion_filedesc_master->maxusedchunks < sion_filedesc_master->multifiles[filenr]->maxusedchunks)
1095  sion_filedesc_master->maxusedchunks = sion_filedesc_master->multifiles[filenr]->maxusedchunks;
1096  }
1097  _sion_realloc_filedesc_blocklist(sion_filedesc_master, sion_filedesc_master->maxusedchunks);
1098  for (blknum = 0; blknum < sion_filedesc_sub->all_blockcount[lrank]; blknum++) {
1099  sion_filedesc_master->blocksizes[blknum] = sion_filedesc_sub->all_blocksizes[sion_filedesc_sub->nlocaltasksinfile * blknum + lrank];
1100  }
1101 
1102 
1103  /* set file pointer */
1104  sion_filedesc_master->fileptr = sion_filedesc_master->multifiles[lfile]->fileptr;
1105 
1106  /* set position */
1107  _sion_file_flush(sion_filedesc_master->fileptr);
1108 
1109  DPRINTFP((32,"sion_paropen_mapped_generic",rank,"set startpointer to %d\n",(int) sion_filedesc_master->currentpos));
1110  _sion_file_set_position(sion_filedesc_master->fileptr, sion_filedesc_master->currentpos);
1111 
1112  }
1113  } /* block */
1114 
1115  /* OUTPUT parameters */
1116  if(fileptr!=NULL) {
1117  if ( (sion_filedesc_master->fileptr!=NULL) && (sion_filedesc_master->fileptr->flags&&SION_FILE_FLAG_ANSI) ) {
1118  *fileptr=sion_filedesc_master->fileptr->fileptr;
1119  sion_filedesc_master->fileptr_exported=1;
1120  } else {
1121  *fileptr=NULL;
1122  sion_filedesc_master->fileptr_exported=0;
1123  }
1124  }
1125 
1126  {
1127  sion_int64 *helpptr_chunksize = NULL;
1128  sion_int32 *helpptr_mapping_filenrs = NULL;
1129  sion_int32 *helpptr_mapping_lranks = NULL;
1130 
1131 
1132  if (chunksizes != NULL) {
1133  if ((*chunksizes) == NULL) {
1134  DPRINTFP((32,"sion_paropen_mapped_generic:",rank,"allocate chunksizes field for parameter size=%d\n",(int) *nlocaltasks ));
1135  helpptr_chunksize = (sion_int64 *) malloc(*nlocaltasks * sizeof(sion_int64));
1136  if (helpptr_chunksize == NULL) {
1137  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"cannot allocate filedescriptor structure of size %lu (chunksizes), aborting ...\n", (unsigned long) sizeof(sion_int64)));
1138  }
1139  *chunksizes = helpptr_chunksize;
1140  } else {
1141  helpptr_chunksize = *chunksizes;
1142  }
1143  }
1144 
1145  if (mapping_filenrs != NULL) {
1146  if ((*mapping_filenrs) == NULL) {
1147  DPRINTFP((32,"sion_paropen_mapped_generic:",rank,"allocate mapping_filenrs field for parameter size=%d\n",(int) *nlocaltasks ));
1148  helpptr_mapping_filenrs = (sion_int32 *) malloc(*nlocaltasks * sizeof(sion_int32));
1149  if (helpptr_mapping_filenrs == NULL) {
1150  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"cannot allocate filedescriptor structure of size %lu (mapping_filenrs), aborting ...\n", (unsigned long) sizeof(sion_int32)));
1151  }
1152  *mapping_filenrs = helpptr_mapping_filenrs;
1153  } else {
1154  helpptr_mapping_filenrs = *mapping_filenrs;
1155  }
1156  }
1157 
1158  if (mapping_lranks != NULL) {
1159  if ((*mapping_lranks) == NULL) {
1160  DPRINTFP((32,"sion_paropen_mapped_generic:",rank,"allocate mapping_lranks field for parameter size=%d\n",(int) *nlocaltasks ));
1161  helpptr_mapping_lranks = (sion_int32 *) malloc(*nlocaltasks * sizeof(sion_int32));
1162  if (helpptr_mapping_lranks == NULL) {
1163  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"cannot allocate filedescriptor structure of size %lu (mapping_lranks), aborting ...\n", (unsigned long) sizeof(sion_int32)));
1164  }
1165  *mapping_lranks = helpptr_mapping_lranks;
1166  } else {
1167  helpptr_mapping_lranks = *mapping_lranks;
1168  }
1169  }
1170 
1171 
1172  if(helpptr_chunksize || helpptr_mapping_filenrs || helpptr_mapping_lranks) {
1173  for(filenr=0;filenr<sion_filedesc_master->nfiles;filenr++) {
1174  sion_filedesc_sub=sion_filedesc_master->multifiles[filenr];
1175  for(ltask=0;ltask<sion_filedesc_sub->nlocaltasksinfile;ltask++) {
1176  for(task=0;task<*nlocaltasks;task++) {
1177  if((*globalranks)[task]==sion_filedesc_sub->all_globalranks[ltask]) {
1178  DPRINTFP((32,"sion_paropen_mapped_generic:",rank," set chunksizes[%d]=%4d (filenr=%d, ltask=%d lrank=%d)\n",
1179  (int) task, (int) sion_filedesc_sub->all_chunksizes[ltask],filenr,ltask, sion_filedesc_sub->all_localranks[ltask]));
1180  if(helpptr_chunksize) helpptr_chunksize[task] = sion_filedesc_sub->all_chunksizes[ltask];
1181  if(helpptr_mapping_filenrs) helpptr_mapping_filenrs[task] = filenr;
1182  if(helpptr_mapping_lranks) helpptr_mapping_lranks[task] = sion_filedesc_sub->all_localranks[ltask];
1183  }
1184  }
1185  }
1186  }
1187  }
1188 
1189  } /* block */
1190 
1191  _sion_print_filedesc(sion_filedesc_master, 512, "_sion_paropen_mapped_generic", _SION_DEBUG_PRINT_ALL|_SION_DEBUG_PRINT_RECURSIVE);
1192 
1193 
1194  if(sion_count) free(sion_count);
1195 
1196  if(lfilemanager) free(lfilemanager);
1197 
1198 
1199 
1200  } else {
1201  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"sion_paropen_multi_mpi: unknown file mode"));
1202  }
1203 
1204 
1205  return (sid);
1206 }
1207 
1208 int _sion_parclose_mapped_generic( int sid,
1209  int rank,
1210  int ntasks,
1211  _sion_generic_gendata *sion_gendata ) {
1212  int rc=SION_SUCCESS;
1213  int lfile, grank, lrank, blknum, filenr, tmpsize, root, ltask, mappingroot, task;
1214  _sion_filedesc *sion_filedesc_master;
1215  _sion_filedesc *sion_filedesc_sub;
1216  sion_int64 *sion_tmpintfield_send = NULL;
1217  sion_int64 *sion_tmpintfield_lrank_recv = NULL;
1218  sion_int64 *sion_tmpintfield_data_recv = NULL;
1219  sion_int64 *sion_tmpintfield_data = NULL;
1220  sion_int32 *mapping = NULL;
1221  sion_int32 *sion_tmpint32field_send = NULL;
1222  sion_int32 *sion_tmpint32field_data_recv = NULL;
1223  sion_int32 *sion_count = NULL;
1224  sion_int32 helpint32;
1225 
1226  DPRINTFP((2, "_sion_parclose_mapped_generic", rank, "enter parallel close sid=%d\n", sid));
1227 
1228  if ((_sion_vcdtype(sid) != SION_FILEDESCRIPTOR) || !(sion_filedesc_master = _sion_vcdtovcon(sid))) {
1229  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_parclose_generic: invalid sion_filedesc_master, aborting %d ...\n", sid));
1230  }
1231 
1232 #ifdef SION_DEBUG
1233  {
1234  int numbytes, numfds;
1235  sion_get_sizeof(sid, &numbytes, &numfds);
1236  DPRINTFP((2, "_sion_parclose_mapped_generic", rank, "internal data size of sid %2d (%d bytes, %d fds) \n", sid,numbytes, numfds));
1237  }
1238 #endif
1239 
1240  if ((sion_filedesc_master->state != SION_FILESTATE_PAROPENMAPPED)
1241  && (sion_filedesc_master->state != SION_FILESTATE_PAROPENMAPPEDMASTER)
1242  && (sion_filedesc_master->state != SION_FILESTATE_PAROPENMAPPEDMANAGED)
1243  ) {
1244  return(_sion_errorprint_on_rank(SION_NOT_SUCCESS,_SION_ERROR_RETURN,sion_filedesc_master->rank,"sion_parclose_mapped: invalid file open state (!PAROPENMAPPED), aborting %d ...", sid));
1245  }
1246 
1247  /* READ MODE: close files on all tasks */
1248  if (sion_filedesc_master->mode == SION_FILEMODE_READ) {
1249 
1250  _sion_print_filedesc(sion_filedesc_master, 512, "_sion_parclose_mapped_generic", _SION_DEBUG_PRINT_ALL|_SION_DEBUG_PRINT_RECURSIVE);
1251 
1252  if(sion_filedesc_master->state == SION_FILESTATE_PAROPENMAPPEDMASTER) {
1253 
1254 
1255  /* pointer to keyval structure -> all_keyvalptr */
1256  if(sion_filedesc_master->keyvalmode!=SION_KEYVAL_NONE) {
1257  lfile=sion_filedesc_master->filenumber;
1258  lrank=sion_filedesc_master->rank; /* index to local list */
1259  if((lrank>=0) && (lfile>=0)) {
1260  sion_filedesc_sub=sion_filedesc_master->multifiles[lfile];
1261  sion_filedesc_sub->all_keyvalptr[lrank] = sion_filedesc_master->keyvalptr;
1262  }
1263  }
1264 
1265  /* loop again over files to close and collect mapping data*/
1266  for(filenr=0;filenr<sion_filedesc_master->nfiles;filenr++) {
1267  sion_filedesc_sub=sion_filedesc_master->multifiles[filenr];
1268 
1269  DPRINTFP((32, "_sion_parclose_mapped_generic", rank, " parallel close (read mode) call fclose on file %s (fileptr=%x)\n", sion_filedesc_sub->fname,sion_filedesc_sub->fileptr));
1270  if (sion_filedesc_sub->keyvalmode!=SION_KEYVAL_NONE) sion_filedesc_sub->keyvalptr = NULL;
1271  if(sion_filedesc_sub->fileptr!=NULL) {
1272  _sion_file_close(sion_filedesc_sub->fileptr);
1273  sion_filedesc_sub->fileptr = NULL;
1274  }
1275  sion_filedesc_sub->state = SION_FILESTATE_CLOSE;
1276  if(sion_filedesc_sub->keyvalmode!=SION_KEYVAL_NONE && (sion_filedesc_sub->keyvalptr!=NULL) && (sion_filedesc_sub->all_keyvalptr!=NULL))
1277  sion_filedesc_sub->all_keyvalptr[sion_filedesc_sub->rank] = sion_filedesc_sub->keyvalptr;
1278 
1279  _sion_free_filedesc(sion_filedesc_sub);
1280  }
1281  }
1282  _SION_SAFE_FREE(mapping, NULL);
1283  _SION_SAFE_FREE(sion_filedesc_master->multifiles, NULL);
1284 
1285  /* the top-level keyvalptr is a pointer to one of the all_keyvalptr of the subfiles, which are already freed */
1286  if(sion_filedesc_master->keyvalmode!=SION_KEYVAL_NONE) sion_filedesc_master->keyvalptr = NULL;
1287 
1288  _sion_free_filedesc(sion_filedesc_master);
1289  sion_filedesc_master = NULL;
1290 
1291  } else {
1292  /* WRITE MODE: gather data from all tasks and close files on all tasks */
1293 
1294  /* update meta data of current rank on master */
1295  _sion_flush_block(sion_filedesc_master);
1296 
1297  if (sion_filedesc_master->usebuffer) {
1298  _sion_buffer_flush(sion_filedesc_master);
1299  }
1300 
1301  _sion_print_filedesc(sion_filedesc_master, 512, "_sion_parclose_mapped_generic", _SION_DEBUG_PRINT_ALL|_SION_DEBUG_PRINT_RECURSIVE);
1302 
1303  /* transfer meta data to corresponding sub datastructure */
1304  lfile=sion_filedesc_master->filenumber;
1305  lrank=sion_filedesc_master->rank; /* index to local list */
1306  sion_filedesc_sub=sion_filedesc_master->multifiles[lfile];
1307 
1308  /* pointer to keyval structure */
1309  if(sion_filedesc_sub->keyvalmode!=SION_KEYVAL_NONE) sion_filedesc_sub->keyvalptr = sion_filedesc_master->keyvalptr;
1310 
1311  sion_filedesc_sub->currentpos = sion_filedesc_master->currentpos;
1312  sion_filedesc_sub->currentblocknr = sion_filedesc_master->currentblocknr;
1313  sion_filedesc_sub->lastchunknr = sion_filedesc_master->lastchunknr;
1314 
1315  /* pointer to keyval structure -> all_keyvalptr */
1316  if(sion_filedesc_sub->keyvalmode!=SION_KEYVAL_NONE) sion_filedesc_sub->all_keyvalptr[lrank] = sion_filedesc_sub->keyvalptr;
1317 
1318  DPRINTFP((4, "_sion_parclose_mapped_generic", rank, "on file %d: sub,maxchunk=%d master,maxchunk=%d \n", lfile,sion_filedesc_sub->maxchunks, sion_filedesc_master->maxchunks));
1319  if(sion_filedesc_sub->maxchunks < sion_filedesc_master->maxchunks) {
1320  _sion_realloc_filedesc_blocklist(sion_filedesc_sub, sion_filedesc_master->maxchunks);
1321  }
1322 
1323  /* store data of current rank on sub datastructure */
1324  DPRINTFP((4, "_sion_parclose_mapped_generic", rank, "store current information lrank=%d lastchunknr=%d\n", lrank,sion_filedesc_sub->lastchunknr));
1325  sion_filedesc_sub->all_currentpos[lrank] = sion_filedesc_sub->currentpos;
1326  sion_filedesc_sub->all_currentblocknr[lrank] = sion_filedesc_sub->lastchunknr;
1327  sion_filedesc_sub->all_blockcount[lrank] = sion_filedesc_sub->lastchunknr + 1;
1328  for (blknum = 0; blknum <= sion_filedesc_sub->lastchunknr; blknum++) {
1329  sion_filedesc_sub->blocksizes[blknum] = sion_filedesc_master->blocksizes[blknum];
1330  sion_filedesc_sub->all_blocksizes[sion_filedesc_sub->ntasks * blknum + lrank] = sion_filedesc_master->blocksizes[blknum];
1331  }
1332 
1333  sion_count = (sion_int32 *) malloc(ntasks * sizeof(sion_int32));
1334  if (sion_count == NULL) {
1335  return(_sion_errorprint(SION_ID_NOT_VALID,_SION_ERROR_RETURN,"_sion_paropen_mapped_generic: cannot allocate temporary memory of size %lu (sion_count), aborting ...\n",
1336  (unsigned long) ntasks * sizeof(sion_int32)));
1337  }
1338 
1339  /* loop over all files */
1340  for(filenr=0;filenr<sion_filedesc_master->nfiles;filenr++) {
1341 
1342  sion_filedesc_sub=sion_filedesc_master->multifiles[filenr];
1343  DPRINTFP((4, "_sion_parclose_mapped_generic", rank, " starting close for file %d: %s \n", filenr,sion_filedesc_sub->fname));
1344 
1345  if (sion_filedesc_sub->usebuffer) {
1346  _sion_buffer_flush(sion_filedesc_sub);
1347  }
1348 
1349  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPED) {
1350  DPRINTFP((32, "_sion_parclose_mapped_generic", rank, ">parallel close (write mode, not managed) call fclose on file %s (fileptr=%x)\n", sion_filedesc_sub->fname,sion_filedesc_sub->fileptr));
1351  _sion_file_close(sion_filedesc_sub->fileptr);
1352  DPRINTFP((32, "_sion_parclose_mapped_generic", rank, "<parallel close (write mode, not managed) call fclose on file %s (fileptr=%x)\n", sion_filedesc_sub->fname,sion_filedesc_sub->fileptr));
1353  sion_filedesc_sub->fileptr = NULL;
1354  sion_filedesc_sub->state = SION_FILESTATE_CLOSE;
1355 
1356  }
1357 
1358  sion_gendata->apidesc->barrier_cb(sion_gendata->comm_data_global);
1359 
1360  /* allocate send field */
1361  tmpsize=sion_filedesc_sub->nlocaltasksinfile;
1362  sion_tmpintfield_send = (sion_int64 *) malloc(tmpsize * sizeof(sion_int64));
1363  if (sion_tmpintfield_send == NULL) {
1364  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_parclose_generic: cannot allocate temporary memory of size %lu (sion_tmpintfield_send), aborting ...\n",
1365  (unsigned long) tmpsize * sizeof(sion_int64)));
1366  }
1367  DPRINTFP((4, "_sion_parclose_mapped_generic", rank, " file %d: allocate send field for all local tasks of file (%d) --> %x\n", filenr, tmpsize, sion_tmpintfield_send));
1368 
1369  root=sion_filedesc_sub->filemanagedbytask;
1370  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
1371 
1372  /* allocate receive fields */
1373  tmpsize=sion_filedesc_sub->ntotaltasksinfile;
1374  sion_tmpintfield_lrank_recv = (sion_int64 *) malloc(tmpsize * sizeof(sion_int64));
1375  if (sion_tmpintfield_lrank_recv == NULL) {
1376  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_parclose_generic: cannot allocate temporary memory of size %lu (sion_tmpintfield_lrank_recv), aborting ...\n",
1377  (unsigned long) tmpsize * sizeof(sion_int64)));
1378  }
1379  sion_tmpintfield_data_recv = (sion_int64 *) malloc(tmpsize * sizeof(sion_int64));
1380  if (sion_tmpintfield_data_recv == NULL) {
1381  free(sion_tmpintfield_lrank_recv);
1382  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_parclose_generic: cannot allocate temporary memory of size %lu (sion_tmpintfield_data_recv), aborting ...\n",
1383  (unsigned long) tmpsize * sizeof(sion_int64)));
1384  }
1385  sion_tmpintfield_data = (sion_int64 *) malloc(tmpsize * sizeof(sion_int64));
1386  if (sion_tmpintfield_data == NULL) {
1387  free(sion_tmpintfield_data_recv);
1388  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_parclose_generic: cannot allocate temporary memory of size %lu (sion_tmpintfield_data), aborting ...\n",
1389  (unsigned long) tmpsize * sizeof(sion_int64)));
1390  }
1391  DPRINTFP((4, "_sion_parclose_mapped_generic", rank, " file %d: allocate fields for all tasks of file (%d)\n", filenr,tmpsize));
1392 
1393 
1394  } else sion_tmpintfield_lrank_recv=sion_tmpintfield_data_recv=sion_tmpintfield_data=NULL;
1395 
1396  /* get number of tasks writing to this file */
1397  helpint32 = sion_filedesc_sub->nlocaltasksinfile;
1398  sion_gendata->apidesc->gatherr_cb(&helpint32, sion_count, sion_gendata->comm_data_global, _SION_INT32, 1, root);
1399 
1400  /* collect local rank mapping */
1401  for (ltask = 0; ltask < sion_filedesc_sub->nlocaltasksinfile; ltask++) {
1402  sion_tmpintfield_send[ltask]=sion_filedesc_sub->all_localranks[ltask];
1403  }
1404  DPRINTFP((4, "_sion_parclose_mapped_generic", rank, " file %d: before call of gathervr_cb %x %x %x %d %d %d\n",
1405  filenr,sion_tmpintfield_lrank_recv, sion_tmpintfield_send, sion_gendata->comm_data_global, _SION_INT64, sion_filedesc_sub->nlocaltasksinfile, root));
1406 
1407  sion_gendata->apidesc->gathervr_cb(sion_tmpintfield_send, sion_tmpintfield_lrank_recv, sion_gendata->comm_data_global, _SION_INT64, sion_count, sion_filedesc_sub->nlocaltasksinfile, root);
1408 
1409  /* collect number of written chunks (blocks) for each file task */
1410  for (ltask = 0; ltask < sion_filedesc_sub->nlocaltasksinfile; ltask++) {
1411  DPRINTFP((4, "_sion_parclose_mapped_generic", rank, " send all_blockcount[%d]: %d\n", ltask, sion_filedesc_sub->all_blockcount[ltask]));
1412  sion_tmpintfield_send[ltask]=sion_filedesc_sub->all_blockcount[ltask];
1413  }
1414  sion_gendata->apidesc->gathervr_cb(sion_tmpintfield_send, sion_tmpintfield_data_recv, sion_gendata->comm_data_global, _SION_INT64, sion_count, sion_filedesc_sub->nlocaltasksinfile, root);
1415 
1416  /* search maxusedchunks */
1417  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
1418  sion_filedesc_sub->maxusedchunks = -1;
1419  for (ltask = 0; ltask < sion_filedesc_sub->ntotaltasksinfile; ltask++) {
1420  if (sion_tmpintfield_data_recv[ltask] > sion_filedesc_sub->maxusedchunks) {
1421  sion_filedesc_sub->maxusedchunks = (int) sion_tmpintfield_data_recv[ltask];
1422  }
1423 
1424  }
1425  }
1426  sion_gendata->apidesc->bcastr_cb(&sion_filedesc_sub->maxusedchunks, sion_gendata->comm_data_global, _SION_INT32, 1, root);
1427  DPRINTFP((4, "_sion_parclose_mapped_generic", rank, " file %d: maxusedchunks=%d\n", filenr,sion_filedesc_sub->maxusedchunks));
1428 
1429  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
1430 
1431  /* sort data */
1432  for(ltask=0;ltask<sion_filedesc_sub->ntotaltasksinfile;ltask++) {
1433  lrank=(int) sion_tmpintfield_lrank_recv[ltask];
1434  DPRINTFP((64, "_sion_parclose_mapped_generic", rank, " sort in ltask=%d --> lrank=%d blkcount=%d\n",
1435  ltask,lrank,sion_tmpintfield_data_recv[ltask]));
1436  sion_tmpintfield_data[lrank]=sion_tmpintfield_data_recv[ltask];
1437 
1438  }
1439  /* calculate and set start_of_varheader */
1440  sion_filedesc_sub->start_of_varheader = sion_filedesc_sub->start_of_data + sion_filedesc_sub->maxusedchunks * sion_filedesc_sub->globalskip;
1441 
1442  /* adjust ntasks to total number so that internal write routines work correctly */
1443  sion_filedesc_sub->ntasks=sion_filedesc_sub->ntotaltasksinfile;
1444 
1445  /* write rest of first meta data block on rank 0 */
1446  _sion_write_header_var_info(sion_filedesc_sub);
1447 
1448  _sion_write_header_var_part_blockcount_from_field(sion_filedesc_sub,sion_filedesc_sub->ntotaltasksinfile,sion_tmpintfield_data);
1449  }
1450 
1451  for (blknum = 0; blknum < sion_filedesc_sub->maxusedchunks; blknum++) {
1452 
1453  DPRINTFP((32, "_sion_parclose_mapped_generic", rank, " collect blocksize step %d of %d\n", blknum+1,sion_filedesc_sub->maxusedchunks));
1454 
1455  /* collect number of written chunks (blocks) for each file task */
1456  DPRINTFP((32,"_sion_parclose_mapped_generic:",rank,"sion_filedesc_sub->nlocaltasksinfile=%d\n",sion_filedesc_sub->nlocaltasksinfile));
1457  for (ltask = 0; ltask < sion_filedesc_sub->nlocaltasksinfile; ltask++) {
1458  sion_tmpintfield_send[ltask]=sion_filedesc_sub->all_blocksizes[sion_filedesc_sub->nlocaltasksinfile * blknum + ltask];
1459  DPRINTFP((32,"_sion_parclose_mapped_generic:",rank,"sort in blksize[%d][%d]=%d\n",blknum, ltask, sion_tmpintfield_send[ltask]));
1460  }
1461  sion_gendata->apidesc->gathervr_cb(sion_tmpintfield_send, sion_tmpintfield_data_recv, sion_gendata->comm_data_global, _SION_INT64, sion_count, sion_filedesc_sub->nlocaltasksinfile, root);
1462 
1463 
1464  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
1465 
1466  /* sort data */
1467  for(ltask=0;ltask<sion_filedesc_sub->ntotaltasksinfile;ltask++) {
1468  lrank=(int) sion_tmpintfield_lrank_recv[ltask];
1469  sion_tmpintfield_data[lrank]=sion_tmpintfield_data_recv[ltask];
1470  DPRINTFP((32,"_sion_parclose_mapped_generic:",rank,"prepare blksize[%d][%d]=%ld\n",blknum,lrank,sion_tmpintfield_data[lrank]));
1471  }
1472 
1473  _sion_write_header_var_part_nextblocksizes_from_field(sion_filedesc_sub,sion_filedesc_sub->ntotaltasksinfile,sion_tmpintfield_data);
1474 
1475  }
1476 
1477  }
1478 
1479  if(sion_tmpintfield_lrank_recv) free(sion_tmpintfield_lrank_recv);
1480  if(sion_tmpintfield_data_recv) free(sion_tmpintfield_data_recv);
1481  if(sion_tmpintfield_data) free(sion_tmpintfield_data);
1482  if(sion_tmpintfield_send) free(sion_tmpintfield_send);
1483 
1484  DPRINTFP((4, "_sion_parclose_mapped_generic", rank, " ending close for file %d: %s \n", filenr,sion_filedesc_sub->fname));
1485 
1486  } /* for */
1487 
1488  /* for mapping table */
1489  mappingroot=sion_filedesc_master->multifiles[0]->filemanagedbytask;
1490  DPRINTFP((32,"_sion_parclose_mapped_generic:",rank,"mappingroot=%d rank=%d\n", mappingroot, rank ));
1491  if(rank==mappingroot) {
1492  DPRINTFP((32,"_sion_parclose_mapped_generic:",rank,"allocate mapping of size %d\n",sion_filedesc_master->mapping_size));
1493  mapping = (sion_int32 *) malloc(sion_filedesc_master->mapping_size * 2 * sizeof(sion_int32));
1494  if (mapping == NULL) {
1495  free(sion_count);
1496  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_ABORT,"_sion_parclose_generic_mapped: Cannot allocate memory for mapping"));
1497  }
1498  }
1499 
1500  /* loop again over files to close and collect mapping data */
1501  for(filenr=0;filenr<sion_filedesc_master->nfiles;filenr++) {
1502  sion_filedesc_sub=sion_filedesc_master->multifiles[filenr];
1503 
1504  /* allocate send field */
1505  tmpsize=2 * sion_filedesc_sub->nlocaltasksinfile;
1506  sion_tmpint32field_send = (sion_int32 *) malloc(tmpsize * sizeof(sion_int32));
1507  if (sion_tmpint32field_send == NULL) {
1508  free(mapping);
1509  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_parclose_generic_mapped: cannot allocate temporary memory of size %lu (sion_tmpintfield_send), aborting ...\n",
1510  (unsigned long) tmpsize * sizeof(sion_int32)));
1511  }
1512 
1513  /* get number of tasks writing to this file */
1514  helpint32 = sion_filedesc_sub->nlocaltasksinfile;
1515  sion_gendata->apidesc->gatherr_cb(&helpint32, sion_count, sion_gendata->comm_data_global, _SION_INT32, 1, mappingroot);
1516 
1517  DPRINTFP((4, "_sion_parclose_mapped_generic", rank, " file %d: allocate send field for all local tasks of file (%d) --> %x\n", filenr, tmpsize, sion_tmpint32field_send));
1518 
1519  if(rank==mappingroot) {
1520  /* allocate receive fields */
1521  tmpsize=2 * sion_filedesc_sub->ntotaltasksinfile;
1522  sion_tmpint32field_data_recv = (sion_int32 *) malloc(tmpsize * sizeof(sion_int32));
1523  if (sion_tmpint32field_data_recv == NULL) {
1524  return(_sion_errorprint(SION_NOT_SUCCESS,_SION_ERROR_RETURN,"_sion_parclose_generic_mapped: cannot allocate temporary memory of size %lu (sion_tmpintfield_data_recv), aborting ...\n",
1525  (unsigned long) tmpsize * sizeof(sion_int32)));
1526  }
1527  } else sion_tmpint32field_data_recv=NULL;
1528 
1529  /* collect local mapping information */
1530  for (ltask = 0; ltask < sion_filedesc_sub->nlocaltasksinfile; ltask++) {
1531  sion_tmpint32field_send[ltask*2+0]= (int) sion_filedesc_sub->all_localranks[ltask];
1532  sion_tmpint32field_send[ltask*2+1]= (int) sion_filedesc_sub->all_globalranks[ltask];
1533  DPRINTFP((32,"_sion_parclose_mapped_generic:",rank,"local lrank[%d]=%d grank[%d]=%d\n",ltask,(int) sion_filedesc_sub->all_localranks[ltask],ltask,(int) sion_filedesc_sub->all_globalranks[ltask]));
1534  }
1535 
1536  for(ltask=0;ltask<sion_filedesc_sub->nlocaltasksinfile*2;ltask++) {
1537  DPRINTFP((32,"_sion_parclose_mapped_generic:",rank," sion_tmpint32field_send: %d -> %d \n",ltask, sion_tmpint32field_send[ltask]));
1538  }
1539 
1540  if (rank == mappingroot) for(task=0;task<ntasks;task++) sion_count[task]*=2;
1541  sion_gendata->apidesc->gathervr_cb(sion_tmpint32field_send, sion_tmpint32field_data_recv, sion_gendata->comm_data_global, _SION_INT32, sion_count, 2*sion_filedesc_sub->nlocaltasksinfile, mappingroot);
1542  if (rank == mappingroot) for(task=0;task<ntasks;task++) sion_count[task]/=2;
1543 
1544  if(rank==mappingroot) {
1545  /* sort data into mapping vector */
1546  for(ltask=0;ltask<sion_filedesc_sub->ntotaltasksinfile*2;ltask++) {
1547  DPRINTFP((32,"_sion_parclose_mapped_generic:",rank," sion_tmpint32field_send: %d -> %d \n",ltask, sion_tmpint32field_data_recv[ltask]));
1548  }
1549  for(ltask=0;ltask<sion_filedesc_sub->ntotaltasksinfile;ltask++) {
1550  lrank=(int) sion_tmpint32field_data_recv[ltask*2+0];
1551  grank=(int) sion_tmpint32field_data_recv[ltask*2+1];
1552  DPRINTFP((32,"_sion_parclose_mapped_generic:",rank,"store mapping[%d]=(%d,%d)\n",grank,filenr,lrank));
1553  mapping[grank*2+0]=filenr;
1554  mapping[grank*2+1]=lrank;
1555  }
1556  }
1557 
1558  if(sion_tmpint32field_data_recv) free(sion_tmpint32field_data_recv);
1559  if(sion_tmpint32field_send) free(sion_tmpint32field_send);
1560  }
1561 
1562  /* loop again over files to close and collect mapping data*/
1563  for(filenr=0;filenr<sion_filedesc_master->nfiles;filenr++) {
1564  sion_filedesc_sub=sion_filedesc_master->multifiles[filenr];
1565 
1566  if(sion_filedesc_sub->state == SION_FILESTATE_PAROPENMAPPEDMANAGED) {
1567 
1568  /* write mapping */
1569  if(filenr==0) {
1570  DPRINTFP((32,"_sion_parclose_mapped_generic:",rank,"mapping size is %d\n",sion_filedesc_master->mapping_size));
1571  _sion_write_header_var_part_mapping(sion_filedesc_sub, sion_filedesc_master->mapping_size, mapping);
1572  }
1573 
1574  DPRINTFP((32, "_sion_parclose_mapped_generic", rank, " parallel close (write mode, managed) call fclose on file %s (fileptr=%x)\n", sion_filedesc_sub->fname,sion_filedesc_sub->fileptr));
1575  _sion_file_close(sion_filedesc_sub->fileptr);
1576  sion_filedesc_sub->fileptr = NULL;
1577  }
1578 
1579  sion_filedesc_sub->state = SION_FILESTATE_CLOSE;
1580  if (sion_filedesc_sub->keyvalmode!=SION_KEYVAL_NONE) sion_filedesc_sub->keyvalptr = NULL;
1581 
1582  /* revert ntasks to local number so that free routines work correctly */
1583  sion_filedesc_sub->ntasks=sion_filedesc_sub->nlocaltasksinfile;
1584 
1585  _sion_free_filedesc(sion_filedesc_sub);
1586  }
1587  if (sion_gendata->apidesc->free_lcg_cb && sion_gendata->comm_data_local) {
1588  sion_gendata->apidesc->free_lcg_cb(sion_gendata->comm_data_local);
1589  }
1590  _SION_SAFE_FREE(mapping, NULL);
1591  _SION_SAFE_FREE(sion_count, NULL);
1592  _SION_SAFE_FREE(sion_filedesc_master->multifiles, NULL);
1593 
1594  if (sion_filedesc_master->keyvalmode!=SION_KEYVAL_NONE) sion_filedesc_master->keyvalptr = NULL;
1595  _sion_free_filedesc(sion_filedesc_master);
1596  sion_filedesc_master = NULL;
1597 
1598  } /* write */
1599 
1600  DPRINTFP((2, "_sion_parclose_mapped_generic", rank, "leave parallel close sid=%d\n", sid));
1601 
1602  return (rc);
1603 }
1604 
1605 /* END OF _sion_parclose_generic */
1606 
long _sion_file_get_opt_blksize(_sion_fileptr *sion_fileptr)
Get optional file system block size for a file.
Definition: sion_file.c:187
sion_int32 filemanagedbytask
sion_int64 _sion_file_get_position(_sion_fileptr *sion_fileptr)
Get new position in file.
Definition: sion_file.c:241
int _sion_buffer_flush(_sion_filedesc *sion_filedesc)
Flush buffer.
Definition: sion_buffer.c:177
int _sion_flush_block(_sion_filedesc *sion_filedesc)
Update the internal data structure.
sion_int64 _sion_file_set_position(_sion_fileptr *sion_fileptr, sion_int64 startpointer)
Set new position in file.
Definition: sion_file.c:219
int _sion_reassignvcd(int sid, void *data, int type)
Definition: sion_fd.c:63
_sion_fileptr * _sion_file_open(const char *fname, unsigned int flags, unsigned int addflags)
Create and open a new file for writing.
Definition: sion_file.c:42
Sion File Descriptor Structure.
Definition: sion_filedesc.h:79
sion_int64 * all_blockcount
#define SION_FILE_FLAG_WRITE
Definition: sion_file.h:26
int _sion_read_header_var_part(_sion_filedesc *sion_filedesc)
Read the second part of SION Meta Block 1.
int _sion_write_header_var_part_mapping(_sion_filedesc *sion_filedesc, sion_int32 mapping_size, sion_int32 *mapping)
Write mapping into the SION Meta Block 2.
int _sion_file_purge(_sion_fileptr *sion_fileptr)
Purge data to file.
Definition: sion_file.c:285
sion_int64 * all_currentpos
sion_int32 filesionpatchlevel
int _sion_paropen_mapped_generic(int sid, char *fname, sion_int64 file_mode_flags, char *prefix, int *numFiles, int *nlocaltasks, int **globalranks, sion_int64 **chunksizes, int **mapping_filenrs, int **mapping_lranks, sion_int32 *fsblksize, int rank, int ntasks, int flag, FILE **fileptr, _sion_generic_gendata *sion_gendata)
Generic parallel open of one direct access file. Mapping sion files to environment with less tasks.
sion_int64 * all_globalranks
int _sion_write_header(_sion_filedesc *sion_filedesc)
Write the SION Meta Block 1.
Definition: sion_metadata.c:38
int _sion_alloc_filedesc_arrays(_sion_filedesc *sion_filedesc)
Allocate memory for the internal sion arrays.
sion_int64 * all_currentblocknr
#define SION_FILE_FLAG_READ
Definition: sion_file.h:27
int _sion_realloc_filedesc_blocklist(_sion_filedesc *sion_filedesc, sion_int32 maxchunks)
Increase the memory used by the internal sion structure for the blocklist.
int _sion_vcdtype(int sid)
Definition: sion_fd.c:58
sion_int32 * all_coll_collector
sion_int32 fileptr_exported
sion_int32 _sion_get_endianness_with_flags(sion_int64 flags)
Return endianness including possible choice via flags.
#define SION_FILE_FLAG_POSIX
Definition: sion_file.h:24
#define SION_KEYVAL_NONE
Definition: sion_const.h:79
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:219
int _sion_write_header_var_part_nextblocksizes_from_field(_sion_filedesc *sion_filedesc, int field_size, sion_int64 *field)
Write the next set of blocksizes from Meta Block 2 Assuming that filepointer is at the correct positi...
#define MAXCHUNKS
Definition: sion_common.h:35
void * _sion_vcdtovcon(int sid)
Definition: sion_fd.c:53
#define SION_FILE_FLAG_ANSI
Definition: sion_file.h:22
#define SION_FILE_FLAG_CREATE
Definition: sion_file.h:25
#define SION_FILEMODE_READ
Definition: sion_filedesc.h:37
sion_int64 * all_startpointers
int _sion_read_header_var_part_blockcount_to_field(_sion_filedesc *sion_filedesc, int field_size, sion_int64 *field)
Read the block sizes from Meta Block 2.
int _sion_file_close(_sion_fileptr *sion_fileptr)
Close file and destroys fileptr structure.
Definition: sion_file.c:109
#define SION_FILESTATE_PAROPENMAPPEDMANAGED
Definition: sion_filedesc.h:33
int sion_get_sizeof(int sid, int *numbytes, int *numfds)
Function returns size of internal data structure for sid.
Definition: sion_common.c:1123
int _sion_write_header_var_info(_sion_filedesc *sion_filedesc)
Write the SION Meta Block 1.
int _sion_free_filedesc_coll_arrays(_sion_filedesc *sion_filedesc)
free memory for the internal sion arrays
int _sion_read_header_fix_part(_sion_filedesc *sion_filedesc)
Read part of the SION Meta Block 1.
sion_int64 * blocksizes
int _sion_write_header_var_part_blockcount_from_field(_sion_filedesc *sion_filedesc, int field_size, sion_int64 *field)
Write the block sizes from Meta Block 2.
#define SION_FILESTATE_PAROPENMAPPEDMASTER
Definition: sion_filedesc.h:32
sion_int32 currentblocknr
Definition: sion_filedesc.h:97
int _sion_alloc_filedesc_block_arrays(_sion_filedesc *sion_filedesc)
Allocate memory for the internal sion structure, fields for all chunksizes of all tasks.
int sion_get_keyval_mode(int sid)
Return selected mode for key value.
char * _sion_get_multi_filename(const char *fname, int filenumber)
generates the multi filename
#define SION_FILEDESCRIPTOR
Definition: sion_fd.h:17
sion_int64 * all_chunksizes
int _sion_print_filedesc(_sion_filedesc *sion_filedesc, int level, char *desc, int flag)
Print the initialized sion file description.
#define SION_FILESTATE_CLOSE
Definition: sion_filedesc.h:35
sion_int64 * all_localranks
_sion_filedesc * _sion_alloc_filedesc(void)
Allocates memory for internal sion structure.
int _sion_alloc_filedesc_coll_arrays(_sion_filedesc *sion_filedesc)
Allocate memory for the internal sion arrays.
int _sion_init_filedesc(_sion_filedesc *sion_filedesc)
Initialize the sion file description.
Definition: sion_filedesc.c:37
#define SION_FILEMODE_WRITE
Definition: sion_filedesc.h:38
int _sion_read_header_var_part_nextblocksizes_to_field(_sion_filedesc *sion_filedesc, int field_size, sion_int64 *field)
Read the next set of blocksizes from Meta Block 2 Assuming that filepointer is at the correct positio...
sion_int32 filesionversion
Sion Time Stamp Header.
sion_int32 * all_coll_collsize
sion_int64 start_of_varheader
sion_int64 * all_blocksizes
sion_int32 ntotaltasksinfile
sion_int32 nlocaltasksinfile
int _sion_file_flush(_sion_fileptr *sion_fileptr)
Flush data to file.
Definition: sion_file.c:263
_sion_filedesc ** multifiles
_sion_fileptr * fileptr
Definition: sion_filedesc.h:82
#define SION_FILESTATE_PAROPENMAPPED
Definition: sion_filedesc.h:34
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