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));