1+ module mpl_allocator_mod
2+
3+ use pluto_module, only : pluto_allocator, pluto_memory_resource
4+ type (pluto_allocator), save :: mpl_allocator
5+ type (pluto_memory_resource), save :: mpl_resource
6+
7+ contains
8+ subroutine mpl_allocator_init (bytes )
9+ use pluto_module, only : pluto, pluto_memory_resource
10+ use iso_fortran_env, only : output_unit
11+ implicit none
12+ integer , intent (in ) :: bytes ! the amount of memory to reserve initially in the pool resource, in bytes
13+
14+ real (8 ), parameter :: GB = 1024 ** 3 ! 1 GB in bytes
15+ call pluto% trace% enable() ! Just for this example to show the trace output of the resource,
16+ ! can also be enabled by setting the environment variable PLUTO_TRACE=1
17+ mpl_resource = pluto% pinned_pool_resource()
18+ mpl_allocator = pluto% make_allocator(mpl_resource)
19+ call mpl_allocator_print()
20+ call mpl_resource% reserve(bytes) ! reserve memory if the resource supports it, otherwise this is a no-op
21+ call mpl_allocator_print()
22+
23+ call pluto% register_resource(" MPL" , mpl_resource) ! So that we can refer to it by name in the future
24+
25+ end subroutine mpl_allocator_init
26+
27+ subroutine mpl_allocator_print ()
28+ use iso_fortran_env, only : output_unit
29+ implicit none
30+ real (8 ), parameter :: GB = 1024 ** 3 ! 1 GB in bytes
31+ write (output_unit, ' (A, F6.2, A, A, F6.2, A)' ) " mpl_allocator: capacity:" , mpl_resource% capacity()/ GB, " GB" , &
32+ " , allocated:" , mpl_resource% size ()/ GB, " GB"
33+ end subroutine mpl_allocator_print
34+
35+ end module
36+
37+ program main
38+ implicit none
39+
40+ ! Initialise the mpl_allocator in a separate block to show that it can be done independently of the rest of the code,
41+ ! and that the resource is registered globally.
42+ block
43+ use mpl_allocator_mod, only : mpl_allocator_init
44+ call mpl_allocator_init(1024 ** 3 ) ! 1 GB
45+ end block
46+
47+ ! Example using mpl_allocator_mod
48+ block
49+ use mpl_allocator_mod, only : mpl_allocator
50+ real (8 ), pointer :: array(:,:)
51+ call mpl_allocator% allocate (array, lbounds= [0 ,0 ], ubounds= [10 , 8 ])
52+ call mpl_allocator% deallocate (array)
53+ end block
54+
55+ ! Example using mpl_resource using pluto%allocate / pluto%deallocate
56+ block
57+ use pluto_module, only : pluto
58+ use mpl_allocator_mod, only : mpl_resource
59+ real (8 ), pointer :: array(:,:)
60+ call pluto% allocate (array, lbounds= [0 ,0 ], ubounds= [10 , 8 ], resource= mpl_resource)
61+ call pluto% deallocate (array, resource= mpl_resource) ! IMPORTANT, must match the resource used for allocation
62+ end block
63+
64+ ! Example independent of mpl_allocator_mod, using the resource name directly.
65+ ! This also shows that the resource is registered globally and can be used in other translation units.
66+ block
67+ use pluto_module, only : pluto, pluto_allocator
68+ type (pluto_allocator) :: allocator
69+ real (8 ), pointer :: array(:,:)
70+ allocator = pluto% make_allocator(" MPL" ) ! This has been registered by name, now equivalent to using mpl_allocator
71+ call allocator% allocate (array, lbounds= [0 ,0 ], ubounds= [10 , 8 ])
72+ call allocator% deallocate (array)
73+ end block
74+
75+ ! Example independent of mpl_allocator_mod, using the resource name directly.
76+ block
77+ use pluto_module, only : pluto
78+ real (8 ), pointer :: array(:,:)
79+ call pluto% allocate (array, lbounds= [0 ,0 ], ubounds= [10 , 8 ], resource= " MPL" )
80+ call pluto% deallocate (array, resource= " MPL" ) ! IMPORTANT, must match the resource used for allocation
81+ end block
82+
83+ ! Example independent of mpl_allocator_mod, modifying the default host allocator in a scope.
84+ ! This is a convenient way to use the resource without having to pass it explicitly to every allocate/deallocate call.
85+ block
86+ use pluto_module, only : pluto
87+ call pluto% scope% push()
88+ call pluto% host% set_default_resource(" MPL" ) ! set the default host resource for this scope to "MPL"
89+ block
90+ real (8 ), pointer :: array(:,:)
91+ call pluto% host% allocate (array, lbounds= [0 ,0 ], ubounds= [10 , 8 ]) ! will use the default resource for the host, which is now "MPL"
92+ call pluto% host% deallocate (array)
93+ end block
94+ call pluto% scope% pop() ! restore the previous default resource for the host
95+ end block
96+
97+ ! Example modifying the default host allocator in a scope.
98+ ! This is a convenient way to use the resource without having to pass it explicitly to every allocate/deallocate call.
99+ block
100+ use pluto_module, only : pluto
101+ use mpl_allocator_mod, only : mpl_resource
102+ call pluto% scope% push()
103+ call pluto% host% set_default_resource(mpl_resource) ! set the default host resource for this scope to mpl_resource
104+ block
105+ real (8 ), pointer :: array(:,:)
106+ call pluto% host% allocate (array, shape= [10 , 8 ]) ! will use the default resource for the host, which is now mpl_resource
107+ call pluto% host% deallocate (array)
108+ end block
109+ call pluto% scope% pop() ! restore the previous default resource for the host
110+ end block
111+
112+ end program
0 commit comments