10 #define _XOPEN_SOURCE 700 
   15 #include "sion_common.h" 
   16 #include "sion_const.h" 
   17 #include "sion_debug.h" 
   18 #include "sion_error_handler.h" 
   19 #include "sion_filedesc.h" 
   20 #include "sion_internal_collstat.h" 
   21 #include "sion_internal_startptr.h" 
   22 #include "sion_metadata.h" 
   26 #define DFUNCTION "_sion_calculate_set_alignment" 
   27 int64_t _sion_calculate_set_alignment(_sion_filedesc *sion_filedesc, 
int t)
 
   29   int64_t lsize = SION_SIZE_NOT_VALID;
 
   36   if (sion_filedesc->fileversion <= 3) {
 
   37     lsize = (sion_filedesc->all_chunksizes[t] % sion_filedesc->fsblksize == 0)
 
   38       ? sion_filedesc->all_chunksizes[t]
 
   39       : ((sion_filedesc->all_chunksizes[t] / sion_filedesc->fsblksize) + 1) * sion_filedesc->fsblksize;
 
   40     DPRINTFP((2048, DFUNCTION, _SION_DEFAULT_RANK, 
"old file version (<=3) task=%d lsize=%ld\n", t, (
long)lsize));
 
   42     if (sion_filedesc->mode == SION_FILEMODE_WRITE) {
 
   43       lsize = (sion_filedesc->all_chunksizes[t] % sion_filedesc->fsblksize == 0)
 
   44         ? sion_filedesc->all_chunksizes[t]
 
   45         : ((sion_filedesc->all_chunksizes[t] / sion_filedesc->fsblksize) + 1) * sion_filedesc->fsblksize;
 
   47       sion_filedesc->all_chunksizes[t] = lsize;
 
   49         (2048, DFUNCTION, _SION_DEFAULT_RANK, 
"new file version (>3) task=%d lsize=%ld, WRITE chunksize set\n", t, (
long)lsize));
 
   51       lsize = sion_filedesc->all_chunksizes[t];
 
   52       DPRINTFP((2048, DFUNCTION, _SION_DEFAULT_RANK, 
"new file version (>3) task=%d lsize=%ld, READ no align\n", t, (
long)lsize));
 
   60 #define DFUNCTION "_sion_get_size_metadatablock1" 
   61 int _sion_get_size_metadatablock1(_sion_filedesc *sion_filedesc, int32_t mapping_size)
 
   68   firstsize = strlen(SION_ID) + 8 * 
sizeof(int32_t) + 2 * sion_filedesc->ntasks * 
sizeof(int64_t) 
 
   69     + 2 * 
sizeof(int64_t); 
 
   70   if (sion_filedesc->fileversion <= 5) {
 
   71     firstsize += SION_FILENAME_LENGTH; 
 
   73     firstsize += sion_filedesc->ntasks * 
sizeof(int64_t) 
 
   74       + (mapping_size * 2 + 1) * 
sizeof(int32_t); 
 
   82 #define DFUNCTION "_sion_calculate_startpointers" 
   83 int _sion_calculate_startpointers(_sion_filedesc *sion_filedesc, int32_t mapping_size)
 
   85   int rc = SION_SUCCESS;
 
   89   DPRINTFP((2, DFUNCTION, _SION_DEFAULT_RANK, 
"enter ntasks=%d fsblksize=%d chunksizes[0]=%lld\n", sion_filedesc->ntasks,
 
   90     sion_filedesc->fsblksize, sion_filedesc->all_chunksizes[0]));
 
   92   firstsize = _sion_get_size_metadatablock1(sion_filedesc, mapping_size);
 
   94 #ifdef WFLARGEMETABLOCK 
   95   if (firstsize < 4 * 1024 * 1024) {
 
   96     firstsize = 4 * 1024 * 1024;
 
  100   DPRINTFP((2, DFUNCTION, _SION_DEFAULT_RANK, 
"firstsize=%d\n", firstsize));
 
  102   sion_filedesc->all_startpointers[0] = (firstsize % sion_filedesc->fsblksize == 0)
 
  104     : ((firstsize / sion_filedesc->fsblksize) + 1) * sion_filedesc->fsblksize;
 
  107   DPRINTFP((2048, DFUNCTION, _SION_DEFAULT_RANK, 
"  startpointers[%2d]=%10lld (%10.4fMB) chunksizes[%2d]=%8lld\n", i,
 
  108     sion_filedesc->all_startpointers[i], sion_filedesc->all_startpointers[i] / 1024.0 / 1024.0, i,
 
  109     sion_filedesc->all_chunksizes[i]));
 
  110   sion_filedesc->globalskip = 0;
 
  111   for (i = 1; i < sion_filedesc->ntasks; i++) {
 
  112     lsize = _sion_calculate_set_alignment(sion_filedesc, i - 1);
 
  114     sion_filedesc->globalskip += lsize;
 
  115     sion_filedesc->all_startpointers[i] = sion_filedesc->all_startpointers[i - 1] + lsize;
 
  117     DPRINTFP((2048, DFUNCTION, _SION_DEFAULT_RANK,
 
  118       "  startpointers[%2d]=%10lld (%10.4fMB) chunksizes[%2d]=%8lld chunksizes[%2d]=%8lld\n", i,
 
  119       sion_filedesc->all_startpointers[i], sion_filedesc->all_startpointers[i] / 1024.0 / 1024.0, i,
 
  120       sion_filedesc->all_chunksizes[i], i - 1, sion_filedesc->all_chunksizes[i - 1]));
 
  123   lsize = _sion_calculate_set_alignment(sion_filedesc, sion_filedesc->ntasks - 1);
 
  124   sion_filedesc->globalskip += lsize;
 
  126   DPRINTFP((2, DFUNCTION, _SION_DEFAULT_RANK, 
"leave globalskip is %lld\n", sion_filedesc->globalskip));
 
  131 #define DFUNCTION "_sion_calculate_num_collector" 
  132 int _sion_calculate_num_collector(_sion_filedesc *sion_filedesc, _sion_collstat *collstat, 
int *num_collectors)
 
  134   int rc = SION_SUCCESS;
 
  135   int max_num_collectors;
 
  138   max_num_collectors = (int)(collstat->gsize / sion_filedesc->fsblksize);
 
  139   if (collstat->gsize % sion_filedesc->fsblksize > 0) {
 
  140     max_num_collectors++;
 
  142   DPRINTFP((2, DFUNCTION, _SION_DEFAULT_RANK, 
"max_num_collectors=%d\n", max_num_collectors));
 
  144   if (sion_filedesc->collsize > 0) {
 
  146     *num_collectors = (int)(sion_filedesc->ntasks / sion_filedesc->collsize);
 
  147     if (sion_filedesc->ntasks % sion_filedesc->collsize > 0) {
 
  152     if (*num_collectors > max_num_collectors) {
 
  153       *num_collectors = max_num_collectors;
 
  156     DPRINTFP((32, DFUNCTION, _SION_DEFAULT_RANK, 
"user given collsize %d -> set num_collectors to %d\n", sion_filedesc->collsize,
 
  160     *num_collectors = max_num_collectors;
 
  163     if (*num_collectors > sion_filedesc->ntasks) {
 
  164       *num_collectors = sion_filedesc->ntasks;
 
  168     if ((sion_filedesc->ntasks >= 512) && (*num_collectors > 32)) {
 
  169       *num_collectors = 32;
 
  170     } 
else if ((sion_filedesc->ntasks >= 256) && (*num_collectors > 16)) {
 
  171       *num_collectors = 16;
 
  172     } 
else if ((sion_filedesc->ntasks >= 128) && (*num_collectors > 8)) {
 
  174     } 
else if ((sion_filedesc->ntasks >= 64) && (*num_collectors > 8)) {
 
  176     } 
else if ((sion_filedesc->ntasks >= 32) && (*num_collectors > 8)) {
 
  178     } 
else if ((sion_filedesc->ntasks >= 16) && (*num_collectors > 4)) {
 
  184     DPRINTFP((2, DFUNCTION, _SION_DEFAULT_RANK, 
"SIONlib heuristic collsize=%d num_collectors=%d\n", sion_filedesc->collsize,
 
  189   collstat->avg_data_per_collector =
 
  190     ((int64_t)(collstat->gsize / *num_collectors) / sion_filedesc->fsblksize) * sion_filedesc->fsblksize;
 
  192   if ((collstat->gsize / *num_collectors) % sion_filedesc->fsblksize > 0) {
 
  193     collstat->avg_data_per_collector += sion_filedesc->fsblksize;
 
  195   DPRINTFP((32, DFUNCTION, _SION_DEFAULT_RANK, 
"avg_data_per_collectors=%ld\n", (
long)collstat->avg_data_per_collector));
 
  201 #define DFUNCTION "_sion_calculate_startpointers_collective" 
  202 int _sion_calculate_startpointers_collective(_sion_filedesc *sion_filedesc, int32_t mapping_size)
 
  204   int rc = SION_SUCCESS;
 
  205   int i, firstsize, num_collectors, numsender, lastcoll, s;
 
  207   int64_t currentsize, aligned_size, startpointer;
 
  208   _sion_collstat *collstat;
 
  210   DPRINTFP((2, DFUNCTION, _SION_DEFAULT_RANK, 
"enter ntasks=%d fsblksize=%d chunksizes[0]=%lld\n", sion_filedesc->ntasks,
 
  211     sion_filedesc->fsblksize, sion_filedesc->all_chunksizes[0]));
 
  213   if (sion_filedesc->fileversion <= 3) {
 
  214     return _sion_errorprint(SION_NOT_SUCCESS, _SION_ERROR_RETURN,
 
  215       "_sion_calculate_startpointers_collective: files with old sionlib file format (<3) can not be read by collective calls, " 
  216       "please use standard read calls, aborting ...\n");
 
  220   collstat = _sion_create_and_init_collstat(sion_filedesc);
 
  223   collstat->firstsize = firstsize = _sion_get_size_metadatablock1(sion_filedesc, mapping_size);
 
  224   _sion_calculate_num_collector(sion_filedesc, collstat, &num_collectors);
 
  225   collstat->req_num_collectors = num_collectors;
 
  227   DPRINTFP((2, DFUNCTION, _SION_DEFAULT_RANK, 
"firstsize=%d collsize=%d num_collectors=%d\n", firstsize, sion_filedesc->collsize,
 
  232   currentsize = sion_filedesc->all_chunksizes[0];
 
  235   for (i = 1; i < sion_filedesc->ntasks; i++) {
 
  236     if ((currentsize + sion_filedesc->all_chunksizes[i] <= collstat->avg_data_per_collector)
 
  237       || (sion_filedesc->all_coll_capability[i] == SION_CAPABILITY_ONLY_SENDER)) {
 
  239       currentsize += sion_filedesc->all_chunksizes[i];
 
  244       for (s = lastcoll; s < i; s++) {
 
  245         sion_filedesc->all_coll_collector[s] = lastcoll;
 
  246         sion_filedesc->all_coll_collsize[s] = numsender;
 
  250       if (sion_filedesc->mode == SION_FILEMODE_WRITE) {
 
  251         aligned_size = ((int64_t)currentsize / sion_filedesc->fsblksize) * sion_filedesc->fsblksize;
 
  252         if (currentsize % sion_filedesc->fsblksize > 0) {
 
  253           aligned_size += sion_filedesc->fsblksize;
 
  256         DPRINTFP((128, DFUNCTION, _SION_DEFAULT_RANK, 
"  align chunksizes[%2d]=%8lld + %lld\n", i - 1,
 
  257           sion_filedesc->all_chunksizes[i - 1], aligned_size - currentsize));
 
  259         sion_filedesc->all_chunksizes[i - 1] += aligned_size - currentsize;
 
  265       currentsize = sion_filedesc->all_chunksizes[i];
 
  270   if (sion_filedesc->mode == SION_FILEMODE_WRITE) {
 
  271     aligned_size = ((int64_t)currentsize / sion_filedesc->fsblksize) * sion_filedesc->fsblksize;
 
  272     if (currentsize % sion_filedesc->fsblksize > 0) {
 
  273       aligned_size += sion_filedesc->fsblksize;
 
  275     DPRINTFP((128, DFUNCTION, _SION_DEFAULT_RANK, 
"  align chunksizes[%2d]=%8lld + %lld\n", sion_filedesc->ntasks - 1,
 
  276       sion_filedesc->all_chunksizes[sion_filedesc->ntasks - 1], aligned_size - currentsize));
 
  277     sion_filedesc->all_chunksizes[sion_filedesc->ntasks - 1] += aligned_size - currentsize;
 
  281   for (s = lastcoll; s < sion_filedesc->ntasks; s++) {
 
  282     sion_filedesc->all_coll_collector[s] = lastcoll;
 
  283     sion_filedesc->all_coll_collsize[s] = numsender;
 
  290   startpointer = (firstsize % sion_filedesc->fsblksize == 0)
 
  292     : ((firstsize / sion_filedesc->fsblksize) + 1) * sion_filedesc->fsblksize;
 
  293   sion_filedesc->globalskip = 0;
 
  295   for (i = 0; i < sion_filedesc->ntasks; i++) {
 
  296     sion_filedesc->all_startpointers[i] = startpointer;
 
  297     startpointer += sion_filedesc->all_chunksizes[i];
 
  298     sion_filedesc->globalskip += sion_filedesc->all_chunksizes[i];
 
  302   if (sion_filedesc->colldebug >= 1) {
 
  303     _sion_update_collstat(collstat, sion_filedesc);
 
  304     _sion_print_collstat(collstat, sion_filedesc);
 
  307   _sion_debugprint_collstat(collstat, sion_filedesc);
 
  309   _sion_destroy_collstat(collstat);
 
  311   DPRINTFP((2, DFUNCTION, _SION_DEFAULT_RANK, 
"leave globalskip is %lld\n", sion_filedesc->globalskip));
 
  316 #define DFUNCTION "_sion_calculate_startpointers_collective_merge" 
  317 int _sion_calculate_startpointers_collective_merge(_sion_filedesc *sion_filedesc, int32_t mapping_size)
 
  319   int rc = SION_SUCCESS;
 
  320   int i, firstsize, num_collectors, numsender, lastcoll, s;
 
  322   int64_t currentsize, newsize, aligned_size, startpointer;
 
  323   _sion_collstat *collstat;
 
  325   DPRINTFP((2, DFUNCTION, _SION_DEFAULT_RANK, 
"enter ntasks=%d fsblksize=%d chunksizes[0]=%lld\n", sion_filedesc->ntasks,
 
  326     sion_filedesc->fsblksize, sion_filedesc->all_chunksizes[0]));
 
  328   if (sion_filedesc->fileversion <= 3) {
 
  329     return _sion_errorprint(SION_NOT_SUCCESS, _SION_ERROR_RETURN,
 
  330       "_sion_calculate_startpointers_collective: files with old sionlib file format (<3) can not be read by collective calls, " 
  331       "please use standard read calls, aborting ...\n");
 
  335   collstat = _sion_create_and_init_collstat(sion_filedesc);
 
  338   collstat->firstsize = firstsize = _sion_get_size_metadatablock1(sion_filedesc, mapping_size);
 
  339   _sion_calculate_num_collector(sion_filedesc, collstat, &num_collectors);
 
  340   collstat->req_num_collectors = num_collectors;
 
  342   DPRINTFP((2, DFUNCTION, _SION_DEFAULT_RANK, 
"firstsize=%d collsize=%d num_collectors=%d\n", firstsize, sion_filedesc->collsize,
 
  347   currentsize = sion_filedesc->all_chunksizes[0];
 
  349   DPRINTFP((128, DFUNCTION, _SION_DEFAULT_RANK, 
"  currentsize=%lld chunksizes[%2d]=%8lld\n", currentsize, 0,
 
  350     sion_filedesc->all_chunksizes[0]));
 
  353   for (i = 1; i < sion_filedesc->ntasks; i++) {
 
  354     if ((currentsize + sion_filedesc->all_chunksizes[i] <= collstat->avg_data_per_collector)
 
  355       || (sion_filedesc->all_coll_capability[i] == SION_CAPABILITY_ONLY_SENDER)) {
 
  357       currentsize += sion_filedesc->all_chunksizes[i];
 
  359       DPRINTFP((128, DFUNCTION, _SION_DEFAULT_RANK, 
"  currentsize=%lld chunksizes[%2d]=%8lld\n", currentsize, i,
 
  360         sion_filedesc->all_chunksizes[i]));
 
  364       if (sion_filedesc->mode == SION_FILEMODE_WRITE) {
 
  365         newsize = currentsize;
 
  368         aligned_size = ((int64_t)newsize / sion_filedesc->fsblksize) * sion_filedesc->fsblksize;
 
  369         if (newsize % sion_filedesc->fsblksize > 0) {
 
  370           aligned_size += sion_filedesc->fsblksize;
 
  373         DPRINTFP((128, DFUNCTION, _SION_DEFAULT_RANK, 
"  resize chunksizes[%2d]=%8lld + %lld\n", lastcoll,
 
  374           sion_filedesc->all_chunksizes[lastcoll], aligned_size - sion_filedesc->all_chunksizes[lastcoll]));
 
  375         sion_filedesc->all_chunksizes[lastcoll] = aligned_size;
 
  377         for (s = lastcoll + 1; s < i; s++) {
 
  381           _sion_calculate_set_alignment(sion_filedesc, s);
 
  389       for (s = lastcoll; s < i; s++) {
 
  390         sion_filedesc->all_coll_collector[s] = lastcoll;
 
  391         sion_filedesc->all_coll_collsize[s] = numsender;
 
  397       currentsize = sion_filedesc->all_chunksizes[i];
 
  402   if (sion_filedesc->mode == SION_FILEMODE_WRITE) {
 
  403     newsize = currentsize;
 
  406     aligned_size = ((int64_t)newsize / sion_filedesc->fsblksize) * sion_filedesc->fsblksize;
 
  407     if (newsize % sion_filedesc->fsblksize > 0) {
 
  408       aligned_size += sion_filedesc->fsblksize;
 
  411     DPRINTFP((128, DFUNCTION, _SION_DEFAULT_RANK, 
"  resize chunksizes[%2d]=%8lld + %lld\n", lastcoll,
 
  412       sion_filedesc->all_chunksizes[lastcoll], aligned_size - sion_filedesc->all_chunksizes[lastcoll]));
 
  413     sion_filedesc->all_chunksizes[lastcoll] = aligned_size;
 
  416     for (s = lastcoll + 1; s < i; s++) {
 
  420       _sion_calculate_set_alignment(sion_filedesc, s);
 
  428   for (s = lastcoll; s < sion_filedesc->ntasks; s++) {
 
  429     sion_filedesc->all_coll_collector[s] = lastcoll;
 
  430     sion_filedesc->all_coll_collsize[s] = numsender;
 
  437   startpointer = (firstsize % sion_filedesc->fsblksize == 0)
 
  439     : ((firstsize / sion_filedesc->fsblksize) + 1) * sion_filedesc->fsblksize;
 
  440   sion_filedesc->globalskip = 0;
 
  442   for (i = 0; i < sion_filedesc->ntasks; i++) {
 
  443     sion_filedesc->all_startpointers[i] = startpointer;
 
  444     startpointer += sion_filedesc->all_chunksizes[i];
 
  445     sion_filedesc->globalskip += sion_filedesc->all_chunksizes[i];
 
  449   if (sion_filedesc->colldebug >= 1) {
 
  450     _sion_update_collstat(collstat, sion_filedesc);
 
  451     _sion_print_collstat(collstat, sion_filedesc);
 
  454   _sion_debugprint_collstat(collstat, sion_filedesc);
 
  456   _sion_destroy_collstat(collstat);
 
  458   DPRINTFP((2, DFUNCTION, _SION_DEFAULT_RANK, 
"leave globalskip is %lld\n", sion_filedesc->globalskip));