Skip to content

Commit 30effab

Browse files
authored
Feature/general indices gatscat (#1832)
1 parent fe2dcd3 commit 30effab

8 files changed

Lines changed: 485 additions & 27 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -723,6 +723,7 @@ if(UNIT_TESTS)
723723
test_fms/mpp/test_mpp_domains.F90
724724
test_fms/mpp/test_mpp.F90
725725
test_fms/mpp/test_mpp_gatscat.F90
726+
test_fms/mpp/test_mpp_pelist_gatscat_gen_ind.F90
726727
test_fms/mpp/test_mpp_get_ascii_lines.F90
727728
test_fms/mpp/test_mpp_global_field_ug.F90
728729
test_fms/mpp/test_mpp_global_sum_ad.F90

mpp/include/mpp_comm.inc

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,9 +393,13 @@ end subroutine mpp_init_legacy
393393
#define MPP_GATHER_1D_ mpp_gather_logical_1d
394394
#define MPP_GATHER_1DV_ mpp_gather_logical_1dv
395395
#undef MPP_GATHER_PELIST_2D_
396+
#undef MPP_GATHER_PELIST_GEN_2D_
396397
#undef MPP_GATHER_PELIST_3D_
398+
#undef MPP_GATHER_PELIST_GEN_3D_
397399
#define MPP_GATHER_PELIST_2D_ mpp_gather_pelist_logical_2d
400+
#define MPP_GATHER_PELIST_GEN_2D_ mpp_gather_pelist_logical_gen_2d
398401
#define MPP_GATHER_PELIST_3D_ mpp_gather_pelist_logical_3d
402+
#define MPP_GATHER_PELIST_GEN_3D_ mpp_gather_pelist_logical_gen_3d
399403
#undef MPI_TYPE_
400404
#define MPI_TYPE_ MPI_LOGICAL
401405
#include <mpp_gather.fh>
@@ -407,9 +411,13 @@ end subroutine mpp_init_legacy
407411
#define MPP_GATHER_1D_ mpp_gather_int4_1d
408412
#define MPP_GATHER_1DV_ mpp_gather_int4_1dv
409413
#undef MPP_GATHER_PELIST_2D_
414+
#undef MPP_GATHER_PELIST_GEN_2D_
410415
#undef MPP_GATHER_PELIST_3D_
416+
#undef MPP_GATHER_PELIST_GEN_3D_
411417
#define MPP_GATHER_PELIST_2D_ mpp_gather_pelist_int4_2d
418+
#define MPP_GATHER_PELIST_GEN_2D_ mpp_gather_pelist_int4_gen_2d
412419
#define MPP_GATHER_PELIST_3D_ mpp_gather_pelist_int4_3d
420+
#define MPP_GATHER_PELIST_GEN_3D_ mpp_gather_pelist_int4_gen_3d
413421
#undef MPI_TYPE_
414422
#define MPI_TYPE_ MPI_INTEGER4
415423
#include <mpp_gather.fh>
@@ -422,9 +430,13 @@ end subroutine mpp_init_legacy
422430
#define MPP_GATHER_1D_ mpp_gather_int8_1d
423431
#define MPP_GATHER_1DV_ mpp_gather_int8_1dv
424432
#undef MPP_GATHER_PELIST_2D_
433+
#undef MPP_GATHER_PELIST_GEN_2D_
425434
#undef MPP_GATHER_PELIST_3D_
435+
#undef MPP_GATHER_PELIST_GEN_3D_
426436
#define MPP_GATHER_PELIST_2D_ mpp_gather_pelist_int8_2d
437+
#define MPP_GATHER_PELIST_GEN_2D_ mpp_gather_pelist_int8_gen_2d
427438
#define MPP_GATHER_PELIST_3D_ mpp_gather_pelist_int8_3d
439+
#define MPP_GATHER_PELIST_GEN_3D_ mpp_gather_pelist_int8_gen_3d
428440
#undef MPI_TYPE_
429441
#define MPI_TYPE_ MPI_INTEGER8
430442
#include <mpp_gather.fh>
@@ -437,9 +449,13 @@ end subroutine mpp_init_legacy
437449
#define MPP_GATHER_1D_ mpp_gather_real4_1d
438450
#define MPP_GATHER_1DV_ mpp_gather_real4_1dv
439451
#undef MPP_GATHER_PELIST_2D_
452+
#undef MPP_GATHER_PELIST_GEN_2D_
440453
#undef MPP_GATHER_PELIST_3D_
454+
#undef MPP_GATHER_PELIST_GEN_3D_
441455
#define MPP_GATHER_PELIST_2D_ mpp_gather_pelist_real4_2d
456+
#define MPP_GATHER_PELIST_GEN_2D_ mpp_gather_pelist_real4_gen_2d
442457
#define MPP_GATHER_PELIST_3D_ mpp_gather_pelist_real4_3d
458+
#define MPP_GATHER_PELIST_GEN_3D_ mpp_gather_pelist_real4_gen_3d
443459
#undef MPI_TYPE_
444460
#define MPI_TYPE_ MPI_REAL4
445461
#include <mpp_gather.fh>
@@ -451,50 +467,70 @@ end subroutine mpp_init_legacy
451467
#define MPP_GATHER_1D_ mpp_gather_real8_1d
452468
#define MPP_GATHER_1DV_ mpp_gather_real8_1dv
453469
#undef MPP_GATHER_PELIST_2D_
470+
#undef MPP_GATHER_PELIST_GEN_2D_
454471
#undef MPP_GATHER_PELIST_3D_
472+
#undef MPP_GATHER_PELIST_GEN_3D_
455473
#define MPP_GATHER_PELIST_2D_ mpp_gather_pelist_real8_2d
474+
#define MPP_GATHER_PELIST_GEN_2D_ mpp_gather_pelist_real8_gen_2d
456475
#define MPP_GATHER_PELIST_3D_ mpp_gather_pelist_real8_3d
476+
#define MPP_GATHER_PELIST_GEN_3D_ mpp_gather_pelist_real8_gen_3d
457477
#undef MPI_TYPE_
458478
#define MPI_TYPE_ MPI_REAL8
459479
#include <mpp_gather.fh>
460480
461481
!#################################################
462482
#undef MPP_SCATTER_PELIST_2D_
483+
#undef MPP_SCATTER_PELIST_GEN_2D_
463484
#undef MPP_SCATTER_PELIST_3D_
485+
#undef MPP_SCATTER_PELIST_GEN_3D_
464486
#undef MPP_TYPE_
465487
#define MPP_TYPE_ integer(i4_kind)
466488
#define MPP_SCATTER_PELIST_2D_ mpp_scatter_pelist_int4_2d
489+
#define MPP_SCATTER_PELIST_GEN_2D_ mpp_scatter_pelist_int4_gen_2d
467490
#define MPP_SCATTER_PELIST_3D_ mpp_scatter_pelist_int4_3d
491+
#define MPP_SCATTER_PELIST_GEN_3D_ mpp_scatter_pelist_int4_gen_3d
468492
#undef MPI_TYPE_
469493
#define MPI_TYPE_ MPI_INTEGER4
470494
#include <mpp_scatter.fh>
471495
472496
#undef MPP_SCATTER_PELIST_2D_
497+
#undef MPP_SCATTER_PELIST_GEN_2D_
473498
#undef MPP_SCATTER_PELIST_3D_
499+
#undef MPP_SCATTER_PELIST_GEN_3D_
474500
#undef MPP_TYPE_
475501
#define MPP_TYPE_ integer(i8_kind)
476502
#define MPP_SCATTER_PELIST_2D_ mpp_scatter_pelist_int8_2d
503+
#define MPP_SCATTER_PELIST_GEN_2D_ mpp_scatter_pelist_int8_gen_2d
477504
#define MPP_SCATTER_PELIST_3D_ mpp_scatter_pelist_int8_3d
505+
#define MPP_SCATTER_PELIST_GEN_3D_ mpp_scatter_pelist_int8_gen_3d
478506
#undef MPI_TYPE_
479507
#define MPI_TYPE_ MPI_INTEGER8
480508
#include <mpp_scatter.fh>
481509
482510
#undef MPP_SCATTER_PELIST_2D_
511+
#undef MPP_SCATTER_PELIST_GEN_2D_
483512
#undef MPP_SCATTER_PELIST_3D_
513+
#undef MPP_SCATTER_PELIST_GEN_3D_
484514
#undef MPP_TYPE_
485515
#define MPP_TYPE_ real(r4_kind)
486516
#define MPP_SCATTER_PELIST_2D_ mpp_scatter_pelist_real4_2d
517+
#define MPP_SCATTER_PELIST_GEN_2D_ mpp_scatter_pelist_real4_gen_2d
487518
#define MPP_SCATTER_PELIST_3D_ mpp_scatter_pelist_real4_3d
519+
#define MPP_SCATTER_PELIST_GEN_3D_ mpp_scatter_pelist_real4_gen_3d
488520
#undef MPI_TYPE_
489521
#define MPI_TYPE_ MPI_REAL4
490522
#include <mpp_scatter.fh>
491523
492524
#undef MPP_SCATTER_PELIST_2D_
525+
#undef MPP_SCATTER_PELIST_GEN_2D_
493526
#undef MPP_SCATTER_PELIST_3D_
527+
#undef MPP_SCATTER_PELIST_GEN_3D_
494528
#undef MPP_TYPE_
495529
#define MPP_TYPE_ real(r8_kind)
496530
#define MPP_SCATTER_PELIST_2D_ mpp_scatter_pelist_real8_2d
531+
#define MPP_SCATTER_PELIST_GEN_2D_ mpp_scatter_pelist_real8_gen_2d
497532
#define MPP_SCATTER_PELIST_3D_ mpp_scatter_pelist_real8_3d
533+
#define MPP_SCATTER_PELIST_GEN_3D_ mpp_scatter_pelist_real8_gen_3d
498534
#undef MPI_TYPE_
499535
#define MPI_TYPE_ MPI_REAL8
500536
#include <mpp_scatter.fh>

mpp/include/mpp_gather.fh

Lines changed: 75 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ subroutine MPP_GATHER_1DV_(sbuf, ssize, rbuf, rsize, pelist)
9696
deallocate(displs)
9797
end subroutine MPP_GATHER_1DV_
9898

99-
10099
subroutine MPP_GATHER_PELIST_2D_(is, ie, js, je, pelist, array_seg, gather_data, is_root_pe, &
101100
ishift, jshift)
102101
integer, intent(in) :: is, ie, js, je
@@ -106,6 +105,26 @@ subroutine MPP_GATHER_PELIST_2D_(is, ie, js, je, pelist, array_seg, gather_data,
106105
logical, intent(in) :: is_root_pe
107106
integer, optional, intent(in) :: ishift, jshift
108107

108+
integer, dimension(3) :: dim_order
109+
110+
dim_order = (/1,2,3/)
111+
112+
call mpp_gather(is, ie, js, je, pelist, array_seg, gather_data, dim_order, is_root_pe, &
113+
ishift, jshift)
114+
return
115+
116+
end subroutine MPP_GATHER_PELIST_2D_
117+
118+
subroutine MPP_GATHER_PELIST_GEN_2D_(is, ie, js, je, pelist, array_seg, gather_data, dim_order, is_root_pe, &
119+
ishift, jshift)
120+
integer, intent(in) :: is, ie, js, je
121+
integer, dimension(:), intent(in) :: pelist
122+
MPP_TYPE_, dimension(:,:), contiguous, target, intent(in) :: array_seg
123+
MPP_TYPE_, dimension(:,:), contiguous, target, intent(inout) :: gather_data
124+
integer, dimension(3), intent(in) :: dim_order
125+
logical, intent(in) :: is_root_pe
126+
integer, optional, intent(in) :: ishift, jshift
127+
109128
MPP_TYPE_, pointer :: arr3D(:,:,:)
110129
MPP_TYPE_, pointer :: data3D(:,:,:)
111130

@@ -116,11 +135,11 @@ subroutine MPP_GATHER_PELIST_2D_(is, ie, js, je, pelist, array_seg, gather_data,
116135
data3D => null()
117136
endif
118137

119-
call mpp_gather(is, ie, js, je, 1, pelist, arr3D, data3D, is_root_pe, &
138+
call mpp_gather(is, ie, js, je, 1, pelist, arr3D, data3D, dim_order, is_root_pe, &
120139
ishift, jshift)
121140
return
122141

123-
end subroutine MPP_GATHER_PELIST_2D_
142+
end subroutine MPP_GATHER_PELIST_GEN_2D_
124143

125144

126145
subroutine MPP_GATHER_PELIST_3D_(is, ie, js, je, nk, pelist, array_seg, gather_data, is_root_pe, &
@@ -132,16 +151,43 @@ subroutine MPP_GATHER_PELIST_3D_(is, ie, js, je, nk, pelist, array_seg, gather_d
132151
logical, intent(in) :: is_root_pe
133152
integer, optional, intent(in) :: ishift, jshift
134153

135-
integer :: i, j, k
154+
integer, dimension(3) :: dim_order
155+
156+
dim_order = (/1, 2, 3/)
157+
158+
call mpp_gather(is, ie, js, je, nk, pelist, array_seg, gather_data, dim_order, is_root_pe, &
159+
ishift, jshift)
160+
return
161+
162+
end subroutine MPP_GATHER_PELIST_3D_
163+
164+
subroutine MPP_GATHER_PELIST_GEN_3D_(is, ie, js, je, nk, pelist, array_seg, gather_data, dim_order, is_root_pe, &
165+
ishift, jshift)
166+
integer, intent(in) :: is, ie, js, je, nk
167+
integer, dimension(:), intent(in) :: pelist
168+
MPP_TYPE_, dimension(:,:,:), intent(in) :: array_seg
169+
MPP_TYPE_, dimension(:,:,:), intent(inout) :: gather_data
170+
integer, dimension(3), intent(in) :: dim_order
171+
logical, intent(in) :: is_root_pe
172+
integer, optional, intent(in) :: ishift, jshift
173+
136174
integer :: root_pe, root_pe_test
175+
integer :: k, us, ue, vs, ve, ws, we
137176
integer :: i1, i2, j1, j2, ioff, joff
138177
integer :: base_idx, send_count, msg_start
139-
integer :: blocksize_i, blocksize_j, blocksize
178+
integer :: blocksize_u, blocksize_v, blocksize_w, blocksize
179+
integer, dimension(3) :: start_idx, stop_idx
140180
integer, dimension(:), allocatable :: gind, counts
141181
MPP_TYPE_, dimension(:), allocatable :: rbuf
142182

143183
if (.not.ANY(mpp_pe().eq.pelist(:))) return
144184

185+
! Check dim_order is a permutation of 1..3
186+
if ( any(dim_order < 1) .or. any(dim_order > 3) ) call mpp_error(FATAL, &
187+
"fms_io(mpp_gather_pelist): dim_order entries must be in {1,2,3}")
188+
if ( dim_order(1) == dim_order(2) .or. dim_order(1) == dim_order(3) .or. dim_order(2) == dim_order(3) ) &
189+
call mpp_error(FATAL, "fms_io(mpp_gather_pelist): dim_order must be a permutation of 1,2,3")
190+
145191
if (is_root_pe) then
146192
root_pe = mpp_pe()
147193
root_pe_test = 999
@@ -160,7 +206,6 @@ subroutine MPP_GATHER_PELIST_3D_(is, ie, js, je, nk, pelist, array_seg, gather_d
160206
if ((is_root_pe) .and. (mpp_pe().ne.root_pe)) call mpp_error(FATAL, &
161207
"fms_io(mpp_gather_pelist): too many root_pes specified")
162208

163-
164209
ioff=0
165210
joff=0
166211
if (present(ishift)) ioff=ishift
@@ -170,7 +215,7 @@ subroutine MPP_GATHER_PELIST_3D_(is, ie, js, je, nk, pelist, array_seg, gather_d
170215
if (is_root_pe) allocate(gind(4*size(pelist)))
171216
call mpp_gather((/is, ie, js, je/), gind, pelist)
172217

173-
! Compute and allocate counts and 1d recv buffer (rbuf)
218+
! Compute recv counts and allocate 1d recv buffer (rbuf)
174219
if (is_root_pe) then
175220
allocate(counts(size(pelist)))
176221

@@ -191,8 +236,14 @@ subroutine MPP_GATHER_PELIST_3D_(is, ie, js, je, nk, pelist, array_seg, gather_d
191236

192237
send_count = (ie-is+1)*(je-js+1)*nk
193238

239+
! Get generalized stop indicies for array_seg
240+
stop_idx = (/ie-is+1, je-js+1, nk/)
241+
ue = stop_idx(dim_order(1))
242+
ve = stop_idx(dim_order(2))
243+
we = stop_idx(dim_order(3))
244+
194245
! gather data into 1d recv buffer
195-
call mpp_gather(reshape(array_seg(is:ie,js:je,1:nk),[send_count]), send_count, rbuf, counts, pelist)
246+
call mpp_gather(reshape(array_seg(1:ue,1:ve,1:we),[send_count]), send_count, rbuf, counts, pelist)
196247

197248
! Unpack recv buffer into return array (gather_data)
198249
if (is_root_pe) then
@@ -202,12 +253,22 @@ subroutine MPP_GATHER_PELIST_3D_(is, ie, js, je, nk, pelist, array_seg, gather_d
202253
i1 = gind( base_idx + 1 ) + ioff ;; i2 = gind( base_idx + 2 ) + ioff
203254
j1 = gind( base_idx + 3 ) + joff ;; j2 = gind( base_idx + 4 ) + joff
204255

205-
blocksize_i = i2 - i1 + 1
206-
blocksize_j = j2 - j1 + 1
207-
blocksize = blocksize_i * blocksize_j * nk
256+
! Get generalized start/stop indicies
257+
start_idx = (/i1,j1,1/)
258+
stop_idx = (/i2,j2,nk/)
259+
260+
us = start_idx(dim_order(1)) ;; ue = stop_idx(dim_order(1))
261+
vs = start_idx(dim_order(2)) ;; ve = stop_idx(dim_order(2))
262+
ws = start_idx(dim_order(3)) ;; we = stop_idx(dim_order(3))
208263

209-
gather_data(i1:i2, j1:j2, 1:nk) = reshape(rbuf(msg_start:msg_start+blocksize-1), &
210-
[blocksize_i, blocksize_j, nk])
264+
! Compute block sizes
265+
blocksize_u = ue - us + 1
266+
blocksize_v = ve - vs + 1
267+
blocksize_w = we - ws + 1
268+
blocksize = blocksize_u * blocksize_v * blocksize_w
269+
270+
gather_data(us:ue, vs:ve, ws:we) = reshape(rbuf(msg_start:msg_start+blocksize-1), &
271+
[blocksize_u, blocksize_v, blocksize_w])
211272

212273
msg_start = msg_start + blocksize
213274
enddo
@@ -219,5 +280,5 @@ subroutine MPP_GATHER_PELIST_3D_(is, ie, js, je, nk, pelist, array_seg, gather_d
219280

220281
call mpp_sync_self()
221282

222-
end subroutine MPP_GATHER_PELIST_3D_
283+
end subroutine MPP_GATHER_PELIST_GEN_3D_
223284
!> @}

0 commit comments

Comments
 (0)