13 USE iso_c_binding,
ONLY: &
14 c_associated, c_char, c_funloc, c_funptr, c_f_pointer, c_int, c_null_char, c_null_ptr, &
19#include "../base/base_uses.f90"
25 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'offload_api'
39 REAL(kind=
dp),
DIMENSION(:),
CONTIGUOUS,
POINTER :: host_buffer => null()
40 TYPE(c_ptr) :: c_ptr = c_null_ptr
53 INTEGER(C_SIZE_T),
VALUE :: length
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
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
66 res = offload_malloc_pinned_mem_c(buffer, length)
75 TYPE(c_ptr),
VALUE :: buffer
79 FUNCTION offload_free_pinned_mem_c(buffer) &
80 BIND(C, name="offload_host_free")
82 INTEGER(KIND=C_INT) :: offload_free_pinned_mem_c
83 TYPE(c_ptr),
VALUE :: buffer
84 END FUNCTION offload_free_pinned_mem_c
87 res = offload_free_pinned_mem_c(buffer)
97 SUBROUTINE offload_init_c() &
98 BIND(C, name="offload_init")
99 END SUBROUTINE offload_init_c
102 CALL offload_init_c()
115 FUNCTION offload_get_device_count_c() &
116 BIND(C, name="offload_get_device_count")
118 INTEGER(KIND=C_INT) :: offload_get_device_count_c
119 END FUNCTION offload_get_device_count_c
122 count = offload_get_device_count_c()
132 INTEGER,
INTENT(IN) :: device_id
135 SUBROUTINE offload_set_chosen_device_c(device_id) &
136 BIND(C, name="offload_set_chosen_device")
138 INTEGER(KIND=C_INT),
VALUE :: device_id
139 END SUBROUTINE offload_set_chosen_device_c
142 CALL offload_set_chosen_device_c(device_id=device_id)
155 FUNCTION offload_get_chosen_device_c() &
156 BIND(C, name="offload_get_chosen_device")
158 INTEGER(KIND=C_INT) :: offload_get_chosen_device_c
159 END FUNCTION offload_get_chosen_device_c
162 device_id = offload_get_chosen_device_c()
164 IF (device_id < 0)
THEN
165 cpabort(
"No offload device has been chosen.")
177 SUBROUTINE offload_activate_chosen_device_c() &
178 BIND(C, name="offload_activate_chosen_device")
179 END SUBROUTINE offload_activate_chosen_device_c
182 CALL offload_activate_chosen_device_c()
192 CHARACTER(LEN=*),
INTENT(IN) :: routinen
195 SUBROUTINE offload_timeset_c(message)
BIND(C, name="offload_timeset")
197 CHARACTER(kind=C_CHAR),
DIMENSION(*),
INTENT(IN) :: message
198 END SUBROUTINE offload_timeset_c
201 CALL offload_timeset_c(trim(routinen)//c_null_char)
212 SUBROUTINE offload_timestop_c()
BIND(C, name="offload_timestop")
213 END SUBROUTINE offload_timestop_c
216 CALL offload_timestop_c()
227 INTEGER(KIND=int_8),
INTENT(OUT) :: free, total
229 INTEGER(KIND=C_SIZE_T) :: my_free, my_total
231 SUBROUTINE offload_mem_info_c(free, total)
BIND(C, name="offload_mem_info")
233 INTEGER(KIND=C_SIZE_T) :: free, total
234 END SUBROUTINE offload_mem_info_c
237 CALL offload_mem_info_c(my_free, my_total)
252 INTEGER,
INTENT(IN) :: length
255 CHARACTER(LEN=*),
PARAMETER :: routinen =
'offload_create_buffer'
258 TYPE(c_ptr) :: host_buffer_c
260 SUBROUTINE offload_create_buffer_c(length, buffer) &
261 BIND(C, name="offload_create_buffer")
262 IMPORT :: c_ptr, c_int
263 INTEGER(KIND=C_INT),
VALUE :: length
264 TYPE(c_ptr) :: buffer
265 END SUBROUTINE offload_create_buffer_c
268 FUNCTION offload_get_buffer_host_pointer_c(buffer) &
269 BIND(C, name="offload_get_buffer_host_pointer")
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
276 CALL timeset(routinen, handle)
278 IF (
ASSOCIATED(buffer%host_buffer))
THEN
279 IF (
SIZE(buffer%host_buffer) == 0)
DEALLOCATE (buffer%host_buffer)
280 IF (
ASSOCIATED(buffer%host_buffer))
NULLIFY (buffer%host_buffer)
283 CALL offload_create_buffer_c(length=length, buffer=buffer%c_ptr)
284 cpassert(c_associated(buffer%c_ptr))
286 IF (length == 0)
THEN
288 ALLOCATE (buffer%host_buffer(0))
290 host_buffer_c = offload_get_buffer_host_pointer_c(buffer%c_ptr)
291 cpassert(c_associated(host_buffer_c))
292 CALL c_f_pointer(host_buffer_c, buffer%host_buffer, shape=[length])
295 CALL timestop(handle)
306 CHARACTER(LEN=*),
PARAMETER :: routinen =
'offload_free_buffer'
310 SUBROUTINE offload_free_buffer_c(buffer) &
311 BIND(C, name="offload_free_buffer")
313 TYPE(c_ptr),
VALUE :: buffer
314 END SUBROUTINE offload_free_buffer_c
317 CALL timeset(routinen, handle)
319 IF (c_associated(buffer%c_ptr))
THEN
321 CALL offload_free_buffer_c(buffer%c_ptr)
323 buffer%c_ptr = c_null_ptr
325 IF (
ASSOCIATED(buffer%host_buffer))
THEN
326 IF (
SIZE(buffer%host_buffer) == 0)
THEN
327 DEALLOCATE (buffer%host_buffer)
329 NULLIFY (buffer%host_buffer)
334 CALL timestop(handle)
345 INTEGER,
INTENT(IN) :: output_unit
348 SUBROUTINE offload_mempool_stats_print_c(mpi_comm, print_func, output_unit) &
349 BIND(C, name="offload_mempool_stats_print")
350 IMPORT :: c_funptr, c_int
351 INTEGER(KIND=C_INT),
VALUE :: mpi_comm
352 TYPE(c_funptr),
VALUE :: print_func
353 INTEGER(KIND=C_INT),
VALUE :: output_unit
354 END SUBROUTINE offload_mempool_stats_print_c
358 CALL offload_mempool_stats_print_c(mpi_comm=mpi_comm%get_handle(), &
359 print_func=c_funloc(print_func), &
360 output_unit=output_unit)
371 SUBROUTINE print_func(msg, msglen, output_unit)
BIND(C, name="offload_api_print_func")
372 CHARACTER(KIND=C_CHAR),
INTENT(IN) :: msg(*)
373 INTEGER(KIND=C_INT),
INTENT(IN),
VALUE :: msglen, output_unit
375 IF (output_unit <= 0)
RETURN
376 WRITE (output_unit, fmt=
"(100A)", advance=
"NO") msg(1:msglen)
377 END SUBROUTINE print_func
387 INTEGER,
INTENT(IN) :: length
390 SUBROUTINE offload_buffer_h2d_c(buffer, length) &
391 BIND(C, name="offload_buffer_h2d")
392 IMPORT :: c_ptr, c_int
393 TYPE(c_ptr),
VALUE :: buffer
394 INTEGER(KIND=C_INT),
VALUE :: length
395 END SUBROUTINE offload_buffer_h2d_c
398 CALL offload_buffer_h2d_c(buffer%c_ptr, length)
408 INTEGER,
INTENT(IN) :: length
411 SUBROUTINE offload_buffer_d2h_c(buffer, length) &
412 BIND(C, name="offload_buffer_d2h")
413 IMPORT :: c_ptr, c_int
414 TYPE(c_ptr),
VALUE :: buffer
415 INTEGER(KIND=C_INT),
VALUE :: length
416 END SUBROUTINE offload_buffer_d2h_c
419 CALL offload_buffer_d2h_c(buffer%c_ptr, length)
430 TYPE(c_ptr) :: device_ptr
433 FUNCTION offload_get_buffer_device_pointer_c(buffer) &
434 BIND(C, name="offload_get_buffer_device_pointer")
436 TYPE(c_ptr),
VALUE :: buffer
437 TYPE(c_ptr) :: offload_get_buffer_device_pointer_c
438 END FUNCTION offload_get_buffer_device_pointer_c
441 device_ptr = offload_get_buffer_device_pointer_c(buffer%c_ptr)
450 SUBROUTINE offload_device_synchronize_c() &
451 BIND(C, name="offload_device_synchronize")
452 END SUBROUTINE offload_device_synchronize_c
455 CALL offload_device_synchronize_c()
464 TYPE(c_ptr) :: host_ptr
467 FUNCTION offload_get_buffer_host_pointer_c(buffer) &
468 BIND(C, name="offload_get_buffer_host_pointer")
470 TYPE(c_ptr),
VALUE :: buffer
471 TYPE(c_ptr) :: offload_get_buffer_host_pointer_c
472 END FUNCTION offload_get_buffer_host_pointer_c
475 host_ptr = offload_get_buffer_host_pointer_c(buffer%c_ptr)
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
Interface to the message passing library MPI.
Fortran API for the offload package, which is written in C.
subroutine, public offload_buffer_h2d(buffer, length)
Copy host data to device.
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().
type(c_ptr) function, public offload_get_buffer_device_pointer(buffer)
Return a C pointer to the buffer's underlying device memory.
type(c_ptr) function, public offload_get_buffer_host_pointer(buffer)
Return a C pointer to the buffer's host memory.
subroutine, public offload_timestop()
Ends a timing range.
integer function, public offload_free_pinned_mem(buffer)
free pinned memory
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.
subroutine, public offload_device_synchronize()
Blocks until all outstanding device work has completed.
subroutine, public offload_init()
Initialize runtime.
subroutine, public offload_mem_info(free, total)
Gets free and total device memory.
subroutine, public offload_mempool_stats_print(mpi_comm, output_unit)
Print allocation statistics.
subroutine, public offload_buffer_d2h(buffer, length)
Copy device data to host.
integer function, public offload_get_chosen_device()
Returns the chosen device.