FMS  2026.01.01-dev
Flexible Modeling System
compressed_write.inc
1 !***********************************************************************
2 !* Apache License 2.0
3 !*
4 !* This file is part of the GFDL Flexible Modeling System (FMS).
5 !*
6 !* Licensed under the Apache License, Version 2.0 (the "License");
7 !* you may not use this file except in compliance with the License.
8 !* You may obtain a copy of the License at
9 !*
10 !* http://www.apache.org/licenses/LICENSE-2.0
11 !*
12 !* FMS is distributed in the hope that it will be useful, but WITHOUT
13 !* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied;
14 !* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 !* PARTICULAR PURPOSE. See the License for the specific language
16 !* governing permissions and limitations under the License.
17 !***********************************************************************
18 !> @file
19 !> @brief Compressed write routines for @ref write_data interface
20 
21 !> @addtogroup fms2_io_mod
22 !> @{
23 
24 !> @brief For variables without a compressed dimension, this routine simply wraps
25 !! netcdf_write data. If the variable does have a compressed axis, the I/O root
26 !! gathers the data from the rest of the ranks and then writes the combined data to
27 !! the netcdf file.
28 subroutine compressed_write_0d(fileobj, variable_name, cdata, unlim_dim_level, &
29  corner)
30 
31  class(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
32  character(len=*), intent(in) :: variable_name !< Variable name.
33  class(*), intent(in) :: cdata !< Compressed data that
34  !! will be gathered and
35  !! written to the
36  !! netcdf file.
37  integer, intent(in), optional :: unlim_dim_level !< Level for the unlimited
38  !! dimension.
39  integer, intent(in), optional :: corner !< Array of starting
40  !! indices describing
41  !! where the data
42  !! will be written to.
43 
44  integer, dimension(2) :: compressed_dim_index
45 
46  compressed_dim_index = get_variable_compressed_dimension_index(fileobj, variable_name)
47  if (compressed_dim_index(1) .eq. dimension_not_found) then
48  call netcdf_write_data(fileobj, variable_name, cdata, &
49  unlim_dim_level=unlim_dim_level, corner=corner)
50  return
51  endif
52 end subroutine compressed_write_0d
53 
54 
55 !> @brief Wrapper to distinguish interfaces.
56 subroutine compressed_write_0d_wrap(fileobj, variable_name, cdata, unlim_dim_level, &
57  corner)
58 
59  type(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
60  character(len=*), intent(in) :: variable_name !< Variable name.
61  class(*), intent(in) :: cdata !< Compressed data that
62  !! will be gathered and
63  !! written to the
64  !! netcdf file.
65  integer, intent(in), optional :: unlim_dim_level !< Level for the unlimited
66  !! dimension.
67  integer, intent(in), optional :: corner !< Array of starting
68  !! indices describing
69  !! where the data
70  !! will be written to.
71 
72  call compressed_write(fileobj, variable_name, cdata, unlim_dim_level, corner)
73 end subroutine compressed_write_0d_wrap
74 
75 
76 !> @brief For variables without a compressed dimension, this routine simply wraps
77 !! netcdf_write data. If the variable does have a compressed axis, the I/O root
78 !! gathers the data from the rest of the ranks and then writes the combined data to
79 !! the netcdf file.
80 subroutine compressed_write_1d(fileobj, variable_name, cdata, unlim_dim_level, &
81  corner, edge_lengths)
82 
83  class(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
84  character(len=*), intent(in) :: variable_name !< Variable name.
85  class(*), dimension(:), intent(in) :: cdata !< Compressed data that
86  !! will be gathered and
87  !! written to the
88  !! netcdf file.
89  integer, intent(in), optional :: unlim_dim_level !< Level for the unlimited
90  !! dimension.
91  integer, dimension(1), intent(in), optional :: corner !< Array of starting
92  !! indices describing
93  !! where the data
94  !! will be written to.
95  integer, dimension(1), intent(in), optional :: edge_lengths !< The number of
96  !! elements that
97  !! will be written
98  !! in each dimension.
99 
100  integer, dimension(2) :: compressed_dim_index !< index of the compressed dimension
101  !! compressed_dim_index(1) relative to cdata
102  !! compressed_dim_index(2) relative to the fileobj
103  integer, dimension(1) :: e !< "edges" number of points to read
104 
105  integer(kind=i4_kind), dimension(:), allocatable :: buf_i4_kind !< Global buffer of data
106  integer(kind=i8_kind), dimension(:), allocatable :: buf_i8_kind !< Global buffer of data
107  real (kind=r4_kind), dimension(:), allocatable :: buf_r4_kind !< Global buffer of data
108  real (kind=r8_kind), dimension(:), allocatable :: buf_r8_kind !< Global buffer of data
109 
110  character(len=200) :: append_error_msg !< Msg to be appended to FATAL error message
111 
112  append_error_msg = "compressed_write_1d: file:"//trim(fileobj%path)//" variable:"//trim(variable_name)
113 
114  compressed_dim_index = get_variable_compressed_dimension_index(fileobj, variable_name)
115 
116  if (compressed_dim_index(1) .eq. dimension_not_found) then
117  call netcdf_write_data(fileobj, variable_name, cdata, &
118  unlim_dim_level=unlim_dim_level, corner=corner, &
119  edge_lengths=edge_lengths)
120  return
121  endif
122 
123  e(:) = shape(cdata)
124  !The root pe creates a buffer big enough to store the data:
125  if (fileobj%is_root) then
126  e(compressed_dim_index(1)) = sum(fileobj%compressed_dims(compressed_dim_index(2))%npes_nelems)
127  select type(cdata)
128  type is (integer(kind=i4_kind))
129  call allocate_array(buf_i4_kind, e)
130  type is (integer(kind=i8_kind))
131  call allocate_array(buf_i8_kind, e)
132  type is (real(kind=r4_kind))
133  call allocate_array(buf_r4_kind, e)
134  type is (real(kind=r8_kind))
135  call allocate_array(buf_r8_kind, e)
136  class default
137  call error("unsupported variable type: "//trim(append_error_msg))
138  end select
139  else
140  select type(cdata)
141  type is (integer(kind=i4_kind))
142  allocate(buf_i4_kind(1))
143  type is (integer(kind=i8_kind))
144  allocate(buf_i8_kind(1))
145  type is (real(kind=r4_kind))
146  allocate(buf_r4_kind(1))
147  type is (real(kind=r8_kind))
148  allocate(buf_r8_kind(1))
149  class default
150  call error("unsupported variable type: "//trim(append_error_msg))
151  end select
152  endif
153 
154  !Gather the data onto the I/O root and write it out.
155  select type(cdata)
156  type is (integer(kind=i4_kind))
157  call mpp_gather(cdata, size(cdata), buf_i4_kind, fileobj%compressed_dims(compressed_dim_index(2))%npes_nelems, &
158  fileobj%pelist)
159  if (fileobj%is_root) call netcdf_write_data(fileobj, variable_name, buf_i4_kind, &
160  unlim_dim_level=unlim_dim_level)
161  type is (integer(kind=i8_kind))
162  call mpp_gather(cdata, size(cdata), buf_i8_kind, fileobj%compressed_dims(compressed_dim_index(2))%npes_nelems, &
163  fileobj%pelist)
164  if (fileobj%is_root) call netcdf_write_data(fileobj, variable_name, buf_i8_kind, &
165  unlim_dim_level=unlim_dim_level)
166  type is (real(kind=r4_kind))
167  call mpp_gather(cdata, size(cdata), buf_r4_kind, fileobj%compressed_dims(compressed_dim_index(2))%npes_nelems, &
168  fileobj%pelist)
169  if (fileobj%is_root) call netcdf_write_data(fileobj, variable_name, buf_r4_kind, &
170  unlim_dim_level=unlim_dim_level)
171  type is (real(kind=r8_kind))
172  call mpp_gather(cdata, size(cdata), buf_r8_kind, fileobj%compressed_dims(compressed_dim_index(2))%npes_nelems, &
173  fileobj%pelist)
174  if (fileobj%is_root) call netcdf_write_data(fileobj, variable_name, buf_r8_kind, &
175  unlim_dim_level=unlim_dim_level)
176  class default
177  call error("unsupported variable type: "//trim(append_error_msg))
178  end select
179  if (allocated(buf_i4_kind)) deallocate(buf_i4_kind)
180  if (allocated(buf_i8_kind)) deallocate(buf_i8_kind)
181  if (allocated(buf_r4_kind)) deallocate(buf_r4_kind)
182  if (allocated(buf_r8_kind)) deallocate(buf_r8_kind)
183 end subroutine compressed_write_1d
184 
185 
186 !> @brief For variables without a compressed dimension, this routine simply wraps
187 !! netcdf_write data. If the variable does have a compressed axis, the I/O root
188 !! gathers the data from the rest of the ranks and then writes the combined data to
189 !! the netcdf file.
190 subroutine compressed_write_2d(fileobj, variable_name, cdata, unlim_dim_level, &
191  corner, edge_lengths)
192 
193  class(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
194  character(len=*), intent(in) :: variable_name !< Variable name.
195  class(*), dimension(:,:), intent(in) :: cdata !< Compressed data that
196  !! will be gathered and
197  !! written to the
198  !! netcdf file.
199  integer, intent(in), optional :: unlim_dim_level !< Level for the unlimited
200  !! dimension.
201  integer, dimension(2), intent(in), optional :: corner !< Array of starting
202  !! indices describing
203  !! where the data
204  !! will be written to.
205  integer, dimension(2), intent(in), optional :: edge_lengths !< The number of
206  !! elements that
207  !! will be written
208  !! in each dimension.
209 
210  integer, dimension(2) :: compressed_dim_index !< index of the compressed dimension
211  !! compressed_dim_index(1) relative to cdata
212  !! compressed_dim_index(2) relative to the fileobj
213  integer, dimension(2) :: c !! corners of the data to read
214  integer, dimension(2) :: e !< "edges" number of points to read
215 
216  integer(kind=i4_kind), dimension(:,:), allocatable :: buf_i4_kind !< Global buffer of data
217  integer(kind=i8_kind), dimension(:,:), allocatable :: buf_i8_kind !< Global buffer of data
218  real (kind=r4_kind), dimension(:,:), allocatable :: buf_r4_kind !< Global buffer of data
219  real (kind=r8_kind), dimension(:,:), allocatable :: buf_r8_kind !< Global buffer of data
220 
221  character(len=200) :: append_error_msg !< Msg to be appended to FATAL error message
222 
223  integer :: index(1) !< index of the PE in the pelist
224 
225  integer :: is !< Starting index of the first dimension
226  integer :: ie !< Ending index of the first dimension
227  integer :: js !< Starting index of the second dimension
228  integer :: je !< Ending index of the second dimension
229 
230  append_error_msg = "compressed_write_2d: file:"//trim(fileobj%path)//" variable:"//trim(variable_name)
231 
232  compressed_dim_index = get_variable_compressed_dimension_index(fileobj, variable_name)
233  if (compressed_dim_index(1) .eq. dimension_not_found) then
234  call netcdf_write_data(fileobj, variable_name, cdata, &
235  unlim_dim_level=unlim_dim_level, corner=corner, &
236  edge_lengths=edge_lengths)
237  return
238  endif
239 
240  e(:) = shape(cdata)
241  !The root pe creates a buffer big enough to store the data:
242  if (fileobj%is_root) then
243  e(compressed_dim_index(1)) = sum(fileobj%compressed_dims(compressed_dim_index(2))%npes_nelems)
244  select type(cdata)
245  type is (integer(kind=i4_kind))
246  call allocate_array(buf_i4_kind, e)
247  type is (integer(kind=i8_kind))
248  call allocate_array(buf_i8_kind, e)
249  type is (real(kind=r4_kind))
250  call allocate_array(buf_r4_kind, e)
251  type is (real(kind=r8_kind))
252  call allocate_array(buf_r8_kind, e)
253  class default
254  call error("unsupported variable type: "//trim(append_error_msg))
255  end select
256  else
257  select type(cdata)
258  type is (integer(kind=i4_kind))
259  allocate(buf_i4_kind(1, 1))
260  type is (integer(kind=i8_kind))
261  allocate(buf_i8_kind(1, 1))
262  type is (real(kind=r4_kind))
263  allocate(buf_r4_kind(1, 1))
264  type is (real(kind=r8_kind))
265  allocate(buf_r8_kind(1, 1))
266  class default
267  call error("unsupported variable type: "//trim(append_error_msg))
268  end select
269  endif
270 
271  c(:) = 1
272  index = findloc(fileobj%pelist, mpp_pe())
273 
274  c(compressed_dim_index(1)) = fileobj%compressed_dims(compressed_dim_index(2))%npes_corner(index(1))
275  e(compressed_dim_index(1)) = fileobj%compressed_dims(compressed_dim_index(2))%npes_nelems(index(1))
276 
277  if (compressed_dim_index(1) .eq. 1) then
278  is = c(compressed_dim_index(1))
279  ie = c(compressed_dim_index(1)) + e(compressed_dim_index(1)) - 1
280  js = 1
281  je = size(cdata,2)
282  else
283  js = c(compressed_dim_index(1))
284  je = c(compressed_dim_index(1)) + e(compressed_dim_index(1)) - 1
285  is = 1
286  ie = size(cdata,2)
287  endif
288 
289  select type(cdata)
290  type is (integer(kind=i4_kind))
291  call mpp_gather(is, ie, js, je, fileobj%pelist, cdata, buf_i4_kind, fileobj%is_root)
292  if (fileobj%is_root) call netcdf_write_data(fileobj, variable_name, buf_i4_kind, &
293  unlim_dim_level=unlim_dim_level)
294  type is (integer(kind=i8_kind))
295  call mpp_gather(is, ie, js, je, fileobj%pelist, cdata, buf_i8_kind, fileobj%is_root)
296  if (fileobj%is_root) call netcdf_write_data(fileobj, variable_name, buf_i8_kind, &
297  unlim_dim_level=unlim_dim_level)
298  type is (real(kind=r4_kind))
299  call mpp_gather(is, ie, js, je, fileobj%pelist, cdata, buf_r4_kind, fileobj%is_root)
300  if (fileobj%is_root) call netcdf_write_data(fileobj, variable_name, buf_r4_kind, &
301  unlim_dim_level=unlim_dim_level)
302  type is (real(kind=r8_kind))
303  call mpp_gather(is, ie, js, je, fileobj%pelist, cdata, buf_r8_kind, fileobj%is_root)
304  if (fileobj%is_root) call netcdf_write_data(fileobj, variable_name, buf_r8_kind, &
305  unlim_dim_level=unlim_dim_level)
306  class default
307  call error("unsupported variable type: "//trim(append_error_msg))
308  end select
309 
310  if (fileobj%is_root) then
311  if (allocated(buf_i4_kind)) deallocate(buf_i4_kind)
312  if (allocated(buf_i8_kind)) deallocate(buf_i8_kind)
313  if (allocated(buf_r4_kind)) deallocate(buf_r4_kind)
314  if (allocated(buf_r8_kind)) deallocate(buf_r8_kind)
315  endif
316 end subroutine compressed_write_2d
317 
318 
319 !> @brief For variables without a compressed dimension, this routine simply wraps
320 !! netcdf_write data. If the variable does have a compressed axis, the I/O root
321 !! gathers the data from the rest of the ranks and then writes the combined data to
322 !! the netcdf file.
323 subroutine compressed_write_3d(fileobj, variable_name, cdata, unlim_dim_level, &
324  corner, edge_lengths)
325 
326  class(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
327  character(len=*), intent(in) :: variable_name !< Variable name.
328  class(*), contiguous, intent(in), target :: cdata(:,:,:) !< Compressed data that
329  !! will be gathered and
330  !! written to the
331  !! netcdf file.
332  integer, intent(in), optional :: unlim_dim_level !< Level for the unlimited
333  !! dimension.
334  integer, dimension(3), intent(in), optional :: corner !< Array of starting
335  !! indices describing
336  !! where the data
337  !! will be written to.
338  integer, dimension(3), intent(in), optional :: edge_lengths !< The number of
339  !! elements that
340  !! will be written
341  !! in each dimension.
342 
343  integer, dimension(2) :: compressed_dim_index !< index of the compressed dimension
344  !! compressed_dim_index(1) relative to cdata
345  !! compressed_dim_index(2) relative to the fileobj
346  integer, dimension(3) :: c !! corners of the data to read
347  integer, dimension(3) :: e !< "edges" number of points to read
348 
349  integer(kind=i4_kind), dimension(:,:,:), allocatable :: buf_i4_kind !< Global buffer of data
350  integer(kind=i8_kind), dimension(:,:,:), allocatable :: buf_i8_kind !< Global buffer of data
351  real (kind=r4_kind), dimension(:,:,:), allocatable :: buf_r4_kind !< Global buffer of data
352  real (kind=r8_kind), dimension(:,:,:), allocatable :: buf_r8_kind !< Global buffer of data
353 
354  character(len=200) :: append_error_msg !< Msg to be appended to FATAL error message
355  class(*), pointer :: cdata_dummy(:,:,:,:)
356 
357  integer :: index(1) !< index of the PE in the pelist
358 
359  integer :: is !< Starting index of the first dimension
360  integer :: ie !< Ending index of the first dimension
361  integer :: js !< Starting index of the second dimension
362  integer :: je !< Ending index of the second dimension
363 
364  append_error_msg = "compressed_write_3d: file:"//trim(fileobj%path)//" variable:"//trim(variable_name)
365 
366  compressed_dim_index = get_variable_compressed_dimension_index(fileobj, variable_name)
367  if (compressed_dim_index(1) .eq. dimension_not_found) then
368  call netcdf_write_data(fileobj, variable_name, cdata, &
369  unlim_dim_level=unlim_dim_level, corner=corner, &
370  edge_lengths=edge_lengths)
371  return
372  else if (compressed_dim_index(1) .eq. 3) then
373  cdata_dummy(1:size(cdata,1), 1:size(cdata,2), 1:size(cdata,3), 1:1) => cdata(:,:,:)
374  call compressed_write_4d(fileobj, variable_name, cdata_dummy, unlim_dim_level)
375  endif
376 
377  e(:) = shape(cdata)
378  !The root pe creates a buffer big enough to store the data:
379  if (fileobj%is_root) then
380  e(compressed_dim_index(1)) = sum(fileobj%compressed_dims(compressed_dim_index(2))%npes_nelems)
381  select type(cdata)
382  type is (integer(kind=i4_kind))
383  call allocate_array(buf_i4_kind, e)
384  type is (integer(kind=i8_kind))
385  call allocate_array(buf_i8_kind, e)
386  type is (real(kind=r4_kind))
387  call allocate_array(buf_r4_kind, e)
388  type is (real(kind=r8_kind))
389  call allocate_array(buf_r8_kind, e)
390  class default
391  call error("unsupported variable type: "//trim(append_error_msg))
392  end select
393  else
394  select type(cdata)
395  type is (integer(kind=i4_kind))
396  allocate(buf_i4_kind(1, 1, 1))
397  type is (integer(kind=i8_kind))
398  allocate(buf_i8_kind(1, 1, 1))
399  type is (real(kind=r4_kind))
400  allocate(buf_r4_kind(1, 1, 1))
401  type is (real(kind=r8_kind))
402  allocate(buf_r8_kind(1, 1, 1))
403  class default
404  call error("unsupported variable type: "//trim(append_error_msg))
405  end select
406  endif
407 
408  c(:) = 1
409  index = findloc(fileobj%pelist, mpp_pe())
410 
411  c(compressed_dim_index(1)) = fileobj%compressed_dims(compressed_dim_index(2))%npes_corner(index(1))
412  e(compressed_dim_index(1)) = fileobj%compressed_dims(compressed_dim_index(2))%npes_nelems(index(1))
413 
414  if (compressed_dim_index(1) .eq. 1) then
415  is = c(compressed_dim_index(1))
416  ie = c(compressed_dim_index(1)) + e(compressed_dim_index(1)) - 1
417  js = 1
418  je = size(cdata,2)
419  else
420  js = c(compressed_dim_index(1))
421  je = c(compressed_dim_index(1)) + e(compressed_dim_index(1)) - 1
422  is = 1
423  ie = size(cdata,2)
424  endif
425 
426  select type(cdata)
427  type is (integer(kind=i4_kind))
428  call mpp_gather(is, ie, js, je, size(cdata,3), &
429  fileobj%pelist, cdata, buf_i4_kind, fileobj%is_root)
430  if (fileobj%is_root) call netcdf_write_data(fileobj, variable_name, buf_i4_kind, &
431  unlim_dim_level=unlim_dim_level)
432  type is (integer(kind=i8_kind))
433  call mpp_gather(is, ie, js, je, size(cdata,3), &
434  fileobj%pelist, cdata, buf_i8_kind, fileobj%is_root)
435  if (fileobj%is_root) call netcdf_write_data(fileobj, variable_name, buf_i8_kind, &
436  unlim_dim_level=unlim_dim_level)
437  type is (real(kind=r4_kind))
438  call mpp_gather(is, ie, js, je, size(cdata,3), &
439  fileobj%pelist, cdata, buf_r4_kind, fileobj%is_root)
440  if (fileobj%is_root) call netcdf_write_data(fileobj, variable_name, buf_r4_kind, &
441  unlim_dim_level=unlim_dim_level)
442  type is (real(kind=r8_kind))
443  call mpp_gather(is, ie, js, je, size(cdata,3), &
444  fileobj%pelist, cdata, buf_r8_kind, fileobj%is_root)
445  if (fileobj%is_root) call netcdf_write_data(fileobj, variable_name, buf_r8_kind, &
446  unlim_dim_level=unlim_dim_level)
447  class default
448  call error("unsupported variable type: "//trim(append_error_msg))
449  end select
450 
451  if (fileobj%is_root) then
452  if (allocated(buf_i4_kind)) deallocate(buf_i4_kind)
453  if (allocated(buf_i8_kind)) deallocate(buf_i8_kind)
454  if (allocated(buf_r4_kind)) deallocate(buf_r4_kind)
455  if (allocated(buf_r8_kind)) deallocate(buf_r8_kind)
456  endif
457 end subroutine compressed_write_3d
458 
459 
460 !> @brief For variables without a compressed dimension, this routine simply wraps
461 !! netcdf_write data. If the variable does have a compressed axis, the I/O root
462 !! gathers the data from the rest of the ranks and then writes the combined data to
463 !! the netcdf file.
464 subroutine compressed_write_4d(fileobj, variable_name, cdata, unlim_dim_level, &
465  corner, edge_lengths)
466 
467  class(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
468  character(len=*), intent(in) :: variable_name !< Variable name.
469  class(*), dimension(:,:,:,:), intent(in) :: cdata !< Compressed data that
470  !! will be gathered and
471  !! written to the
472  !! netcdf file.
473  integer, intent(in), optional :: unlim_dim_level !< Level for the unlimited
474  !! dimension.
475  integer, dimension(4), intent(in), optional :: corner !< Array of starting
476  !! indices describing
477  !! where the data
478  !! will be written to.
479  integer, dimension(4), intent(in), optional :: edge_lengths !< The number of
480  !! elements that
481  !! will be written
482  !! in each dimension.
483 
484  integer, dimension(2) :: compressed_dim_index
485  integer, dimension(4) :: c
486  integer, dimension(4) :: e
487  integer :: i
488  integer(kind=i4_kind), dimension(:,:,:,:), allocatable :: buf_i4_kind
489  integer(kind=i8_kind), dimension(:,:,:,:), allocatable :: buf_i8_kind
490  real(kind=r4_kind), dimension(:,:,:,:), allocatable :: buf_r4_kind
491  real(kind=r8_kind), dimension(:,:,:,:), allocatable :: buf_r8_kind
492  character(len=200) :: append_error_msg !< Msg to be appended to FATAL error message
493 
494  append_error_msg = "compressed_write_4d: file:"//trim(fileobj%path)//" variable:"//trim(variable_name)
495 
496  compressed_dim_index = get_variable_compressed_dimension_index(fileobj, variable_name)
497  if (compressed_dim_index(1) .eq. dimension_not_found) then
498  call netcdf_write_data(fileobj, variable_name, cdata, &
499  unlim_dim_level=unlim_dim_level, corner=corner, &
500  edge_lengths=edge_lengths)
501  return
502  endif
503 
504  !Gather the data onto the I/O root and write it out.
505  if (fileobj%is_root) then
506  c(:) = 1
507  e(:) = shape(cdata)
508  do i = 1, size(fileobj%pelist)
509  c(compressed_dim_index(1)) = fileobj%compressed_dims(compressed_dim_index(2))%npes_corner(i)
510  e(compressed_dim_index(1)) = fileobj%compressed_dims(compressed_dim_index(2))%npes_nelems(i)
511  if (i .eq. 1) then
512  call netcdf_write_data(fileobj, variable_name, cdata, &
513  unlim_dim_level=unlim_dim_level, corner=c, &
514  edge_lengths=e)
515  else
516  select type(cdata)
517  type is (integer(kind=i4_kind))
518  call allocate_array(buf_i4_kind, e)
519  call mpp_recv(buf_i4_kind, size(buf_i4_kind), fileobj%pelist(i), block=.true.)
520  call netcdf_write_data(fileobj, variable_name, buf_i4_kind, &
521  unlim_dim_level=unlim_dim_level, corner=c, &
522  edge_lengths=e)
523  deallocate(buf_i4_kind)
524  type is (integer(kind=i8_kind))
525  call allocate_array(buf_i8_kind, e)
526  call mpp_recv(buf_i8_kind, size(buf_i8_kind), fileobj%pelist(i), block=.true.)
527  call netcdf_write_data(fileobj, variable_name, buf_i8_kind, &
528  unlim_dim_level=unlim_dim_level, corner=c, &
529  edge_lengths=e)
530  deallocate(buf_i8_kind)
531  type is (real(kind=r4_kind))
532  call allocate_array(buf_r4_kind, e)
533  call mpp_recv(buf_r4_kind, size(buf_r4_kind), fileobj%pelist(i), block=.true.)
534  call netcdf_write_data(fileobj, variable_name, buf_r4_kind, &
535  unlim_dim_level=unlim_dim_level, corner=c, &
536  edge_lengths=e)
537  deallocate(buf_r4_kind)
538  type is (real(kind=r8_kind))
539  call allocate_array(buf_r8_kind, e)
540  call mpp_recv(buf_r8_kind, size(buf_r8_kind), fileobj%pelist(i), block=.true.)
541  call netcdf_write_data(fileobj, variable_name, buf_r8_kind, &
542  unlim_dim_level=unlim_dim_level, corner=c, &
543  edge_lengths=e)
544  deallocate(buf_r8_kind)
545  class default
546  call error("unsupported variable type: "//trim(append_error_msg))
547  end select
548  endif
549  enddo
550  else
551  select type(cdata)
552  type is (integer(kind=i4_kind))
553  call mpp_send(cdata, size(cdata), fileobj%io_root)
554  type is (integer(kind=i8_kind))
555  call mpp_send(cdata, size(cdata), fileobj%io_root)
556  type is (real(kind=r4_kind))
557  call mpp_send(cdata, size(cdata), fileobj%io_root)
558  type is (real(kind=r8_kind))
559  call mpp_send(cdata, size(cdata), fileobj%io_root)
560  class default
561  call error("unsupported variable type: "//trim(append_error_msg))
562  end select
563  call mpp_sync_self(check=event_send)
564  endif
565 end subroutine compressed_write_4d
566 
567 
568 !> @brief For variables without a compressed dimension, this routine simply wraps
569 !! netcdf_write data. If the variable does have a compressed axis, the I/O root
570 !! gathers the data from the rest of the ranks and then writes the combined data to
571 !! the netcdf file.
572 subroutine compressed_write_5d(fileobj, variable_name, cdata, unlim_dim_level, &
573  corner, edge_lengths)
574 
575  class(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
576  character(len=*), intent(in) :: variable_name !< Variable name.
577  class(*), dimension(:,:,:,:,:), intent(in) :: cdata !< Compressed data that
578  !! will be gathered and
579  !! written to the
580  !! netcdf file.
581  integer, intent(in), optional :: unlim_dim_level !< Level for the unlimited
582  !! dimension.
583  integer, dimension(5), intent(in), optional :: corner !< Array of starting
584  !! indices describing
585  !! where the data
586  !! will be written to.
587  integer, dimension(5), intent(in), optional :: edge_lengths !< The number of
588  !! elements that
589  !! will be written
590  !! in each dimension.
591 
592  integer, dimension(2) :: compressed_dim_index
593  integer, dimension(5) :: c
594  integer, dimension(5) :: e
595  integer :: i
596  integer(kind=i4_kind), dimension(:,:,:,:,:), allocatable :: buf_i4_kind
597  integer(kind=i8_kind), dimension(:,:,:,:,:), allocatable :: buf_i8_kind
598  real(kind=r4_kind), dimension(:,:,:,:,:), allocatable :: buf_r4_kind
599  real(kind=r8_kind), dimension(:,:,:,:,:), allocatable :: buf_r8_kind
600  character(len=200) :: append_error_msg !< Msg to be appended to FATAL error message
601 
602  append_error_msg = "compressed_write_5d: file:"//trim(fileobj%path)//" variable:"//trim(variable_name)
603 
604  compressed_dim_index = get_variable_compressed_dimension_index(fileobj, variable_name)
605  if (compressed_dim_index(1) .eq. dimension_not_found) then
606  call netcdf_write_data(fileobj, variable_name, cdata, &
607  unlim_dim_level=unlim_dim_level, corner=corner, &
608  edge_lengths=edge_lengths)
609  return
610  endif
611 
612  !Gather the data onto the I/O root and write it out.
613  if (fileobj%is_root) then
614  c(:) = 1
615  e(:) = shape(cdata)
616  do i = 1, size(fileobj%pelist)
617  c(compressed_dim_index(1)) = fileobj%compressed_dims(compressed_dim_index(2))%npes_corner(i)
618  e(compressed_dim_index(1)) = fileobj%compressed_dims(compressed_dim_index(2))%npes_nelems(i)
619  if (i .eq. 1) then
620  call netcdf_write_data(fileobj, variable_name, cdata, &
621  unlim_dim_level=unlim_dim_level, corner=c, &
622  edge_lengths=e)
623  else
624  select type(cdata)
625  type is (integer(kind=i4_kind))
626  call allocate_array(buf_i4_kind, e)
627  call mpp_recv(buf_i4_kind, size(buf_i4_kind), fileobj%pelist(i), block=.true.)
628  call netcdf_write_data(fileobj, variable_name, buf_i4_kind, &
629  unlim_dim_level=unlim_dim_level, corner=c, &
630  edge_lengths=e)
631  deallocate(buf_i4_kind)
632  type is (integer(kind=i8_kind))
633  call allocate_array(buf_i8_kind, e)
634  call mpp_recv(buf_i8_kind, size(buf_i8_kind), fileobj%pelist(i), block=.true.)
635  call netcdf_write_data(fileobj, variable_name, buf_i8_kind, &
636  unlim_dim_level=unlim_dim_level, corner=c, &
637  edge_lengths=e)
638  deallocate(buf_i8_kind)
639  type is (real(kind=r4_kind))
640  call allocate_array(buf_r4_kind, e)
641  call mpp_recv(buf_r4_kind, size(buf_r4_kind), fileobj%pelist(i), block=.true.)
642  call netcdf_write_data(fileobj, variable_name, buf_r4_kind, &
643  unlim_dim_level=unlim_dim_level, corner=c, &
644  edge_lengths=e)
645  deallocate(buf_r4_kind)
646  type is (real(kind=r8_kind))
647  call allocate_array(buf_r8_kind, e)
648  call mpp_recv(buf_r8_kind, size(buf_r8_kind), fileobj%pelist(i), block=.true.)
649  call netcdf_write_data(fileobj, variable_name, buf_r8_kind, &
650  unlim_dim_level=unlim_dim_level, corner=c, &
651  edge_lengths=e)
652  deallocate(buf_r8_kind)
653  class default
654  call error("unsupported variable type: "//trim(append_error_msg))
655  end select
656  endif
657  enddo
658  else
659  select type(cdata)
660  type is (integer(kind=i4_kind))
661  call mpp_send(cdata, size(cdata), fileobj%io_root)
662  type is (integer(kind=i8_kind))
663  call mpp_send(cdata, size(cdata), fileobj%io_root)
664  type is (real(kind=r4_kind))
665  call mpp_send(cdata, size(cdata), fileobj%io_root)
666  type is (real(kind=r8_kind))
667  call mpp_send(cdata, size(cdata), fileobj%io_root)
668  class default
669  call error("unsupported variable type: "//trim(append_error_msg))
670  end select
671  call mpp_sync_self(check=event_send)
672  endif
673 end subroutine compressed_write_5d
674 
675 
676 !> @brief Wrapper to distinguish interfaces.
677 subroutine compressed_write_1d_wrap(fileobj, variable_name, cdata, unlim_dim_level, &
678  corner, edge_lengths)
679 
680  type(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
681  character(len=*), intent(in) :: variable_name !< Variable name.
682  class(*), dimension(:), intent(in) :: cdata !< Compressed data that
683  !! will be gathered and
684  !! written to the
685  !! netcdf file.
686  integer, intent(in), optional :: unlim_dim_level !< Level for the unlimited
687  !! dimension.
688  integer, dimension(1), intent(in), optional :: corner !< Array of starting
689  !! indices describing
690  !! where the data
691  !! will be written to.
692  integer, dimension(1), intent(in), optional :: edge_lengths !< The number of
693  !! elements that
694  !! will be written
695  !! in each dimension.
696 
697  call compressed_write(fileobj, variable_name, cdata, unlim_dim_level, corner, &
698  edge_lengths=edge_lengths)
699 
700 end subroutine compressed_write_1d_wrap
701 
702 
703 !> @brief Wrapper to distinguish interfaces.
704 subroutine compressed_write_2d_wrap(fileobj, variable_name, cdata, unlim_dim_level, &
705  corner, edge_lengths)
706 
707  type(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
708  character(len=*), intent(in) :: variable_name !< Variable name.
709  class(*), dimension(:,:), intent(in) :: cdata !< Compressed data that
710  !! will be gathered and
711  !! written to the
712  !! netcdf file.
713  integer, intent(in), optional :: unlim_dim_level !< Level for the unlimited
714  !! dimension.
715  integer, dimension(2), intent(in), optional :: corner !< Array of starting
716  !! indices describing
717  !! where the data
718  !! will be written to.
719  integer, dimension(2), intent(in), optional :: edge_lengths !< The number of
720  !! elements that
721  !! will be written
722  !! in each dimension.
723 
724  call compressed_write(fileobj, variable_name, cdata, unlim_dim_level, corner, &
725  edge_lengths=edge_lengths)
726 end subroutine compressed_write_2d_wrap
727 
728 
729 !> @brief Wrapper to distinguish interfaces.
730 subroutine compressed_write_3d_wrap(fileobj, variable_name, cdata, unlim_dim_level, &
731  corner, edge_lengths)
732 
733  type(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
734  character(len=*), intent(in) :: variable_name !< Variable name.
735  class(*), dimension(:,:,:), intent(in) :: cdata !< Compressed data that
736  !! will be gathered and
737  !! written to the
738  !! netcdf file.
739  integer, intent(in), optional :: unlim_dim_level !< Level for the unlimited
740  !! dimension.
741  integer, dimension(3), intent(in), optional :: corner !< Array of starting
742  !! indices describing
743  !! where the data
744  !! will be written to.
745  integer, dimension(3), intent(in), optional :: edge_lengths !< The number of
746  !! elements that
747  !! will be written
748  !! in each dimension.
749 
750  call compressed_write(fileobj, variable_name, cdata, unlim_dim_level, corner, &
751  edge_lengths=edge_lengths)
752 end subroutine compressed_write_3d_wrap
753 
754 
755 !> @brief Wrapper to distinguish interfaces.
756 subroutine compressed_write_4d_wrap(fileobj, variable_name, cdata, unlim_dim_level, &
757  corner, edge_lengths)
758 
759  type(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
760  character(len=*), intent(in) :: variable_name !< Variable name.
761  class(*), dimension(:,:,:,:), intent(in) :: cdata !< Compressed data that
762  !! will be gathered and
763  !! written to the
764  !! netcdf file.
765  integer, intent(in), optional :: unlim_dim_level !< Level for the unlimited
766  !! dimension.
767  integer, dimension(4), intent(in), optional :: corner !< Array of starting
768  !! indices describing
769  !! where the data
770  !! will be written to.
771  integer, dimension(4), intent(in), optional :: edge_lengths !< The number of
772  !! elements that
773  !! will be written
774  !! in each dimension.
775 
776  call compressed_write(fileobj, variable_name, cdata, unlim_dim_level, corner, &
777  edge_lengths=edge_lengths)
778 end subroutine compressed_write_4d_wrap
779 
780 
781 !> @brief Wrapper to distinguish interfaces.
782 subroutine compressed_write_5d_wrap(fileobj, variable_name, cdata, unlim_dim_level, &
783  corner, edge_lengths)
784 
785  type(fmsnetcdffile_t), intent(in) :: fileobj !< File object.
786  character(len=*), intent(in) :: variable_name !< Variable name.
787  class(*), dimension(:,:,:,:,:), intent(in) :: cdata !< Compressed data that
788  !! will be gathered and
789  !! written to the
790  !! netcdf file.
791  integer, intent(in), optional :: unlim_dim_level !< Level for the unlimited
792  !! dimension.
793  integer, dimension(5), intent(in), optional :: corner !< Array of starting
794  !! indices describing
795  !! where the data
796  !! will be written to.
797  integer, dimension(5), intent(in), optional :: edge_lengths !< The number of
798  !! elements that
799  !! will be written
800  !! in each dimension.
801 
802  call compressed_write(fileobj, variable_name, cdata, unlim_dim_level, corner, &
803  edge_lengths=edge_lengths)
804 end subroutine compressed_write_5d_wrap
805 !> @}
subroutine compressed_write_1d_wrap(fileobj, variable_name, cdata, unlim_dim_level, corner, edge_lengths)
Wrapper to distinguish interfaces.
subroutine compressed_write_3d(fileobj, variable_name, cdata, unlim_dim_level, corner, edge_lengths)
For variables without a compressed dimension, this routine simply wraps netcdf_write data....
subroutine compressed_write_5d_wrap(fileobj, variable_name, cdata, unlim_dim_level, corner, edge_lengths)
Wrapper to distinguish interfaces.
subroutine compressed_write_0d(fileobj, variable_name, cdata, unlim_dim_level, corner)
For variables without a compressed dimension, this routine simply wraps netcdf_write data....
subroutine compressed_write_5d(fileobj, variable_name, cdata, unlim_dim_level, corner, edge_lengths)
For variables without a compressed dimension, this routine simply wraps netcdf_write data....
subroutine compressed_write_0d_wrap(fileobj, variable_name, cdata, unlim_dim_level, corner)
Wrapper to distinguish interfaces.
subroutine compressed_write_4d(fileobj, variable_name, cdata, unlim_dim_level, corner, edge_lengths)
For variables without a compressed dimension, this routine simply wraps netcdf_write data....
subroutine compressed_write_2d_wrap(fileobj, variable_name, cdata, unlim_dim_level, corner, edge_lengths)
Wrapper to distinguish interfaces.
subroutine compressed_write_1d(fileobj, variable_name, cdata, unlim_dim_level, corner, edge_lengths)
For variables without a compressed dimension, this routine simply wraps netcdf_write data....
subroutine compressed_write_4d_wrap(fileobj, variable_name, cdata, unlim_dim_level, corner, edge_lengths)
Wrapper to distinguish interfaces.
subroutine compressed_write_2d(fileobj, variable_name, cdata, unlim_dim_level, corner, edge_lengths)
For variables without a compressed dimension, this routine simply wraps netcdf_write data....
subroutine compressed_write_3d_wrap(fileobj, variable_name, cdata, unlim_dim_level, corner, edge_lengths)
Wrapper to distinguish interfaces.
subroutine mpp_sync_self(pelist, check, request, msg_size, msg_type)
This is to check if current PE's outstanding puts are complete but we can't use shmem_fence because w...
integer function mpp_pe()
Returns processor ID.
Definition: mpp_util.inc:406