6 #include "gadgetconfig.h"
15 #include "../data/allvars.h"
16 #include "../data/dtypes.h"
17 #include "../data/mymalloc.h"
18 #include "../logs/logs.h"
19 #include "../main/simulation.h"
20 #include "../mpi_utils/mpi_utils.h"
21 #include "../mpi_utils/shared_mem_handler.h"
22 #include "../system/system.h"
56 BlockSize = (
size_t *)malloc(
MAXBLOCKS *
sizeof(
size_t));
57 Table = (
char **)malloc(
MAXBLOCKS *
sizeof(
void *));
58 MovableFlag = (
char *)malloc(
MAXBLOCKS *
sizeof(
char));
59 GenericFlag = (
char *)malloc(
MAXBLOCKS *
sizeof(
char));
60 BasePointers = (
char ***)malloc(
MAXBLOCKS *
sizeof(
void **));
65 LineNumber = (
int *)malloc(
MAXBLOCKS *
sizeof(
int));
67 HighMarkTabBufWithoutGeneric = (
char *)malloc((100 + 4 *
MAXCHARS) * (
MAXBLOCKS + 10));
74 size_t n = maxmemsize * ((size_t)1024 * 1024);
80 RestartFlag = restartflag;
82 MPI_Barrier(MPI_COMM_WORLD);
87 MPI_Info_create(&win_info);
88 MPI_Info_set(win_info,
"alloc_shared_noncontig",
"true");
102 MPI_Info_free(&win_info);
113 HighMarkBytesWithoutGeneric = 0;
114 OldGlobHighMarkMB = 0;
115 OldGlobHighMarkMBWithoutGeneric = 0;
129 sprintf(buf,
"%s%s",
All.
OutputDir,
"memory_ghostranks.txt");
131 if(!(FdMemory = fopen(buf, mode)))
132 Terminate(
"error in opening file '%s'\n", buf);
170 Mem.myfree(off_list);
173 void memory::report_memory_usage(
int rank,
char *tabbuf)
182 cc += sprintf(buf + cc,
"\nMEMORY: Largest Allocation = %g Mbyte | Largest Allocation Without Generic = %g Mbyte\n\n",
183 OldGlobHighMarkMB, OldGlobHighMarkMBWithoutGeneric);
185 cc += sprintf(buf + cc,
"%s", tabbuf);
190 fprintf(FdMemory,
"%s", buf);
202 if(thistask == 0 && rank > 0)
206 char *buf = (
char *)
mymalloc(
"buf", cc + 1);
210 fprintf(FdMemory,
"%s", buf);
233 local.rank = thistask;
235 MPI_Allreduce(&local, &global, 1, MPI_DOUBLE_INT, MPI_MAXLOC,
Communicator);
237 if(global.mem >= 1.05 * OldGlobHighMarkMB)
239 OldGlobHighMarkMB = global.mem;
244 local.rank = thistask;
246 MPI_Allreduce(&local, &global, 1, MPI_DOUBLE_INT, MPI_MAXLOC,
Communicator);
248 if(global.mem >= 1.05 * OldGlobHighMarkMBWithoutGeneric)
250 OldGlobHighMarkMBWithoutGeneric = global.mem;
255 report_memory_usage(global.rank, HighMarkTabBufWithoutGeneric);
258 report_memory_usage(global.rank, HighMarkTabBuf);
266 char *buf = (
char *)malloc(200 * (Nblocks + 10));
267 dump_memory_table_buffer(buf);
277 int memory::dump_memory_table_buffer(
char *p)
280 size_t totBlocksize = 0;
285 sprintf(p + cc,
"-------------------------- Allocated Memory Blocks---- ( Step %8d )------------------\n",
All.
NumCurrentTiStep);
286 cc += sprintf(p + cc,
"Task Nr F Variable MBytes Cumulative Function|File|Linenumber\n");
287 cc += sprintf(p + cc,
"------------------------------------------------------------------------------------------\n");
288 for(
int i = 0; i < Nblocks; i++)
290 totBlocksize += BlockSize[i];
292 cc += sprintf(p + cc,
"%4d %5d %d %40s %10.4f %10.4f %s%s()|%s|%d\n", thistask, i, MovableFlag[i], VarName + i *
MAXCHARS,
296 cc += sprintf(p + cc,
"------------------------------------------------------------------------------------------\n");
312 int movable_flag,
int clear_flag,
char *callorigin)
321 Terminate(
"No blocks left in mymalloc_fullinfo() at %s()/%s/line %d. MAXBLOCKS=%d\n", func, file, line,
MAXBLOCKS);
327 "\nNot enough memory in mymalloc_fullinfo() to allocate %g MB for variable '%s' at %s()/%s/line %d (FreeBytes=%g MB).\n",
337 GenericFlag[Nblocks] = 1;
338 AllocatedBytesGeneric += n;
343 GenericFlag[Nblocks] = 0;
347 LineNumber[Nblocks] = line;
350 BlockSize[Nblocks] = n;
351 MovableFlag[Nblocks] = movable_flag;
352 BasePointers[Nblocks] = (
char **)ptr;
356 if(
AllocatedBytes - AllocatedBytesGeneric > HighMarkBytesWithoutGeneric)
358 HighMarkBytesWithoutGeneric =
AllocatedBytes - AllocatedBytesGeneric;
359 dump_memory_table_buffer(HighMarkTabBufWithoutGeneric);
365 dump_memory_table_buffer(HighMarkTabBuf);
369 memset(Table[Nblocks - 1], 0, n);
371 return Table[Nblocks - 1];
385 Terminate(
"no allocated blocks that could be returned");
387 return Table[Nblocks - 1];
402 Terminate(
"no allocated blocks that could be freed");
409 for(nr = Nblocks - 1; nr >= 0; nr--)
416 Terminate(
"Wrong call of myfree_movable() from %s()/%s/line %d - this block has not been allocated!\n", func, file, line);
422 for(
int i = nr + 1; i < Nblocks; i++)
423 if(MovableFlag[i] == 0)
428 "Wrong call of myfree_movable() from %s()/%s/line %d - behind block=%d there are subsequent non-movable allocated "
430 func, file, line, nr);
440 Terminate(
"Wrong call of myfree() at %s()/%s/line %d: not the last allocated block!\n", func, file, line);
445 AllocatedBytesGeneric -= BlockSize[nr];
451 *BasePointers[nr] = NULL;
455 ptrdiff_t offset = -BlockSize[nr];
458 for(
int i = nr + 1; i < Nblocks; i++)
459 length += BlockSize[i];
462 memmove(Table[nr + 1] + offset, Table[nr + 1], length);
464 for(
int i = nr + 1; i < Nblocks; i++)
467 *BasePointers[i] = *BasePointers[i] + offset;
470 for(
int i = nr + 1; i < Nblocks; i++)
472 Table[i - 1] = Table[i];
473 BasePointers[i - 1] = BasePointers[i];
474 BlockSize[i - 1] = BlockSize[i];
475 MovableFlag[i - 1] = MovableFlag[i];
476 GenericFlag[i - 1] = GenericFlag[i];
482 LineNumber[i - 1] = LineNumber[i];
509 Terminate(
"no allocated blocks that could be reallocated");
516 for(nr = Nblocks - 1; nr >= 0; nr--)
523 Terminate(
"Wrong call of myrealloc_movable() from %s()/%s/line %d - this block has not been allocated!\n", func, file, line);
529 for(
int i = nr + 1; i < Nblocks; i++)
530 if(MovableFlag[i] == 0)
534 "Wrong call of myrealloc_movable() from %s()/%s/line %d - behind block=%d there are subsequent non-movable "
535 "allocated blocks\n",
536 func, file, line, nr);
547 Terminate(
"Wrong call of myrealloc() at %s()/%s/line %d - not the last allocated block!\n", func, file, line);
560 Terminate(
"At %s()/%s/line %d: Not enough memory in myremalloc_movable(n=%g MB). previous=%g FreeBytes=%g MB\n", func, file,
564 ptrdiff_t offset = n - BlockSize[nr];
567 for(
int i = nr + 1; i < Nblocks; i++)
568 length += BlockSize[i];
571 memmove(Table[nr + 1] + offset, Table[nr + 1], length);
573 for(
int i = nr + 1; i < Nblocks; i++)
577 *BasePointers[i] = *BasePointers[i] + offset;
587 dump_memory_table_buffer(HighMarkTabBuf);
595 int errflag = 0, errflag_tot;
599 char name[MPI_MAX_PROCESSOR_NAME];
601 MPI_Get_processor_name(name, &len);
603 printf(
"On node '%s', we have %d MPI ranks and at most %g MB available. This is not enough space for MaxMemSize = %g MB\n", name,
611 char name[MPI_MAX_PROCESSOR_NAME];
613 MPI_Get_processor_name(name, &len);
616 "On node '%s', we have %d MPI ranks and at most %g MB of *shared* memory available. This is not enough space for MaxMemSize "
623 MPI_Allreduce(&errflag, &errflag_tot, 1, MPI_INT, MPI_MAX,
Communicator);
626 Terminate(
"At least one node has insufficient memory");
global_data_all_processes All
double timediff(double t0, double t1)
void * myrealloc_movable_fullinfo(void *p, size_t n, const char *func, const char *file, int line, int movable_flag)
Reallocate an existing movable memory block.
void * mymalloc_movable_fullinfo(void *ptr, const char *varname, size_t n, const char *func, const char *file, int line, int movable_flag, int clear_flag, char *originflag)
Allocate a movable memory block and store the relative information.
void myfree_movable_fullinfo(void *p, const char *func, const char *file, int line, int movable_flag)
Deallocate a movable memory block.
void * myfree_query_last_block(void)
void dump_memory_table(void)
Dump the buffer where the memory information is stored to the standard output.
void report_detailed_memory_usage_of_largest_task(void)
Output memory usage for the task with the greatest amount of memory allocated.
void check_maxmemsize_setting(int maxmemsize)
void mymalloc_init(int maxmemsize, enum restart_options restartflag)
Initialize memory manager.
size_t roundup_to_multiple_of_cacheline_size(size_t n)
void mpi_printf(const char *fmt,...)
long long SharedMemoryOnNode
int * GetNodeIDForSimulCommRank
void ** SharedMemBaseAddr
int * GetShmRankForSimulCommRank
int Island_Smallest_WorldTask
int * GetGhostRankForSimulCommRank
#define MAXLEN_PATH_EXTRA
enum restart_options RestartFlag
char OutputDir[MAXLEN_PATH]
void myflush(FILE *fstream)