18 module offloading_io_mod
21 use fms_string_utils_mod,
only:
string
23 use metadata_transfer_mod
29 integer :: current_files_init
30 logical :: module_is_initialized
32 integer :: max_files = 10
34 namelist / offloading_io_nml / max_files
39 character(len=:),
allocatable :: filename
40 class(fmsnetcdffile_t),
allocatable :: fileobj
48 procedure :: register_netcdf_axis_offload
49 procedure :: register_domain_axis_offload
55 procedure :: write_data_offload_2d
56 procedure :: write_data_offload_3d
60 type(offloading_obj_out),
allocatable,
target :: offloading_objs(:)
64 public :: offloading_io_init, open_file_offload
67 public :: create_cubic_domain, create_lat_lon_domain
72 subroutine offloading_io_init()
74 if (module_is_initialized)
return
75 current_files_init = 0
76 allocate(offloading_objs(max_files))
77 module_is_initialized = .true.
78 read (input_nml_file, offloading_io_nml, iostat=io)
80 end subroutine offloading_io_init
85 subroutine open_file_offload(fileobj, filename, domain_in, pe_in, pe_out)
86 class(FmsNetcdfFile_t),
intent(inout) :: fileobj
87 character(len=*),
intent(in) :: filename
88 type(domain2D),
intent(inout) :: domain_in
89 integer,
intent(in) :: pe_in(:)
90 integer,
intent(in) :: pe_out(:)
92 integer,
parameter :: str_len = 255
93 character(len=str_len) :: filename_out(1)
95 integer :: global_domain_size(2)
97 integer,
allocatable :: all_current_pes(:)
98 integer,
allocatable :: broadcasting_pes(:)
101 is_pe_out = any(pe_out .eq.
mpp_pe())
104 if (.not. module_is_initialized) &
105 call mpp_error(fatal,
"offloading_io_mod is not initialized")
107 allocate(all_current_pes(
mpp_npes()))
108 call mpp_get_current_pelist(all_current_pes)
111 if (
mpp_pe() .eq. pe_in(1))
then
116 if ( mod(
size(pe_out), ntile) .ne. 0 ) &
117 call mpp_error(fatal,
"The number of offloading PEs must be the same as the number of tiles of the domain")
118 filename_out(1) = filename
124 if (
mpp_pe() .eq. pe_in(1) .or. is_pe_out)
then
125 allocate(broadcasting_pes(1 +
size(pe_out)))
126 broadcasting_pes(1) = pe_in(1)
127 broadcasting_pes(2:
size(broadcasting_pes)) = pe_out
131 call mpp_broadcast(global_domain_size,
size(global_domain_size), pe_in(1))
143 object_id = init_offloading_object(filename_out(1), global_domain_size(1), global_domain_size(2),&
150 call fileobj%offloading_obj_in%init(object_id, pe_out, pe_in, domain_in)
151 end subroutine open_file_offload
154 subroutine global_metadata_offload(fileobj, attribute_name, attribute_value)
155 class(FmsNetcdfFile_t),
intent(inout) :: fileobj
156 character(len=*),
intent(in) :: attribute_name
157 class(*),
intent(in) :: attribute_value
160 type(offloading_obj_out),
pointer :: this
163 integer,
allocatable :: offloading_pes(:)
164 integer,
allocatable :: model_pes(:)
165 integer,
allocatable :: all_current_pes(:)
166 integer,
allocatable :: broadcasting_pes(:)
167 logical :: is_model_pe
168 character(len=255) :: att_name(1)
171 real(r4_kind),
allocatable :: r4_tmp(:)
172 real(r8_kind),
allocatable :: r8_tmp(:)
173 integer(i4_kind) ,
allocatable :: i4_tmp(:)
174 integer(i8_kind) ,
allocatable :: i8_tmp(:)
175 character(len=:),
allocatable :: str_tmp
176 class(metadata_class),
allocatable :: transfer_obj
178 select type (attribute_value)
179 type is (real(kind=r8_kind))
181 call transfer_obj%fms_metadata_transfer_init(real8_type)
182 type is (real(kind=r4_kind))
184 call transfer_obj%fms_metadata_transfer_init(real4_type)
185 type is (
integer(kind=i4_kind))
187 call transfer_obj%fms_metadata_transfer_init(int4_type)
188 type is (
integer(kind=i8_kind))
190 call transfer_obj%fms_metadata_transfer_init(int8_type)
191 type is (
character(*))
193 call transfer_obj%fms_metadata_transfer_init(str_type)
195 call mpp_error(fatal,
"Unsupported attribute type for offloading: " //
string(attribute_value))
198 offloading_pes = fileobj%offloading_obj_in%offloading_pes
199 model_pes = fileobj%offloading_obj_in%model_pes
200 is_model_pe = fileobj%offloading_obj_in%is_model_pe
202 id = fileobj%offloading_obj_in%id
203 this => offloading_objs(id)
205 if (is_model_pe)
then
206 att_name(1) = attribute_name
207 call transfer_obj%set_attribute_name(attribute_name)
210 allocate(all_current_pes(
mpp_npes()))
211 call mpp_get_current_pelist(all_current_pes)
213 if (
mpp_pe() .eq. model_pes(1) .or. .not. is_model_pe)
then
215 allocate(broadcasting_pes(1 +
size(offloading_pes)))
216 broadcasting_pes(1) = model_pes(1)
217 broadcasting_pes(2:
size(broadcasting_pes)) = offloading_pes
220 select type (attribute_value)
221 type is (real(kind=r4_kind))
223 if (is_model_pe)
then
224 select type(transfer_obj)
226 call transfer_obj%set_attribute_value([attribute_value])
229 call transfer_obj%fms_metadata_broadcast()
230 select type(transfer_obj)
232 r4_tmp = transfer_obj%get_attribute_value()
234 att_name(1) = transfer_obj%get_attribute_name()
235 if (.not. is_model_pe)
then
236 call register_global_attribute(this%fileobj, att_name(1), r4_tmp)
239 type is (real(kind=r8_kind))
241 if (is_model_pe)
then
242 select type(transfer_obj)
244 call transfer_obj%set_attribute_value([attribute_value])
247 call transfer_obj%fms_metadata_broadcast()
248 select type(transfer_obj)
250 r8_tmp = transfer_obj%get_attribute_value()
252 att_name(1) = transfer_obj%get_attribute_name()
253 if (.not. is_model_pe)
then
254 call register_global_attribute(this%fileobj, att_name(1), r8_tmp)
257 type is (
integer(kind=i4_kind))
258 if (is_model_pe)
then
259 select type(transfer_obj)
261 call transfer_obj%set_attribute_value([attribute_value])
262 int_buf = attribute_value
265 call transfer_obj%fms_metadata_broadcast()
266 select type(transfer_obj)
268 i4_tmp = transfer_obj%get_attribute_value()
270 att_name(1) = transfer_obj%get_attribute_name()
271 if (.not. is_model_pe)
then
272 call register_global_attribute(this%fileobj, att_name(1), i4_tmp)
275 type is (
integer(kind=i8_kind))
277 if (is_model_pe)
then
278 select type(transfer_obj)
280 call transfer_obj%set_attribute_value([attribute_value])
283 call transfer_obj%fms_metadata_broadcast()
284 select type(transfer_obj)
286 i8_tmp = transfer_obj%get_attribute_value()
288 att_name(1) = transfer_obj%get_attribute_name()
289 if (.not. is_model_pe)
then
290 call register_global_attribute(this%fileobj, att_name(1), i8_tmp)
293 type is (
character(len=*))
295 if (is_model_pe)
then
296 select type(transfer_obj)
298 call transfer_obj%set_attribute_value(attribute_value)
301 call transfer_obj%fms_metadata_broadcast()
302 select type(transfer_obj)
304 str_tmp = transfer_obj%get_attribute_value()
306 att_name(1) = transfer_obj%get_attribute_name()
307 if (.not. is_model_pe)
then
308 call register_global_attribute(this%fileobj, att_name(1), str_tmp)
318 subroutine register_domain_axis_offload(fileobj, axis_name, cart)
319 class(FmsNetcdfFile_t),
intent(inout) :: fileobj
320 character(len=*),
intent(in) :: axis_name
321 character(len=1),
intent(in) :: cart
324 type(offloading_obj_out),
pointer :: this
326 integer,
allocatable :: offloading_pes(:)
327 integer,
allocatable :: model_pes(:)
328 integer,
allocatable :: all_current_pes(:)
329 integer,
allocatable :: broadcasting_pes(:)
330 logical :: is_model_pe
331 character(len=ATTR_NAME_MAX_LENGTH) :: var_info(2)
333 offloading_pes = fileobj%offloading_obj_in%offloading_pes
334 model_pes = fileobj%offloading_obj_in%model_pes
335 is_model_pe = fileobj%offloading_obj_in%is_model_pe
337 id = fileobj%offloading_obj_in%id
338 this => offloading_objs(id)
340 if (is_model_pe)
then
341 var_info(1) = axis_name
345 allocate(all_current_pes(
mpp_npes()))
346 call mpp_get_current_pelist(all_current_pes)
348 if (
mpp_pe() .eq. model_pes(1) .or. .not. is_model_pe)
then
349 allocate(broadcasting_pes(1 +
size(offloading_pes)))
350 broadcasting_pes(1) = model_pes(1)
351 broadcasting_pes(2:
size(broadcasting_pes)) = offloading_pes
356 if (.not. is_model_pe)
then
357 select type(file=>this%fileobj)
358 type is(fmsnetcdfdomainfile_t)
359 call register_axis(file, trim(var_info(1)), trim(var_info(2)))
362 "offloading_io_mod::register_domain_axis_offload currently only supports FmsNetcdfDomainFile_t")
367 end subroutine register_domain_axis_offload
370 subroutine register_netcdf_axis_offload(fileobj, axis_name, length)
371 class(FmsNetcdfFile_t),
intent(inout) :: fileobj
372 character(len=*),
intent(in) :: axis_name
373 integer,
intent(in) :: length
376 type(offloading_obj_out),
pointer :: this
379 integer,
allocatable :: offloading_pes(:)
380 integer,
allocatable :: model_pes(:)
381 integer,
allocatable :: all_current_pes(:)
382 integer,
allocatable :: broadcasting_pes(:)
383 logical :: is_model_pe
384 character(len=255) :: var_axis(1)
385 integer :: var_length
386 integer :: axis_length
388 offloading_pes = fileobj%offloading_obj_in%offloading_pes
389 model_pes = fileobj%offloading_obj_in%model_pes
390 is_model_pe = fileobj%offloading_obj_in%is_model_pe
392 id = fileobj%offloading_obj_in%id
393 this => offloading_objs(id)
396 if (
mpp_pe() .eq. model_pes(1))
then
397 var_axis(1) = trim(axis_name)
398 axis_length = len_trim(var_axis(1))
402 allocate(all_current_pes(
mpp_npes()))
403 call mpp_get_current_pelist(all_current_pes)
406 if (
mpp_pe() .eq. model_pes(1) .or. .not. is_model_pe)
then
407 allocate(broadcasting_pes(1 +
size(offloading_pes)))
408 broadcasting_pes(1) = model_pes(1)
409 broadcasting_pes(2:
size(broadcasting_pes)) = offloading_pes
417 if (.not. is_model_pe)
then
418 select type(wut=>this%fileobj)
419 type is(fmsnetcdfdomainfile_t)
420 call register_axis(this%fileobj, var_axis(1)(1:axis_length), var_length)
423 "offloading_io_mod::register_netcdf_axis_offload currently only supports FmsNetcdfDomainFile_t")
428 end subroutine register_netcdf_axis_offload
431 subroutine register_field_offload(fileobj, varname, vartype, dimensions)
432 class(FmsNetcdfFile_t),
intent(inout) :: fileobj
433 character(len=*),
intent(in) :: varname
434 character(len=*),
intent(in) :: vartype
436 character(len=*),
intent(in) :: dimensions(:)
439 type(offloading_obj_out),
pointer :: this
443 integer,
allocatable :: offloading_pes(:)
444 integer,
allocatable :: model_pes(:)
445 integer,
allocatable :: all_current_pes(:)
446 integer,
allocatable :: broadcasting_pes(:)
447 logical :: is_model_pe
448 character(len=255),
allocatable :: var_info(:)
450 offloading_pes = fileobj%offloading_obj_in%offloading_pes
451 model_pes = fileobj%offloading_obj_in%model_pes
452 is_model_pe = fileobj%offloading_obj_in%is_model_pe
454 id = fileobj%offloading_obj_in%id
455 this => offloading_objs(id)
457 allocate(all_current_pes(
mpp_npes()))
458 call mpp_get_current_pelist(all_current_pes)
460 if (is_model_pe)
then
461 ndim =
size(dimensions)
463 allocate(var_info(ndim + 2))
464 var_info(1) = varname
465 var_info(2) = vartype
466 var_info(3:) = dimensions
470 if (
mpp_pe() .eq. model_pes(1) .or. .not. is_model_pe)
then
471 allocate(broadcasting_pes(1 +
size(offloading_pes)))
472 broadcasting_pes(1) = model_pes(1)
473 broadcasting_pes(2:
size(broadcasting_pes)) = offloading_pes
477 if (.not. is_model_pe)
allocate(var_info(ndim + 2))
481 if (.not. is_model_pe)
then
484 call register_field(this%fileobj, trim(var_info(1)), trim(var_info(2)), var_info(3:))
492 subroutine write_data_offload_3d(fileobj, varname, vardata, unlim_dim_level)
493 class(FmsNetcdfFile_t),
intent(inout) :: fileobj
494 character(len=*),
intent(in) :: varname
495 real(kind=r4_kind),
intent(in) :: vardata(:,:,:)
496 integer,
intent(in),
optional :: unlim_dim_level
499 type(offloading_obj_out),
pointer :: this
502 integer,
allocatable :: offloading_pes(:)
503 integer,
allocatable :: model_pes(:)
504 integer,
allocatable :: all_current_pes(:)
505 logical :: is_model_pe
507 real(kind=r4_kind),
allocatable :: var_r4_data(:,:,:)
508 type(domain2D) :: domain_out
509 type(domain2D) :: domain_in
510 integer :: isc, iec, jsc, jec, nz, redistribute_clock
511 character(len=ATTR_NAME_MAX_LENGTH) :: varname_tmp(1)
513 offloading_pes = fileobj%offloading_obj_in%offloading_pes
514 model_pes = fileobj%offloading_obj_in%model_pes
515 is_model_pe = fileobj%offloading_obj_in%is_model_pe
517 id = fileobj%offloading_obj_in%id
518 this => offloading_objs(id)
520 allocate(all_current_pes(
mpp_npes()))
521 call mpp_get_current_pelist(all_current_pes)
524 call mpp_clock_begin(redistribute_clock)
526 nz =
size(vardata, 3)
530 if (.not. is_model_pe)
then
531 domain_out = this%domain_out
533 allocate(var_r4_data(isc:iec, jsc:jec, nz))
536 domain_in = fileobj%offloading_obj_in%domain_in
545 call mpp_redistribute( domain_in, vardata, domain_out, var_r4_data, free=.true.)
547 if(
mpp_pe() .eq. model_pes(1))
then
548 varname_tmp(1) = trim(varname)
552 call mpp_clock_end(redistribute_clock)
554 if (.not. is_model_pe)
then
555 select type(wut=>this%fileobj)
556 type is(fmsnetcdfdomainfile_t)
557 if (
present(unlim_dim_level))
then
558 call write_data(wut, varname, var_r4_data, unlim_dim_level=unlim_dim_level)
565 end subroutine write_data_offload_3d
568 subroutine write_data_offload_2d(fileobj, varname, vardata)
569 class(FmsNetcdfFile_t),
intent(inout) :: fileobj
570 character(len=*),
intent(in) :: varname
571 real(kind=r4_kind),
intent(in) :: vardata(:,:)
574 type(offloading_obj_out),
pointer :: this
577 integer,
allocatable :: offloading_pes(:)
578 integer,
allocatable :: model_pes(:)
579 integer,
allocatable :: all_current_pes(:)
580 logical :: is_model_pe
582 real(kind=r4_kind),
allocatable :: var_r4_data(:,:)
583 type(domain2D) :: domain_out
584 type(domain2D) :: domain_in
585 integer :: isc, iec, jsc, jec
586 character(len=255) :: varname_tmp(1)
588 offloading_pes = fileobj%offloading_obj_in%offloading_pes
589 model_pes = fileobj%offloading_obj_in%model_pes
590 is_model_pe = fileobj%offloading_obj_in%is_model_pe
592 id = fileobj%offloading_obj_in%id
593 this => offloading_objs(id)
595 allocate(all_current_pes(
mpp_npes()))
596 call mpp_get_current_pelist(all_current_pes)
599 if (.not. is_model_pe)
then
600 domain_out = this%domain_out
602 allocate(var_r4_data(isc:iec, jsc:jec))
605 domain_in = fileobj%offloading_obj_in%domain_in
614 call mpp_redistribute( domain_in, vardata, domain_out, var_r4_data, free=.true.)
617 if(
mpp_pe() .eq. model_pes(1))
then
618 varname_tmp(1) = trim(varname)
622 if (.not. is_model_pe)
then
623 select type(wut=>this%fileobj)
624 type is(fmsnetcdfdomainfile_t)
625 call write_data(wut, varname_tmp(1), var_r4_data)
629 end subroutine write_data_offload_2d
632 subroutine close_file_offload(fileobj)
633 class(FmsNetcdfFile_t),
intent(inout) :: fileobj
636 type(offloading_obj_out),
pointer :: this
637 logical :: is_model_pe
639 id = fileobj%offloading_obj_in%id
640 this => offloading_objs(id)
641 is_model_pe = fileobj%offloading_obj_in%is_model_pe
643 if (.not. is_model_pe)
call close_file(this%fileobj)
644 end subroutine close_file_offload
647 integer function init_offloading_object(filename, nx, ny, ntile)
648 character(len=*),
intent(in) :: filename
649 integer,
intent(in) :: nx
650 integer,
intent(in) :: ny
651 integer,
intent(in) :: ntile
653 type(offloading_obj_out),
pointer :: this
654 integer,
allocatable :: curr_pelist(:)
656 current_files_init = current_files_init + 1
657 if (current_files_init .gt. max_files) &
658 call mpp_error(fatal,
"The number of files is too large")
661 this => offloading_objs(current_files_init)
662 this%id = current_files_init
663 this%filename = trim(filename)
667 call mpp_get_current_pelist(curr_pelist)
671 this%domain_out = create_lat_lon_domain(nx, ny)
673 this%domain_out = create_cubic_domain(nx, ny, ntile, (/1,1/), offload_pes=curr_pelist)
675 call mpp_error(fatal,
"Unsupported number of tiles for offloading: " // trim(adjustl(
string(ntile))))
678 allocate(fmsnetcdfdomainfile_t :: this%fileobj)
679 select type (fileobj => this%fileobj)
680 type is (fmsnetcdfdomainfile_t)
681 if ( .not.
open_file(fileobj, trim(this%filename),
"overwrite", this%domain_out)) &
682 call mpp_error(fatal,
"Error opening file")
685 init_offloading_object = current_files_init
689 function create_lat_lon_domain(nx_in, ny_in, halox, haloy ) &
691 integer,
intent(in) :: nx_in
692 integer,
intent(in) :: ny_in
693 integer,
intent(in),
optional :: halox
694 integer,
intent(in),
optional :: haloy
695 type(domain2d) :: domain_out
699 call mpp_define_domains( (/1,nx_in,1,ny_in/), layout, domain_out, xhalo=halox, yhalo=haloy)
701 end function create_lat_lon_domain
704 function create_cubic_domain(nx_in, ny_in, ntiles, io_layout, nhalos, offload_pes, layout) &
706 integer,
intent(in) :: nx_in
707 integer,
intent(in) :: ny_in
708 integer,
intent(in) :: ntiles
709 integer,
intent(in) :: io_layout(2)
710 integer,
intent(in),
optional :: nhalos
711 integer,
intent(in),
optional :: offload_pes(:)
712 integer,
optional :: layout(2)
714 type(domain2d) :: domain_out
717 integer :: npes_per_tile
718 integer :: layout_tmp(2)
719 integer,
allocatable :: global_indices(:,:)
720 integer,
allocatable :: layout2D(:,:)
721 integer,
allocatable :: pe_start(:)
722 integer,
allocatable :: pe_end(:)
726 if( mod(npes, ntiles) .NE. 0 )
call mpp_error(fatal, &
727 "create_cubic_domain: npes is not divisible by ntiles")
729 npes_per_tile = npes/ntiles
730 if( .not.
present(layout))
then
736 allocate(global_indices(4, ntiles))
737 allocate(layout2d(2, ntiles))
738 allocate(pe_start(ntiles), pe_end(ntiles))
741 global_indices(:,n) = (/1,nx_in,1,ny_in/)
742 layout2d(:,n) = layout_tmp
743 if(
present(offload_pes))
then
744 pe_start(n) = offload_pes((n-1)*npes_per_tile+1)
745 pe_end(n) = offload_pes((n)*npes_per_tile)
747 pe_start(n) = (n-1)*npes_per_tile
748 pe_end(n) = n*npes_per_tile-1
752 print *,
"pe: ",
mpp_pe(),
"creating mosaic with pe_start", pe_start,
"pe_end", pe_end
754 call define_cubic_mosaic(domain_out, (/nx_in,nx_in,nx_in,nx_in,nx_in,nx_in/), &
755 (/ny_in,ny_in,ny_in,ny_in,ny_in,ny_in/), &
756 global_indices, layout2d, pe_start, pe_end, io_layout, nhalos )
757 end function create_cubic_domain
761 subroutine define_cubic_mosaic(domain, ni, nj, global_indices, layout, pe_start, pe_end, &
764 integer,
dimension(:),
intent(in) :: ni
765 integer,
dimension(:),
intent(in) :: nj
766 integer,
dimension(:,:),
intent(in) :: global_indices
767 integer,
dimension(:,:),
intent(in) :: layout
768 integer,
dimension(:),
intent(in) :: pe_start
769 integer,
dimension(:),
intent(in) :: pe_end
770 integer,
dimension(2),
intent(in) :: io_layout
771 type(domain2d),
intent(inout) :: domain
772 integer,
optional,
intent(in) :: nhalos
774 integer,
dimension(12) :: tile1
775 integer,
dimension(12) :: tile2
776 integer,
dimension(12) :: istart1
777 integer,
dimension(12) :: iend1
778 integer,
dimension(12) :: jstart1
779 integer,
dimension(12) :: jend1
780 integer,
dimension(12) :: istart2
781 integer,
dimension(12) :: iend2
782 integer,
dimension(12) :: jstart2
783 integer,
dimension(12) :: jend2
785 integer :: num_contact
786 integer,
dimension(2) :: msize
796 if (
present(nhalos)) whalo = nhalos
801 if (
size(pe_start) .ne. 6 .or.
size(pe_end) .ne. 6 )
then
802 call mpp_error(fatal,
"size of pe_start and pe_end should be 6.")
804 if (
size(global_indices,1) .ne. 4)
then
805 call mpp_error(fatal,
"size of first dimension of global_indices should be 4.")
807 if (
size(global_indices,2) .ne. 6)
then
808 call mpp_error(fatal,
"size of second dimension of global_indices should be 6.")
810 if (
size(layout,1) .ne. 2)
then
811 call mpp_error(fatal,
"size of first dimension of layout should be 2.")
813 if (
size(layout,2) .ne. 6)
then
814 call mpp_error(fatal,
"size of second dimension of layout should be 6.")
816 if (
size(ni) .ne. 6 .or.
size(nj) .ne. 6)
then
817 call mpp_error(fatal,
"size of ni and nj should be 6.")
963 msize(1) = maxval(ni(:)/layout(1,:)) + whalo + ehalo + 1
964 msize(2) = maxval(nj(:)/layout(2,:)) + shalo + nhalo + 1
965 call mpp_define_mosaic(global_indices, layout, domain, ntiles, num_contact, tile1, &
966 tile2, istart1, iend1, jstart1, jend1, istart2, iend2, &
967 jstart2, jend2, pe_start, pe_end, symmetry = .true., &
968 whalo=whalo, ehalo=ehalo, shalo=shalo, nhalo=nhalo, &
969 name=trim(
"Cubed-sphere"), memory_size=msize)
971 end subroutine define_cubic_mosaic
972 end module offloading_io_mod
Close a netcdf or domain file opened with open_file or open_virtual_file.
Opens a given netcdf or domain file.
Add a dimension to a given file.
Defines a new field within the given file Example usage:
Write data to a defined field within a file Example usage:
integer function, public check_nml_error(IOSTAT, NML_NAME)
Checks the iostat argument that is returned after reading a namelist and determines if the error code...
character(:) function, allocatable, public string(v, fmt)
Converts a number or a Boolean value to a string.
integer function mpp_get_ntile_count(domain)
Returns number of tiles in mosaic.
subroutine mpp_define_io_domain(domain, io_layout)
Define the layout for IO pe's for the given domain.
subroutine mpp_define_mosaic(global_indices, layout, domain, num_tile, num_contact, tile1, tile2, istart1, iend1, jstart1, jend1, istart2, iend2, jstart2, jend2, pe_start, pe_end, pelist, whalo, ehalo, shalo, nhalo, xextent, yextent, maskmap, name, memory_size, symmetry, xflags, yflags, tile_id)
Defines a domain for mosaic tile grids.
Broadcasts domain to every pe. Only useful outside the context of it's own pelist.
Set up a domain decomposition.
Retrieve layout associated with a domain decomposition. Given a global 2D domain and the number of di...
Defines a nullified 1D or 2D domain.
These routines retrieve the axis specifications associated with the compute domains....
These routines retrieve the axis specifications associated with the data domains. The domain is a der...
These routines retrieve the axis specifications associated with the global domains....
Reorganization of distributed global arrays. mpp_redistribute is used to reorganize a distributed ar...
The domain2D type contains all the necessary information to define the global, compute and data domai...
subroutine mpp_set_current_pelist(pelist, no_sync)
Set context pelist.
integer function mpp_npes()
Returns processor count for current pelist.
integer function mpp_pe()
Returns processor ID.
integer function mpp_clock_id(name, flags, grain)
Return an ID for a new or existing clock.
Perform parallel broadcasts.
Offload equivalent of register_axis in fms2_io_mod Registers an axis to a netcdf file on offloaded PE...
Offload equivalent of write_data in fms2_io_mod Writes data to a netcdf file on offloaded PEs....
Structure to hold offloading file information.