SIONlib  1.7.7
Scalable I/O library for parallel access to task-local files
ompi_partest.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 
10 #define _XOPEN_SOURCE 700
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <mpi.h>
17 #include <time.h>
18 #include <math.h>
19 
20 #include "sion_debug.h"
21 #include "sion_printts.h"
22 #include "sion.h"
23 #include "ompi_partest.h"
24 #include "partest_opts.h"
25 
26 #include <omp.h>
27 
28 
29 #ifdef _SION_BGP
30 /* #include <mpix.h> */
31 #include <common/bgp_personality.h>
32 #include <common/bgp_personality_inlines.h>
33 #endif
34 
35 #ifdef _SION_AIX
36 #include <unistd.h>
37 #endif
38 
39 #ifdef _SION_LINUX
40 #include <unistd.h>
41 #endif
42 
53 int barrier_after_start(MPI_Comm comm)
54 {
55  #pragma omp master
56  {
57  MPI_Barrier(comm);
58  }
59  #pragma omp barrier
60  return (1);
61 }
62 
63 int barrier_after_malloc(MPI_Comm comm)
64 {
65  #pragma omp master
66  {
67  MPI_Barrier(comm);
68  }
69  #pragma omp barrier
70 
71  return (1);
72 }
73 
74 int barrier_after_open(MPI_Comm comm)
75 {
76  #pragma omp master
77  {
78  MPI_Barrier(comm);
79  }
80  #pragma omp barrier
81  return (1);
82 }
83 
84 int barrier_after_write(MPI_Comm comm)
85 {
86  #pragma omp master
87  {
88  MPI_Barrier(comm);
89  }
90  #pragma omp barrier
91  return (1);
92 }
93 
94 int barrier_after_read(MPI_Comm comm)
95 {
96  #pragma omp master
97  {
98  MPI_Barrier(comm);
99  }
100  #pragma omp barrier
101  return (1);
102 }
103 
104 int barrier_after_close(MPI_Comm comm)
105 {
106  #pragma omp master
107  {
108  MPI_Barrier(comm);
109  }
110  #pragma omp barrier
111  return (1);
112 }
113 
114 int barrier_before_unlink(MPI_Comm comm)
115 {
116  #pragma omp master
117  {
118  MPI_Barrier(comm);
119  }
120  #pragma omp barrier
121  return (1);
122 }
123 
124 int barrier_after_unlink(MPI_Comm comm)
125 {
126  #pragma omp master
127  {
128  MPI_Barrier(comm);
129  }
130  #pragma omp barrier
131  return (1);
132 }
133 
134 static char * __collective_print_pointer;
135 
136 int collective_print_gather(char *cbuffer, MPI_Comm comm )
137 {
138  int rank, size, p;
139  char *lbuffer;
140  int num_threads = omp_get_num_threads();
141 
142  #pragma omp barrier
143 
144  #pragma omp master
145  {
146  __collective_print_pointer = (char *) malloc(MAXCHARLEN * num_threads);
147  }
148 
149  #pragma omp barrier
150 
151  memcpy(__collective_print_pointer+(MAXCHARLEN * omp_get_thread_num()),cbuffer,MAXCHARLEN);
152 
153  #pragma omp barrier
154 
155  #pragma omp master
156  {
157  MPI_Comm_size(comm, &size);
158  MPI_Comm_rank(comm, &rank);
159  if(rank==0) lbuffer = (char *) malloc(MAXCHARLEN * num_threads * size);
160  else lbuffer = NULL;
161 
162  MPI_Gather(__collective_print_pointer, MAXCHARLEN*num_threads, MPI_CHAR, lbuffer, MAXCHARLEN*num_threads, MPI_CHAR, 0, comm);
163 
164 
165  if (rank == 0) {
166 
167  for (p = 0; p < (size*num_threads); p++) {
168 
169  fprintf(stderr, "%s", lbuffer + p * MAXCHARLEN);
170  }
171  }
172 
173  if(rank==0) free(lbuffer);
174 
175  free(__collective_print_pointer);
176  }
177 #pragma omp barrier
178 
179  return (1);
180 }
181 
182 
192 static void * __thread_sync_pointer;
193 
194 void reduce_omp(void *syncdata, void * out, MPI_Op op, int dtype)
195 {
196  int thread_num = omp_get_thread_num();
197  int num_threads = omp_get_num_threads();
198  {
199  #pragma omp barrier
200  }
201  #pragma omp master
202  {
203  switch (dtype) {
204  case _PARTEST_SION_INT32:
205  {
206  __thread_sync_pointer = malloc(sizeof(sion_int32)*num_threads);
207  }
208  break;
209  case _PARTEST_SION_INT64:
210  {
211  __thread_sync_pointer = malloc(sizeof(sion_int64)*num_threads);
212  }
213  break;
214  case _PARTEST_DOUBLE:
215  {
216  __thread_sync_pointer = malloc(sizeof(double)*num_threads);
217  }
218  break;
219  default:
220  {
221  __thread_sync_pointer = malloc(sizeof(sion_int64)*num_threads);
222  }
223  break;
224  }
225  }
226  {
227  #pragma omp barrier
228  }
229  switch (dtype) {
230  case _PARTEST_SION_INT32:
231  {
232  ((sion_int32 *)__thread_sync_pointer)[thread_num] = * (sion_int32*)syncdata;
233  }
234  break;
235  case _PARTEST_SION_INT64:
236  {
237  ((sion_int64 *)__thread_sync_pointer)[thread_num] = *((sion_int64*)syncdata);
238  }
239  break;
240  case _PARTEST_DOUBLE:
241  {
242  ((double *)__thread_sync_pointer)[thread_num] = *(double*)syncdata;
243  }
244  break;
245  default:
246  {
247  ((sion_int64 *)__thread_sync_pointer)[thread_num] = *(sion_int64*)syncdata;
248  }
249  break;
250  }
251  {
252  #pragma omp barrier
253  }
254 
255  #pragma omp master
256  {
257  int i;
258  switch (dtype) {
259  case _PARTEST_SION_INT32:
260  {
261  if(op == MPI_SUM){
262  *((sion_int32 *) out) = 0;
263  for(i=0;i<num_threads;i++){
264  *((sion_int32 *) out) += ((sion_int32 *)__thread_sync_pointer)[i];
265  }
266  }else if(op == MPI_MAX){
267  *((sion_int32 *) out) = ((sion_int32 *)__thread_sync_pointer)[0];
268  for(i=1;i<num_threads;i++){
269  if(((sion_int32 *)__thread_sync_pointer)[i] > *((sion_int32 *) out)) *((sion_int32 *) out) = ((sion_int32 *)__thread_sync_pointer)[i];
270  }
271  }
272  }
273  break;
274  case _PARTEST_SION_INT64:
275  {
276  if(op == MPI_SUM){
277  *((sion_int64 *) out) = 0;
278  for(i=0;i<num_threads;i++){
279  *((sion_int64 *) out) += ((sion_int64 *)__thread_sync_pointer)[i];
280  }
281  }else if(op == MPI_MAX){
282  *((sion_int64 *) out) = ((sion_int64 *)__thread_sync_pointer)[0];
283  for(i=1;i<num_threads;i++){
284  if(((sion_int64 *)__thread_sync_pointer)[i] > *((sion_int64 *) out)) *((sion_int64 *) out) = ((sion_int64 *)__thread_sync_pointer)[i];
285  }
286  }
287  }
288  break;
289  case _PARTEST_DOUBLE:
290  {
291  if(op == MPI_SUM){
292  *((double *) out) = 0;
293  for(i=0;i<num_threads;i++){
294  *((double *) out) += ((double *)__thread_sync_pointer)[i];
295  }
296  }else if(op == MPI_MAX){
297  *((double *) out) = ((double *)__thread_sync_pointer)[0];
298  for(i=1;i<num_threads;i++){
299  if(((double *)__thread_sync_pointer)[i] > *((double *) out)) *((double *) out) = ((double *)__thread_sync_pointer)[i];
300  }
301  }
302  }
303  break;
304  default:
305  {
306  if(op == MPI_SUM){
307  *((sion_int64 *) out) = 0;
308  for(i=0;i<num_threads;i++){
309  *((sion_int64 *) out) += ((sion_int64 *)__thread_sync_pointer)[i];
310  }
311  }else if(op == MPI_MAX){
312  *((sion_int64 *) out) = ((sion_int64 *)__thread_sync_pointer)[0];
313  for(i=1;i<num_threads;i++){
314  if(((sion_int64 *)__thread_sync_pointer)[i] > *((sion_int64 *) out)) *((sion_int64 *) out) = ((sion_int64 *)__thread_sync_pointer)[i];
315  }
316  }
317  }
318  break;
319  }
320  free(__thread_sync_pointer);
321  }
322 #pragma omp barrier
323 }
324 
325 int split_communicator(_test_communicators * communicators, int bluegene, int bluegene_np, int numfiles, int read_task_offset, int verbose);
326 
327 
328 int main(int argc, char **argv)
329 {
330  int rank, size, rc = 0;
331  char *localbuffer;
332  time_t t;
333  sion_int64 commwork_size64 = 1;
334 
335  /* communicators */
336  _test_communicators communicators;
337 
338  /* options */
339  _test_options options;
340 
341  MPI_Init(&argc, &argv);
342  MPI_Comm_size(MPI_COMM_WORLD, &size);
343  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
344  /* */ DPRINTFTS(rank, "after MPI_Init");
345 
346  /* srand ( time(NULL)*rank ); */
347 
348  /* printf("starting partest %02d of %02d\n", rank,size); */
349 
350  init_options(&options);
351 
352  if (rank == 0) {
353 #ifdef _SION_AIX
354  parse_options_std(argc, argv, &options);
355  if(rc==0) {
356  usage(argv[0]);
357  }
358 #else
359  rc=parse_options_long(argc, argv, &options);
360  if(rc==0) {
361  usage_long(argv[0]);
362  }
363 #endif
364  }
365  MPI_Bcast(&rc, 1, MPI_INT, 0, MPI_COMM_WORLD);
366  if(rc==0) {
367  MPI_Abort(MPI_COMM_WORLD, 1);
368  }
369 
370  distribute_options_mpi(&options);
371 
372 
373  /* adjust communicators */
374  communicators.all = MPI_COMM_WORLD;
375  MPI_Comm_size(MPI_COMM_WORLD, &communicators.all_size);
376  MPI_Comm_rank(MPI_COMM_WORLD, &communicators.all_rank);
377  split_communicator(&communicators, options.bluegene, options.bluegene_np, options.numfiles, options.read_task_offset, options.verbose);
378 
379  /* determine global and local size of data to be written and read */
380  sion_int64 num_threads = (sion_int64) omp_get_max_threads();
381  MPI_Allreduce(&num_threads, &commwork_size64, 1, SION_MPI_INT64, MPI_SUM, communicators.work);
382 
383  if (options.globalsize > 0) {
384  options.totalsize = (sion_int64) options.globalsize / commwork_size64;
385  }
386  else {
387  options.globalsize = options.totalsize * commwork_size64;
388  }
389 
390  if((options.totalsize>options.bufsize) || (options.read_task_offset>0) || (options.do_write==0)) {
391  options.suppress_checksum=1;
392  }
393 
394  if(options.fsblksize<0) options.fsblksize=-1;
395 
396  if ( (communicators.work_size>0) && (communicators.work_rank==0) ) {
397  time(&t);
398  fprintf(stderr, "------------------------------------------------------------------------------------------\n");
399  fprintf(stderr, "SION parallel file I/O benchmark 'ompi_partest': start at %s", ctime(&t));
400  fprintf(stderr, "partest Number of MPI tasks that will use the file tasks: running on %d tasks\n", size);
401  fprintf(stderr, "------------------------------------------------------------------------------------------\n");
402 #ifndef CHECKSUM
403  fprintf(stderr, "partest parameter: CHECKSUM DISABLED!\n\n");
404 #else
405  if(options.suppress_checksum) {
406  fprintf(stderr, "partest parameter: CHECKSUM not possible, DISABLED!\n\n");
407  }
408 #endif
409  fprintf(stderr, "partest parameter: (-f) datafile = %s\n", options.filename);
410  fprintf(stderr, "partest parameter: (-n) number of files = %d\n", options.numfiles);
411  fprintf(stderr, "partest parameter: (-F) random factor = %13.4f\n", options.factor);
412  fprintf(stderr, "partest parameter: (-X) remove files after test = %d\n", options.unlink_files);
413  fprintf(stderr, "partest parameter: (-b/-B) local buffer size / sion task = %15lld bytes %10.3f MB\n", options.bufsize, options.bufsize / (1.0 MB));
414  fprintf(stderr, "partest parameter: (-g/-G) global total data size = %15lld bytes %10.3f GB\n", options.globalsize, options.globalsize / (1024.0 MB));
415  fprintf(stderr, "partest parameter: (-s/-S) total data size / sion task = %15lld bytes %10.3f MB\n", options.totalsize, options.totalsize / (1.0 MB));
416  fprintf(stderr, "partest parameter: (-r/-R) sion chunk size = %15lld bytes %10.3f MB\n", options.chunksize, options.chunksize / (1.0 MB));
417  fprintf(stderr, "partest parameter: (-Q) fs block size = %15d bytes %10.3f MB\n", options.fsblksize, options.fsblksize / (1.0 MB));
418  if (options.type == 0)
419  fprintf(stderr, "partest parameter: (-T) test type = %d (sion OMPI, collective read)\n", options.type);
420  if (options.type == 1)
421  fprintf(stderr, "partest parameter: (-T) test type = %d (sion OMPI, independant read)\n", options.type);
422  if (options.type == 2)
423  fprintf(stderr, "partest parameter: (-T) test type = %d (sion OMP, collective read)\n", options.type);
424  if (options.type == 3)
425  fprintf(stderr, "partest parameter: (-T) test type = %d (sion OMP, independant read)\n", options.type);
426  fprintf(stderr, "partest parameter: (-j) serialize_blocknum = %d\n", options.serialize_blocknum);
427  fprintf(stderr, "partest parameter: (-Z) read task offset = %d\n", options.read_task_offset);
428  fprintf(stderr, "partest parameter: (-o) start offset bytes = %d\n", options.startoffset);
429  fprintf(stderr, "partest parameter: (-v) verbose = %d\n", options.verbose);
430  fprintf(stderr, "partest parameter: (-d) debug = %d\n", options.debug);
431  fprintf(stderr, "partest parameter: (-D) Debug = %d\n", options.Debug);
432  fprintf(stderr, "partest parameter: (-M) collective write = %d\n", options.collectivewrite);
433  fprintf(stderr, "partest parameter: (-m) collective read = %d\n", options.collectiveread);
434 
435 
436  fprintf(stderr, "partest parameter: (-P) Blue Gene, I/O nodes = %d\n", options.bluegene);
437  fprintf(stderr, "partest parameter: () Blue Gene: tasks/IO-node = %d\n", options.bluegene_np);
438  fprintf(stderr, "partest parameter: (-w) MPI-IO, IBM, Large Block IO = %d\n", options.mpiio_lb);
439  fprintf(stderr, "partest parameter: (-W) MPI-IO, IBM, IO bufsize = %d KB\n", options.mpiio_bs);
440  fprintf(stderr, "partest parameter: (-x) MPI-IO, IBM, sparse access = %d\n", options.mpiio_sa);
441  fprintf(stderr, "partest parameter: ( ) OpenMP number of threads = %d\n", omp_get_max_threads());
442  fprintf(stderr, "partest parameter: ( ) commwork_size64 = %lld\n", commwork_size64);
443  fprintf(stderr, "partest parameter: ( ) suppress_checksum = %d\n", options.suppress_checksum);
444  fprintf(stderr, "partest parameter: ( ) do_write = %d\n", options.do_write);
445  fprintf(stderr, "partest parameter: ( ) do_read = %d\n", options.do_read);
446  fprintf(stderr, "partest parameter: ( ) use_posix = %d\n", options.use_posix);
447 
448  }
449 
450  barrier_after_start(MPI_COMM_WORLD);
451 
452  if ( (communicators.work_size>0) && (communicators.work_rank==0) ) {
453  fprintf(stderr, "partest parameter: ( ) comm(all) = %d of %d\n", communicators.all_rank, communicators.all_size);
454  fprintf(stderr, "partest parameter: ( ) comm(work) = %d of %d\n", communicators.work_rank, communicators.work_size);
455  fprintf(stderr, "partest parameter: ( ) comm(local) = %d of %d\n", communicators.local_rank, communicators.local_size);
456  fprintf(stderr, "------------------------------------------------------------------------------------------\n");
457  }
458  #pragma omp parallel private(localbuffer,t)
459  {
460  barrier_after_start(MPI_COMM_WORLD);
461  char l_filename[MAXCHARLEN];
462  strcpy(l_filename,options.filename);
463 
464  _test_communicators local_communicators = communicators;
465  _test_options local_options = options;
466  /* */ DPRINTFTS(rank, "after pstart");
467  /* Init the local buffer that will be written to the file */
468  localbuffer = (char *) malloc(options.bufsize);
469 
470  srand(time(NULL)*local_communicators.work_rank*omp_get_thread_num());
471  /* for (i = 0; i < (options.bufsize / sizeof(int)); i++) */
472  /* localbuffer[i] = (char) rand() % 256; */
473 
474  /* memset (localbuffer, 'a'+rank%26, bufsize); */
475  memset (localbuffer, 'a'+rank%26, local_options.bufsize);
476  barrier_after_malloc(MPI_COMM_WORLD);
477  /* */ DPRINTFTS(rank, "after malloc");
478 
479  /* random factor handling */
480 
481  if(local_options.factor>0.0) {
482  if((local_options.collectivewrite) || (local_options.collectiveread)) {
483  if(local_options.bufsize<local_options.totalsize*(1+local_options.factor)) {
484  #pragma omp master
485  {
486  fprintf(stderr, "partest: ERROR deadlock possible if collective read/write and random factor used, and buffer is too small aborting\n");
487  MPI_Abort(MPI_COMM_WORLD,0);
488  }
489 #pragma omp barrier
490  exit(0);
491  }
492  }
493 
494  local_options.totalsize += ((sion_int64) (local_options.factor * (sion_int64) local_options.totalsize * (sion_int64) rand() / (sion_int64) RAND_MAX));
495  local_options.chunksize += ((sion_int64) (local_options.factor * (sion_int64) local_options.totalsize * (sion_int64) rand() / (sion_int64) RAND_MAX));
496  fprintf(stderr, "partest parameter: ( ) new totalsize[%4d,t%4d] = %lld\n", local_communicators.work_rank,omp_get_thread_num(),local_options.totalsize);
497  }
498 
499 
500 
501  /* */ DPRINTFTS(rank, "before scall2");
502  #pragma omp master
503  {
504  if ( (local_communicators.work_size>0) && (local_communicators.work_rank==0) ) {
505  fprintf(stderr, "partest parameter: ( ) new totalsize = %lld\n", local_options.totalsize);
506  }
507  }
508 #pragma omp barrier
509  barrier_after_malloc(MPI_COMM_WORLD);
510  if (local_options.type == 0) {
511  local_options.collectiveopenforread = 1;
512  test_paropen_multi_ompi(l_filename, localbuffer, &local_communicators, &local_options);
513 
514  }else if(local_options.type == 1) {
515  local_options.collectiveopenforread = 0;
516  test_paropen_multi_ompi(l_filename, localbuffer, &local_communicators, &local_options);
517  }else if(local_options.type == 2) {
518  local_options.collectiveopenforread = 1;
519  test_paropen_omp(l_filename, localbuffer, &local_communicators, &local_options);
520  }else if(local_options.type == 3) {
521  local_options.collectiveopenforread = 0;
522  test_paropen_omp(l_filename, localbuffer, &local_communicators, &local_options);
523  }
524 
525  /* */ DPRINTFTS(rank, "before MPI_Finalize");
526  barrier_after_malloc(MPI_COMM_WORLD);
527  #pragma omp master
528  {
529  if ( (local_communicators.work_size>0) && (local_communicators.work_rank==0) ) {
530  time(&t);
531  fprintf(stderr, "SION parallel file I/O benchmark 'ompi_partest': end at %s\n", ctime(&t));
532  }
533  }
534 #pragma omp barrier
535  }
536 
537  MPI_Finalize();
538  return (0);
539 }
540 
541 
542 int split_communicator(_test_communicators * communicators, int bluegene, int bluegene_np, int numfiles, int read_task_offset, int verbose)
543 {
544  int proc_per_file;
545 
546  communicators->work_size = communicators->work_rank = -2;
547  communicators->local_size = communicators->local_rank = -2;
548 
549 
550 
551 #ifdef _SION_BGP
552  if (bluegene) { /* order MPI-tasks by I/O-node */
553  _BGP_Personality_t personality;
554  MPI_Comm commSame, commDiff;
555  int sizeSame, sizeDiff;
556  int rankSame, rankDiff;
557  char location[128];
558  unsigned procid, x, y, z, t;
559  char cbuffer[MAXCHARLEN];
560 
561  /* get location information */
562  Kernel_GetPersonality(&personality, sizeof(personality));
563  BGP_Personality_getLocationString(&personality, location);
564  procid = Kernel_PhysicalProcessorID();
565  MPIX_rank2torus(communicators->all_rank, &x, &y, &z, &t);
566 
567  /* task of communicator working with different I/O-nodes */
568  MPIX_Pset_diff_comm_create(&commDiff);
569  MPI_Comm_size(commDiff, &sizeDiff);
570  MPI_Comm_rank(commDiff, &rankDiff);
571  communicators->ionode_number = rankDiff;
572 
573  /* communicator consists of all task working with the same I/O-node */
574  MPIX_Pset_same_comm_create(&commSame);
575  MPI_Comm_size(commSame, &sizeSame);
576  MPI_Comm_rank(commSame, &rankSame);
577 
578  /* if -p not specified all proc will write! */
579  if (bluegene_np == 0) {
580  bluegene_np = sizeSame;
581  }
582 
583  /* Get a communicator with all writing tasks => new global communicator */
584  MPI_Comm_split(communicators->all, (rankSame < bluegene_np), communicators->all_rank, &communicators->work);
585  MPI_Comm_size(communicators->work, &communicators->work_size);
586  MPI_Comm_rank(communicators->work, &communicators->work_rank);
587  if (rankSame >= bluegene_np) {
588  /* not working task */
589  communicators->work_size = communicators->work_rank = -1;
590  communicators->local_size = communicators->local_rank = -1;
591  }
592 
593  /* If only one file will be used => dont split further */
594  /* if numfile > 1 sion will generate correct local communicator */
595  if (numfiles >= 1) {
596  communicators->local = communicators->work;
597  }
598  else if(numfiles<0) {
599  if(numfiles==-1) {
600  /* Split the common communicator for each IO node to get a local comm with only the writing tasks for this IO Node */
601  MPI_Comm_split(commSame, (rankSame < bluegene_np), communicators->all_rank, &communicators->local);
602  } else {
603  /* local communicator contains only one task per IO-node */
604  /* bluegene_np has to be 512 */
605  communicators->local=commDiff;
606  }
607  }
608  MPI_Comm_size(communicators->local, &communicators->local_size);
609  MPI_Comm_rank(communicators->local, &communicators->local_rank);
610 
611  /* determine filenumber */
612  if (numfiles < 1) {
613  /* one file per I/O-node */
614  if(numfiles==-1) communicators->file_number = rankDiff;
615  else communicators->file_number = rankSame;
616  }
617  else {
618  communicators->file_number = -1;
619  }
620 
621  /* print log message about location, ... */
622  sprintf(cbuffer, "");
623  if (rankSame < bluegene_np) {
624  if (verbose) {
625  sprintf(cbuffer, "BGP[%05d] diff_comm: %4d of %4d same_comm: %5d of %5d file_comm: %5d of %5d %s phys_xyzt(%ud,%ud,%ud,%ud)\n",
626  communicators->all_rank, rankDiff + 1, sizeDiff, rankSame + 1, sizeSame, communicators->local_rank + 1, communicators->local_size,
627  location, x, y, z, t);
628  }
629  }
630  collective_print_gather(cbuffer, communicators->work);
631 
632  }
633 #endif
634 
635 #ifdef _SION_AIX
636  /* no communicator adjustment */
637 #endif
638 
639  /* initial set of communicators */
640  if (communicators->work_size == -2) {
641  /* all task do work */
642  communicators->work = communicators->all;
643  MPI_Comm_size(communicators->work, &communicators->work_size);
644  MPI_Comm_rank(communicators->work, &communicators->work_rank);
645  }
646  /* local communicators */
647  if (communicators->local_size == -2) {
648  if (numfiles == 1) {
649  communicators->local = communicators->work;
650  }
651  /* set a default distribution on files, will be computed again by sion_open */
652  if (numfiles < 1) {
653  numfiles = communicators->work_size / 2;
654  if (numfiles == 0)
655  numfiles = 1;
656  }
657  proc_per_file = communicators->work_size / numfiles;
658 
659  /* remaining tasks are write/read to/from the last file */
660  if (communicators->work_rank >= (numfiles * proc_per_file)) {
661  communicators->file_number = numfiles - 1;
662  }
663  else {
664  communicators->file_number = communicators->work_rank / proc_per_file;
665  }
666 
667  MPI_Comm_split(communicators->work, communicators->file_number, communicators->all_rank, &communicators->local);
668 
669  MPI_Comm_size(communicators->local, &communicators->local_size);
670  MPI_Comm_rank(communicators->local, &communicators->local_rank);
671 
672  communicators->ionode_number = communicators->file_number;
673 
674  }
675 
676 #ifdef _SION_LINUX
677  if (verbose) {
678  char location[256];
679  gethostname(location, 256);
680  char cbuffer[MAXCHARLEN];
681  sprintf(cbuffer, "LINUX[%03d] diff_comm: %4d of %4d same_comm: %4d of %4d file_comm: %4d of %4d %s\n",
682  communicators->all_rank, communicators->all_rank, communicators->all_size,
683  communicators->work_rank, communicators->work_size, communicators->local_rank, communicators->local_size, location);
684  collective_print_gather(cbuffer, communicators->all);
685  }
686 
687 #endif
688 
689 #ifdef _SION_AIX
690  if (verbose) {
691  char location[256];
692  gethostname(location, 256);
693  int sizeSame = 0, sizeDiff = 0;
694  char cbuffer[MAXCHARLEN];
695  sprintf(cbuffer, "AIX[%03d] diff_comm: %4d of %4d same_comm: %4d of %4d file_comm: %4d of %4d %s\n",
696  communicators->all_rank, communicators->all_rank, communicators->all_size,
697  communicators->work_rank, communicators->work_size, communicators->local_rank, communicators->local_size, location);
698  collective_print_gather(cbuffer, communicators->all);
699  }
700 
701 #endif
702 
703  /* shift working tasks */
704  if (communicators->work_size != -1) {
705  /* only if task in communicator work */
706  int newtasknr;
707  newtasknr=(communicators->work_rank+read_task_offset)%communicators->work_size;
708  MPI_Comm_split(communicators->work, 0, newtasknr, &communicators->workread);
709 
710  MPI_Comm_size(communicators->workread, &communicators->workread_size);
711  MPI_Comm_rank(communicators->workread, &communicators->workread_rank);
712  /* printf("WF: %d %d %% %d-> %d (%d %d)\n",
713  communicators->work_rank,read_task_offset,
714  communicators->work_size,newtasknr,
715  communicators->workread_rank,communicators->workread_size);*/
716 
717  } else {
718  /* this rtask will not be used for reading */
719  communicators->workread_size = communicators->workread_rank = -1;
720  communicators->local_size = communicators->local_rank = -1;
721  }
722 
723  return(1);
724 }
Sion Time Stamp Header.