8#include "../mpiwrap/cp_mpi.h"
20#if defined(__parallel)
24#define OFFLOAD_MEMPOOL_PRINT(FN, MSG, OUTPUT_UNIT) \
25 ((FN)(MSG, (int)strlen(MSG), OUTPUT_UNIT))
26#define OFFLOAD_MEMPOOL_OMPALLOC 1
63static inline uint64_t
imax(uint64_t x, uint64_t y) {
return (x > y ? x : y); }
78 offload_activate_chosen_device();
79 offloadMalloc(&memory, size);
81 offload_activate_chosen_device();
82 offloadMallocHost(&memory, size);
84#elif OFFLOAD_MEMPOOL_OMPALLOC && (201811 <= _OPENMP)
85 memory = omp_alloc(size, omp_null_allocator);
86#elif defined(__parallel) && !OFFLOAD_MEMPOOL_OMPALLOC
87 if (MPI_SUCCESS != MPI_Alloc_mem((MPI_Aint)size, MPI_INFO_NULL, &memory)) {
88 fprintf(stderr,
"ERROR: MPI_Alloc_mem failed at %s:%i\n", name, __FILE__,
90 MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
93 memory = malloc(size);
105 assert(memory != NULL);
114 if (NULL == memory) {
118#if defined(__OFFLOAD)
120 offload_activate_chosen_device();
123 offload_activate_chosen_device();
124 offloadFreeHost(memory);
126#elif OFFLOAD_MEMPOOL_OMPALLOC && (201811 <= _OPENMP)
128 omp_free(memory, omp_null_allocator);
129#elif defined(__parallel) && !OFFLOAD_MEMPOOL_OMPALLOC
131 if (MPI_SUCCESS != MPI_Free_mem(memory)) {
132 fprintf(stderr,
"ERROR: MPI_Free_mem failed at %s:%i\n", name, __FILE__,
134 MPI_Abort(MPI_COMM_WORLD, EXIT_FAILURE);
147 const bool on_device) {
154#pragma omp critical(offload_mempool_modify)
160 while (*indirect != NULL) {
161 const size_t s = (*indirect)->
size;
162 if (size <= s && (reuse == NULL || s < (*reuse)->
size)) {
167 }
else if (reclaim == NULL || (*reclaim)->size < s) {
170 indirect = &(*indirect)->
next;
177 *reuse = chunk->
next;
178 }
else if (reclaim != NULL) {
181 *reclaim = chunk->
next;
185 assert(chunk != NULL);
190 if (chunk->
size < size) {
199#pragma omp critical(offload_mempool_modify)
233#pragma omp critical(offload_mempool_modify)
237 while (*indirect != NULL && (*indirect)->
mem != mem) {
238 indirect = &(*indirect)->
next;
241 assert(chunk != NULL && chunk->
mem == mem);
244 *indirect = chunk->
next;
273 const bool on_device) {
275#pragma omp critical(offload_mempool_modify)
277 uint64_t pool_size = 0;
287 pool_size += chunk->
size;
310 uint64_t size_sum = 0;
312 chunk = chunk->
next) {
313 size_sum += chunk->size;
323 uint64_t used_sum = 0;
325 chunk = chunk->
next) {
326 used_sum += chunk->used;
336 assert(NULL != memstats);
337#pragma omp critical(offload_mempool_modify)
360void offload_mempool_stats_print(
int fortran_comm,
363 assert(omp_get_num_threads() == 1);
376 " ----------------------------------------------------------------"
387 " - OFFLOAD MEMPOOL STATISTICS "
397 " ----------------------------------------------------------------"
401 " Memory consumption "
402 " Number of allocations Used [MiB] Size [MiB]\n",
405#if defined(__OFFLOAD)
408 snprintf(buffer,
sizeof(buffer),
410 " %20" PRIuPTR
" %10" PRIuPTR
" %10" PRIuPTR
"\n",
412 (uintptr_t)((memstats.
device_used + (512U << 10)) >> 20),
413 (uintptr_t)((memstats.
device_peak + (512U << 10)) >> 20));
419 snprintf(buffer,
sizeof(buffer),
421 " %20" PRIuPTR
" %10" PRIuPTR
" %10" PRIuPTR
"\n",
423 (uintptr_t)((memstats.
host_used + (512U << 10)) >> 20),
424 (uintptr_t)((memstats.
host_peak + (512U << 10)) >> 20));
430 " ----------------------------------------------------------------"
void cp_mpi_max_uint64(uint64_t *values, const int count, const cp_mpi_comm_t comm)
Wrapper around MPI_Allreduce for op MPI_MAX and datatype MPI_UINT64_T.
cp_mpi_comm_t cp_mpi_comm_f2c(const int fortran_comm)
Wrapper around MPI_Comm_f2c.
static void print_func(const char *msg, int msglen, int output_unit)
Wrapper for printf, passed to dbm_library_print_stats.
static void internal_mempool_free(offload_mempool_t *pool, const void *mem)
Private routine for releasing memory back to the pool.
struct offload_memchunk offload_memchunk_t
Private struct for storing a chunk of memory.
static offload_mempool_t mempool_device
static void actual_free(void *memory, const bool on_device)
Private routine for actually freeing system memory.
void offload_mempool_host_free(const void *memory)
Internal routine for releasing memory back to the pool.
void offload_mempool_clear(void)
Internal routine for freeing all memory in the pool.
void offload_mempool_device_free(const void *memory)
Internal routine for releasing memory back to the pool.
static void * internal_mempool_malloc(offload_mempool_t *pool, const size_t size, const bool on_device)
Private routine for allocating host or device memory from the pool.
#define OFFLOAD_MEMPOOL_PRINT(FN, MSG, OUTPUT_UNIT)
static uint64_t host_malloc_counter
Private counters for statistics.
void offload_mempool_stats_get(offload_mempool_stats_t *memstats)
Internal routine to query statistics.
static void * actual_malloc(const size_t size, const bool on_device)
Private routine for actually allocating system memory.
static void internal_mempool_clear(offload_mempool_t *pool, const bool on_device)
Private routine for freeing all memory in the pool.
static uint64_t sum_chunks_used(const offload_memchunk_t *head)
Private routine for summing used sizes of all chunks in given list.
static uint64_t imax(uint64_t x, uint64_t y)
Returns the larger of two given integer (missing from the C standard)
struct offload_mempool offload_mempool_t
Private struct for storing a memory pool.
static uint64_t device_malloc_counter
void * offload_mempool_host_malloc(const size_t size)
Internal routine for allocating host memory from the pool.
void * offload_mempool_device_malloc(const size_t size)
Internal routine for allocating device memory from the pool.
static offload_mempool_t mempool_host
Private pools for host and device memory.
static uint64_t sum_chunks_size(const offload_memchunk_t *head)
Private routine for summing alloc sizes of all chunks in given list.
Private struct for storing a chunk of memory.
struct offload_memchunk * next
Internal struct for pool statistics.
Private struct for storing a memory pool.
offload_memchunk_t * allocated_head
offload_memchunk_t * available_head