Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
checkpoint.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!
36 use num_types, only : rp, dp
39 use space, only : space_t
42 use utils, only : neko_error
43 use mesh, only : mesh_t
45 use time_state, only : time_state_t
46 use, intrinsic :: iso_c_binding, only : c_associated
47 implicit none
48 private
49
51 type, public :: chkp_t
53 type(checkpoint_payload_ptr_t), allocatable :: payloads(:)
54
56 real(kind=dp) :: t = 0d0
58 type(mesh_t) :: previous_mesh
60 type(space_t) :: previous_xh
62 real(kind=dp) :: mesh2mesh_tol = glob_interp_tol
63 contains
65 procedure, pass(this) :: init => chkp_init
67 procedure, pass(this) :: sync_host => chkp_sync_host
69 procedure, pass(this) :: sync_device => chkp_sync_device
71 procedure, pass(this) :: add_payload => chkp_add_payload
73 procedure, pass(this) :: get_payload => chkp_get_payload
75 procedure, pass(this) :: payload_count => chkp_payload_count
77 procedure, pass(this) :: scalar_payload_count => chkp_scalar_payload_count
79 procedure, pass(this) :: add_time_state => chkp_add_time_state
81 procedure, pass(this) :: get_time_history => chkp_get_time_history
83 procedure, pass(this) :: restart_time => chkp_restart_time
85 procedure, pass(this) :: set_time_state => chkp_set_time_state
87 procedure, pass(this) :: free => chkp_free
88 end type chkp_t
89
90contains
91
93 subroutine chkp_init(this)
94 class(chkp_t), intent(inout) :: this
95
96 ! Make sure the object is clean
97 call this%free()
98
99 end subroutine chkp_init
100
102 subroutine chkp_free(this)
103 class(chkp_t), intent(inout) :: this
104 integer :: i
105
106 this%t = 0d0
107
108 if (allocated(this%payloads)) then
109 do i = 1, size(this%payloads)
110 if (associated(this%payloads(i)%ptr)) then
111 call this%payloads(i)%ptr%free()
112 deallocate(this%payloads(i)%ptr)
113 end if
114 end do
115 deallocate(this%payloads)
116 end if
117
118 call this%previous_mesh%free()
119 call this%previous_Xh%free()
120
121 end subroutine chkp_free
122
124 subroutine chkp_sync_host(this)
125 class(chkp_t), intent(inout) :: this
126 integer :: i, j
127
128 if (neko_bcknd_device .eq. 1) then
129 do i = 1, this%payload_count()
130 do j = 1, this%payloads(i)%ptr%field_count()
131 call this%payloads(i)%ptr%fields(j)%ptr%copy_from( &
132 device_to_host, sync = .false.)
133 end do
134 do j = 1, this%payloads(i)%ptr%series_count()
135 block
136 integer :: k
137 do k = 1, this%payloads(i)%ptr%series(j)%ptr%size()
138 call this%payloads(i)%ptr%series(j)%ptr%lf(k)%copy_from( &
139 device_to_host, sync = .false.)
140 end do
141 end block
142 end do
143 do j = 1, this%payloads(i)%ptr%array_count()
144 if (c_associated( &
145 this%payloads(i)%ptr%arrays(j)%ptr%x_d)) then
146 call device_memcpy( &
147 this%payloads(i)%ptr%arrays(j)%ptr%x, &
148 this%payloads(i)%ptr%arrays(j)%ptr%x_d, &
149 size(this%payloads(i)%ptr%arrays(j)%ptr%x), &
150 device_to_host, .false.)
151 end if
152 end do
153 do j = 1, this%payloads(i)%ptr%mesh_array_count()
154 if (c_associated( &
155 this%payloads(i)%ptr%mesh_arrays(j)%ptr%x_d)) then
156 call device_memcpy( &
157 this%payloads(i)%ptr%mesh_arrays(j)%ptr%x, &
158 this%payloads(i)%ptr%mesh_arrays(j)%ptr%x_d, &
159 size(this%payloads(i)%ptr%mesh_arrays(j)%ptr%x), &
160 device_to_host, .false.)
161 end if
162 end do
163 end do
164
166 end if
167
168 end subroutine chkp_sync_host
169
171 subroutine chkp_sync_device(this)
172 class(chkp_t), intent(inout) :: this
173 integer :: i, j
174
175 if (neko_bcknd_device .eq. 1) then
176 do i = 1, this%payload_count()
177 do j = 1, this%payloads(i)%ptr%field_count()
178 call this%payloads(i)%ptr%fields(j)%ptr%copy_from( &
179 host_to_device, sync = .false.)
180 end do
181 do j = 1, this%payloads(i)%ptr%series_count()
182 block
183 integer :: k
184 do k = 1, this%payloads(i)%ptr%series(j)%ptr%size()
185 call this%payloads(i)%ptr%series(j)%ptr%lf(k)%copy_from( &
186 host_to_device, sync = .false.)
187 end do
188 end block
189 end do
190 do j = 1, this%payloads(i)%ptr%array_count()
191 if (c_associated( &
192 this%payloads(i)%ptr%arrays(j)%ptr%x_d)) then
193 call device_memcpy( &
194 this%payloads(i)%ptr%arrays(j)%ptr%x, &
195 this%payloads(i)%ptr%arrays(j)%ptr%x_d, &
196 size(this%payloads(i)%ptr%arrays(j)%ptr%x), &
197 host_to_device, .false.)
198 end if
199 end do
200 do j = 1, this%payloads(i)%ptr%mesh_array_count()
201 if (c_associated( &
202 this%payloads(i)%ptr%mesh_arrays(j)%ptr%x_d)) then
203 call device_memcpy( &
204 this%payloads(i)%ptr%mesh_arrays(j)%ptr%x, &
205 this%payloads(i)%ptr%mesh_arrays(j)%ptr%x_d, &
206 size(this%payloads(i)%ptr%mesh_arrays(j)%ptr%x), &
207 host_to_device, .false.)
208 end if
209 end do
210 end do
211
212 end if
213
214 end subroutine chkp_sync_device
215
218 pure function chkp_scalar_payload_count(this) result(n)
219 class(chkp_t), intent(in) :: this
220 integer :: i, n
221
222 n = 0
223 do i = 1, this%payload_count()
224 if (index(trim(this%payloads(i)%ptr%name), "scalars/") .eq. 1) then
225 n = n + 1
226 end if
227 end do
228
229 end function chkp_scalar_payload_count
230
234 function chkp_add_payload(this, name) result(payload)
235 class(chkp_t), intent(inout) :: this
236 character(len=*), intent(in) :: name
237 type(checkpoint_payload_t), pointer :: payload
238 type(checkpoint_payload_ptr_t), allocatable :: tmp(:)
239 integer :: i, n
240
241 do i = 1, this%payload_count()
242 if (trim(this%payloads(i)%ptr%name) .eq. trim(name)) then
243 payload => this%payloads(i)%ptr
244 return
245 end if
246 end do
247
248 n = this%payload_count()
249 allocate(tmp(n + 1))
250 if (n .gt. 0) tmp(1:n) = this%payloads
251 allocate(tmp(n + 1)%ptr)
252 call tmp(n + 1)%ptr%init(name)
253 call move_alloc(tmp, this%payloads)
254 payload => this%payloads(n + 1)%ptr
255
256 end function chkp_add_payload
257
261 function chkp_get_payload(this, name) result(payload)
262 class(chkp_t), intent(in) :: this
263 character(len=*), intent(in) :: name
264 type(checkpoint_payload_t), pointer :: payload
265 integer :: i
266
267 nullify(payload)
268 do i = 1, this%payload_count()
269 if (trim(this%payloads(i)%ptr%name) .eq. trim(name)) then
270 payload => this%payloads(i)%ptr
271 return
272 end if
273 end do
274
275 call neko_error("Checkpoint payload '" // trim(name) // "' not found")
276
277 end function chkp_get_payload
278
281 pure function chkp_payload_count(this) result(n)
282 class(chkp_t), intent(in) :: this
283 integer :: n
284
285 if (allocated(this%payloads)) then
286 n = size(this%payloads)
287 else
288 n = 0
289 end if
290
291 end function chkp_payload_count
292
295 subroutine chkp_add_time_state(this, time_state)
296 class(chkp_t), intent(inout) :: this
297 type(time_state_t), target, intent(inout) :: time_state
298 type(checkpoint_payload_t), pointer :: payload
299
300 payload => this%add_payload("time")
301 call payload%add_array_dp("tlag", time_state%tlag, replicated = .true.)
302 call payload%add_array_dp("dtlag", time_state%dtlag, replicated = .true.)
303
304 end subroutine chkp_add_time_state
305
309 subroutine chkp_get_time_history(this, tlag, dtlag)
310 class(chkp_t), intent(in) :: this
311 real(kind=dp), pointer, intent(out) :: tlag(:), dtlag(:)
312 type(checkpoint_payload_t), pointer :: payload
313 type(checkpoint_array_t), pointer :: array
314
315 payload => this%get_payload("time")
316 array => payload%find_array("tlag")
317 tlag => array%x_dp
318 array => payload%find_array("dtlag")
319 dtlag => array%x_dp
320
321 end subroutine chkp_get_time_history
322
325 pure function chkp_restart_time(this) result(rtime)
326 class(chkp_t), intent(in) :: this
327 real(kind=dp) :: rtime
328
329 rtime = this%t
330 end function chkp_restart_time
331
334 subroutine chkp_set_time_state(this, time_state)
335 class(chkp_t), intent(in) :: this
336 type(time_state_t), intent(inout) :: time_state
337 real(kind=dp), pointer :: tlag(:), dtlag(:)
338
339 call this%get_time_history(tlag, dtlag)
340 time_state%t = this%t
341 time_state%dtlag = dtlag
342 time_state%tlag = tlag
343 end subroutine chkp_set_time_state
344
345end module checkpoint
Copy data between host and device (or device and device)
Definition device.F90:72
Synchronize a device or stream.
Definition device.F90:119
Format-independent checkpoint payloads.
Defines format-independent checkpoint registration and restart state.
pure integer function chkp_payload_count(this)
Return the number of registered checkpoint payloads.
subroutine chkp_sync_host(this)
Synchronise registered checkpoint data from device to host.
subroutine chkp_set_time_state(this, time_state)
Restore a simulation time state from the checkpoint.
subroutine chkp_sync_device(this)
Synchronise registered checkpoint data from host to device.
pure real(kind=dp) function chkp_restart_time(this)
Return the restart time from a loaded checkpoint.
subroutine chkp_free(this)
Release all checkpoint payloads and restart metadata.
pure integer function chkp_scalar_payload_count(this)
Return the number of registered scalar payloads.
subroutine chkp_get_time_history(this, tlag, dtlag)
Return pointers to the simulation time history.
type(checkpoint_payload_t) function, pointer chkp_add_payload(this, name)
Add or return a checkpoint payload.
subroutine chkp_init(this)
Initialize an empty checkpoint.
type(checkpoint_payload_t) function, pointer chkp_get_payload(this, name)
Return a checkpoint payload by name.
subroutine chkp_add_time_state(this, time_state)
Register the simulation time history as a replicated payload.
Device abstraction, common interface for various accelerators.
Definition device.F90:34
integer, parameter, public host_to_device
Definition device.F90:48
integer, parameter, public device_to_host
Definition device.F90:48
type(c_ptr), bind(C), public glb_cmd_queue
Global command queue.
Definition device.F90:52
Implements global_interpolation given a dofmap.
real(kind=dp), parameter, public glob_interp_tol
Defines a mesh.
Definition mesh.f90:34
Build configurations.
integer, parameter neko_bcknd_device
integer, parameter, public dp
Definition num_types.f90:10
integer, parameter, public rp
Global precision used in computations.
Definition num_types.f90:14
Defines a function space.
Definition space.f90:34
Module with things related to the simulation time.
Utilities.
Definition utils.f90:35
Collection of live simulation data registered for checkpointing.
A named real array and its selection in a global checkpoint dataset.
Pointer wrapper used to keep payload addresses stable as the list grows.
A named collection of live fields to checkpoint together.
The function space for the SEM solution fields.
Definition space.f90:64
A struct that contains all info about the time, expand as needed.