Neko 1.99.6
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
hip_intf.F90
Go to the documentation of this file.
1! Copyright (c) 2021-2026, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
35 use utils, only : neko_error
36 use, intrinsic :: iso_c_binding
37 implicit none
38
39#ifdef HAVE_HIP
40
42 enum, bind(c)
43 enumerator :: hipsuccess = 0
44 enumerator :: hiperrorinvalidcontext = 1
45 enumerator :: hiperrorinvalidkernelfile = 2
46 enumerator :: hiperrormemoryallocation = 3
48 enumerator :: hiperrorlaunchfailure = 5
50 enumerator :: hiperrorinvaliddevice = 7
51 enumerator :: hiperrorinvalidvalue = 8
54 enumerator :: hiperrorunknown = 11
56 enumerator :: hiperrornotready = 13
57 enumerator :: hiperrornodevice = 14
60 enumerator :: hiperrorruntimememory = 17
61 enumerator :: hiperrorruntimeother = 18
65 enumerator :: hiperrortbd = 22
66 end enum
67
69 enum, bind(c)
70 enumerator :: hipmemcpyhosttohost = 0
71 enumerator :: hipmemcpyhosttodevice = 1
72 enumerator :: hipmemcpydevicetohost = 2
73 enumerator :: hipmemcpydevicetodevice = 3
74 enumerator :: hipmemcpydefault = 4
75 end enum
76
77 interface
78 integer(c_int) function hipmalloc(ptr_d, s) &
79 bind(c, name = 'hipMalloc')
80 use, intrinsic :: iso_c_binding
81 implicit none
82 type(c_ptr) :: ptr_d
83 integer(c_size_t), value :: s
84 end function hipmalloc
85
86 integer(c_int) function hipfree(ptr_d) &
87 bind(c, name = 'hipFree')
88 use, intrinsic :: iso_c_binding
89 implicit none
90 type(c_ptr), value :: ptr_d
91 end function hipfree
92
93 integer(c_int) function hipmemcpy(ptr_dst, ptr_src, s, dir) &
94 bind(c, name = 'hipMemcpy')
95 use, intrinsic :: iso_c_binding
96 implicit none
97 type(c_ptr), value :: ptr_dst, ptr_src
98 integer(c_size_t), value :: s
99 integer(c_int), value :: dir
100 end function hipmemcpy
101
102 integer(c_int) function hipmemcpyasync(ptr_dst, ptr_src, s, dir, stream) &
103 bind(c, name = 'hipMemcpyAsync')
104 use, intrinsic :: iso_c_binding
105 implicit none
106 type(c_ptr), value :: ptr_dst, ptr_src, stream
107 integer(c_size_t), value :: s
108 integer(c_int), value :: dir
109 end function hipmemcpyasync
110
111 integer(c_int) function hipmemsetasync(ptr, v, s, stream) &
112 bind(c, name = 'hipMemsetAsync')
113 use, intrinsic :: iso_c_binding
114 implicit none
115 type(c_ptr), value :: ptr, stream
116 integer(c_int), value :: v
117 integer(c_size_t), value :: s
118 end function hipmemsetasync
119
120 integer(c_int) function hipdevicesynchronize() &
121 bind(c, name = 'hipDeviceSynchronize')
122 use, intrinsic :: iso_c_binding
123 implicit none
124 end function hipdevicesynchronize
125
126 integer(c_int) function hipdevicereset() &
127 bind(c, name = 'hipDeviceReset')
128 use, intrinsic :: iso_c_binding
129 implicit none
130 end function hipdevicereset
131
132 subroutine hip_buffer_free_all() &
133 bind(c, name = 'hip_buffer_free_all')
134 end subroutine hip_buffer_free_all
135
136 integer(c_int) function hipdevicegetname(name, len, device) &
137 bind(c, name = 'hipDeviceGetName')
138 use, intrinsic :: iso_c_binding
139 implicit none
140 type(c_ptr), value :: name
141 integer(c_int), value :: len
142 integer(c_int), value :: device
143 end function hipdevicegetname
144
145 integer(c_int) function hipgetdevicecount(amount) &
146 bind(c, name = 'hipGetDeviceCount')
147 use, intrinsic :: iso_c_binding
148 implicit none
149 integer(c_int) :: amount
150 end function hipgetdevicecount
151
152 integer(c_int) function hipstreamcreate(stream) &
153 bind(c, name = 'hipStreamCreate')
154 use, intrinsic :: iso_c_binding
155 implicit none
156 type(c_ptr) :: stream
157 end function hipstreamcreate
158
159 integer(c_int) function hipstreamcreatewithflags(stream, flags) &
160 bind(c, name = 'hipStreamCreateWithFlags')
161 use, intrinsic :: iso_c_binding
162 implicit none
163 type(c_ptr) :: stream
164 integer(c_int), value :: flags
165 end function hipstreamcreatewithflags
166
167 integer(c_int) function hipstreamcreatewithpriority(stream, flags, prio) &
168 bind(c, name = 'hipStreamCreateWithPriority')
169 use, intrinsic :: iso_c_binding
170 implicit none
171 type(c_ptr) :: stream
172 integer(c_int), value :: flags, prio
173 end function hipstreamcreatewithpriority
174
175 integer(c_int) function hipstreamdestroy(steam) &
176 bind(c, name = 'hipStreamDestroy')
177 use, intrinsic :: iso_c_binding
178 implicit none
179 type(c_ptr), value :: steam
180 end function hipstreamdestroy
181
182 integer(c_int) function hipstreamsynchronize(stream) &
183 bind(c, name = 'hipStreamSynchronize')
184 use, intrinsic :: iso_c_binding
185 implicit none
186 type(c_ptr), value :: stream
187 end function hipstreamsynchronize
188
189 integer(c_int) function hipstreamwaitevent(stream, event, flags) &
190 bind(c, name = 'hipStreamWaitEvent')
191 use, intrinsic :: iso_c_binding
192 implicit none
193 type(c_ptr), value :: stream, event
194 integer(c_int), value :: flags
195 end function hipstreamwaitevent
196
197 integer(c_int) function hipdevicegetstreampriorityrange(low_prio, &
198 high_prio) &
199 bind(c, name = 'hipDeviceGetStreamPriorityRange')
200 use, intrinsic :: iso_c_binding
201 implicit none
202 integer(c_int) :: low_prio, high_prio
204
205 integer(c_int) function hipeventcreate(event) &
206 bind(c, name = 'hipEventCreate')
207 use, intrinsic :: iso_c_binding
208 implicit none
209 type(c_ptr) :: event
210 end function hipeventcreate
211
212 integer(c_int) function hipeventdestroy(event) &
213 bind(c, name = 'hipEventDestroy')
214 use, intrinsic :: iso_c_binding
215 implicit none
216 type(c_ptr), value :: event
217 end function hipeventdestroy
218
219 integer(c_int) function hipeventcreatewithflags(event, flags) &
220 bind(c, name = 'hipEventCreateWithFlags')
221 use, intrinsic :: iso_c_binding
222 implicit none
223 type(c_ptr) :: event
224 integer(c_int), value :: flags
225 end function hipeventcreatewithflags
226
227 integer(c_int) function hipeventrecord(event, stream) &
228 bind(c, name = 'hipEventRecord')
229 use, intrinsic :: iso_c_binding
230 implicit none
231 type(c_ptr), value :: event, stream
232 end function hipeventrecord
233
234 integer(c_int) function hipeventsynchronize(event) &
235 bind(c, name = 'hipEventSynchronize')
236 use, intrinsic :: iso_c_binding
237 implicit none
238 type(c_ptr), value :: event
239 end function hipeventsynchronize
240 end interface
241
242contains
243
244 subroutine hip_init(glb_cmd_queue, aux_cmd_queue, &
245 STRM_HIGH_PRIO, STRM_LOW_PRIO)
246 type(c_ptr), intent(inout) :: glb_cmd_queue
247 type(c_ptr), intent(inout) :: aux_cmd_queue
248 integer, intent(inout) :: STRM_HIGH_PRIO
249 integer, intent(inout) :: STRM_LOW_PRIO
250
251 if (hipdevicegetstreampriorityrange(strm_low_prio, strm_high_prio) &
252 .ne. hipsuccess) then
253 call neko_error('Error retrieving stream priority range')
254 end if
255
256 if (hipstreamcreatewithpriority(glb_cmd_queue, 1, strm_high_prio) &
257 .ne. hipsuccess) then
258 call neko_error('Error creating main stream')
259 end if
260
261 if (hipstreamcreatewithpriority(aux_cmd_queue, 1, strm_low_prio) &
262 .ne. hipsuccess) then
263 call neko_error('Error creating main stream')
264 end if
265 end subroutine hip_init
266
267 subroutine hip_finalize(glb_cmd_queue, aux_cmd_queue)
268 type(c_ptr), intent(inout) :: glb_cmd_queue
269 type(c_ptr), intent(inout) :: aux_cmd_queue
270 integer :: ierr
271
272 ! Release all device buffers held by the device layer
274
275 if (hipstreamdestroy(glb_cmd_queue) .ne. hipsuccess) then
276 call neko_error('Error destroying main stream')
277 end if
278
279 if (hipstreamdestroy(aux_cmd_queue) .ne. hipsuccess) then
280 call neko_error('Error destroying aux stream')
281 end if
282
283 ierr = hipdevicesynchronize()
284
285 ! Best-effort context teardown to release runtime-owned allocations.
286 ! Skipped in pFUnit-enabled builds: unit tests cycle device
287 ! init/finalize with MPI still up, and device-aware communication
288 ! backends (GPU-aware MPI, RCCL) cache device state from first
289 ! use; resetting the device here would leave them with dangling
290 ! handles
291#ifndef HAVE_PFUNIT
292 ierr = hipdevicereset()
293#endif
294 end subroutine hip_finalize
295
296 subroutine hip_device_name(name)
297 character(len=*), intent(inout) :: name
298 character(kind=c_char, len=1024), target :: c_name
299 integer :: end_pos
300
301 if (hipdevicegetname(c_loc(c_name), 1024, 0) .ne. hipsuccess) then
302 call neko_error('Failed to query device')
303 end if
304
305 end_pos = scan(c_name, c_null_char)
306 if (end_pos .ge. 2) then
307 name(1:end_pos-1) = c_name(1:end_pos-1)
308 end if
309
310 end subroutine hip_device_name
311
313 integer function hip_device_count()
314 type(c_ptr) :: hip_count_ptr
315 integer :: amount
316
317 if (hipgetdevicecount(amount) .ne. hipsuccess) then
318 call neko_error('Failed to query device count')
319 end if
320
321 hip_device_count = amount
322 end function hip_device_count
323
324#endif
325
326end module hip_intf
Device abstraction, common interface for various accelerators.
Definition device.F90:34
Fortran HIP interface.
Definition hip_intf.F90:34
subroutine hip_device_name(name)
Definition hip_intf.F90:297
@ hipmemcpyhosttohost
Definition hip_intf.F90:70
@ hipmemcpydevicetohost
Definition hip_intf.F90:72
@ hipmemcpydefault
Definition hip_intf.F90:74
@ hipmemcpydevicetodevice
Definition hip_intf.F90:73
@ hipmemcpyhosttodevice
Definition hip_intf.F90:71
subroutine hip_init(glb_cmd_queue, aux_cmd_queue, strm_high_prio, strm_low_prio)
Definition hip_intf.F90:246
subroutine hip_finalize(glb_cmd_queue, aux_cmd_queue)
Definition hip_intf.F90:268
@ hiperrortbd
Definition hip_intf.F90:65
@ hiperrormapbufferobjectfailed
Definition hip_intf.F90:64
@ hiperrorinvaliddevicepointer
Definition hip_intf.F90:52
@ hiperrorlaunchfailure
Definition hip_intf.F90:48
@ hiperrorpeeraccessnotenabled
Definition hip_intf.F90:59
@ hiperrorinvalidkernelfile
Definition hip_intf.F90:45
@ hiperrorpeeraccessalreadyenabled
Definition hip_intf.F90:58
@ hiperrorinvalidresourcehandle
Definition hip_intf.F90:55
@ hiperrorhostmemorynotregistered
Definition hip_intf.F90:63
@ hiperrormemoryallocation
Definition hip_intf.F90:46
@ hiperrorruntimeother
Definition hip_intf.F90:61
@ hiperrorlaunchoutofresources
Definition hip_intf.F90:49
@ hiperrorinvalidmemcpydirection
Definition hip_intf.F90:53
@ hiperrornotready
Definition hip_intf.F90:56
@ hiperrorruntimememory
Definition hip_intf.F90:60
@ hiperrornodevice
Definition hip_intf.F90:57
@ hiperrorinvalidvalue
Definition hip_intf.F90:51
@ hiperrorinitializationerror
Definition hip_intf.F90:47
@ hiperrorinvaliddevice
Definition hip_intf.F90:50
@ hiperrorinvalidcontext
Definition hip_intf.F90:44
@ hiperrorhostmemoryalreadyregistered
Definition hip_intf.F90:62
@ hiperrorunknown
Definition hip_intf.F90:54
integer function hip_device_count()
Return the number of available HIP devices.
Definition hip_intf.F90:314
Utilities.
Definition utils.f90:35