6#include "gadgetconfig.h"
19#include "../data/allvars.h"
20#include "../data/dtypes.h"
21#include "../data/mymalloc.h"
22#include "../logs/logs.h"
23#include "../main/simulation.h"
24#include "../mpi_utils/mpi_utils.h"
25#include "../mpi_utils/shared_mem_handler.h"
26#include "../system/system.h"
60 BlockSize = (
size_t *)malloc(
MAXBLOCKS *
sizeof(
size_t));
61 Table = (
char **)malloc(
MAXBLOCKS *
sizeof(
void *));
62 MovableFlag = (
char *)malloc(
MAXBLOCKS *
sizeof(
char));
63 GenericFlag = (
char *)malloc(
MAXBLOCKS *
sizeof(
char));
64 BasePointers = (
char ***)malloc(
MAXBLOCKS *
sizeof(
void **));
69 LineNumber = (
int *)malloc(
MAXBLOCKS *
sizeof(
int));
71 HighMarkTabBufWithoutGeneric = (
char *)malloc((100 + 4 *
MAXCHARS) * (
MAXBLOCKS + 10));
78 size_t n = maxmemsize * ((size_t)1024 * 1024);
84 RestartFlag = restartflag;
86 MPI_Barrier(MPI_COMM_WORLD);
91 MPI_Info_create(&win_info);
92 MPI_Info_set(win_info,
"alloc_shared_noncontig",
"true");
106 MPI_Info_free(&win_info);
117 HighMarkBytesWithoutGeneric = 0;
118 OldGlobHighMarkMB = 0;
119 OldGlobHighMarkMBWithoutGeneric = 0;
133 sprintf(buf,
"%s%s",
All.
OutputDir,
"memory_ghostranks.txt");
135 if(!(FdMemory = fopen(buf, mode)))
136 Terminate(
"error in opening file '%s'\n", buf);
174 Mem.myfree(off_list);
179#ifndef ALLOCATE_SHARED_MEMORY_VIA_POSIX
180 return MPI_Win_allocate_shared(size, disp_unit, info, comm, baseptr, win);
183 char shmpath[NAME_MAX];
188 long long *size_list = (
long long *)malloc(
Shmem.
Island_NTask *
sizeof(
long long));
190 long long loc_bytes = size;
191 MPI_Allgather(&loc_bytes, 1, MPI_LONG_LONG, size_list, 1, MPI_LONG_LONG, comm);
193 long long tot_bytes = 0;
195 tot_bytes += size_list[i];
199 sprintf(shmpath,
"/G4-%lld.dat", (
long long)getpid());
201 int fd = shm_open(shmpath, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
203 Terminate(
"shm_open failed in creation");
205 if(ftruncate(fd, tot_bytes) == -1)
210 void *buf = mmap(NULL, tot_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
211 if(buf == MAP_FAILED)
214 Shmem.SharedMemBaseAddrRaw[0] = (
char *)buf;
217 MPI_Bcast(shmpath, NAME_MAX, MPI_BYTE, 0, comm);
221 int fd = shm_open(shmpath, O_RDWR, 0);
225 void *buf = mmap(NULL, tot_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
226 if(buf == MAP_FAILED)
229 Shmem.SharedMemBaseAddrRaw[0] = (
char *)buf;
233 Shmem.SharedMemBaseAddrRaw[i] = (
char *)
Shmem.SharedMemBaseAddrRaw[i - 1] + size_list[i - 1];
235 char **p = (
char **)baseptr;
252#ifndef ALLOCATE_SHARED_MEMORY_VIA_POSIX
253 return MPI_Win_shared_query(win, rank, size, disp_unit, baseptr);
256 char **p = (
char **)baseptr;
258 *p =
Shmem.SharedMemBaseAddrRaw[rank];
264void memory::report_memory_usage(
int rank,
char *tabbuf)
273 cc += sprintf(buf + cc,
"\nMEMORY: Largest Allocation = %g Mbyte | Largest Allocation Without Generic = %g Mbyte\n\n",
274 OldGlobHighMarkMB, OldGlobHighMarkMBWithoutGeneric);
276 cc += sprintf(buf + cc,
"%s", tabbuf);
281 fprintf(FdMemory,
"%s", buf);
293 if(thistask == 0 && rank > 0)
297 char *buf = (
char *)
mymalloc(
"buf", cc + 1);
301 fprintf(FdMemory,
"%s", buf);
324 local.rank = thistask;
326 MPI_Allreduce(&local, &global, 1, MPI_DOUBLE_INT, MPI_MAXLOC,
Communicator);
328 if(global.mem >= 1.05 * OldGlobHighMarkMB)
330 OldGlobHighMarkMB = global.mem;
335 local.rank = thistask;
337 MPI_Allreduce(&local, &global, 1, MPI_DOUBLE_INT, MPI_MAXLOC,
Communicator);
339 if(global.mem >= 1.05 * OldGlobHighMarkMBWithoutGeneric)
341 OldGlobHighMarkMBWithoutGeneric = global.mem;
346 report_memory_usage(global.rank, HighMarkTabBufWithoutGeneric);
349 report_memory_usage(global.rank, HighMarkTabBuf);
357 char *buf = (
char *)malloc(200 * (Nblocks + 10));
358 dump_memory_table_buffer(buf);
368int memory::dump_memory_table_buffer(
char *p)
371 size_t totBlocksize = 0;
376 sprintf(p + cc,
"-------------------------- Allocated Memory Blocks---- ( Step %8d )------------------\n",
All.
NumCurrentTiStep);
377 cc += sprintf(p + cc,
"Task Nr F Variable MBytes Cumulative Function|File|Linenumber\n");
378 cc += sprintf(p + cc,
"------------------------------------------------------------------------------------------\n");
379 for(
int i = 0; i < Nblocks; i++)
381 totBlocksize += BlockSize[i];
383 cc += sprintf(p + cc,
"%4d %5d %d %40s %10.4f %10.4f %s%s()|%s|%d\n", thistask, i, MovableFlag[i], VarName + i *
MAXCHARS,
387 cc += sprintf(p + cc,
"------------------------------------------------------------------------------------------\n");
403 int movable_flag,
int clear_flag,
char *callorigin)
412 Terminate(
"No blocks left in mymalloc_fullinfo() at %s()/%s/line %d. MAXBLOCKS=%d\n", func, file, line,
MAXBLOCKS);
418 "\nNot enough memory in mymalloc_fullinfo() to allocate %g MB for variable '%s' at %s()/%s/line %d (FreeBytes=%g MB).\n",
428 GenericFlag[Nblocks] = 1;
429 AllocatedBytesGeneric += n;
434 GenericFlag[Nblocks] = 0;
438 LineNumber[Nblocks] = line;
441 BlockSize[Nblocks] = n;
442 MovableFlag[Nblocks] = movable_flag;
443 BasePointers[Nblocks] = (
char **)ptr;
447 if(
AllocatedBytes - AllocatedBytesGeneric > HighMarkBytesWithoutGeneric)
449 HighMarkBytesWithoutGeneric =
AllocatedBytes - AllocatedBytesGeneric;
450 dump_memory_table_buffer(HighMarkTabBufWithoutGeneric);
456 dump_memory_table_buffer(HighMarkTabBuf);
460 memset(Table[Nblocks - 1], 0, n);
462 return Table[Nblocks - 1];
476 Terminate(
"no allocated blocks that could be returned");
478 return Table[Nblocks - 1];
493 Terminate(
"no allocated blocks that could be freed");
500 for(nr = Nblocks - 1; nr >= 0; nr--)
507 Terminate(
"Wrong call of myfree_movable() from %s()/%s/line %d - this block has not been allocated!\n", func, file, line);
513 for(
int i = nr + 1; i < Nblocks; i++)
514 if(MovableFlag[i] == 0)
519 "Wrong call of myfree_movable() from %s()/%s/line %d - behind block=%d there are subsequent non-movable allocated "
521 func, file, line, nr);
531 Terminate(
"Wrong call of myfree() at %s()/%s/line %d: not the last allocated block!\n", func, file, line);
536 AllocatedBytesGeneric -= BlockSize[nr];
542 *BasePointers[nr] = NULL;
546 ptrdiff_t offset = -BlockSize[nr];
549 for(
int i = nr + 1; i < Nblocks; i++)
550 length += BlockSize[i];
553 memmove(Table[nr + 1] + offset, Table[nr + 1], length);
555 for(
int i = nr + 1; i < Nblocks; i++)
558 *BasePointers[i] = *BasePointers[i] + offset;
561 for(
int i = nr + 1; i < Nblocks; i++)
563 Table[i - 1] = Table[i];
564 BasePointers[i - 1] = BasePointers[i];
565 BlockSize[i - 1] = BlockSize[i];
566 MovableFlag[i - 1] = MovableFlag[i];
567 GenericFlag[i - 1] = GenericFlag[i];
573 LineNumber[i - 1] = LineNumber[i];
600 Terminate(
"no allocated blocks that could be reallocated");
607 for(nr = Nblocks - 1; nr >= 0; nr--)
614 Terminate(
"Wrong call of myrealloc_movable() from %s()/%s/line %d - this block has not been allocated!\n", func, file, line);
620 for(
int i = nr + 1; i < Nblocks; i++)
621 if(MovableFlag[i] == 0)
625 "Wrong call of myrealloc_movable() from %s()/%s/line %d - behind block=%d there are subsequent non-movable "
626 "allocated blocks\n",
627 func, file, line, nr);
638 Terminate(
"Wrong call of myrealloc() at %s()/%s/line %d - not the last allocated block!\n", func, file, line);
651 Terminate(
"At %s()/%s/line %d: Not enough memory in myremalloc_movable(n=%g MB). previous=%g FreeBytes=%g MB\n", func, file,
655 ptrdiff_t offset = n - BlockSize[nr];
658 for(
int i = nr + 1; i < Nblocks; i++)
659 length += BlockSize[i];
662 memmove(Table[nr + 1] + offset, Table[nr + 1], length);
664 for(
int i = nr + 1; i < Nblocks; i++)
668 *BasePointers[i] = *BasePointers[i] + offset;
678 dump_memory_table_buffer(HighMarkTabBuf);
686 int errflag = 0, errflag_tot;
690 char name[MPI_MAX_PROCESSOR_NAME];
692 MPI_Get_processor_name(name, &len);
694 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,
702 char name[MPI_MAX_PROCESSOR_NAME];
704 MPI_Get_processor_name(name, &len);
707 "On node '%s', we have %d MPI ranks and at most %g MB of *shared* memory available. This is not enough space for MaxMemSize "
714 MPI_Allreduce(&errflag, &errflag_tot, 1, MPI_INT, MPI_MAX,
Communicator);
717 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.
int myMPI_Win_allocate_shared(MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm, void *baseptr, MPI_Win *win)
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)
int myMPI_Win_shared_query(MPI_Win win, int rank, MPI_Aint *size, int *disp_unit, void *baseptr)
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)