(git:374b731)
Loading...
Searching...
No Matches
offload_api.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: BSD-3-Clause !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Fortran API for the offload package, which is written in C.
10!> \author Ole Schuett
11! **************************************************************************************************
13 USE iso_c_binding, ONLY: c_associated,&
14 c_char,&
15 c_f_pointer,&
16 c_int,&
17 c_null_char,&
18 c_null_ptr,&
19 c_ptr,&
20 c_size_t
21 USE kinds, ONLY: dp,&
22 int_8
23#include "../base/base_uses.f90"
24
25 IMPLICIT NONE
26
27 PRIVATE
28
29 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'offload_api'
30
31 PUBLIC :: offload_init
37
39 REAL(kind=dp), DIMENSION(:), CONTIGUOUS, POINTER :: host_buffer => null()
40 TYPE(c_ptr) :: c_ptr = c_null_ptr
41 END TYPE offload_buffer_type
42
43CONTAINS
44
45! **************************************************************************************************
46!> \brief allocate pinned memory.
47!> \param buffer address of the buffer
48!> \param length length of the buffer
49!> \return 0
50! **************************************************************************************************
51 FUNCTION offload_malloc_pinned_mem(buffer, length) RESULT(res)
52 TYPE(c_ptr) :: buffer
53 INTEGER(C_SIZE_T), VALUE :: length
54 INTEGER :: res
55
56 INTERFACE
57 FUNCTION offload_malloc_pinned_mem_c(buffer, length) &
58 BIND(C, name="offload_host_malloc")
59 IMPORT c_size_t, c_ptr, c_int
60 TYPE(c_ptr) :: buffer
61 INTEGER(C_SIZE_T), VALUE :: length
62 INTEGER(KIND=C_INT) :: offload_malloc_pinned_mem_c
63 END FUNCTION offload_malloc_pinned_mem_c
64 END INTERFACE
65
66 res = offload_malloc_pinned_mem_c(buffer, length)
67 END FUNCTION offload_malloc_pinned_mem
68
69! **************************************************************************************************
70!> \brief free pinned memory
71!> \param buffer address of the buffer
72!> \return 0
73! **************************************************************************************************
74 FUNCTION offload_free_pinned_mem(buffer) RESULT(res)
75 TYPE(c_ptr), VALUE :: buffer
76 INTEGER :: res
77
78 INTERFACE
79 FUNCTION offload_free_pinned_mem_c(buffer) &
80 BIND(C, name="offload_host_free")
81 IMPORT c_ptr, c_int
82 INTEGER(KIND=C_INT) :: offload_free_pinned_mem_c
83 TYPE(c_ptr), VALUE :: buffer
84 END FUNCTION offload_free_pinned_mem_c
85 END INTERFACE
86
87 res = offload_free_pinned_mem_c(buffer)
88 END FUNCTION offload_free_pinned_mem
89
90! **************************************************************************************************
91!> \brief Initialize runtime.
92!> \return ...
93!> \author Rocco Meli
94! **************************************************************************************************
95 SUBROUTINE offload_init()
96 INTERFACE
97 SUBROUTINE offload_init_c() &
98 BIND(C, name="offload_init")
99 END SUBROUTINE offload_init_c
100 END INTERFACE
101
102 CALL offload_init_c()
103
104 END SUBROUTINE offload_init
105
106! **************************************************************************************************
107!> \brief Returns the number of available devices.
108!> \return ...
109!> \author Ole Schuett
110! **************************************************************************************************
111 FUNCTION offload_get_device_count() RESULT(count)
112 INTEGER :: count
113
114 INTERFACE
115 FUNCTION offload_get_device_count_c() &
116 BIND(C, name="offload_get_device_count")
117 IMPORT :: c_int
118 INTEGER(KIND=C_INT) :: offload_get_device_count_c
119 END FUNCTION offload_get_device_count_c
120 END INTERFACE
121
122 count = offload_get_device_count_c()
123
124 END FUNCTION offload_get_device_count
125
126! **************************************************************************************************
127!> \brief Selects the chosen device to be used.
128!> \param device_id ...
129!> \author Ole Schuett
130! **************************************************************************************************
131 SUBROUTINE offload_set_chosen_device(device_id)
132 INTEGER, INTENT(IN) :: device_id
133
134 INTERFACE
135 SUBROUTINE offload_set_chosen_device_c(device_id) &
136 BIND(C, name="offload_set_chosen_device")
137 IMPORT :: c_int
138 INTEGER(KIND=C_INT), VALUE :: device_id
139 END SUBROUTINE offload_set_chosen_device_c
140 END INTERFACE
141
142 CALL offload_set_chosen_device_c(device_id=device_id)
143
144 END SUBROUTINE offload_set_chosen_device
145
146! **************************************************************************************************
147!> \brief Returns the chosen device.
148!> \return ...
149!> \author Ole Schuett
150! **************************************************************************************************
151 FUNCTION offload_get_chosen_device() RESULT(device_id)
152 INTEGER :: device_id
153
154 INTERFACE
155 FUNCTION offload_get_chosen_device_c() &
156 BIND(C, name="offload_get_chosen_device")
157 IMPORT :: c_int
158 INTEGER(KIND=C_INT) :: offload_get_chosen_device_c
159 END FUNCTION offload_get_chosen_device_c
160 END INTERFACE
161
162 device_id = offload_get_chosen_device_c()
163
164 IF (device_id < 0) &
165 cpabort("No offload device has been chosen.")
166
167 END FUNCTION offload_get_chosen_device
168
169! **************************************************************************************************
170!> \brief Activates the device selected via offload_set_chosen_device()
171!> \author Ole Schuett
172! **************************************************************************************************
174
175 INTERFACE
176 SUBROUTINE offload_activate_chosen_device_c() &
177 BIND(C, name="offload_activate_chosen_device")
178 END SUBROUTINE offload_activate_chosen_device_c
179 END INTERFACE
180
181 CALL offload_activate_chosen_device_c()
182
183 END SUBROUTINE offload_activate_chosen_device
184
185! **************************************************************************************************
186!> \brief Starts a timing range.
187!> \param routineN ...
188!> \author Ole Schuett
189! **************************************************************************************************
190 SUBROUTINE offload_timeset(routineN)
191 CHARACTER(LEN=*), INTENT(IN) :: routinen
192
193 INTERFACE
194 SUBROUTINE offload_timeset_c(message) BIND(C, name="offload_timeset")
195 IMPORT :: c_char
196 CHARACTER(kind=C_CHAR), DIMENSION(*), INTENT(IN) :: message
197 END SUBROUTINE offload_timeset_c
198 END INTERFACE
199
200 CALL offload_timeset_c(trim(routinen)//c_null_char)
201
202 END SUBROUTINE offload_timeset
203
204! **************************************************************************************************
205!> \brief Ends a timing range.
206!> \author Ole Schuett
207! **************************************************************************************************
208 SUBROUTINE offload_timestop()
209
210 INTERFACE
211 SUBROUTINE offload_timestop_c() BIND(C, name="offload_timestop")
212 END SUBROUTINE offload_timestop_c
213 END INTERFACE
214
215 CALL offload_timestop_c()
216
217 END SUBROUTINE offload_timestop
218
219! **************************************************************************************************
220!> \brief Gets free and total device memory.
221!> \param free ...
222!> \param total ...
223!> \author Ole Schuett
224! **************************************************************************************************
225 SUBROUTINE offload_mem_info(free, total)
226 INTEGER(KIND=int_8), INTENT(OUT) :: free, total
227
228 INTEGER(KIND=C_SIZE_T) :: my_free, my_total
229 INTERFACE
230 SUBROUTINE offload_mem_info_c(free, total) BIND(C, name="offload_mem_info")
231 IMPORT :: c_size_t
232 INTEGER(KIND=C_SIZE_T) :: free, total
233 END SUBROUTINE offload_mem_info_c
234 END INTERFACE
235
236 CALL offload_mem_info_c(my_free, my_total)
237
238 ! On 32-bit architectures this converts from int_4 to int_8.
239 free = my_free
240 total = my_total
241
242 END SUBROUTINE offload_mem_info
243
244! **************************************************************************************************
245!> \brief Allocates a buffer of given length, ie. number of elements.
246!> \param length ...
247!> \param buffer ...
248!> \author Ole Schuett
249! **************************************************************************************************
250 SUBROUTINE offload_create_buffer(length, buffer)
251 INTEGER, INTENT(IN) :: length
252 TYPE(offload_buffer_type), INTENT(INOUT) :: buffer
253
254 CHARACTER(LEN=*), PARAMETER :: routinen = 'offload_create_buffer'
255
256 INTEGER :: handle
257 TYPE(c_ptr) :: host_buffer_c
258 INTERFACE
259 SUBROUTINE offload_create_buffer_c(length, buffer) &
260 BIND(C, name="offload_create_buffer")
261 IMPORT :: c_ptr, c_int
262 INTEGER(KIND=C_INT), VALUE :: length
263 TYPE(c_ptr) :: buffer
264 END SUBROUTINE offload_create_buffer_c
265 END INTERFACE
266 INTERFACE
267
268 FUNCTION offload_get_buffer_host_pointer_c(buffer) &
269 BIND(C, name="offload_get_buffer_host_pointer")
270 IMPORT :: c_ptr
271 TYPE(c_ptr), VALUE :: buffer
272 TYPE(c_ptr) :: offload_get_buffer_host_pointer_c
273 END FUNCTION offload_get_buffer_host_pointer_c
274 END INTERFACE
275
276 CALL timeset(routinen, handle)
277
278 IF (ASSOCIATED(buffer%host_buffer)) THEN
279 IF (SIZE(buffer%host_buffer) == 0) DEALLOCATE (buffer%host_buffer)
280 END IF
281
282 CALL offload_create_buffer_c(length=length, buffer=buffer%c_ptr)
283 cpassert(c_associated(buffer%c_ptr))
284
285 IF (length == 0) THEN
286 ! While C_F_POINTER usually accepts a NULL pointer it's not standard compliant.
287 ALLOCATE (buffer%host_buffer(0))
288 ELSE
289 host_buffer_c = offload_get_buffer_host_pointer_c(buffer%c_ptr)
290 cpassert(c_associated(host_buffer_c))
291 CALL c_f_pointer(host_buffer_c, buffer%host_buffer, shape=(/length/))
292 END IF
293
294 CALL timestop(handle)
295 END SUBROUTINE offload_create_buffer
296
297! **************************************************************************************************
298!> \brief Deallocates given buffer.
299!> \param buffer ...
300!> \author Ole Schuett
301! **************************************************************************************************
302 SUBROUTINE offload_free_buffer(buffer)
303 TYPE(offload_buffer_type), INTENT(INOUT) :: buffer
304
305 CHARACTER(LEN=*), PARAMETER :: routinen = 'offload_free_buffer'
306
307 INTEGER :: handle
308 INTERFACE
309 SUBROUTINE offload_free_buffer_c(buffer) &
310 BIND(C, name="offload_free_buffer")
311 IMPORT :: c_ptr
312 TYPE(c_ptr), VALUE :: buffer
313 END SUBROUTINE offload_free_buffer_c
314 END INTERFACE
315
316 CALL timeset(routinen, handle)
317
318 IF (c_associated(buffer%c_ptr)) THEN
319
320 CALL offload_free_buffer_c(buffer%c_ptr)
321
322 buffer%c_ptr = c_null_ptr
323
324 IF (SIZE(buffer%host_buffer) == 0) THEN
325 DEALLOCATE (buffer%host_buffer)
326 ELSE
327 NULLIFY (buffer%host_buffer)
328 END IF
329 END IF
330
331 CALL timestop(handle)
332 END SUBROUTINE offload_free_buffer
333END MODULE offload_api
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public int_8
Definition kinds.F:54
integer, parameter, public dp
Definition kinds.F:34
Fortran API for the offload package, which is written in C.
Definition offload_api.F:12
subroutine, public offload_set_chosen_device(device_id)
Selects the chosen device to be used.
subroutine, public offload_free_buffer(buffer)
Deallocates given buffer.
subroutine, public offload_activate_chosen_device()
Activates the device selected via offload_set_chosen_device()
subroutine, public offload_timestop()
Ends a timing range.
integer function, public offload_free_pinned_mem(buffer)
free pinned memory
Definition offload_api.F:75
subroutine, public offload_timeset(routinen)
Starts a timing range.
integer function, public offload_get_device_count()
Returns the number of available devices.
subroutine, public offload_create_buffer(length, buffer)
Allocates a buffer of given length, ie. number of elements.
integer function, public offload_malloc_pinned_mem(buffer, length)
allocate pinned memory.
Definition offload_api.F:52
subroutine, public offload_init()
Initialize runtime.
Definition offload_api.F:96
subroutine, public offload_mem_info(free, total)
Gets free and total device memory.
integer function, public offload_get_chosen_device()
Returns the chosen device.