Neko  0.8.99
A portable framework for high-order spectral element flow simulations
checkpoint.f90
Go to the documentation of this file.
1 ! Copyright (c) 2021, 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 !
34 module checkpoint
35  use neko_config
36  use num_types, only : rp, dp
37  use field_series, only : field_series_t
38  use space
39  use device
40  use field, only : field_t
41  use utils, only : neko_error
42  use mesh, only: mesh_t
43  implicit none
44  private
45 
46  type, public :: chkp_t
47  type(field_t), pointer :: u => null()
48  type(field_t), pointer :: v => null()
49  type(field_t), pointer :: w => null()
50  type(field_t), pointer :: p => null()
51 
52 
53  !
54  ! Optional payload
55  !
56  type(field_series_t), pointer :: ulag => null()
57  type(field_series_t), pointer :: vlag => null()
58  type(field_series_t), pointer :: wlag => null()
59 
60  real(kind=rp), pointer :: tlag(:) => null()
61  real(kind=rp), pointer :: dtlag(:) => null()
62 
64  type(field_t), pointer :: abx1 => null()
65  type(field_t), pointer :: abx2 => null()
66  type(field_t), pointer :: aby1 => null()
67  type(field_t), pointer :: aby2 => null()
68  type(field_t), pointer :: abz1 => null()
69  type(field_t), pointer :: abz2 => null()
70 
71  type(field_t), pointer :: s => null()
72  type(field_series_t), pointer :: slag => null()
73 
74  type(field_t), pointer :: abs1 => null()
75  type(field_t), pointer :: abs2 => null()
76 
77  real(kind=dp) :: t
78  type(mesh_t) :: previous_mesh
79  real(kind=rp) :: mesh2mesh_tol = 1d-6
80 
81  contains
82  procedure, pass(this) :: init => chkp_init
83  procedure, pass(this) :: sync_host => chkp_sync_host
84  procedure, pass(this) :: sync_device => chkp_sync_device
85  procedure, pass(this) :: add_lag => chkp_add_lag
86  procedure, pass(this) :: add_scalar => chkp_add_scalar
87  procedure, pass(this) :: restart_time => chkp_restart_time
88  final :: chkp_free
89  end type chkp_t
90 
91 contains
92 
94  subroutine chkp_init(this, u, v, w, p)
95  class(chkp_t), intent(inout) :: this
96  type(field_t), intent(in), target :: u
97  type(field_t), intent(in), target :: v
98  type(field_t), intent(in), target :: w
99  type(field_t), intent(in), target :: p
100 
101  ! Check that all velocity components are defined on the same
102  ! function space
103  if ( u%Xh .ne. v%Xh .or. &
104  u%Xh .ne. w%Xh ) then
105  call neko_error('Different function spaces for each velocity component')
106  end if
107 
108  ! Check that both velocity and pressure is defined on the same mesh
109  if ( u%msh%nelv .ne. p%msh%nelv ) then
110  call neko_error('Velocity and pressure defined on different meshes')
111  end if
112 
113  this%u => u
114  this%v => v
115  this%w => w
116  this%p => p
117 
118  this%t = 0d0
119 
120  end subroutine chkp_init
121 
123  subroutine chkp_free(this)
124  type(chkp_t), intent(inout) :: this
125 
126  nullify(this%u)
127  nullify(this%v)
128  nullify(this%w)
129  nullify(this%p)
130 
131  nullify(this%ulag)
132  nullify(this%vlag)
133  nullify(this%wlag)
134 
135  end subroutine chkp_free
136 
138  subroutine chkp_sync_host(this)
139  class(chkp_t), intent(inout) :: this
140 
141  if (neko_bcknd_device .eq. 1) then
142  associate(u=>this%u, v=>this%v, w=>this%w, &
143  ulag=>this%ulag, vlag=>this%vlag, wlag=>this%wlag, &
144  p=>this%p)
145 
146  if (associated(this%u) .and. associated(this%v) .and. &
147  associated(this%w) .and. associated(this%p)) then
148  call device_memcpy(u%x, u%x_d, u%dof%size(), device_to_host, sync=.false.)
149  call device_memcpy(v%x, v%x_d, v%dof%size(), device_to_host, sync=.false.)
150  call device_memcpy(w%x, w%x_d, w%dof%size(), device_to_host, sync=.false.)
151  call device_memcpy(p%x, p%x_d, p%dof%size(), device_to_host, sync=.false.)
152  end if
153 
154  if (associated(this%ulag) .and. associated(this%vlag) .and. &
155  associated(this%wlag)) then
156  call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, &
157  u%dof%size(), device_to_host, sync=.false.)
158  call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, &
159  u%dof%size(), device_to_host, sync=.false.)
160 
161  call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, &
162  v%dof%size(), device_to_host, sync=.false.)
163  call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, &
164  v%dof%size(), device_to_host, sync=.false.)
165 
166  call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, &
167  w%dof%size(), device_to_host, sync=.false.)
168  call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, &
169  w%dof%size(), device_to_host, sync=.false.)
170  call device_memcpy(this%abx1%x, this%abx1%x_d, &
171  w%dof%size(), device_to_host, sync=.false.)
172  call device_memcpy(this%abx2%x, this%abx2%x_d, &
173  w%dof%size(), device_to_host, sync=.false.)
174  call device_memcpy(this%aby1%x, this%aby1%x_d, &
175  w%dof%size(), device_to_host, sync=.false.)
176  call device_memcpy(this%aby2%x, this%aby2%x_d, &
177  w%dof%size(), device_to_host, sync=.false.)
178  call device_memcpy(this%abz1%x, this%abz1%x_d, &
179  w%dof%size(), device_to_host, sync=.false.)
180  call device_memcpy(this%abz2%x, this%abz2%x_d, &
181  w%dof%size(), device_to_host, sync=.false.)
182  end if
183  if (associated(this%s)) then
184  call device_memcpy(this%s%x, this%s%x_d, &
185  this%s%dof%size(), device_to_host, sync=.false.)
186  call device_memcpy(this%slag%lf(1)%x, this%slag%lf(1)%x_d, &
187  this%s%dof%size(), device_to_host, sync=.false.)
188  call device_memcpy(this%slag%lf(2)%x, this%slag%lf(2)%x_d, &
189  this%s%dof%size(), device_to_host, sync=.false.)
190  call device_memcpy(this%abs1%x, this%abs1%x_d, &
191  w%dof%size(), device_to_host, sync=.false.)
192  call device_memcpy(this%abs2%x, this%abs2%x_d, &
193  w%dof%size(), device_to_host, sync=.false.)
194  end if
195  end associate
196  call device_sync(glb_cmd_queue)
197  end if
198 
199  end subroutine chkp_sync_host
200 
202  subroutine chkp_sync_device(this)
203  class(chkp_t), intent(inout) :: this
204 
205  if (neko_bcknd_device .eq. 1) then
206  associate(u=>this%u, v=>this%v, w=>this%w, &
207  ulag=>this%ulag, vlag=>this%vlag, wlag=>this%wlag,&
208  p=>this%p)
209 
210  if (associated(this%u) .and. associated(this%v) .and. &
211  associated(this%w)) then
212  call device_memcpy(u%x, u%x_d, u%dof%size(), &
213  host_to_device, sync=.false.)
214  call device_memcpy(v%x, v%x_d, v%dof%size(), &
215  host_to_device, sync=.false.)
216  call device_memcpy(w%x, w%x_d, w%dof%size(), &
217  host_to_device, sync=.false.)
218  call device_memcpy(p%x, p%x_d, p%dof%size(), &
219  host_to_device, sync=.false.)
220  end if
221 
222  if (associated(this%ulag) .and. associated(this%vlag) .and. &
223  associated(this%wlag)) then
224  call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, u%dof%size(), &
225  host_to_device, sync=.false.)
226  call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, u%dof%size(), &
227  host_to_device, sync=.false.)
228 
229  call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, v%dof%size(), &
230  host_to_device, sync=.false.)
231  call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, v%dof%size(), &
232  host_to_device, sync=.false.)
233 
234  call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, w%dof%size(), &
235  host_to_device, sync=.false.)
236  call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, w%dof%size(), &
237  host_to_device, sync=.false.)
238  end if
239  if (associated(this%s)) then
240  call device_memcpy(this%s%x, this%s%x_d, this%s%dof%size(), &
241  host_to_device, sync=.false.)
242 
243  call device_memcpy(this%slag%lf(1)%x, this%slag%lf(1)%x_d, &
244  this%s%dof%size(), host_to_device, sync=.false.)
245  call device_memcpy(this%slag%lf(2)%x, this%slag%lf(2)%x_d, &
246  this%s%dof%size(), host_to_device, sync=.false.)
247  call device_memcpy(this%abs1%x, this%abs1%x_d, &
248  w%dof%size(), host_to_device, sync=.false.)
249  call device_memcpy(this%abs2%x, this%abs2%x_d, &
250  w%dof%size(), host_to_device, sync=.false.)
251  end if
252  end associate
253  end if
254 
255  end subroutine chkp_sync_device
256 
258  subroutine chkp_add_lag(this, ulag, vlag, wlag)
259  class(chkp_t), intent(inout) :: this
260  type(field_series_t), target :: ulag
261  type(field_series_t), target :: vlag
262  type(field_series_t), target :: wlag
263 
264  this%ulag => ulag
265  this%vlag => vlag
266  this%wlag => wlag
267 
268  end subroutine chkp_add_lag
269 
271  subroutine chkp_add_scalar(this, s)
272  class(chkp_t), intent(inout) :: this
273  type(field_t), target :: s
274 
275  this%s => s
276 
277  end subroutine chkp_add_scalar
278 
279 
281  pure function chkp_restart_time(this) result(rtime)
282  class(chkp_t), intent(in) :: this
283  real(kind=dp) :: rtime
284 
285  rtime = this%t
286  end function chkp_restart_time
287 
288 end module checkpoint
Copy data between host and device (or device and device)
Definition: device.F90:51
Synchronize a device or stream.
Definition: device.F90:87
Defines a checkpoint.
Definition: checkpoint.f90:34
subroutine chkp_sync_host(this)
Synchronize checkpoint with device.
Definition: checkpoint.f90:139
subroutine chkp_init(this, u, v, w, p)
Initialize checkpoint structure with mandatory data.
Definition: checkpoint.f90:95
subroutine chkp_sync_device(this)
Synchronize device with checkpoint.
Definition: checkpoint.f90:203
subroutine chkp_add_scalar(this, s)
Add scalars.
Definition: checkpoint.f90:272
pure real(kind=dp) function chkp_restart_time(this)
Return restart time from a loaded checkpoint.
Definition: checkpoint.f90:282
subroutine chkp_free(this)
Reset checkpoint.
Definition: checkpoint.f90:124
subroutine chkp_add_lag(this, ulag, vlag, wlag)
Add lagged velocity terms.
Definition: checkpoint.f90:259
Device abstraction, common interface for various accelerators.
Definition: device.F90:34
integer, parameter, public device_to_host
Definition: device.F90:47
Stores a series fields.
Defines a field.
Definition: field.f90:34
Defines a mesh.
Definition: mesh.f90:34
Build configurations.
Definition: neko_config.f90:34
integer, parameter neko_bcknd_device
Definition: neko_config.f90:44
integer, parameter, public dp
Definition: num_types.f90:9
integer, parameter, public rp
Global precision used in computations.
Definition: num_types.f90:12
Defines a function space.
Definition: space.f90:34
Utilities.
Definition: utils.f90:35