! 1. Include header
#include<y_memory.h>
! 2. Use module
use y_memory_alloc
! 3. Allocate
YAMBO_ALLOC(array_name, (dim1, dim2, ...))
! 4. Use array
array_name = some_value
! 5. Free
YAMBO_FREE(array_name)
complex(SP), allocatable :: A(:,:)
YAMBO_ALLOC(A, (100, 200))
YAMBO_FREE(A)
real(SP), allocatable :: E(:,:)
integer :: nb(2) = [1, 100]
YAMBO_ALLOC(E, (nb(1):nb(2), nk)) ! E(1:100, 1:nk)
YAMBO_FREE(E)
if (.not. allocated(array)) then
YAMBO_ALLOC(array, (n, m))
endif
if (allocated(array)) YAMBO_FREE(array)
| Macro | Purpose | Example |
|---|---|---|
YAMBO_ALLOC(x, SIZE) |
Allocate array | YAMBO_ALLOC(A, (n, m)) |
YAMBO_FREE(x) |
Deallocate array | YAMBO_FREE(A) |
YAMBO_ALLOC_P(x, SIZE) |
Allocate pointer | YAMBO_ALLOC_P(ptr, (n)) |
YAMBO_FREE_P(x) |
Deallocate pointer | YAMBO_FREE_P(ptr) |
YAMBO_ALLOC_SOURCE(x, y) |
Allocate from source | YAMBO_ALLOC_SOURCE(A, B) |
YAMBO_ALLOC_MOLD(x, y) |
Allocate with mold | YAMBO_ALLOC_MOLD(A, B) |
YAMBO_ALLOC_GPU(x, SIZE) |
GPU allocation | YAMBO_ALLOC_GPU(A, (n, m)) |
YAMBO_FREE_GPU(x) |
GPU deallocation | YAMBO_FREE_GPU(A) |
YAMBO_PAR_ALLOC[1-6](x, SIZE) |
MPI-aware allocation | YAMBO_PAR_ALLOC3(A, SIZE) |
#if defined _OPENACC
! Allocate on host and map to device
YAMBO_ALLOC_GPU(A, (n, m))
! Use on GPU
!$acc parallel loop present(A)
do i = 1, n
A(i,:) = compute_something()
enddo
!$acc end parallel loop
! Free (automatically unmaps)
YAMBO_FREE_GPU(A)
#endif
use parallel_m, ONLY: PAR_G_k_range
integer :: nk_local, LOCAL_SIZE(3)
! Local k-points for this rank
nk_local = PAR_G_k_range(2) - PAR_G_k_range(1) + 1
LOCAL_SIZE = [nb, nb, nk_local]
! Allocate locally, report globally
YAMBO_PAR_ALLOC3(G_lesser, LOCAL_SIZE)
! Each rank has G_lesser(nb, nb, nk_local)
! Master reports total memory across all ranks
YAMBO_FREE(G_lesser)
subroutine RT_allocate_Greens_functions()
use real_time, ONLY: G_lesser, dG_lesser, G_lesser_reference, &
RT_bands, RT_nk, G_MEM_steps
use electrons, ONLY: n_sp_pol
use parallel_m, ONLY: PAR_G_k_range
use y_memory_alloc
implicit none
integer :: nk(2)
nk = PAR_G_k_range ! Local k-point range
! Reference (equilibrium) - replicated on all ranks
YAMBO_ALLOC(G_lesser_reference, (RT_bands(1):RT_bands(2), &
RT_bands(1):RT_bands(2), &
RT_nk, n_sp_pol))
! Time-dependent - distributed over k-points
YAMBO_ALLOC(G_lesser, (RT_bands(1):RT_bands(2), &
RT_bands(1):RT_bands(2), &
nk(1):nk(2), n_sp_pol, G_MEM_steps))
! Time derivative - distributed over k-points
YAMBO_ALLOC(dG_lesser, (RT_bands(1):RT_bands(2), &
RT_bands(1):RT_bands(2), &
nk(1):nk(2), n_sp_pol, G_MEM_steps))
! Initialize
G_lesser_reference = cZERO
G_lesser = cZERO
dG_lesser = cZERO
end subroutine
subroutine RT_free_Greens_functions()
use real_time, ONLY: G_lesser, dG_lesser, G_lesser_reference
use y_memory_alloc
implicit none
YAMBO_FREE(G_lesser_reference)
YAMBO_FREE(G_lesser)
YAMBO_FREE(dG_lesser)
end subroutine
[MEMORY] Alloc G_lesser(234.5 Mb) TOTAL: 1.23 Gb (traced)
[MEMORY] Free G_lesser(234.5 Mb) TOTAL: 1.00 Gb (traced)
[MEMORY] In use: TOTAL: 2.45 Gb (traced) 2.51 Gb (memstat)
[MEMORY] Alloc A(7.63 Mb) (DEV) TOTAL: 234.5 Mb (traced)
[ERROR] Allocation of G_lesser failed with code 1
Out of memory
Fix: Reduce array size or increase system memory
[WARNING] Allocation of G_lesser failed with code 0
[WARNING] Object was already allocated in [G_lesser]
Fix: Free before reallocating
if (allocated(G_lesser)) YAMBO_FREE(G_lesser)
YAMBO_ALLOC(G_lesser, (n, m))
[ERROR] Trying to deallocate var A still on device memory
Fix: Use GPU-specific free
YAMBO_FREE_GPU(A) ! Not YAMBO_FREE(A)
[ERROR] Allocation of G_lesser leads total memory above USER limit [16Gb]
Fix: Increase limit or reduce array sizes
yambo -M 32Gb # Increase to 32 Gb
Memory (bytes) = num_elements × bytes_per_element
| Type | Bytes | Example |
|---|---|---|
integer |
4 | integer :: i |
integer(LP) |
8 | integer(LP) :: big_i |
real(SP) |
4 | real(SP) :: x |
real(DP) |
8 | real(DP) :: y |
complex(SP) |
8 | complex(SP) :: z |
complex(DP) |
16 | complex(DP) :: w |
logical |
4 | logical :: flag |
1D array:
real(SP) :: A(1000)
! Memory = 1000 × 4 = 4,000 bytes = 3.91 Kb
2D array:
complex(SP) :: G(100, 100)
! Memory = 100 × 100 × 8 = 80,000 bytes = 78.1 Kb
4D array:
complex(SP) :: G_lesser(100, 100, 10, 2)
! Memory = 100 × 100 × 10 × 2 × 8 = 1,600,000 bytes = 1.53 Mb
5D array (time-dependent):
complex(SP) :: G_lesser(100, 100, 10, 2, 3)
! Memory = 100 × 100 × 10 × 2 × 3 × 8 = 4,800,000 bytes = 4.58 Mb
./configure --enable-memory-profile
Or manually:
-D_MEM_CHECK
./configure --enable-open-acc
# or
./configure --enable-openmp-gpu
Defines: -D_OPENACC or -D_OPENMP_GPU
./configure --enable-mpi
Defines: -D_MPI
if (allocated(array)) then
print *, "Array is allocated, size:", size(array)
else
print *, "Array is NOT allocated"
endif
use y_memory, ONLY: TOT_MEM_Kb, MAX_MEM_Kb
print *, "Current memory (Kb):", TOT_MEM_Kb(HOST_)
print *, "Peak memory (Kb):", MAX_MEM_Kb(HOST_)
call MEM_report() ! Prints detailed allocation table
! At start of routine
call MEM_report()
integer :: mem_start = TOT_MEM_Kb(HOST_)
! ... allocations and deallocations ...
! At end of routine
call MEM_report()
integer :: mem_end = TOT_MEM_Kb(HOST_)
if (mem_end /= mem_start) then
print *, "WARNING: Memory leak detected!"
print *, "Leaked:", mem_end - mem_start, "Kb"
endif
YAMBO_ALLOC instead of allocateYAMBO_FREE instead of deallocate#include<y_memory.h> at top of fileuse y_memory_alloc in subroutinesallocated() before freeingYAMBO_FREE_GPU for GPU arraysYAMBO_PAR_ALLOC for MPI-distributed arrays-M flag)allocate(A(n, m)) ! Not tracked by memory system
Correct:
YAMBO_ALLOC(A, (n, m)) ! Tracked allocation
subroutine compute()
YAMBO_ALLOC(temp, (n, n))
! ... use temp ...
! Missing: YAMBO_FREE(temp)
end subroutine
Correct:
subroutine compute()
YAMBO_ALLOC(temp, (n, n))
! ... use temp ...
YAMBO_FREE(temp)
end subroutine
do i = 1, 1000
YAMBO_ALLOC(temp, (n, n)) ! Allocates 1000 times repeatedly
! ...
YAMBO_FREE(temp)
enddo
Correct:
YAMBO_ALLOC(temp, (n, n)) ! Allocate once before loop
do i = 1, 1000
! ... use temp ...
enddo
YAMBO_FREE(temp)
YAMBO_ALLOC_GPU(A, (n, m))
! ...
YAMBO_FREE(A) ! Incorrect for GPU arrays
Correct:
YAMBO_ALLOC_GPU(A, (n, m))
! ...
YAMBO_FREE_GPU(A) ! Proper GPU deallocation
YAMBO_ALLOC(huge_array, (10000, 10000, 10000))
! May fail silently if _MEM_CHECK not defined
Correct:
YAMBO_ALLOC(huge_array, (10000, 10000, 10000))
if (.not. allocated(huge_array)) then
call error("Failed to allocate huge_array")
endif
Recommended:
YAMBO_ALLOC(work, (n, n))
do iter = 1, n_iterations
call compute(work)
enddo
YAMBO_FREE(work)
Avoid:
do iter = 1, n_iterations
YAMBO_ALLOC(work, (n, n))
call compute(work)
YAMBO_FREE(work)
enddo
YAMBO_ALLOC(temp1, (n, n))
YAMBO_ALLOC(temp2, (n, n))
call step1(temp1, temp2)
YAMBO_FREE(temp1) ! Free when no longer needed
call step2(temp2)
YAMBO_FREE(temp2) ! Free when no longer needed
! If single precision is enough:
complex(SP) :: A(n, n) ! 8 bytes per element
! Instead of:
complex(DP) :: A(n, n) ! 16 bytes per element (2× memory!)
YAMBO_ALLOC_DOCUMENTATION.mdinclude/headers/common/y_memory.hsrc/modules/mod_memory.Fsrc/memory/MEM_*.Fsrc/real_time_control/RT_alloc.Fsrc/pol_function/X_irredux.FQuick Reference Version: 1.0
Last Updated: 2024