FMS 2025.01.02-dev
Flexible Modeling System
Loading...
Searching...
No Matches
compute_global_checksum.inc
1!***********************************************************************
2!* GNU Lesser General Public License
3!*
4!* This file is part of the GFDL Flexible Modeling System (FMS).
5!*
6!* FMS is free software: you can redistribute it and/or modify it under
7!* the terms of the GNU Lesser General Public License as published by
8!* the Free Software Foundation, either version 3 of the License, or (at
9!* your option) any later version.
10!*
11!* FMS is distributed in the hope that it will be useful, but WITHOUT
12!* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13!* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14!* for more details.
15!*
16!* You should have received a copy of the GNU Lesser General Public
17!* License along with FMS. If not, see <http://www.gnu.org/licenses/>.
18!***********************************************************************
19!> @file
20!> @brief Routines for calculating variable checksums across pes for the @ref compute_global_checksum interface
21
22!> @addtogroup fms_netcdf_domain_io_mod
23!> @{
24
25!> @briefs Calculates a variable's checksum across all ranks in the current pelist.
26!! @return A hex string containing the checksum.
27function compute_global_checksum_2d(fileobj, variable_name, variable_data, is_decomposed) &
28 result(chksum)
29
30 class(fmsnetcdfdomainfile_t), intent(in) :: fileobj !< File object.
31 character(len=*), intent(in) :: variable_name !< Variable name.
32 class(*), dimension(:,:), intent(in) :: variable_data !< Data to be checksummed.
33 logical, intent(out) :: is_decomposed !< Flag telling if the variable is decomposed.
34 character(len=32) :: chksum
35
36 integer :: xdim
37 integer :: ydim
38 type(domain2d), pointer :: io_domain
39 integer :: xpos
40 integer :: ypos
41 integer :: isd
42 integer :: isc
43 integer :: xc_size
44 integer :: jsd
45 integer :: jsc
46 integer :: yc_size
47 logical :: buffer_includes_halos
48 logical :: extra_x
49 logical :: extra_y
50 integer, dimension(2) :: c
51 integer, dimension(2) :: e
52 integer(kind=i4_kind), dimension(:,:), allocatable :: buf_i4_kind
53 integer(kind=i8_kind), dimension(:,:), allocatable :: buf_i8_kind
54 real(kind=r4_kind), dimension(:,:), allocatable :: buf_r4_kind
55 real(kind=r8_kind), dimension(:,:), allocatable :: buf_r8_kind
56 integer(kind=i4_kind) :: fill_i4_kind
57 integer(kind=i8_kind) :: fill_i8_kind
58 real(kind=r4_kind) :: fill_r4_kind
59 real(kind=r8_kind) :: fill_r8_kind
60 integer(kind=i8_kind) :: chksum_val
61
62 is_decomposed = is_variable_domain_decomposed(fileobj, variable_name, &
63 xindex=xdim, yindex=ydim, &
64 xpos=xpos, ypos=ypos)
65 if (.not. is_decomposed) then
66 chksum = ""
67 return
68 endif
69 io_domain => mpp_get_io_domain(fileobj%domain)
70 call domain_offsets(size(variable_data, xdim), size(variable_data, ydim), fileobj%domain, &
71 xpos, ypos, isd, isc, xc_size, jsd, jsc, &
72 yc_size, buffer_includes_halos, extra_x, extra_y, &
73 msg="file:"//trim(fileobj%path)//" and variable:"//trim(variable_name))
74 c(:) = 1
75 if (buffer_includes_halos) then
76 !Adjust if the input buffer has room for halos.
77 c(xdim) = isc - isd + 1
78 c(ydim) = jsc - jsd + 1
79 endif
80 e(:) = shape(variable_data)
81 e(xdim) = xc_size
82 e(ydim) = yc_size
83
84 if (extra_x) then
85 !Adjust sizes since compute domains overlap whe there are non-centered
86 !domain position.
87 e(xdim) = e(xdim) - 1
88 endif
89
90 if (extra_y) then
91 !Adjust sizes since compute domains overlap whe there are non-centered
92 !domain position.
93 e(ydim) = e(ydim) - 1
94 endif
95
96 select type (variable_data)
97 type is (integer(kind=i4_kind))
98 call allocate_array(buf_i4_kind, e)
99 call get_array_section(buf_i4_kind, variable_data, c, e)
100 if (get_fill_value(fileobj, variable_name, fill_i4_kind)) then
101 chksum_val = mpp_chksum(buf_i4_kind, mask_val=fill_i4_kind)
102 else
103 chksum_val = mpp_chksum(buf_i4_kind)
104 endif
105 deallocate(buf_i4_kind)
106 type is (integer(kind=i8_kind))
107 call allocate_array(buf_i8_kind, e)
108 call get_array_section(buf_i8_kind, variable_data, c, e)
109 if (get_fill_value(fileobj, variable_name, fill_i8_kind)) then
110 chksum_val = mpp_chksum(buf_i8_kind, mask_val=fill_i8_kind)
111 else
112 chksum_val = mpp_chksum(buf_i8_kind)
113 endif
114 deallocate(buf_i8_kind)
115 type is (real(kind=r4_kind))
116 call allocate_array(buf_r4_kind, e)
117 call get_array_section(buf_r4_kind, variable_data, c, e)
118 if (get_fill_value(fileobj, variable_name, fill_r4_kind)) then
119 chksum_val = mpp_chksum(buf_r4_kind, mask_val=fill_r4_kind)
120 else
121 chksum_val = mpp_chksum(buf_r4_kind)
122 endif
123 deallocate(buf_r4_kind)
124 type is (real(kind=r8_kind))
125 call allocate_array(buf_r8_kind, e)
126 call get_array_section(buf_r8_kind, variable_data, c, e)
127 if (get_fill_value(fileobj, variable_name, fill_r8_kind)) then
128 chksum_val = mpp_chksum(buf_r8_kind, mask_val=fill_r8_kind)
129 else
130 chksum_val = mpp_chksum(buf_r8_kind)
131 endif
132 deallocate(buf_r8_kind)
133 class default
134 call error("unsupported variable type: compute_global_checksum_2d: file: "//trim(fileobj%path)//" variable:"// &
135 & trim(variable_name))
136 end select
137 chksum = ""
138 write(chksum, "(Z16)") chksum_val
140
141
142!> @briefs Calculates a variable's checksum across all ranks in the current pelist.
143!! @return A hex string containing the checksum.
144function compute_global_checksum_3d(fileobj, variable_name, variable_data, is_decomposed) &
145 result(chksum)
146
147 class(fmsnetcdfdomainfile_t), intent(in) :: fileobj !< File object.
148 character(len=*), intent(in) :: variable_name !< Variable name.
149 class(*), dimension(:,:,:), intent(in) :: variable_data !< Data to be checksummed.
150 logical, intent(out) :: is_decomposed !< Flag telling if the variable is decomposed.
151 character(len=32) :: chksum
152
153 integer :: xdim
154 integer :: ydim
155 type(domain2d), pointer :: io_domain
156 integer :: xpos
157 integer :: ypos
158 integer :: isd
159 integer :: isc
160 integer :: xc_size
161 integer :: jsd
162 integer :: jsc
163 integer :: yc_size
164 logical :: buffer_includes_halos
165 logical :: extra_x
166 logical :: extra_y
167 integer, dimension(3) :: c
168 integer, dimension(3) :: e
169 integer(kind=i4_kind), dimension(:,:,:), allocatable :: buf_i4_kind
170 integer(kind=i8_kind), dimension(:,:,:), allocatable :: buf_i8_kind
171 real(kind=r4_kind), dimension(:,:,:), allocatable :: buf_r4_kind
172 real(kind=r8_kind), dimension(:,:,:), allocatable :: buf_r8_kind
173 integer(kind=i4_kind) :: fill_i4_kind
174 integer(kind=i8_kind) :: fill_i8_kind
175 real(kind=r4_kind) :: fill_r4_kind
176 real(kind=r8_kind) :: fill_r8_kind
177 integer(kind=i8_kind) :: chksum_val
178
179 is_decomposed = is_variable_domain_decomposed(fileobj, variable_name, &
180 xindex=xdim, yindex=ydim, &
181 xpos=xpos, ypos=ypos)
182 if (.not. is_decomposed) then
183 chksum = ""
184 return
185 endif
186 io_domain => mpp_get_io_domain(fileobj%domain)
187 call domain_offsets(size(variable_data, xdim), size(variable_data, ydim), fileobj%domain, &
188 xpos, ypos, isd, isc, xc_size, jsd, jsc, &
189 yc_size, buffer_includes_halos, extra_x, extra_y, &
190 msg="file:"//trim(fileobj%path)//" and variable:"//trim(variable_name))
191 c(:) = 1
192 if (buffer_includes_halos) then
193 !Adjust if the input buffer has room for halos.
194 c(xdim) = isc - isd + 1
195 c(ydim) = jsc - jsd + 1
196 endif
197 e(:) = shape(variable_data)
198 e(xdim) = xc_size
199 e(ydim) = yc_size
200
201 if (extra_x) then
202 !Adjust sizes since compute domains overlap whe there are non-centered
203 !domain position.
204 e(xdim) = e(xdim) - 1
205 endif
206
207 if (extra_y) then
208 !Adjust sizes since compute domains overlap whe there are non-centered
209 !domain position.
210 e(ydim) = e(ydim) - 1
211 endif
212 select type (variable_data)
213 type is (integer(kind=i4_kind))
214 call allocate_array(buf_i4_kind, e)
215 call get_array_section(buf_i4_kind, variable_data, c, e)
216 if (get_fill_value(fileobj, variable_name, fill_i4_kind)) then
217 chksum_val = mpp_chksum(buf_i4_kind, mask_val=fill_i4_kind)
218 else
219 chksum_val = mpp_chksum(buf_i4_kind)
220 endif
221 deallocate(buf_i4_kind)
222 type is (integer(kind=i8_kind))
223 call allocate_array(buf_i8_kind, e)
224 call get_array_section(buf_i8_kind, variable_data, c, e)
225 if (get_fill_value(fileobj, variable_name, fill_i8_kind)) then
226 chksum_val = mpp_chksum(buf_i8_kind, mask_val=fill_i8_kind)
227 else
228 chksum_val = mpp_chksum(buf_i8_kind)
229 endif
230 deallocate(buf_i8_kind)
231 type is (real(kind=r4_kind))
232 call allocate_array(buf_r4_kind, e)
233 call get_array_section(buf_r4_kind, variable_data, c, e)
234 if (get_fill_value(fileobj, variable_name, fill_r4_kind)) then
235 chksum_val = mpp_chksum(buf_r4_kind, mask_val=fill_r4_kind)
236 else
237 chksum_val = mpp_chksum(buf_r4_kind)
238 endif
239 deallocate(buf_r4_kind)
240 type is (real(kind=r8_kind))
241 call allocate_array(buf_r8_kind, e)
242 call get_array_section(buf_r8_kind, variable_data, c, e)
243 if (get_fill_value(fileobj, variable_name, fill_r8_kind)) then
244 chksum_val = mpp_chksum(buf_r8_kind, mask_val=fill_r8_kind)
245 else
246 chksum_val = mpp_chksum(buf_r8_kind)
247 endif
248 deallocate(buf_r8_kind)
249 class default
250 call error("unsupported variable type: compute_global_checksum_3d: file: "//trim(fileobj%path)//" variable:"// &
251 & trim(variable_name))
252 end select
253 chksum = ""
254 write(chksum, "(Z16)") chksum_val
256
257
258!> @briefs Calculates a variable's checksum across all ranks in the current pelist.
259!! @return A hex string containing the checksum.
260function compute_global_checksum_4d(fileobj, variable_name, variable_data, is_decomposed) &
261 result(chksum)
262
263 class(fmsnetcdfdomainfile_t), intent(in) :: fileobj !< File object.
264 character(len=*), intent(in) :: variable_name !< Variable name.
265 class(*), dimension(:,:,:,:), intent(in) :: variable_data !< Data to be checksummed.
266 logical, intent(out) :: is_decomposed !< Flag telling if the variable is decomposed.
267 character(len=32) :: chksum
268
269 integer :: xdim
270 integer :: ydim
271 type(domain2d), pointer :: io_domain
272 integer :: xpos
273 integer :: ypos
274 integer :: isd
275 integer :: isc
276 integer :: xc_size
277 integer :: jsd
278 integer :: jsc
279 integer :: yc_size
280 logical :: buffer_includes_halos
281 logical :: extra_x
282 logical :: extra_y
283 integer, dimension(4) :: c
284 integer, dimension(4) :: e
285 integer(kind=i4_kind), dimension(:,:,:,:), allocatable :: buf_i4_kind
286 integer(kind=i8_kind), dimension(:,:,:,:), allocatable :: buf_i8_kind
287 real(kind=r4_kind), dimension(:,:,:,:), allocatable :: buf_r4_kind
288 real(kind=r8_kind), dimension(:,:,:,:), allocatable :: buf_r8_kind
289 integer(kind=i4_kind) :: fill_i4_kind
290 integer(kind=i8_kind) :: fill_i8_kind
291 real(kind=r4_kind) :: fill_r4_kind
292 real(kind=r8_kind) :: fill_r8_kind
293 integer(kind=i8_kind) :: chksum_val
294
295 is_decomposed = is_variable_domain_decomposed(fileobj, variable_name, &
296 xindex=xdim, yindex=ydim, &
297 xpos=xpos, ypos=ypos)
298 if (.not. is_decomposed) then
299 chksum = ""
300 return
301 endif
302 io_domain => mpp_get_io_domain(fileobj%domain)
303 call domain_offsets(size(variable_data, xdim), size(variable_data, ydim), fileobj%domain, &
304 xpos, ypos, isd, isc, xc_size, jsd, jsc, &
305 yc_size, buffer_includes_halos, extra_x, extra_y, &
306 msg="file:"//trim(fileobj%path)//" and variable:"//trim(variable_name))
307 c(:) = 1
308 if (buffer_includes_halos) then
309 !Adjust if the input buffer has room for halos.
310 c(xdim) = isc - isd + 1
311 c(ydim) = jsc - jsd + 1
312 endif
313 e(:) = shape(variable_data)
314 e(xdim) = xc_size
315 e(ydim) = yc_size
316
317 if (extra_x) then
318 !Adjust sizes since compute domains overlap whe there are non-centered
319 !domain position.
320 e(xdim) = e(xdim) - 1
321 endif
322
323 if (extra_y) then
324 !Adjust sizes since compute domains overlap whe there are non-centered
325 !domain position.
326 e(ydim) = e(ydim) - 1
327 endif
328
329 select type (variable_data)
330 type is (integer(kind=i4_kind))
331 call allocate_array(buf_i4_kind, e)
332 call get_array_section(buf_i4_kind, variable_data, c, e)
333 if (get_fill_value(fileobj, variable_name, fill_i4_kind)) then
334 chksum_val = mpp_chksum(buf_i4_kind, mask_val=fill_i4_kind)
335 else
336 chksum_val = mpp_chksum(buf_i4_kind)
337 endif
338 deallocate(buf_i4_kind)
339 type is (integer(kind=i8_kind))
340 call allocate_array(buf_i8_kind, e)
341 call get_array_section(buf_i8_kind, variable_data, c, e)
342 if (get_fill_value(fileobj, variable_name, fill_i8_kind)) then
343 chksum_val = mpp_chksum(buf_i8_kind, mask_val=fill_i8_kind)
344 else
345 chksum_val = mpp_chksum(buf_i8_kind)
346 endif
347 deallocate(buf_i8_kind)
348 type is (real(kind=r4_kind))
349 call allocate_array(buf_r4_kind, e)
350 call get_array_section(buf_r4_kind, variable_data, c, e)
351 if (get_fill_value(fileobj, variable_name, fill_r4_kind)) then
352 chksum_val = mpp_chksum(buf_r4_kind, mask_val=fill_r4_kind)
353 else
354 chksum_val = mpp_chksum(buf_r4_kind)
355 endif
356 deallocate(buf_r4_kind)
357 type is (real(kind=r8_kind))
358 call allocate_array(buf_r8_kind, e)
359 call get_array_section(buf_r8_kind, variable_data, c, e)
360 if (get_fill_value(fileobj, variable_name, fill_r8_kind)) then
361 chksum_val = mpp_chksum(buf_r8_kind, mask_val=fill_r8_kind)
362 else
363 chksum_val = mpp_chksum(buf_r8_kind)
364 endif
365 deallocate(buf_r8_kind)
366 class default
367 call error("unsupported variable type: compute_global_checksum_4d: file: "//trim(fileobj%path)//" variable:"// &
368 & trim(variable_name))
369 end select
370 chksum = ""
371 write(chksum, "(Z16)") chksum_val
373!> @}
character(len=32) function compute_global_checksum_3d(fileobj, variable_name, variable_data, is_decomposed)
@briefs Calculates a variable's checksum across all ranks in the current pelist.
character(len=32) function compute_global_checksum_4d(fileobj, variable_name, variable_data, is_decomposed)
@briefs Calculates a variable's checksum across all ranks in the current pelist.
character(len=32) function compute_global_checksum_2d(fileobj, variable_name, variable_data, is_decomposed)
@briefs Calculates a variable's checksum across all ranks in the current pelist.
type(domain2d) function, pointer mpp_get_io_domain(domain)
Set user stack size.