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  type(space_t) :: previous_xh
80  real(kind=rp) :: mesh2mesh_tol = 1d-6
81 
82  contains
83  procedure, pass(this) :: init => chkp_init
84  procedure, pass(this) :: sync_host => chkp_sync_host
85  procedure, pass(this) :: sync_device => chkp_sync_device
86  procedure, pass(this) :: add_lag => chkp_add_lag
87  procedure, pass(this) :: add_scalar => chkp_add_scalar
88  procedure, pass(this) :: restart_time => chkp_restart_time
89  final :: chkp_free
90  end type chkp_t
91 
92 contains
93 
95  subroutine chkp_init(this, u, v, w, p)
96  class(chkp_t), intent(inout) :: this
97  type(field_t), intent(in), target :: u
98  type(field_t), intent(in), target :: v
99  type(field_t), intent(in), target :: w
100  type(field_t), intent(in), target :: p
101 
102  ! Check that all velocity components are defined on the same
103  ! function space
104  if ( u%Xh .ne. v%Xh .or. &
105  u%Xh .ne. w%Xh ) then
106  call neko_error('Different function spaces for each velocity component')
107  end if
108 
109  ! Check that both velocity and pressure is defined on the same mesh
110  if ( u%msh%nelv .ne. p%msh%nelv ) then
111  call neko_error('Velocity and pressure defined on different meshes')
112  end if
113 
114  this%u => u
115  this%v => v
116  this%w => w
117  this%p => p
118 
119  this%t = 0d0
120 
121  end subroutine chkp_init
122 
124  subroutine chkp_free(this)
125  type(chkp_t), intent(inout) :: this
126 
127  nullify(this%u)
128  nullify(this%v)
129  nullify(this%w)
130  nullify(this%p)
131 
132  nullify(this%ulag)
133  nullify(this%vlag)
134  nullify(this%wlag)
135 
136  end subroutine chkp_free
137 
139  subroutine chkp_sync_host(this)
140  class(chkp_t), intent(inout) :: this
141 
142  if (neko_bcknd_device .eq. 1) then
143  associate(u=>this%u, v=>this%v, w=>this%w, &
144  ulag=>this%ulag, vlag=>this%vlag, wlag=>this%wlag, &
145  p=>this%p)
146 
147  if (associated(this%u) .and. associated(this%v) .and. &
148  associated(this%w) .and. associated(this%p)) then
149  call device_memcpy(u%x, u%x_d, u%dof%size(), device_to_host, sync=.false.)
150  call device_memcpy(v%x, v%x_d, v%dof%size(), device_to_host, sync=.false.)
151  call device_memcpy(w%x, w%x_d, w%dof%size(), device_to_host, sync=.false.)
152  call device_memcpy(p%x, p%x_d, p%dof%size(), device_to_host, sync=.false.)
153  end if
154 
155  if (associated(this%ulag) .and. associated(this%vlag) .and. &
156  associated(this%wlag)) then
157  call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, &
158  u%dof%size(), device_to_host, sync=.false.)
159  call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, &
160  u%dof%size(), device_to_host, sync=.false.)
161 
162  call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, &
163  v%dof%size(), device_to_host, sync=.false.)
164  call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, &
165  v%dof%size(), device_to_host, sync=.false.)
166 
167  call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, &
168  w%dof%size(), device_to_host, sync=.false.)
169  call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, &
170  w%dof%size(), device_to_host, sync=.false.)
171  call device_memcpy(this%abx1%x, this%abx1%x_d, &
172  w%dof%size(), device_to_host, sync=.false.)
173  call device_memcpy(this%abx2%x, this%abx2%x_d, &
174  w%dof%size(), device_to_host, sync=.false.)
175  call device_memcpy(this%aby1%x, this%aby1%x_d, &
176  w%dof%size(), device_to_host, sync=.false.)
177  call device_memcpy(this%aby2%x, this%aby2%x_d, &
178  w%dof%size(), device_to_host, sync=.false.)
179  call device_memcpy(this%abz1%x, this%abz1%x_d, &
180  w%dof%size(), device_to_host, sync=.false.)
181  call device_memcpy(this%abz2%x, this%abz2%x_d, &
182  w%dof%size(), device_to_host, sync=.false.)
183  end if
184  if (associated(this%s)) then
185  call device_memcpy(this%s%x, this%s%x_d, &
186  this%s%dof%size(), device_to_host, sync=.false.)
187  call device_memcpy(this%slag%lf(1)%x, this%slag%lf(1)%x_d, &
188  this%s%dof%size(), device_to_host, sync=.false.)
189  call device_memcpy(this%slag%lf(2)%x, this%slag%lf(2)%x_d, &
190  this%s%dof%size(), device_to_host, sync=.false.)
191  call device_memcpy(this%abs1%x, this%abs1%x_d, &
192  w%dof%size(), device_to_host, sync=.false.)
193  call device_memcpy(this%abs2%x, this%abs2%x_d, &
194  w%dof%size(), device_to_host, sync=.false.)
195  end if
196  end associate
197  call device_sync(glb_cmd_queue)
198  end if
199 
200  end subroutine chkp_sync_host
201 
203  subroutine chkp_sync_device(this)
204  class(chkp_t), intent(inout) :: this
205 
206  if (neko_bcknd_device .eq. 1) then
207  associate(u=>this%u, v=>this%v, w=>this%w, &
208  ulag=>this%ulag, vlag=>this%vlag, wlag=>this%wlag,&
209  p=>this%p)
210 
211  if (associated(this%u) .and. associated(this%v) .and. &
212  associated(this%w)) then
213  call device_memcpy(u%x, u%x_d, u%dof%size(), &
214  host_to_device, sync=.false.)
215  call device_memcpy(v%x, v%x_d, v%dof%size(), &
216  host_to_device, sync=.false.)
217  call device_memcpy(w%x, w%x_d, w%dof%size(), &
218  host_to_device, sync=.false.)
219  call device_memcpy(p%x, p%x_d, p%dof%size(), &
220  host_to_device, sync=.false.)
221  end if
222 
223  if (associated(this%ulag) .and. associated(this%vlag) .and. &
224  associated(this%wlag)) then
225  call device_memcpy(ulag%lf(1)%x, ulag%lf(1)%x_d, u%dof%size(), &
226  host_to_device, sync=.false.)
227  call device_memcpy(ulag%lf(2)%x, ulag%lf(2)%x_d, u%dof%size(), &
228  host_to_device, sync=.false.)
229 
230  call device_memcpy(vlag%lf(1)%x, vlag%lf(1)%x_d, v%dof%size(), &
231  host_to_device, sync=.false.)
232  call device_memcpy(vlag%lf(2)%x, vlag%lf(2)%x_d, v%dof%size(), &
233  host_to_device, sync=.false.)
234 
235  call device_memcpy(wlag%lf(1)%x, wlag%lf(1)%x_d, w%dof%size(), &
236  host_to_device, sync=.false.)
237  call device_memcpy(wlag%lf(2)%x, wlag%lf(2)%x_d, w%dof%size(), &
238  host_to_device, sync=.false.)
239  end if
240  if (associated(this%s)) then
241  call device_memcpy(this%s%x, this%s%x_d, this%s%dof%size(), &
242  host_to_device, sync=.false.)
243 
244  call device_memcpy(this%slag%lf(1)%x, this%slag%lf(1)%x_d, &
245  this%s%dof%size(), host_to_device, sync=.false.)
246  call device_memcpy(this%slag%lf(2)%x, this%slag%lf(2)%x_d, &
247  this%s%dof%size(), host_to_device, sync=.false.)
248  call device_memcpy(this%abs1%x, this%abs1%x_d, &
249  w%dof%size(), host_to_device, sync=.false.)
250  call device_memcpy(this%abs2%x, this%abs2%x_d, &
251  w%dof%size(), host_to_device, sync=.false.)
252  end if
253  end associate
254  end if
255 
256  end subroutine chkp_sync_device
257 
259  subroutine chkp_add_lag(this, ulag, vlag, wlag)
260  class(chkp_t), intent(inout) :: this
261  type(field_series_t), target :: ulag
262  type(field_series_t), target :: vlag
263  type(field_series_t), target :: wlag
264 
265  this%ulag => ulag
266  this%vlag => vlag
267  this%wlag => wlag
268 
269  end subroutine chkp_add_lag
270 
272  subroutine chkp_add_scalar(this, s)
273  class(chkp_t), intent(inout) :: this
274  type(field_t), target :: s
275 
276  this%s => s
277 
278  end subroutine chkp_add_scalar
279 
280 
282  pure function chkp_restart_time(this) result(rtime)
283  class(chkp_t), intent(in) :: this
284  real(kind=dp) :: rtime
285 
286  rtime = this%t
287  end function chkp_restart_time
288 
289 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:140
subroutine chkp_init(this, u, v, w, p)
Initialize checkpoint structure with mandatory data.
Definition: checkpoint.f90:96
subroutine chkp_sync_device(this)
Synchronize device with checkpoint.
Definition: checkpoint.f90:204
subroutine chkp_add_scalar(this, s)
Add scalars.
Definition: checkpoint.f90:273
pure real(kind=dp) function chkp_restart_time(this)
Return restart time from a loaded checkpoint.
Definition: checkpoint.f90:283
subroutine chkp_free(this)
Reset checkpoint.
Definition: checkpoint.f90:125
subroutine chkp_add_lag(this, ulag, vlag, wlag)
Add lagged velocity terms.
Definition: checkpoint.f90:260
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
The function space for the SEM solution fields.
Definition: space.f90:62