SIONlib  1.7.4
Scalable I/O library for parallel access to task-local files
sioncat.c
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 #define _XOPEN_SOURCE 700
10 
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <ctype.h>
15 
16 #include "sion.h"
17 #include "sion_debug.h"
18 #include "sion_file.h"
19 
20 #define FILENAME_LENGTH 1024
21 
22 static void usage(char *name);
23 
24 int main(int argc, char **argv)
25 {
26  _sion_fileptr *outfp;
27  char infilename[FILENAME_LENGTH];
28  char outfilename[FILENAME_LENGTH];
29 
30  int i, rank, blk, startrank, endrank, startblk, endblk;
31  char *localbuffer;
32  sion_int64 chunksize = 0;
33  sion_int64 left, bread, bsumread, bwrote;
34 
35  /* options */
36  int verbose = 0;
37  int use_outfile = 0;
38  int tasknum = -1;
39  int blknum = -1;
40 
41  /* for file infomation */
42  int sid, ntasks, nfiles, maxblocks;
43  sion_int32 fsblksize;
44  sion_int64 globalskip;
45  sion_int64 start_of_varheader;
46  sion_int64 *sion_localsizes;
47  sion_int64 *sion_globalranks;
48  sion_int64 *sion_blockcount;
49  sion_int64 *sion_blocksizes;
50  sion_int64 *sioncat_sum_bytes_per_task;
51  sion_int64 sioncat_sum_bytes;
52  sion_int64 sioncat_filesize;
53 
54 
55  /* parse command line */
56  i = 1;
57  if (argc < 2)
58  usage(argv[0]);
59 
60  while (i < argc) {
61  if (argv[i][0] == '-') {
62  switch (argv[i][1]) {
63  case 'o':
64  use_outfile = 1;
65  strcpy(outfilename,argv[++i]);
66  break;
67  case 't':
68  tasknum=atoi(argv[++i]);
69  break;
70  case 'b':
71  blknum=atoi(argv[++i]);
72  break;
73  case 'v':
74  verbose++;
75  break;
76  case 'V':
77  fprintf(stderr, "SIONlib utility %s (Version %d.%dp%d, fileformat version %d)\n", argv[0],
78  SION_MAIN_VERSION,SION_SUB_VERSION,
79  SION_VERSION_PATCHLEVEL,SION_FILEFORMAT_VERSION);
80  exit(1);
81  case 'h':
82  usage(argv[0]);
83  break;
84  default:
85  usage(argv[0]);
86  }
87  }
88  i++;
89  }
90 
91  strcpy(infilename, argv[argc - 1]);
92 
93  if(verbose) fprintf(stderr,"sioncat: filename: %-30s\n", infilename);
94  if(verbose) fprintf(stderr,"sioncat: outfile: %-30s\n", outfilename);
95 
96  sid = sion_open(infilename, "rb,posix", &nfiles, &ntasks, NULL, &fsblksize, NULL, NULL);
97 
98  if(verbose) fprintf(stderr,"sioncat: sid: %d\n", sid);
99  if(verbose) fprintf(stderr,"sioncat: filename: %-30s\n", infilename);
100  if(verbose) fprintf(stderr,"sioncat: number of tasks: %d\n", ntasks);
101  if(verbose) fprintf(stderr,"sioncat: write data of task: %d\n", tasknum);
102  if(verbose) fprintf(stderr,"sioncat: write data of block: %d\n", blknum);
103  if(verbose) fprintf(stderr,"sioncat: current endianness: %s\n", (sion_get_endianness())? "big" : "little");
104  if(verbose) fprintf(stderr,"sioncat: file endianness: %s\n", (sion_get_file_endianness(sid)) ? "big" : "little");
105  if(verbose) fprintf(stderr,"sioncat: fsblksize: %lu bytes (%6.2f MB)\n", (unsigned long) fsblksize, fsblksize / 1024.0 / 1024.0);
106 
107  sion_get_locations(sid, &ntasks, &maxblocks, &globalskip, &start_of_varheader, &sion_localsizes, &sion_globalranks, &sion_blockcount,
108  &sion_blocksizes);
109 
110  if(verbose) fprintf(stderr,"sioncat: max number of chunks: %d\n", maxblocks);
111 
112  /* analysis */
113  sioncat_sum_bytes_per_task = (sion_int64 *) malloc(ntasks * sizeof(sion_int64));
114  for (rank = 0; rank < ntasks; rank++)
115  sioncat_sum_bytes_per_task[rank] = 0;
116  for (rank = 0; rank < ntasks; rank++) {
117  for (blk = 0; blk < maxblocks; blk++) {
118  sioncat_sum_bytes_per_task[rank] += sion_blocksizes[ntasks * blk + rank];
119  }
120  }
121 
122  sioncat_sum_bytes = 0;
123  for (rank = 0; rank < ntasks; rank++)
124  sioncat_sum_bytes += sioncat_sum_bytes_per_task[rank];
125 
126  if(verbose) fprintf(stderr,"sioncat: datasize in file (aggr.): %lld bytes (%6.2f MB)\n", sioncat_sum_bytes, sioncat_sum_bytes / 1024.0 / 1024.0);
127 
128  sioncat_filesize = start_of_varheader + (maxblocks + 1) * rank * sizeof(sion_int64);
129 
130  if(verbose) fprintf(stderr,"sioncat: start_of_varheader: %lld bytes (%6.2f MB)\n", start_of_varheader, start_of_varheader / 1024.0 / 1024.0);
131  if(verbose) fprintf(stderr,"sioncat: size of file: %lld bytes (%6.2f MB)\n", sioncat_filesize, sioncat_filesize / 1024.0 / 1024.0);
132 
133  if (sioncat_filesize > 0) {
134  if(verbose) fprintf(stderr,"sioncat: file usage: %8.6f%%\n", (double) sioncat_sum_bytes / (double) sioncat_filesize * 100.0);
135  }
136  chunksize = 0;
137 
138  for (rank = 0; rank < ntasks; rank++) {
139  if (chunksize<sion_localsizes[rank]) chunksize=sion_localsizes[rank];
140  if (chunksize<sion_blocksizes[rank]) chunksize=sion_blocksizes[rank];
141  }
142  if(verbose) fprintf(stderr,"sioncat: max chunksize: %lld\n", chunksize);
143  localbuffer = (char *) malloc(chunksize * sizeof(char));
144  if (localbuffer == NULL) {
145  fprintf(stderr, "cannot allocate localbuffer of size %lld , aborting ...\n", chunksize * sizeof(char));
146  free(sioncat_sum_bytes_per_task);
147  return (1);
148  }
149 
150 
151  if(use_outfile) {
153  if (outfp == NULL) {
154  fprintf(stderr, "cannot open outfile %s , aborting ...\n", outfilename);
155  free(localbuffer);
156  free(sioncat_sum_bytes_per_task);
157  return (1);
158  }
159  }
160  if(tasknum>=0) {
161  if (tasknum>=ntasks) {
162  fprintf(stderr, "task number %d out of range %d .. %d , aborting ...\n", tasknum,0,ntasks-1);
163  free(localbuffer);
164  free(sioncat_sum_bytes_per_task);
165  return (1);
166  }
167  startrank=tasknum;
168  endrank=tasknum;
169  } else {
170  startrank=0;
171  endrank=ntasks-1;
172  }
173 
174  for (rank = startrank; rank <= endrank; rank++) {
175 
176  if(verbose) fprintf(stderr, "sioncat: processing task: %6d\n", rank);
177 
178  if(blknum>=0) {
179  if (blknum>=sion_blockcount[rank]) {
180  fprintf(stderr, "blk number %d out of range %d .. %d , aborting ...\n", blknum,0,(int) sion_blockcount[rank]-1);
181  free(sioncat_sum_bytes_per_task);
182  return (1);
183  }
184  startblk=blknum;
185  endblk=blknum;
186  } else {
187  startblk=0;
188  endblk=sion_blockcount[rank]-1;
189  }
190 
191  for (blk = startblk; blk <= endblk; blk++) {
192 
193  /* seek position of block */
194  sion_seek(sid, rank, blk, 0);
195  DPRINTFP((1, "sioncat", 0, "after sion_seek sid=%d rank=%d blknum=%d fileposition=%lld\n",
196  sid, rank, blk, sion_get_position(sid)));
197 
198  /* read data from block */
199  left = sion_blocksizes[ntasks * blk + rank];
200  bsumread = 0;
201  while (left > 0) {
202  DPRINTFP((8, "sioncat", 0, "will read %lld bytes localbuffer+%lld\n", left, bsumread));
203  bread = sion_fread(localbuffer + bsumread, 1, left, sid);
204  left -= bread;
205  bsumread += bread;
206  if(verbose) fprintf(stderr,"sioncat: %lld read left=%lld \n", bread, left);
207  }
208 
209  /* write data to outfile */
210  left = sion_blocksizes[ntasks * blk + rank];
211  if(use_outfile) {
212  _sion_file_write(localbuffer, left, outfp);
213  } else {
214  bwrote = fwrite(localbuffer, 1, left, stdout);
215  if (bwrote != left) {
216  fprintf(stderr, "problems writing data of size %d on stdout (rc=%d) , aborting ...\n", (int) left, (int) bwrote);
217  free(sioncat_sum_bytes_per_task);
218  free(localbuffer);
219  return (1);
220  }
221  }
222 
223  }
224 
225 
226  }
227 
228  if(use_outfile) {
229  _sion_file_close(outfp);
230  }
231 
232  free(sioncat_sum_bytes_per_task);
233  free(localbuffer);
234  sion_close(sid);
235 
236  return (0);
237 }
238 
239 void usage(char *name)
240 {
241  fprintf(stderr, "Usage: %s options <sionfn> \n\n", name);
242 
243  fprintf(stderr, "%s <sionfn> extracts data from SIONlib file <sionfn>. With -t the\n", name);
244  fprintf(stderr, "output can be restricted to a single task and with -b to a single\n");
245  fprintf(stderr, "block. %s does not extract any SIONlib meta data.\n\n", name);
246 
247  fprintf(stderr, "Options:\n");
248  fprintf(stderr, " [-v] verbose mode \n");
249  fprintf(stderr, " [-t <tasknum>] write only data of task <tasknum>\n");
250  fprintf(stderr, " [-b <blknum>] write only data of block <blknum>\n");
251  fprintf(stderr, " [-o <outfile>] file data will be written to, if not specified stdout\n");
252  fprintf(stderr, " is used\n");
253  fprintf(stderr, " [-V] show version of SIONlib\n");
254  fprintf(stderr, " [-h] show this help\n");
255  exit(1);
256 }
sion_int64 _sion_file_write(const void *data, sion_int64 bytes, _sion_fileptr *sion_fileptr)
Write data to file.
Definition: sion_file.c:141
_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
int sion_get_endianness(void)
Return endianness.
Definition: sion_tools.c:32
sion_int64 sion_get_position(int sid)
Function that returns the current file position.
Definition: sion_common.c:930
#define SION_FILE_FLAG_WRITE
Definition: sion_file.h:26
int sion_get_file_endianness(int sid)
Returns edianness of data in file sid.
Definition: sion_common.c:253
int sion_close(int sid)
Close a sion file.
Definition: sion_serial.c:106
int sion_get_locations(int sid, int *ntasks, int *maxchunks, sion_int64 *globalskip, sion_int64 *start_of_varheader, sion_int64 **sion_chunksizes, sion_int64 **sion_globalranks, sion_int64 **sion_blockcount, sion_int64 **sion_blocksizes)
Returns pointers to internal fields.
Definition: sion_common.c:84
#define SION_FILE_FLAG_ANSI
Definition: sion_file.h:22
#define SION_FILE_FLAG_CREATE
Definition: sion_file.h:25
int sion_seek(int sid, int rank, int currentblocknr, sion_int64 posinblk)
Function to set the file pointer to a new position.
Definition: sion_common.c:698
int _sion_file_close(_sion_fileptr *sion_fileptr)
Close file and destroys fileptr structure.
Definition: sion_file.c:109
size_t sion_fread(void *data, size_t size, size_t nitems, int sid)
Read data from sion file.
Definition: sion_common.c:609
int sion_open(char *fname, const char *file_mode, int *ntasks, int *nfiles, sion_int64 **chunksizes, sion_int32 *fsblksize, int **globalranks, FILE **fileptr)
Open a sion file in serial mode.
Definition: sion_serial.c:54