8
integer, parameter :: rr_ = selected_real_kind(p=6) ! single (real*4)
9
integer, parameter :: rd_ = selected_real_kind(p=15) ! double (real*8)
10
integer, parameter :: is_ = selected_int_kind(4) ! short (integer*2)
11
integer, parameter :: ii_ = selected_int_kind(9) ! int (integer*4)
12
integer, parameter :: il_ = selected_int_kind(18) ! long (integer*8)
13
integer, parameter, private :: BUD_ID_LEn = 36
14
character(len=*), parameter, private :: &
15
BUD_MOd = 'BUD_CC2(BUD_MOD,_)BUD_MOD_NAME'
16
character(len=*), parameter, private :: &
19
module procedure get_elem1_
23
module procedure get_elem1p_
27
module procedure get_elem2_
31
module procedure get_elem2p_
35
module procedure dimensions_
38
interface distributed_index
39
module procedure distributed_index_
41
public :: distributed_index
43
module procedure distribute_
47
module procedure new_dist_index_
50
type(iD1D_b1D_), pointer :: D => null()
57
character(len=BUD_ID_LEN) :: id_ = "null_id"
61
module procedure new_data_
64
interface assignment(=)
65
module procedure get_elem1_assign_
66
module procedure get_elem2_assign_
67
module procedure set_elem1_
68
module procedure set_elem2_
71
module procedure get_elem1_
72
module procedure get_elem2_
75
module procedure set_elem1_
76
module procedure set_elem2_
79
module procedure get_elem1_
82
interface set_element1
83
module procedure set_elem1_
85
public :: set_element1
87
module procedure get_elem1p_
91
module procedure get_elem2_
94
interface set_element2
95
module procedure set_elem2_
97
public :: set_element2
99
module procedure get_elem2p_
104
interface assignment(=)
105
module procedure common_assign_
107
public :: assignment(=)
108
private :: common_assign_
110
module procedure common_initialize_
113
private :: common_initialize_
114
interface is_initialized
115
module procedure common_is_initialized_
117
public :: is_initialized
118
private :: common_is_initialized_
119
interface initialized
120
module procedure common_is_initialized_
122
public :: initialized
124
module procedure common_is_initialized_
128
module procedure common_is_same_
131
private :: common_is_same_
133
module procedure common_is_same_
137
module procedure common_delete_
140
private :: common_delete_
142
module procedure common_nullify_
145
private :: common_nullify_
147
module procedure copy_
150
private :: common_copy_
152
module procedure print_
156
module procedure common_references_
159
private :: common_references_
161
module procedure common_references_
165
module procedure common_set_error_is_
166
module procedure common_set_error_ii_
167
module procedure common_set_error_il_
170
private :: common_set_error_is_
171
private :: common_set_error_ii_
172
private :: common_set_error_il_
174
module procedure common_error_
177
private :: common_error_
179
subroutine common_copy_(from, to)
180
type(iD1D_b1D), intent(in) :: from
181
type(iD1D_b1D), intent(inout) :: to
182
call set_error(to, error(from))
183
end subroutine common_copy_
184
subroutine common_initialize_(this)
185
type(iD1D_b1D), intent(inout) :: this
188
allocate(this%D, stat=error)
189
call set_error(this, error)
190
if ( error /= 0 ) return
192
call common_tag_object_(this)
193
end subroutine common_initialize_
194
pure function common_is_initialized_(this) result(init)
195
type(iD1D_b1D), intent(in) :: this
197
init = associated(this%D)
198
end function common_is_initialized_
199
elemental function common_is_same_(lhs, rhs) result(same)
200
type(iD1D_b1D), intent(in) :: lhs, rhs
202
same = is_initd(lhs) .and. is_initd(rhs)
203
if ( .not. same ) return
204
same = associated(lhs%D, target=rhs%D)
205
end function common_is_same_
206
subroutine common_delete_(this)
207
type(iD1D_b1D), intent(inout) :: this
209
call set_error(this, 0)
210
if (.not. is_initd(this) ) return
211
this%D%refs_ = this%D%refs_ - 1
212
if ( 0 == this%D%refs_ ) then
214
deallocate(this%D, stat=error)
215
call set_error(this, error)
218
end subroutine common_delete_
219
elemental subroutine common_nullify_(this)
220
type(iD1D_b1D), intent(inout) :: this
221
if (.not. is_initd(this) ) return
223
end subroutine common_nullify_
224
subroutine common_assign_(lhs, rhs)
225
type(iD1D_b1D), intent(inout) :: lhs
226
type(iD1D_b1D), intent(in) :: rhs
228
if ( .not. is_initd(rhs) ) return
230
lhs%D%refs_ = rhs%D%refs_ + 1
231
end subroutine common_assign_
232
elemental function common_references_(this) result(refs)
233
type(iD1D_b1D), intent(in) :: this
235
if ( is_initd(this) ) then
240
end function common_references_
241
elemental function common_error_(this) result(error)
242
type(iD1D_b1D), intent(in) :: this
244
if ( is_initd(this) ) then
249
end function common_error_
250
elemental subroutine common_set_error_is_(this, error)
251
type(iD1D_b1D), intent(inout) :: this
252
integer(is_), intent(in) :: error
254
end subroutine common_set_error_is_
255
elemental subroutine common_set_error_ii_(this, error)
256
type(iD1D_b1D), intent(inout) :: this
257
integer(ii_), intent(in) :: error
259
end subroutine common_set_error_ii_
260
elemental subroutine common_set_error_il_(this, error)
261
type(iD1D_b1D), intent(inout) :: this
262
integer(il_), intent(in) :: error
264
end subroutine common_set_error_il_
265
elemental function common_id_(this) result(str)
266
type(iD1D_b1D), intent(in) :: this
267
character(len=BUD_ID_LEn) :: str
269
end function common_id_
270
subroutine common_tag_object_(this)
271
type(iD1D_b1D), intent(inout) :: this
272
end subroutine common_tag_object_
273
subroutine delete_(this)
274
type(iD1D_b1D), intent(inout) :: this
275
call set_error(this, 0)
276
call delete(this%D%e1)
277
if ( 0 /= error(this%D%e1) ) &
278
call set_error(this, error(this%D%e1))
279
call delete(this%D%e2)
280
if ( 0 /= error(this%D%e2) ) &
281
call set_error(this, error(this%D%e2))
282
end subroutine delete_
283
subroutine copy_(from, to)
284
type(iD1D_b1D), intent(in) :: from
285
type(iD1D_b1D), intent(inout) :: to
287
if ( .not. is_initd(from) ) return
289
call common_copy_(from, to)
290
call copy(from%D%e1, to%D%e1)
291
call copy(from%D%e2, to%D%e2)
293
subroutine new_data_(this, a, b &
295
type(iD1D_b1D), intent(inout) :: this
296
type(iDist1D), intent(inout) :: a
297
type(bArray1D), intent(inout) :: b
301
end subroutine new_data_
302
subroutine new_(this)
303
type(iD1D_b1D), intent(inout) :: this
304
call initialize(this)
306
subroutine get_elem1_(this, item)
307
type(iD1D_b1D), intent(in) :: this
308
type(iDist1D), intent(inout) :: item
309
if ( .not. is_initd(this) ) then
315
subroutine get_elem1_assign_(item, this)
316
type(iDist1D), intent(inout) :: item
317
type(iD1D_b1D), intent(in) :: this
318
if ( .not. is_initd(this) ) then
324
subroutine set_elem1_(this, item)
325
type(iD1D_b1D), intent(inout) :: this
326
type(iDist1D), intent(in) :: item
327
if ( .not. is_initd(this) ) return
330
function get_elem1p_(this) result(p)
331
type(iD1D_b1D), intent(inout) :: this
332
type(iDist1D), pointer :: p
333
if ( .not. is_initd(this) ) then
339
subroutine get_elem2_(this, item)
340
type(iD1D_b1D), intent(in) :: this
341
type(bArray1D), intent(inout) :: item
342
if ( .not. is_initd(this) ) then
348
subroutine get_elem2_assign_(item, this)
349
type(bArray1D), intent(inout) :: item
350
type(iD1D_b1D), intent(in) :: this
351
if ( .not. is_initd(this) ) then
357
subroutine set_elem2_(this, item)
358
type(iD1D_b1D), intent(inout) :: this
359
type(bArray1D), intent(in) :: item
360
if ( .not. is_initd(this) ) return
363
function get_elem2p_(this) result(p)
364
type(iD1D_b1D), intent(inout) :: this
365
type(bArray1D), pointer :: p
366
if ( .not. is_initd(this) ) then
372
subroutine print_(this, info, indent)
373
type(iD1D_b1D), intent(in) :: this
374
character(len=*), intent(in), optional :: info
375
integer, intent(in), optional :: indent
377
character(len=32) :: fmt
378
character(len=256) :: name
380
if ( present(info) ) name = info
382
if ( present(indent) ) lindent = indent
383
write(fmt, '(a,i0,a)') '(t',lindent,',3a)'
384
if ( .not. is_initd(this) ) then
385
write(*,fmt) "<", trim(name), " not initialized>"
388
write(fmt, '(a,i0,a)') '(t',lindent,',3a)'
389
lindent = lindent + 2 ! step indentation
390
write(*,fmt) "<<", trim(name), " coll>"
391
call print(this%D%e1, indent = lindent)
392
call print(this%D%e2, indent = lindent)
393
lindent = lindent - 2 ! go back to requested indentation
394
write(fmt, '(a,i0,a)') '(t',lindent,',a,i0,a)'
395
write(*,fmt) " <coll-refs: ", references(this), ">>"
396
end subroutine print_
397
subroutine new_dist_index_(this, dist, arr, dist_idx)
398
type(iD1D_b1D), intent(inout) :: this
399
type(iDist1D), intent(inout) :: dist
400
type(bArray1D), intent(inout) :: arr
401
integer, intent(in) :: dist_idx
402
call new(this, dist, arr)
403
end subroutine new_dist_index_
404
function distributed_index_(this) result(idx)
405
type(iD1D_b1D), intent(in) :: this
407
if ( is_initd(this) ) then
412
end function distributed_index_
413
pure function dimensions_(this) result(d)
414
type(iD1D_b1D), intent(in) :: this
416
if ( is_initd(this) ) then
421
end function dimensions_
422
subroutine distribute_(this, parent, out_dist, out)
423
type(iD1D_b1D), intent(inout) :: this
424
type(MP_Comm), intent(inout) :: parent
425
type(iDist1D), intent(inout) :: out_dist
426
type(iD1D_b1D), intent(inout) :: out
427
type(MP_Comm) :: comm, out_comm
428
type(iDist1D) :: fake_dist, dist
429
type(bArray1D) :: arr
430
integer(ii_) :: ir, nranks, my_root, rank, in_rank
431
logical :: is_distr, my_distr
432
integer(ii_) :: dist_idx, dims
433
integer(ii_) :: nl, ng
435
integer(ii_), allocatable :: ranks(:)
436
integer(ii_), allocatable :: ashape(:), itmp1(:)
437
if ( .not. is_communicator(parent) ) return
438
rank = comm_rank(parent)
439
nranks = comm_size(parent)
441
in_rank = comm_rank(dist)
442
if ( in_rank < 0 ) in_rank = in_rank - 1
445
dims = dimensions(arr)
446
call AllReduce_Max(dims, ir, parent)
448
allocate(ashape(dims))
449
if ( is_initd(arr) ) then
450
dist_idx = distributed_index(this)
452
ashape(ir) = size(arr, ir)
460
call AllReduce_Max(dist_idx, ir, parent)
462
allocate(itmp1(dims))
463
call AllReduce_Max(ashape, itmp1, parent)
465
if ( ir /= dist_idx ) then
466
ashape(ir) = itmp1(ir)
471
if ( is_communicator(out_comm) ) then
472
if ( comm_rank(out_comm) == 0 ) then
473
ir = comm_rank(parent)
477
call AllReduce_Max(ir, my_root, out_comm)
481
ng = size_global(dist)
482
call AllReduce_Max(ng, nl, parent)
484
nl = size_local(dist)
485
do ir = 0 , nranks - 1
486
if ( my_root == ir ) then
491
call AllReduce_LOr(my_distr, is_distr, parent)
492
if ( .not. is_distr ) cycle
494
call new_remote(parent, out_dist)
495
call create_ranks(out_dist)
496
call sub_dist(out_dist)
498
call new_remote(parent, fake_dist)
499
call create_ranks(fake_dist)
500
call sub_dist(fake_dist)
501
call delete(fake_dist)
508
call delete(out_comm)
510
subroutine create_ranks(dist)
511
type(iDist1D), intent(inout) :: dist
512
type(MP_Comm) :: comm
514
call child_Bcast(parent, comm, size=nout)
515
allocate(ranks(-1:nout-1))
517
call child_Bcast_ranks(parent, comm, nout, ranks(0:))
519
end subroutine create_ranks
520
subroutine sub_dist(out_dist)
521
use bud_Transfer, only: transfer_dim
522
type(iDist1D), intent(inout) :: out_dist
523
type(MP_Comm) :: out_comm
524
type(bArray1D) :: out_arr
526
logical, pointer :: dat (:)
527
logical, pointer :: odat (:)
528
integer(ii_) :: il, ig, oil
529
integer(ii_) :: out_nl
531
integer :: send_R, recv_R
532
integer(ii_), allocatable :: reqs(:), stats(:,:)
533
integer(ii_) :: stat(MPI_STATUS_SIZE)
535
if ( .not. run ) return
537
out_nl = size_local(out_dist)
538
if ( is_communicator(out_comm) ) then
539
ashape(dist_idx) = out_nl
540
call new(out_arr, ashape(:))
541
call new(out, out_dist, out_arr)
542
odat => array_p(out_arr)
545
if ( is_initd(dist) ) then
546
allocate(reqs(nl), stats(MPI_STATUS_SIZE, nl))
548
reqs(il) = MPI_REQUEST_NULL
552
if ( dist_idx == dims ) then
554
send_R = g2rank(dist, ig)
555
recv_R = ranks(g2rank(out_dist, ig))
556
if ( recv_R == rank .and. &
557
send_R == in_rank ) then
559
oil = g2l(out_dist, ig)
561
else if ( recv_R == rank ) then
562
oil = g2l(out_dist, ig)
563
call Recv(odat(oil), MPI_ANY_SOURCE, ig, &
565
else if ( send_R == in_rank ) then
567
call ISSend(dat(il), recv_R, ig, &
571
if ( allocated(reqs) ) &
572
call WaitAll(nl, reqs, stats, parent)
573
else if ( dist_idx == 1 ) then
574
do i2 = 1 , ashape(2)
576
send_R = g2rank(dist, ig)
577
recv_R = ranks(g2rank(out_dist, ig))
578
if ( recv_R == rank .and. &
579
send_R == in_rank ) then
581
oil = g2l(out_dist, ig)
582
else if ( recv_R == rank ) then
583
oil = g2l(out_dist, ig)
584
else if ( send_R == in_rank ) then
588
if ( allocated(reqs) ) &
589
call WaitAll(nl, reqs, stats, parent)
592
if ( allocated(reqs) ) deallocate(reqs)
594
call delete(out_comm)
595
end subroutine sub_dist
596
end subroutine distribute_
597
subroutine write_(f, this)
599
use bud_Transfer, only: transfer_dim
600
type( File ), intent(inout) :: f
601
type(iD1D_b1D), intent(in) :: this
602
type(iDist1D) :: dist
603
type(bArray1D) :: arr
604
type( MP_Comm ) :: comm
605
logical :: formatted, do_io
606
integer :: iu, io_rank, dat_rank, rank
607
character(len=64), parameter :: fmt_ = '(e20.16)'
608
logical, pointer :: dat (:)
609
logical, allocatable :: rdat(:)
610
integer :: dist_idx, l, n, ndat
612
integer :: status(MPI_STATUS_SIZE)
613
if ( .not. is_initd(this) ) return
617
rank = comm_rank(comm)
618
if ( is_open(f) ) then
623
call AllReduce_Max(io_rank, iu, comm)
625
if ( io_rank < 0 ) then
631
do_io = io_rank == rank
633
formatted = is_formatted(f)
639
dist_idx = distributed_index(this)
640
if ( dist_idx == 1 ) then
641
ndat = size_global(dist)
647
if ( formatted ) then
649
write(iu, '(i16)') d1
655
if ( dist_idx == 1 ) then
657
do while ( i1 <= d1 )
658
n = consecutive(dist, i1)
659
dat_rank = global2rank(dist, i1)
660
if ( do_io .and. rank == dat_rank ) then
661
l = global2local(dist, i1)
662
call transfer_dim(n, rdat(i1:), n, dat(l:))
663
else if ( do_io ) then
664
call Recv(rdat(i1), n, dat_rank, i1, comm, status)
665
else if ( rank == dat_rank ) then
666
l = global2local(dist, i1)
667
call SSend(dat(l), n, io_rank, i1, comm)
672
if ( formatted ) then
673
write(iu, fmt_) rdat(:)
679
if ( do_io ) deallocate(rdat)
682
end subroutine write_
683
subroutine read_(f, dist, this, dist_idx)
685
use bud_Transfer, only: transfer_dim
686
type( File ), intent(inout) :: f
687
type(iDist1D), intent(inout) :: dist
688
type(iD1D_b1D), intent(inout) :: this
689
integer, intent(in), optional :: dist_idx
690
type(bArray1D) :: arr
691
type( MP_Comm ) :: comm
692
logical :: formatted, do_io
693
integer :: iu, io_rank, dat_rank, rank
694
character(len=64), parameter :: fmt_ = '(e20.16)'
695
integer(ii_) :: ashape(1)
696
logical, pointer :: dat (:)
697
logical, allocatable :: rdat(:)
698
integer :: ldist_idx, l, n
700
integer :: status(MPI_STATUS_SIZE)
701
if ( .not. is_initd(this) ) return
703
if ( present(dist_idx) ) ldist_idx = dist_idx
705
rank = comm_rank(comm)
706
if ( is_open(f) ) then
711
call AllReduce_Max(io_rank, iu, comm)
713
if ( io_rank < 0 ) then
716
call set_error(this, -1)
719
do_io = io_rank == rank
721
formatted = is_formatted(f)
723
if ( formatted ) then
725
read(iu, '(i16)') ashape
733
select case ( ldist_idx )
735
ashape(1) = size_local(dist)
737
call new(arr, ashape)
739
call new(this, dist, arr, ldist_idx)
745
if ( formatted ) then
746
read(iu, fmt_) rdat(:)
751
select case ( ldist_idx )
754
do while ( i1 <= d1 )
755
n = consecutive(dist, i1)
756
dat_rank = global2rank(dist, i1)
757
if ( do_io .and. rank == dat_rank ) then
758
l = global2local(dist, i1)
759
call transfer_dim(n, dat(l:), n, rdat(i1:))
760
else if ( do_io ) then
761
call SSend(rdat(i1), n, dat_rank, i1, comm)
762
else if ( rank == dat_rank ) then
763
l = global2local(dist, i1)
764
call Recv(dat(l), n, io_rank, i1, comm, status)
772
module bud_iDist1D_r1D
779
integer, parameter :: rr_ = selected_real_kind(p=6) ! single (real*4)
780
integer, parameter :: rd_ = selected_real_kind(p=15) ! double (real*8)
781
integer, parameter :: is_ = selected_int_kind(4) ! short (integer*2)
782
integer, parameter :: ii_ = selected_int_kind(9) ! int (integer*4)
783
integer, parameter :: il_ = selected_int_kind(18) ! long (integer*8)
784
integer, parameter, private :: BUD_ID_LEn = 36
785
character(len=*), parameter, private :: &
786
BUD_MOd = 'BUD_CC2(BUD_MOD,_)BUD_MOD_NAME'
787
character(len=*), parameter, private :: &
788
BUD_TYPe = "iD1D_r1D"
790
module procedure get_elem1_
794
module procedure get_elem1p_
798
module procedure get_elem2_
802
module procedure get_elem2p_
806
module procedure dimensions_
809
interface distributed_index
810
module procedure distributed_index_
812
public :: distributed_index
814
module procedure distribute_
818
module procedure new_dist_index_
821
type(iD1D_r1D_), pointer :: D => null()
822
integer :: error_ = 0
828
character(len=BUD_ID_LEN) :: id_ = "null_id"
831
module procedure new_
832
module procedure new_data_
835
interface assignment(=)
836
module procedure get_elem1_assign_
837
module procedure get_elem2_assign_
838
module procedure set_elem1_
839
module procedure set_elem2_
842
module procedure get_elem1_
843
module procedure get_elem2_
845
interface set_element
846
module procedure set_elem1_
847
module procedure set_elem2_
850
module procedure get_elem1_
853
interface set_element1
854
module procedure set_elem1_
856
public :: set_element1
858
module procedure get_elem1p_
862
module procedure get_elem2_
865
interface set_element2
866
module procedure set_elem2_
868
public :: set_element2
870
module procedure get_elem2p_
875
interface assignment(=)
876
module procedure common_assign_
878
public :: assignment(=)
879
private :: common_assign_
881
module procedure common_initialize_
884
private :: common_initialize_
885
interface is_initialized
886
module procedure common_is_initialized_
888
public :: is_initialized
889
private :: common_is_initialized_
890
interface initialized
891
module procedure common_is_initialized_
893
public :: initialized
895
module procedure common_is_initialized_
899
module procedure common_is_same_
902
private :: common_is_same_
904
module procedure common_is_same_
908
module procedure common_delete_
911
private :: common_delete_
913
module procedure common_nullify_
916
private :: common_nullify_
918
module procedure copy_
921
private :: common_copy_
923
module procedure print_
927
module procedure common_references_
930
private :: common_references_
932
module procedure common_references_
936
module procedure common_set_error_is_
937
module procedure common_set_error_ii_
938
module procedure common_set_error_il_
941
private :: common_set_error_is_
942
private :: common_set_error_ii_
943
private :: common_set_error_il_
945
module procedure common_error_
948
private :: common_error_
950
subroutine common_copy_(from, to)
951
type(iD1D_r1D), intent(in) :: from
952
type(iD1D_r1D), intent(inout) :: to
953
call set_error(to, error(from))
954
end subroutine common_copy_
955
subroutine common_initialize_(this)
956
type(iD1D_r1D), intent(inout) :: this
959
allocate(this%D, stat=error)
960
call set_error(this, error)
961
if ( error /= 0 ) return
963
call common_tag_object_(this)
964
end subroutine common_initialize_
965
pure function common_is_initialized_(this) result(init)
966
type(iD1D_r1D), intent(in) :: this
968
init = associated(this%D)
969
end function common_is_initialized_
970
elemental function common_is_same_(lhs, rhs) result(same)
971
type(iD1D_r1D), intent(in) :: lhs, rhs
973
same = is_initd(lhs) .and. is_initd(rhs)
974
if ( .not. same ) return
975
same = associated(lhs%D, target=rhs%D)
976
end function common_is_same_
977
subroutine common_delete_(this)
978
type(iD1D_r1D), intent(inout) :: this
980
call set_error(this, 0)
981
if (.not. is_initd(this) ) return
982
this%D%refs_ = this%D%refs_ - 1
983
if ( 0 == this%D%refs_ ) then
985
deallocate(this%D, stat=error)
986
call set_error(this, error)
989
end subroutine common_delete_
990
elemental subroutine common_nullify_(this)
991
type(iD1D_r1D), intent(inout) :: this
992
if (.not. is_initd(this) ) return
994
end subroutine common_nullify_
995
subroutine common_assign_(lhs, rhs)
996
type(iD1D_r1D), intent(inout) :: lhs
997
type(iD1D_r1D), intent(in) :: rhs
999
if ( .not. is_initd(rhs) ) return
1001
lhs%D%refs_ = rhs%D%refs_ + 1
1002
end subroutine common_assign_
1003
elemental function common_references_(this) result(refs)
1004
type(iD1D_r1D), intent(in) :: this
1006
if ( is_initd(this) ) then
1011
end function common_references_
1012
elemental function common_error_(this) result(error)
1013
type(iD1D_r1D), intent(in) :: this
1015
if ( is_initd(this) ) then
1020
end function common_error_
1021
elemental subroutine common_set_error_is_(this, error)
1022
type(iD1D_r1D), intent(inout) :: this
1023
integer(is_), intent(in) :: error
1025
end subroutine common_set_error_is_
1026
elemental subroutine common_set_error_ii_(this, error)
1027
type(iD1D_r1D), intent(inout) :: this
1028
integer(ii_), intent(in) :: error
1030
end subroutine common_set_error_ii_
1031
elemental subroutine common_set_error_il_(this, error)
1032
type(iD1D_r1D), intent(inout) :: this
1033
integer(il_), intent(in) :: error
1035
end subroutine common_set_error_il_
1036
elemental function common_id_(this) result(str)
1037
type(iD1D_r1D), intent(in) :: this
1038
character(len=BUD_ID_LEn) :: str
1040
end function common_id_
1041
subroutine common_tag_object_(this)
1042
type(iD1D_r1D), intent(inout) :: this
1043
end subroutine common_tag_object_
1044
subroutine delete_(this)
1045
type(iD1D_r1D), intent(inout) :: this
1046
call set_error(this, 0)
1047
call delete(this%D%e1)
1048
if ( 0 /= error(this%D%e1) ) &
1049
call set_error(this, error(this%D%e1))
1050
call delete(this%D%e2)
1051
if ( 0 /= error(this%D%e2) ) &
1052
call set_error(this, error(this%D%e2))
1053
end subroutine delete_
1054
subroutine copy_(from, to)
1055
type(iD1D_r1D), intent(in) :: from
1056
type(iD1D_r1D), intent(inout) :: to
1058
if ( .not. is_initd(from) ) return
1060
call common_copy_(from, to)
1061
call copy(from%D%e1, to%D%e1)
1062
call copy(from%D%e2, to%D%e2)
1063
end subroutine copy_
1064
subroutine new_data_(this, a, b &
1066
type(iD1D_r1D), intent(inout) :: this
1067
type(iDist1D), intent(inout) :: a
1068
type(rArray1D), intent(inout) :: b
1072
end subroutine new_data_
1073
subroutine new_(this)
1074
type(iD1D_r1D), intent(inout) :: this
1075
call initialize(this)
1077
subroutine get_elem1_(this, item)
1078
type(iD1D_r1D), intent(in) :: this
1079
type(iDist1D), intent(inout) :: item
1080
if ( .not. is_initd(this) ) then
1086
subroutine get_elem1_assign_(item, this)
1087
type(iDist1D), intent(inout) :: item
1088
type(iD1D_r1D), intent(in) :: this
1089
if ( .not. is_initd(this) ) then
1095
subroutine set_elem1_(this, item)
1096
type(iD1D_r1D), intent(inout) :: this
1097
type(iDist1D), intent(in) :: item
1098
if ( .not. is_initd(this) ) return
1101
function get_elem1p_(this) result(p)
1102
type(iD1D_r1D), intent(inout) :: this
1103
type(iDist1D), pointer :: p
1104
if ( .not. is_initd(this) ) then
1110
subroutine get_elem2_(this, item)
1111
type(iD1D_r1D), intent(in) :: this
1112
type(rArray1D), intent(inout) :: item
1113
if ( .not. is_initd(this) ) then
1119
subroutine get_elem2_assign_(item, this)
1120
type(rArray1D), intent(inout) :: item
1121
type(iD1D_r1D), intent(in) :: this
1122
if ( .not. is_initd(this) ) then
1128
subroutine set_elem2_(this, item)
1129
type(iD1D_r1D), intent(inout) :: this
1130
type(rArray1D), intent(in) :: item
1131
if ( .not. is_initd(this) ) return
1134
function get_elem2p_(this) result(p)
1135
type(iD1D_r1D), intent(inout) :: this
1136
type(rArray1D), pointer :: p
1137
if ( .not. is_initd(this) ) then
1143
subroutine print_(this, info, indent)
1144
type(iD1D_r1D), intent(in) :: this
1145
character(len=*), intent(in), optional :: info
1146
integer, intent(in), optional :: indent
1148
character(len=32) :: fmt
1149
character(len=256) :: name
1151
if ( present(info) ) name = info
1153
if ( present(indent) ) lindent = indent
1154
write(fmt, '(a,i0,a)') '(t',lindent,',3a)'
1155
if ( .not. is_initd(this) ) then
1156
write(*,fmt) "<", trim(name), " not initialized>"
1159
write(fmt, '(a,i0,a)') '(t',lindent,',3a)'
1160
lindent = lindent + 2 ! step indentation
1161
write(*,fmt) "<<", trim(name), " coll>"
1162
call print(this%D%e1, indent = lindent)
1163
call print(this%D%e2, indent = lindent)
1164
lindent = lindent - 2 ! go back to requested indentation
1165
write(fmt, '(a,i0,a)') '(t',lindent,',a,i0,a)'
1166
write(*,fmt) " <coll-refs: ", references(this), ">>"
1167
end subroutine print_
1168
subroutine new_dist_index_(this, dist, arr, dist_idx)
1169
type(iD1D_r1D), intent(inout) :: this
1170
type(iDist1D), intent(inout) :: dist
1171
type(rArray1D), intent(inout) :: arr
1172
integer, intent(in) :: dist_idx
1173
call new(this, dist, arr)
1174
end subroutine new_dist_index_
1175
function distributed_index_(this) result(idx)
1176
type(iD1D_r1D), intent(in) :: this
1178
if ( is_initd(this) ) then
1183
end function distributed_index_
1184
pure function dimensions_(this) result(d)
1185
type(iD1D_r1D), intent(in) :: this
1187
if ( is_initd(this) ) then
1192
end function dimensions_
1193
subroutine distribute_(this, parent, out_dist, out)
1194
type(iD1D_r1D), intent(inout) :: this
1195
type(MP_Comm), intent(inout) :: parent
1196
type(iDist1D), intent(inout) :: out_dist
1197
type(iD1D_r1D), intent(inout) :: out
1198
type(MP_Comm) :: comm, out_comm
1199
type(iDist1D) :: fake_dist, dist
1200
type(rArray1D) :: arr
1201
integer(ii_) :: ir, nranks, my_root, rank, in_rank
1202
logical :: is_distr, my_distr
1203
integer(ii_) :: dist_idx, dims
1204
integer(ii_) :: nl, ng
1205
integer(ii_) :: nout
1206
integer(ii_), allocatable :: ranks(:)
1207
integer(ii_), allocatable :: ashape(:), itmp1(:)
1208
if ( .not. is_communicator(parent) ) return
1209
rank = comm_rank(parent)
1210
nranks = comm_size(parent)
1212
in_rank = comm_rank(dist)
1213
if ( in_rank < 0 ) in_rank = in_rank - 1
1216
dims = dimensions(arr)
1217
call AllReduce_Max(dims, ir, parent)
1219
allocate(ashape(dims))
1220
if ( is_initd(arr) ) then
1221
dist_idx = distributed_index(this)
1223
ashape(ir) = size(arr, ir)
1231
call AllReduce_Max(dist_idx, ir, parent)
1233
allocate(itmp1(dims))
1234
call AllReduce_Max(ashape, itmp1, parent)
1236
if ( ir /= dist_idx ) then
1237
ashape(ir) = itmp1(ir)
1242
if ( is_communicator(out_comm) ) then
1243
if ( comm_rank(out_comm) == 0 ) then
1244
ir = comm_rank(parent)
1248
call AllReduce_Max(ir, my_root, out_comm)
1252
ng = size_global(dist)
1253
call AllReduce_Max(ng, nl, parent)
1255
nl = size_local(dist)
1256
do ir = 0 , nranks - 1
1257
if ( my_root == ir ) then
1262
call AllReduce_LOr(my_distr, is_distr, parent)
1263
if ( .not. is_distr ) cycle
1264
if ( my_distr ) then
1265
call new_remote(parent, out_dist)
1266
call create_ranks(out_dist)
1267
call sub_dist(out_dist)
1269
call new_remote(parent, fake_dist)
1270
call create_ranks(fake_dist)
1271
call sub_dist(fake_dist)
1272
call delete(fake_dist)
1279
call delete(out_comm)
1281
subroutine create_ranks(dist)
1282
type(iDist1D), intent(inout) :: dist
1283
type(MP_Comm) :: comm
1285
call child_Bcast(parent, comm, size=nout)
1286
allocate(ranks(-1:nout-1))
1288
call child_Bcast_ranks(parent, comm, nout, ranks(0:))
1290
end subroutine create_ranks
1291
subroutine sub_dist(out_dist)
1292
use bud_Transfer, only: transfer_dim
1293
type(iDist1D), intent(inout) :: out_dist
1294
type(MP_Comm) :: out_comm
1295
type(rArray1D) :: out_arr
1297
real(rr_), pointer :: dat (:)
1298
real(rr_), pointer :: odat (:)
1299
integer(ii_) :: il, ig, oil
1300
integer(ii_) :: out_nl
1302
integer :: send_R, recv_R
1303
integer(ii_), allocatable :: reqs(:), stats(:,:)
1304
integer(ii_) :: stat(MPI_STATUS_SIZE)
1306
if ( .not. run ) return
1308
out_nl = size_local(out_dist)
1309
if ( is_communicator(out_comm) ) then
1310
ashape(dist_idx) = out_nl
1311
call new(out_arr, ashape(:))
1312
call new(out, out_dist, out_arr)
1313
odat => array_p(out_arr)
1314
call delete(out_arr)
1316
if ( is_initd(dist) ) then
1317
allocate(reqs(nl), stats(MPI_STATUS_SIZE, nl))
1319
reqs(il) = MPI_REQUEST_NULL
1323
if ( dist_idx == dims ) then
1325
send_R = g2rank(dist, ig)
1326
recv_R = ranks(g2rank(out_dist, ig))
1327
if ( recv_R == rank .and. &
1328
send_R == in_rank ) then
1330
oil = g2l(out_dist, ig)
1332
else if ( recv_R == rank ) then
1333
oil = g2l(out_dist, ig)
1334
call Recv(odat(oil), MPI_ANY_SOURCE, ig, &
1336
else if ( send_R == in_rank ) then
1338
call ISSend(dat(il), recv_R, ig, &
1342
if ( allocated(reqs) ) &
1343
call WaitAll(nl, reqs, stats, parent)
1344
else if ( dist_idx == 1 ) then
1345
do i2 = 1 , ashape(2)
1347
send_R = g2rank(dist, ig)
1348
recv_R = ranks(g2rank(out_dist, ig))
1349
if ( recv_R == rank .and. &
1350
send_R == in_rank ) then
1352
oil = g2l(out_dist, ig)
1353
else if ( recv_R == rank ) then
1354
oil = g2l(out_dist, ig)
1355
else if ( send_R == in_rank ) then
1359
if ( allocated(reqs) ) &
1360
call WaitAll(nl, reqs, stats, parent)
1363
if ( allocated(reqs) ) deallocate(reqs)
1364
call Barrier(parent)
1365
call delete(out_comm)
1366
end subroutine sub_dist
1367
end subroutine distribute_
1368
subroutine write_(f, this)
1370
use bud_Transfer, only: transfer_dim
1371
type( File ), intent(inout) :: f
1372
type(iD1D_r1D), intent(in) :: this
1373
type(iDist1D) :: dist
1374
type(rArray1D) :: arr
1375
type( MP_Comm ) :: comm
1376
logical :: formatted, do_io
1377
integer :: iu, io_rank, dat_rank, rank
1378
character(len=64), parameter :: fmt_ = '(e20.16)'
1379
real(rr_), pointer :: dat (:)
1380
real(rr_), allocatable :: rdat(:)
1381
integer :: dist_idx, l, n, ndat
1383
integer :: status(MPI_STATUS_SIZE)
1384
if ( .not. is_initd(this) ) return
1388
rank = comm_rank(comm)
1389
if ( is_open(f) ) then
1394
call AllReduce_Max(io_rank, iu, comm)
1396
if ( io_rank < 0 ) then
1402
do_io = io_rank == rank
1404
formatted = is_formatted(f)
1410
dist_idx = distributed_index(this)
1411
if ( dist_idx == 1 ) then
1412
ndat = size_global(dist)
1417
allocate(rdat(ndat))
1418
if ( formatted ) then
1419
write(iu, '(i16)') 1
1420
write(iu, '(i16)') d1
1426
if ( dist_idx == 1 ) then
1428
do while ( i1 <= d1 )
1429
n = consecutive(dist, i1)
1430
dat_rank = global2rank(dist, i1)
1431
if ( do_io .and. rank == dat_rank ) then
1432
l = global2local(dist, i1)
1433
call transfer_dim(n, rdat(i1:), n, dat(l:))
1434
else if ( do_io ) then
1435
call Recv(rdat(i1), n, dat_rank, i1, comm, status)
1436
else if ( rank == dat_rank ) then
1437
l = global2local(dist, i1)
1438
call SSend(dat(l), n, io_rank, i1, comm)
1443
if ( formatted ) then
1444
write(iu, fmt_) rdat(:)
1450
if ( do_io ) deallocate(rdat)
1453
end subroutine write_
1454
subroutine read_(f, dist, this, dist_idx)
1456
use bud_Transfer, only: transfer_dim
1457
type( File ), intent(inout) :: f
1458
type(iDist1D), intent(inout) :: dist
1459
type(iD1D_r1D), intent(inout) :: this
1460
integer, intent(in), optional :: dist_idx
1461
type(rArray1D) :: arr
1462
type( MP_Comm ) :: comm
1463
logical :: formatted, do_io
1464
integer :: iu, io_rank, dat_rank, rank
1465
character(len=64), parameter :: fmt_ = '(e20.16)'
1466
integer(ii_) :: ashape(1)
1467
real(rr_), pointer :: dat (:)
1468
real(rr_), allocatable :: rdat(:)
1469
integer :: ldist_idx, l, n
1471
integer :: status(MPI_STATUS_SIZE)
1472
if ( .not. is_initd(this) ) return
1474
if ( present(dist_idx) ) ldist_idx = dist_idx
1476
rank = comm_rank(comm)
1477
if ( is_open(f) ) then
1482
call AllReduce_Max(io_rank, iu, comm)
1484
if ( io_rank < 0 ) then
1487
call set_error(this, -1)
1490
do_io = io_rank == rank
1492
formatted = is_formatted(f)
1494
if ( formatted ) then
1496
read(iu, '(i16)') ashape
1504
select case ( ldist_idx )
1506
ashape(1) = size_local(dist)
1508
call new(arr, ashape)
1510
call new(this, dist, arr, ldist_idx)
1516
if ( formatted ) then
1517
read(iu, fmt_) rdat(:)
1522
select case ( ldist_idx )
1525
do while ( i1 <= d1 )
1526
n = consecutive(dist, i1)
1527
dat_rank = global2rank(dist, i1)
1528
if ( do_io .and. rank == dat_rank ) then
1529
l = global2local(dist, i1)
1530
call transfer_dim(n, dat(l:), n, rdat(i1:))
1531
else if ( do_io ) then
1532
call SSend(rdat(i1), n, dat_rank, i1, comm)
1533
else if ( rank == dat_rank ) then
1534
l = global2local(dist, i1)
1535
call Recv(dat(l), n, io_rank, i1, comm, status)
1541
end subroutine read_
1543
module bud_iDist1D_d1D
1550
integer, parameter :: rr_ = selected_real_kind(p=6) ! single (real*4)
1551
integer, parameter :: rd_ = selected_real_kind(p=15) ! double (real*8)
1552
integer, parameter :: is_ = selected_int_kind(4) ! short (integer*2)
1553
integer, parameter :: ii_ = selected_int_kind(9) ! int (integer*4)
1554
integer, parameter :: il_ = selected_int_kind(18) ! long (integer*8)
1555
integer, parameter, private :: BUD_ID_LEn = 36
1556
character(len=*), parameter, private :: &
1557
BUD_MOd = 'BUD_CC2(BUD_MOD,_)BUD_MOD_NAME'
1558
character(len=*), parameter, private :: &
1559
BUD_TYPe = "iD1D_d1D"
1561
module procedure get_elem1_
1565
module procedure get_elem1p_
1569
module procedure get_elem2_
1573
module procedure get_elem2p_
1576
interface dimensions
1577
module procedure dimensions_
1579
public :: dimensions
1580
interface distributed_index
1581
module procedure distributed_index_
1583
public :: distributed_index
1584
interface distribute
1585
module procedure distribute_
1587
public :: distribute
1589
module procedure new_dist_index_
1592
type(iD1D_d1D_), pointer :: D => null()
1593
integer :: error_ = 0
1597
type(dArray1D) :: e2
1598
integer :: refs_ = 0
1599
character(len=BUD_ID_LEN) :: id_ = "null_id"
1602
module procedure new_
1603
module procedure new_data_
1606
interface assignment(=)
1607
module procedure get_elem1_assign_
1608
module procedure get_elem2_assign_
1609
module procedure set_elem1_
1610
module procedure set_elem2_
1613
module procedure get_elem1_
1614
module procedure get_elem2_
1616
interface set_element
1617
module procedure set_elem1_
1618
module procedure set_elem2_
1621
module procedure get_elem1_
1624
interface set_element1
1625
module procedure set_elem1_
1627
public :: set_element1
1628
interface element1_p
1629
module procedure get_elem1p_
1631
public :: element1_p
1633
module procedure get_elem2_
1636
interface set_element2
1637
module procedure set_elem2_
1639
public :: set_element2
1640
interface element2_p
1641
module procedure get_elem2p_
1643
public :: element2_p
1645
private :: iD1D_d1D_
1646
interface assignment(=)
1647
module procedure common_assign_
1649
public :: assignment(=)
1650
private :: common_assign_
1651
interface initialize
1652
module procedure common_initialize_
1654
public :: initialize
1655
private :: common_initialize_
1656
interface is_initialized
1657
module procedure common_is_initialized_
1659
public :: is_initialized
1660
private :: common_is_initialized_
1661
interface initialized
1662
module procedure common_is_initialized_
1664
public :: initialized
1666
module procedure common_is_initialized_
1670
module procedure common_is_same_
1673
private :: common_is_same_
1675
module procedure common_is_same_
1679
module procedure common_delete_
1682
private :: common_delete_
1684
module procedure common_nullify_
1687
private :: common_nullify_
1689
module procedure copy_
1692
private :: common_copy_
1694
module procedure print_
1697
interface references
1698
module procedure common_references_
1700
public :: references
1701
private :: common_references_
1703
module procedure common_references_
1707
module procedure common_set_error_is_
1708
module procedure common_set_error_ii_
1709
module procedure common_set_error_il_
1712
private :: common_set_error_is_
1713
private :: common_set_error_ii_
1714
private :: common_set_error_il_
1716
module procedure common_error_
1719
private :: common_error_
1721
subroutine common_copy_(from, to)
1722
type(iD1D_d1D), intent(in) :: from
1723
type(iD1D_d1D), intent(inout) :: to
1724
call set_error(to, error(from))
1725
end subroutine common_copy_
1726
subroutine common_initialize_(this)
1727
type(iD1D_d1D), intent(inout) :: this
1730
allocate(this%D, stat=error)
1731
call set_error(this, error)
1732
if ( error /= 0 ) return
1734
call common_tag_object_(this)
1735
end subroutine common_initialize_
1736
pure function common_is_initialized_(this) result(init)
1737
type(iD1D_d1D), intent(in) :: this
1739
init = associated(this%D)
1740
end function common_is_initialized_
1741
elemental function common_is_same_(lhs, rhs) result(same)
1742
type(iD1D_d1D), intent(in) :: lhs, rhs
1744
same = is_initd(lhs) .and. is_initd(rhs)
1745
if ( .not. same ) return
1746
same = associated(lhs%D, target=rhs%D)
1747
end function common_is_same_
1748
subroutine common_delete_(this)
1749
type(iD1D_d1D), intent(inout) :: this
1751
call set_error(this, 0)
1752
if (.not. is_initd(this) ) return
1753
this%D%refs_ = this%D%refs_ - 1
1754
if ( 0 == this%D%refs_ ) then
1756
deallocate(this%D, stat=error)
1757
call set_error(this, error)
1760
end subroutine common_delete_
1761
elemental subroutine common_nullify_(this)
1762
type(iD1D_d1D), intent(inout) :: this
1763
if (.not. is_initd(this) ) return
1765
end subroutine common_nullify_
1766
subroutine common_assign_(lhs, rhs)
1767
type(iD1D_d1D), intent(inout) :: lhs
1768
type(iD1D_d1D), intent(in) :: rhs
1770
if ( .not. is_initd(rhs) ) return
1772
lhs%D%refs_ = rhs%D%refs_ + 1
1773
end subroutine common_assign_
1774
elemental function common_references_(this) result(refs)
1775
type(iD1D_d1D), intent(in) :: this
1777
if ( is_initd(this) ) then
1782
end function common_references_
1783
elemental function common_error_(this) result(error)
1784
type(iD1D_d1D), intent(in) :: this
1786
if ( is_initd(this) ) then
1791
end function common_error_
1792
elemental subroutine common_set_error_is_(this, error)
1793
type(iD1D_d1D), intent(inout) :: this
1794
integer(is_), intent(in) :: error
1796
end subroutine common_set_error_is_
1797
elemental subroutine common_set_error_ii_(this, error)
1798
type(iD1D_d1D), intent(inout) :: this
1799
integer(ii_), intent(in) :: error
1801
end subroutine common_set_error_ii_
1802
elemental subroutine common_set_error_il_(this, error)
1803
type(iD1D_d1D), intent(inout) :: this
1804
integer(il_), intent(in) :: error
1806
end subroutine common_set_error_il_
1807
elemental function common_id_(this) result(str)
1808
type(iD1D_d1D), intent(in) :: this
1809
character(len=BUD_ID_LEn) :: str
1811
end function common_id_
1812
subroutine common_tag_object_(this)
1813
type(iD1D_d1D), intent(inout) :: this
1814
end subroutine common_tag_object_
1815
subroutine delete_(this)
1816
type(iD1D_d1D), intent(inout) :: this
1817
call set_error(this, 0)
1818
call delete(this%D%e1)
1819
if ( 0 /= error(this%D%e1) ) &
1820
call set_error(this, error(this%D%e1))
1821
call delete(this%D%e2)
1822
if ( 0 /= error(this%D%e2) ) &
1823
call set_error(this, error(this%D%e2))
1824
end subroutine delete_
1825
subroutine copy_(from, to)
1826
type(iD1D_d1D), intent(in) :: from
1827
type(iD1D_d1D), intent(inout) :: to
1829
if ( .not. is_initd(from) ) return
1831
call common_copy_(from, to)
1832
call copy(from%D%e1, to%D%e1)
1833
call copy(from%D%e2, to%D%e2)
1834
end subroutine copy_
1835
subroutine new_data_(this, a, b &
1837
type(iD1D_d1D), intent(inout) :: this
1838
type(iDist1D), intent(inout) :: a
1839
type(dArray1D), intent(inout) :: b
1843
end subroutine new_data_
1844
subroutine new_(this)
1845
type(iD1D_d1D), intent(inout) :: this
1846
call initialize(this)
1848
subroutine get_elem1_(this, item)
1849
type(iD1D_d1D), intent(in) :: this
1850
type(iDist1D), intent(inout) :: item
1851
if ( .not. is_initd(this) ) then
1857
subroutine get_elem1_assign_(item, this)
1858
type(iDist1D), intent(inout) :: item
1859
type(iD1D_d1D), intent(in) :: this
1860
if ( .not. is_initd(this) ) then
1866
subroutine set_elem1_(this, item)
1867
type(iD1D_d1D), intent(inout) :: this
1868
type(iDist1D), intent(in) :: item
1869
if ( .not. is_initd(this) ) return
1872
function get_elem1p_(this) result(p)
1873
type(iD1D_d1D), intent(inout) :: this
1874
type(iDist1D), pointer :: p
1875
if ( .not. is_initd(this) ) then
1881
subroutine get_elem2_(this, item)
1882
type(iD1D_d1D), intent(in) :: this
1883
type(dArray1D), intent(inout) :: item
1884
if ( .not. is_initd(this) ) then
1890
subroutine get_elem2_assign_(item, this)
1891
type(dArray1D), intent(inout) :: item
1892
type(iD1D_d1D), intent(in) :: this
1893
if ( .not. is_initd(this) ) then
1899
subroutine set_elem2_(this, item)
1900
type(iD1D_d1D), intent(inout) :: this
1901
type(dArray1D), intent(in) :: item
1902
if ( .not. is_initd(this) ) return
1905
function get_elem2p_(this) result(p)
1906
type(iD1D_d1D), intent(inout) :: this
1907
type(dArray1D), pointer :: p
1908
if ( .not. is_initd(this) ) then
1914
subroutine print_(this, info, indent)
1915
type(iD1D_d1D), intent(in) :: this
1916
character(len=*), intent(in), optional :: info
1917
integer, intent(in), optional :: indent
1919
character(len=32) :: fmt
1920
character(len=256) :: name
1922
if ( present(info) ) name = info
1924
if ( present(indent) ) lindent = indent
1925
write(fmt, '(a,i0,a)') '(t',lindent,',3a)'
1926
if ( .not. is_initd(this) ) then
1927
write(*,fmt) "<", trim(name), " not initialized>"
1930
write(fmt, '(a,i0,a)') '(t',lindent,',3a)'
1931
lindent = lindent + 2 ! step indentation
1932
write(*,fmt) "<<", trim(name), " coll>"
1933
call print(this%D%e1, indent = lindent)
1934
call print(this%D%e2, indent = lindent)
1935
lindent = lindent - 2 ! go back to requested indentation
1936
write(fmt, '(a,i0,a)') '(t',lindent,',a,i0,a)'
1937
write(*,fmt) " <coll-refs: ", references(this), ">>"
1938
end subroutine print_
1939
subroutine new_dist_index_(this, dist, arr, dist_idx)
1940
type(iD1D_d1D), intent(inout) :: this
1941
type(iDist1D), intent(inout) :: dist
1942
type(dArray1D), intent(inout) :: arr
1943
integer, intent(in) :: dist_idx
1944
call new(this, dist, arr)
1945
end subroutine new_dist_index_
1946
function distributed_index_(this) result(idx)
1947
type(iD1D_d1D), intent(in) :: this
1949
if ( is_initd(this) ) then
1954
end function distributed_index_
1955
pure function dimensions_(this) result(d)
1956
type(iD1D_d1D), intent(in) :: this
1958
if ( is_initd(this) ) then
1963
end function dimensions_
1964
subroutine distribute_(this, parent, out_dist, out)
1965
type(iD1D_d1D), intent(inout) :: this
1966
type(MP_Comm), intent(inout) :: parent
1967
type(iDist1D), intent(inout) :: out_dist
1968
type(iD1D_d1D), intent(inout) :: out
1969
type(MP_Comm) :: comm, out_comm
1970
type(iDist1D) :: fake_dist, dist
1971
type(dArray1D) :: arr
1972
integer(ii_) :: ir, nranks, my_root, rank, in_rank
1973
logical :: is_distr, my_distr
1974
integer(ii_) :: dist_idx, dims
1975
integer(ii_) :: nl, ng
1976
integer(ii_) :: nout
1977
integer(ii_), allocatable :: ranks(:)
1978
integer(ii_), allocatable :: ashape(:), itmp1(:)
1979
if ( .not. is_communicator(parent) ) return
1980
rank = comm_rank(parent)
1981
nranks = comm_size(parent)
1983
in_rank = comm_rank(dist)
1984
if ( in_rank < 0 ) in_rank = in_rank - 1
1987
dims = dimensions(arr)
1988
call AllReduce_Max(dims, ir, parent)
1990
allocate(ashape(dims))
1991
if ( is_initd(arr) ) then
1992
dist_idx = distributed_index(this)
1994
ashape(ir) = size(arr, ir)
2002
call AllReduce_Max(dist_idx, ir, parent)
2004
allocate(itmp1(dims))
2005
call AllReduce_Max(ashape, itmp1, parent)
2007
if ( ir /= dist_idx ) then
2008
ashape(ir) = itmp1(ir)
2013
if ( is_communicator(out_comm) ) then
2014
if ( comm_rank(out_comm) == 0 ) then
2015
ir = comm_rank(parent)
2019
call AllReduce_Max(ir, my_root, out_comm)
2023
ng = size_global(dist)
2024
call AllReduce_Max(ng, nl, parent)
2026
nl = size_local(dist)
2027
do ir = 0 , nranks - 1
2028
if ( my_root == ir ) then
2033
call AllReduce_LOr(my_distr, is_distr, parent)
2034
if ( .not. is_distr ) cycle
2035
if ( my_distr ) then
2036
call new_remote(parent, out_dist)
2037
call create_ranks(out_dist)
2038
call sub_dist(out_dist)
2040
call new_remote(parent, fake_dist)
2041
call create_ranks(fake_dist)
2042
call sub_dist(fake_dist)
2043
call delete(fake_dist)
2050
call delete(out_comm)
2052
subroutine create_ranks(dist)
2053
type(iDist1D), intent(inout) :: dist
2054
type(MP_Comm) :: comm
2056
call child_Bcast(parent, comm, size=nout)
2057
allocate(ranks(-1:nout-1))
2059
call child_Bcast_ranks(parent, comm, nout, ranks(0:))
2061
end subroutine create_ranks
2062
subroutine sub_dist(out_dist)
2063
use bud_Transfer, only: transfer_dim
2064
type(iDist1D), intent(inout) :: out_dist
2065
type(MP_Comm) :: out_comm
2066
type(dArray1D) :: out_arr
2068
real(rd_), pointer :: dat (:)
2069
real(rd_), pointer :: odat (:)
2070
integer(ii_) :: il, ig, oil
2071
integer(ii_) :: out_nl
2073
integer :: send_R, recv_R
2074
integer(ii_), allocatable :: reqs(:), stats(:,:)
2075
integer(ii_) :: stat(MPI_STATUS_SIZE)
2077
if ( .not. run ) return
2079
out_nl = size_local(out_dist)
2080
if ( is_communicator(out_comm) ) then
2081
ashape(dist_idx) = out_nl
2082
call new(out_arr, ashape(:))
2083
call new(out, out_dist, out_arr)
2084
odat => array_p(out_arr)
2085
call delete(out_arr)
2087
if ( is_initd(dist) ) then
2088
allocate(reqs(nl), stats(MPI_STATUS_SIZE, nl))
2090
reqs(il) = MPI_REQUEST_NULL
2094
if ( dist_idx == dims ) then
2096
send_R = g2rank(dist, ig)
2097
recv_R = ranks(g2rank(out_dist, ig))
2098
if ( recv_R == rank .and. &
2099
send_R == in_rank ) then
2101
oil = g2l(out_dist, ig)
2103
else if ( recv_R == rank ) then
2104
oil = g2l(out_dist, ig)
2105
call Recv(odat(oil), MPI_ANY_SOURCE, ig, &
2107
else if ( send_R == in_rank ) then
2109
call ISSend(dat(il), recv_R, ig, &
2113
if ( allocated(reqs) ) &
2114
call WaitAll(nl, reqs, stats, parent)
2115
else if ( dist_idx == 1 ) then
2116
do i2 = 1 , ashape(2)
2118
send_R = g2rank(dist, ig)
2119
recv_R = ranks(g2rank(out_dist, ig))
2120
if ( recv_R == rank .and. &
2121
send_R == in_rank ) then
2123
oil = g2l(out_dist, ig)
2124
else if ( recv_R == rank ) then
2125
oil = g2l(out_dist, ig)
2126
else if ( send_R == in_rank ) then
2130
if ( allocated(reqs) ) &
2131
call WaitAll(nl, reqs, stats, parent)
2134
if ( allocated(reqs) ) deallocate(reqs)
2135
call Barrier(parent)
2136
call delete(out_comm)
2137
end subroutine sub_dist
2138
end subroutine distribute_
2139
subroutine write_(f, this)
2141
use bud_Transfer, only: transfer_dim
2142
type( File ), intent(inout) :: f
2143
type(iD1D_d1D), intent(in) :: this
2144
type(iDist1D) :: dist
2145
type(dArray1D) :: arr
2146
type( MP_Comm ) :: comm
2147
logical :: formatted, do_io
2148
integer :: iu, io_rank, dat_rank, rank
2149
character(len=64), parameter :: fmt_ = '(e20.16)'
2150
real(rd_), pointer :: dat (:)
2151
real(rd_), allocatable :: rdat(:)
2152
integer :: dist_idx, l, n, ndat
2154
integer :: status(MPI_STATUS_SIZE)
2155
if ( .not. is_initd(this) ) return
2159
rank = comm_rank(comm)
2160
if ( is_open(f) ) then
2165
call AllReduce_Max(io_rank, iu, comm)
2167
if ( io_rank < 0 ) then
2173
do_io = io_rank == rank
2175
formatted = is_formatted(f)
2181
dist_idx = distributed_index(this)
2182
if ( dist_idx == 1 ) then
2183
ndat = size_global(dist)
2188
allocate(rdat(ndat))
2189
if ( formatted ) then
2190
write(iu, '(i16)') 1
2191
write(iu, '(i16)') d1
2197
if ( dist_idx == 1 ) then
2199
do while ( i1 <= d1 )
2200
n = consecutive(dist, i1)
2201
dat_rank = global2rank(dist, i1)
2202
if ( do_io .and. rank == dat_rank ) then
2203
l = global2local(dist, i1)
2204
call transfer_dim(n, rdat(i1:), n, dat(l:))
2205
else if ( do_io ) then
2206
call Recv(rdat(i1), n, dat_rank, i1, comm, status)
2207
else if ( rank == dat_rank ) then
2208
l = global2local(dist, i1)
2209
call SSend(dat(l), n, io_rank, i1, comm)
2214
if ( formatted ) then
2215
write(iu, fmt_) rdat(:)
2221
if ( do_io ) deallocate(rdat)
2224
end subroutine write_
2225
subroutine read_(f, dist, this, dist_idx)
2227
use bud_Transfer, only: transfer_dim
2228
type( File ), intent(inout) :: f
2229
type(iDist1D), intent(inout) :: dist
2230
type(iD1D_d1D), intent(inout) :: this
2231
integer, intent(in), optional :: dist_idx
2232
type(dArray1D) :: arr
2233
type( MP_Comm ) :: comm
2234
logical :: formatted, do_io
2235
integer :: iu, io_rank, dat_rank, rank
2236
character(len=64), parameter :: fmt_ = '(e20.16)'
2237
integer(ii_) :: ashape(1)
2238
real(rd_), pointer :: dat (:)
2239
real(rd_), allocatable :: rdat(:)
2240
integer :: ldist_idx, l, n
2242
integer :: status(MPI_STATUS_SIZE)
2243
if ( .not. is_initd(this) ) return
2245
if ( present(dist_idx) ) ldist_idx = dist_idx
2247
rank = comm_rank(comm)
2248
if ( is_open(f) ) then
2253
call AllReduce_Max(io_rank, iu, comm)
2255
if ( io_rank < 0 ) then
2258
call set_error(this, -1)
2261
do_io = io_rank == rank
2263
formatted = is_formatted(f)
2265
if ( formatted ) then
2267
read(iu, '(i16)') ashape
2275
select case ( ldist_idx )
2277
ashape(1) = size_local(dist)
2279
call new(arr, ashape)
2281
call new(this, dist, arr, ldist_idx)
2287
if ( formatted ) then
2288
read(iu, fmt_) rdat(:)
2293
select case ( ldist_idx )
2296
do while ( i1 <= d1 )
2297
n = consecutive(dist, i1)
2298
dat_rank = global2rank(dist, i1)
2299
if ( do_io .and. rank == dat_rank ) then
2300
l = global2local(dist, i1)
2301
call transfer_dim(n, dat(l:), n, rdat(i1:))
2302
else if ( do_io ) then
2303
call SSend(rdat(i1), n, dat_rank, i1, comm)
2304
else if ( rank == dat_rank ) then
2305
l = global2local(dist, i1)
2306
call Recv(dat(l), n, io_rank, i1, comm, status)
2312
end subroutine read_
2314
module bud_iDist1D_c1D
2321
integer, parameter :: rr_ = selected_real_kind(p=6) ! single (real*4)
2322
integer, parameter :: rd_ = selected_real_kind(p=15) ! double (real*8)
2323
integer, parameter :: is_ = selected_int_kind(4) ! short (integer*2)
2324
integer, parameter :: ii_ = selected_int_kind(9) ! int (integer*4)
2325
integer, parameter :: il_ = selected_int_kind(18) ! long (integer*8)
2326
integer, parameter, private :: BUD_ID_LEn = 36
2327
character(len=*), parameter, private :: &
2328
BUD_MOd = 'BUD_CC2(BUD_MOD,_)BUD_MOD_NAME'
2329
character(len=*), parameter, private :: &
2330
BUD_TYPe = "iD1D_c1D"
2332
module procedure get_elem1_
2336
module procedure get_elem1p_
2340
module procedure get_elem2_
2344
module procedure get_elem2p_
2347
interface dimensions
2348
module procedure dimensions_
2350
public :: dimensions
2351
interface distributed_index
2352
module procedure distributed_index_
2354
public :: distributed_index
2355
interface distribute
2356
module procedure distribute_
2358
public :: distribute
2360
module procedure new_dist_index_
2363
type(iD1D_c1D_), pointer :: D => null()
2364
integer :: error_ = 0
2368
type(cArray1D) :: e2
2369
integer :: refs_ = 0
2370
character(len=BUD_ID_LEN) :: id_ = "null_id"
2373
module procedure new_
2374
module procedure new_data_
2377
interface assignment(=)
2378
module procedure get_elem1_assign_
2379
module procedure get_elem2_assign_
2380
module procedure set_elem1_
2381
module procedure set_elem2_
2384
module procedure get_elem1_
2385
module procedure get_elem2_
2387
interface set_element
2388
module procedure set_elem1_
2389
module procedure set_elem2_
2392
module procedure get_elem1_
2395
interface set_element1
2396
module procedure set_elem1_
2398
public :: set_element1
2399
interface element1_p
2400
module procedure get_elem1p_
2402
public :: element1_p
2404
module procedure get_elem2_
2407
interface set_element2
2408
module procedure set_elem2_
2410
public :: set_element2
2411
interface element2_p
2412
module procedure get_elem2p_
2414
public :: element2_p
2416
private :: iD1D_c1D_
2417
interface assignment(=)
2418
module procedure common_assign_
2420
public :: assignment(=)
2421
private :: common_assign_
2422
interface initialize
2423
module procedure common_initialize_
2425
public :: initialize
2426
private :: common_initialize_
2427
interface is_initialized
2428
module procedure common_is_initialized_
2430
public :: is_initialized
2431
private :: common_is_initialized_
2432
interface initialized
2433
module procedure common_is_initialized_
2435
public :: initialized
2437
module procedure common_is_initialized_
2441
module procedure common_is_same_
2444
private :: common_is_same_
2446
module procedure common_is_same_
2450
module procedure common_delete_
2453
private :: common_delete_
2455
module procedure common_nullify_
2458
private :: common_nullify_
2460
module procedure copy_
2463
private :: common_copy_
2465
module procedure print_
2468
interface references
2469
module procedure common_references_
2471
public :: references
2472
private :: common_references_
2474
module procedure common_references_
2478
module procedure common_set_error_is_
2479
module procedure common_set_error_ii_
2480
module procedure common_set_error_il_
2483
private :: common_set_error_is_
2484
private :: common_set_error_ii_
2485
private :: common_set_error_il_
2487
module procedure common_error_
2490
private :: common_error_
2492
subroutine common_copy_(from, to)
2493
type(iD1D_c1D), intent(in) :: from
2494
type(iD1D_c1D), intent(inout) :: to
2495
call set_error(to, error(from))
2496
end subroutine common_copy_
2497
subroutine common_initialize_(this)
2498
type(iD1D_c1D), intent(inout) :: this
2501
allocate(this%D, stat=error)
2502
call set_error(this, error)
2503
if ( error /= 0 ) return
2505
call common_tag_object_(this)
2506
end subroutine common_initialize_
2507
pure function common_is_initialized_(this) result(init)
2508
type(iD1D_c1D), intent(in) :: this
2510
init = associated(this%D)
2511
end function common_is_initialized_
2512
elemental function common_is_same_(lhs, rhs) result(same)
2513
type(iD1D_c1D), intent(in) :: lhs, rhs
2515
same = is_initd(lhs) .and. is_initd(rhs)
2516
if ( .not. same ) return
2517
same = associated(lhs%D, target=rhs%D)
2518
end function common_is_same_
2519
subroutine common_delete_(this)
2520
type(iD1D_c1D), intent(inout) :: this
2522
call set_error(this, 0)
2523
if (.not. is_initd(this) ) return
2524
this%D%refs_ = this%D%refs_ - 1
2525
if ( 0 == this%D%refs_ ) then
2527
deallocate(this%D, stat=error)
2528
call set_error(this, error)
2531
end subroutine common_delete_
2532
elemental subroutine common_nullify_(this)
2533
type(iD1D_c1D), intent(inout) :: this
2534
if (.not. is_initd(this) ) return
2536
end subroutine common_nullify_
2537
subroutine common_assign_(lhs, rhs)
2538
type(iD1D_c1D), intent(inout) :: lhs
2539
type(iD1D_c1D), intent(in) :: rhs
2541
if ( .not. is_initd(rhs) ) return
2543
lhs%D%refs_ = rhs%D%refs_ + 1
2544
end subroutine common_assign_
2545
elemental function common_references_(this) result(refs)
2546
type(iD1D_c1D), intent(in) :: this
2548
if ( is_initd(this) ) then
2553
end function common_references_
2554
elemental function common_error_(this) result(error)
2555
type(iD1D_c1D), intent(in) :: this
2557
if ( is_initd(this) ) then
2562
end function common_error_
2563
elemental subroutine common_set_error_is_(this, error)
2564
type(iD1D_c1D), intent(inout) :: this
2565
integer(is_), intent(in) :: error
2567
end subroutine common_set_error_is_
2568
elemental subroutine common_set_error_ii_(this, error)
2569
type(iD1D_c1D), intent(inout) :: this
2570
integer(ii_), intent(in) :: error
2572
end subroutine common_set_error_ii_
2573
elemental subroutine common_set_error_il_(this, error)
2574
type(iD1D_c1D), intent(inout) :: this
2575
integer(il_), intent(in) :: error
2577
end subroutine common_set_error_il_
2578
elemental function common_id_(this) result(str)
2579
type(iD1D_c1D), intent(in) :: this
2580
character(len=BUD_ID_LEn) :: str
2582
end function common_id_
2583
subroutine common_tag_object_(this)
2584
type(iD1D_c1D), intent(inout) :: this
2585
end subroutine common_tag_object_
2586
subroutine delete_(this)
2587
type(iD1D_c1D), intent(inout) :: this
2588
call set_error(this, 0)
2589
call delete(this%D%e1)
2590
if ( 0 /= error(this%D%e1) ) &
2591
call set_error(this, error(this%D%e1))
2592
call delete(this%D%e2)
2593
if ( 0 /= error(this%D%e2) ) &
2594
call set_error(this, error(this%D%e2))
2595
end subroutine delete_
2596
subroutine copy_(from, to)
2597
type(iD1D_c1D), intent(in) :: from
2598
type(iD1D_c1D), intent(inout) :: to
2600
if ( .not. is_initd(from) ) return
2602
call common_copy_(from, to)
2603
call copy(from%D%e1, to%D%e1)
2604
call copy(from%D%e2, to%D%e2)
2605
end subroutine copy_
2606
subroutine new_data_(this, a, b &
2608
type(iD1D_c1D), intent(inout) :: this
2609
type(iDist1D), intent(inout) :: a
2610
type(cArray1D), intent(inout) :: b
2614
end subroutine new_data_
2615
subroutine new_(this)
2616
type(iD1D_c1D), intent(inout) :: this
2617
call initialize(this)
2619
subroutine get_elem1_(this, item)
2620
type(iD1D_c1D), intent(in) :: this
2621
type(iDist1D), intent(inout) :: item
2622
if ( .not. is_initd(this) ) then
2628
subroutine get_elem1_assign_(item, this)
2629
type(iDist1D), intent(inout) :: item
2630
type(iD1D_c1D), intent(in) :: this
2631
if ( .not. is_initd(this) ) then
2637
subroutine set_elem1_(this, item)
2638
type(iD1D_c1D), intent(inout) :: this
2639
type(iDist1D), intent(in) :: item
2640
if ( .not. is_initd(this) ) return
2643
function get_elem1p_(this) result(p)
2644
type(iD1D_c1D), intent(inout) :: this
2645
type(iDist1D), pointer :: p
2646
if ( .not. is_initd(this) ) then
2652
subroutine get_elem2_(this, item)
2653
type(iD1D_c1D), intent(in) :: this
2654
type(cArray1D), intent(inout) :: item
2655
if ( .not. is_initd(this) ) then
2661
subroutine get_elem2_assign_(item, this)
2662
type(cArray1D), intent(inout) :: item
2663
type(iD1D_c1D), intent(in) :: this
2664
if ( .not. is_initd(this) ) then
2670
subroutine set_elem2_(this, item)
2671
type(iD1D_c1D), intent(inout) :: this
2672
type(cArray1D), intent(in) :: item
2673
if ( .not. is_initd(this) ) return
2676
function get_elem2p_(this) result(p)
2677
type(iD1D_c1D), intent(inout) :: this
2678
type(cArray1D), pointer :: p
2679
if ( .not. is_initd(this) ) then
2685
subroutine print_(this, info, indent)
2686
type(iD1D_c1D), intent(in) :: this
2687
character(len=*), intent(in), optional :: info
2688
integer, intent(in), optional :: indent
2690
character(len=32) :: fmt
2691
character(len=256) :: name
2693
if ( present(info) ) name = info
2695
if ( present(indent) ) lindent = indent
2696
write(fmt, '(a,i0,a)') '(t',lindent,',3a)'
2697
if ( .not. is_initd(this) ) then
2698
write(*,fmt) "<", trim(name), " not initialized>"
2701
write(fmt, '(a,i0,a)') '(t',lindent,',3a)'
2702
lindent = lindent + 2 ! step indentation
2703
write(*,fmt) "<<", trim(name), " coll>"
2704
call print(this%D%e1, indent = lindent)
2705
call print(this%D%e2, indent = lindent)
2706
lindent = lindent - 2 ! go back to requested indentation
2707
write(fmt, '(a,i0,a)') '(t',lindent,',a,i0,a)'
2708
write(*,fmt) " <coll-refs: ", references(this), ">>"
2709
end subroutine print_
2710
subroutine new_dist_index_(this, dist, arr, dist_idx)
2711
type(iD1D_c1D), intent(inout) :: this
2712
type(iDist1D), intent(inout) :: dist
2713
type(cArray1D), intent(inout) :: arr
2714
integer, intent(in) :: dist_idx
2715
call new(this, dist, arr)
2716
end subroutine new_dist_index_
2717
function distributed_index_(this) result(idx)
2718
type(iD1D_c1D), intent(in) :: this
2720
if ( is_initd(this) ) then
2725
end function distributed_index_
2726
pure function dimensions_(this) result(d)
2727
type(iD1D_c1D), intent(in) :: this
2729
if ( is_initd(this) ) then
2734
end function dimensions_
2735
subroutine distribute_(this, parent, out_dist, out)
2736
type(iD1D_c1D), intent(inout) :: this
2737
type(MP_Comm), intent(inout) :: parent
2738
type(iDist1D), intent(inout) :: out_dist
2739
type(iD1D_c1D), intent(inout) :: out
2740
type(MP_Comm) :: comm, out_comm
2741
type(iDist1D) :: fake_dist, dist
2742
type(cArray1D) :: arr
2743
integer(ii_) :: ir, nranks, my_root, rank, in_rank
2744
logical :: is_distr, my_distr
2745
integer(ii_) :: dist_idx, dims
2746
integer(ii_) :: nl, ng
2747
integer(ii_) :: nout
2748
integer(ii_), allocatable :: ranks(:)
2749
integer(ii_), allocatable :: ashape(:), itmp1(:)
2750
if ( .not. is_communicator(parent) ) return
2751
rank = comm_rank(parent)
2752
nranks = comm_size(parent)
2754
in_rank = comm_rank(dist)
2755
if ( in_rank < 0 ) in_rank = in_rank - 1
2758
dims = dimensions(arr)
2759
call AllReduce_Max(dims, ir, parent)
2761
allocate(ashape(dims))
2762
if ( is_initd(arr) ) then
2763
dist_idx = distributed_index(this)
2765
ashape(ir) = size(arr, ir)
2773
call AllReduce_Max(dist_idx, ir, parent)
2775
allocate(itmp1(dims))
2776
call AllReduce_Max(ashape, itmp1, parent)
2778
if ( ir /= dist_idx ) then
2779
ashape(ir) = itmp1(ir)
2784
if ( is_communicator(out_comm) ) then
2785
if ( comm_rank(out_comm) == 0 ) then
2786
ir = comm_rank(parent)
2790
call AllReduce_Max(ir, my_root, out_comm)
2794
ng = size_global(dist)
2795
call AllReduce_Max(ng, nl, parent)
2797
nl = size_local(dist)
2798
do ir = 0 , nranks - 1
2799
if ( my_root == ir ) then
2804
call AllReduce_LOr(my_distr, is_distr, parent)
2805
if ( .not. is_distr ) cycle
2806
if ( my_distr ) then
2807
call new_remote(parent, out_dist)
2808
call create_ranks(out_dist)
2809
call sub_dist(out_dist)
2811
call new_remote(parent, fake_dist)
2812
call create_ranks(fake_dist)
2813
call sub_dist(fake_dist)
2814
call delete(fake_dist)
2821
call delete(out_comm)
2823
subroutine create_ranks(dist)
2824
type(iDist1D), intent(inout) :: dist
2825
type(MP_Comm) :: comm
2827
call child_Bcast(parent, comm, size=nout)
2828
allocate(ranks(-1:nout-1))
2830
call child_Bcast_ranks(parent, comm, nout, ranks(0:))
2832
end subroutine create_ranks
2833
subroutine sub_dist(out_dist)
2834
use bud_Transfer, only: transfer_dim
2835
type(iDist1D), intent(inout) :: out_dist
2836
type(MP_Comm) :: out_comm
2837
type(cArray1D) :: out_arr
2839
complex(rr_), pointer :: dat (:)
2840
complex(rr_), pointer :: odat (:)
2841
integer(ii_) :: il, ig, oil
2842
integer(ii_) :: out_nl
2844
integer :: send_R, recv_R
2845
integer(ii_), allocatable :: reqs(:), stats(:,:)
2846
integer(ii_) :: stat(MPI_STATUS_SIZE)
2848
if ( .not. run ) return
2850
out_nl = size_local(out_dist)
2851
if ( is_communicator(out_comm) ) then
2852
ashape(dist_idx) = out_nl
2853
call new(out_arr, ashape(:))
2854
call new(out, out_dist, out_arr)
2855
odat => array_p(out_arr)
2856
call delete(out_arr)
2858
if ( is_initd(dist) ) then
2859
allocate(reqs(nl), stats(MPI_STATUS_SIZE, nl))
2861
reqs(il) = MPI_REQUEST_NULL
2865
if ( dist_idx == dims ) then
2867
send_R = g2rank(dist, ig)
2868
recv_R = ranks(g2rank(out_dist, ig))
2869
if ( recv_R == rank .and. &
2870
send_R == in_rank ) then
2872
oil = g2l(out_dist, ig)
2874
else if ( recv_R == rank ) then
2875
oil = g2l(out_dist, ig)
2876
call Recv(odat(oil), MPI_ANY_SOURCE, ig, &
2878
else if ( send_R == in_rank ) then
2880
call ISSend(dat(il), recv_R, ig, &
2884
if ( allocated(reqs) ) &
2885
call WaitAll(nl, reqs, stats, parent)
2886
else if ( dist_idx == 1 ) then
2887
do i2 = 1 , ashape(2)
2889
send_R = g2rank(dist, ig)
2890
recv_R = ranks(g2rank(out_dist, ig))
2891
if ( recv_R == rank .and. &
2892
send_R == in_rank ) then
2894
oil = g2l(out_dist, ig)
2895
else if ( recv_R == rank ) then
2896
oil = g2l(out_dist, ig)
2897
else if ( send_R == in_rank ) then
2901
if ( allocated(reqs) ) &
2902
call WaitAll(nl, reqs, stats, parent)
2905
if ( allocated(reqs) ) deallocate(reqs)
2906
call Barrier(parent)
2907
call delete(out_comm)
2908
end subroutine sub_dist
2909
end subroutine distribute_
2910
subroutine write_(f, this)
2912
use bud_Transfer, only: transfer_dim
2913
type( File ), intent(inout) :: f
2914
type(iD1D_c1D), intent(in) :: this
2915
type(iDist1D) :: dist
2916
type(cArray1D) :: arr
2917
type( MP_Comm ) :: comm
2918
logical :: formatted, do_io
2919
integer :: iu, io_rank, dat_rank, rank
2920
character(len=64), parameter :: fmt_ = '(e20.16)'
2921
complex(rr_), pointer :: dat (:)
2922
complex(rr_), allocatable :: rdat(:)
2923
integer :: dist_idx, l, n, ndat
2925
integer :: status(MPI_STATUS_SIZE)
2926
if ( .not. is_initd(this) ) return
2930
rank = comm_rank(comm)
2931
if ( is_open(f) ) then
2936
call AllReduce_Max(io_rank, iu, comm)
2938
if ( io_rank < 0 ) then
2944
do_io = io_rank == rank
2946
formatted = is_formatted(f)
2952
dist_idx = distributed_index(this)
2953
if ( dist_idx == 1 ) then
2954
ndat = size_global(dist)
2959
allocate(rdat(ndat))
2960
if ( formatted ) then
2961
write(iu, '(i16)') 1
2962
write(iu, '(i16)') d1
2968
if ( dist_idx == 1 ) then
2970
do while ( i1 <= d1 )
2971
n = consecutive(dist, i1)
2972
dat_rank = global2rank(dist, i1)
2973
if ( do_io .and. rank == dat_rank ) then
2974
l = global2local(dist, i1)
2975
call transfer_dim(n, rdat(i1:), n, dat(l:))
2976
else if ( do_io ) then
2977
call Recv(rdat(i1), n, dat_rank, i1, comm, status)
2978
else if ( rank == dat_rank ) then
2979
l = global2local(dist, i1)
2980
call SSend(dat(l), n, io_rank, i1, comm)
2985
if ( formatted ) then
2986
write(iu, fmt_) rdat(:)
2992
if ( do_io ) deallocate(rdat)
2995
end subroutine write_
2996
subroutine read_(f, dist, this, dist_idx)
2998
use bud_Transfer, only: transfer_dim
2999
type( File ), intent(inout) :: f
3000
type(iDist1D), intent(inout) :: dist
3001
type(iD1D_c1D), intent(inout) :: this
3002
integer, intent(in), optional :: dist_idx
3003
type(cArray1D) :: arr
3004
type( MP_Comm ) :: comm
3005
logical :: formatted, do_io
3006
integer :: iu, io_rank, dat_rank, rank
3007
character(len=64), parameter :: fmt_ = '(e20.16)'
3008
integer(ii_) :: ashape(1)
3009
complex(rr_), pointer :: dat (:)
3010
complex(rr_), allocatable :: rdat(:)
3011
integer :: ldist_idx, l, n
3013
integer :: status(MPI_STATUS_SIZE)
3014
if ( .not. is_initd(this) ) return
3016
if ( present(dist_idx) ) ldist_idx = dist_idx
3018
rank = comm_rank(comm)
3019
if ( is_open(f) ) then
3024
call AllReduce_Max(io_rank, iu, comm)
3026
if ( io_rank < 0 ) then
3029
call set_error(this, -1)
3032
do_io = io_rank == rank
3034
formatted = is_formatted(f)
3036
if ( formatted ) then
3038
read(iu, '(i16)') ashape
3046
select case ( ldist_idx )
3048
ashape(1) = size_local(dist)
3050
call new(arr, ashape)
3052
call new(this, dist, arr, ldist_idx)
3058
if ( formatted ) then
3059
read(iu, fmt_) rdat(:)
3064
select case ( ldist_idx )
3067
do while ( i1 <= d1 )
3068
n = consecutive(dist, i1)
3069
dat_rank = global2rank(dist, i1)
3070
if ( do_io .and. rank == dat_rank ) then
3071
l = global2local(dist, i1)
3072
call transfer_dim(n, dat(l:), n, rdat(i1:))
3073
else if ( do_io ) then
3074
call SSend(rdat(i1), n, dat_rank, i1, comm)
3075
else if ( rank == dat_rank ) then
3076
l = global2local(dist, i1)
3077
call Recv(dat(l), n, io_rank, i1, comm, status)
3083
end subroutine read_
3085
module bud_iDist1D_z1D
3092
integer, parameter :: rr_ = selected_real_kind(p=6) ! single (real*4)
3093
integer, parameter :: rd_ = selected_real_kind(p=15) ! double (real*8)
3094
integer, parameter :: is_ = selected_int_kind(4) ! short (integer*2)
3095
integer, parameter :: ii_ = selected_int_kind(9) ! int (integer*4)
3096
integer, parameter :: il_ = selected_int_kind(18) ! long (integer*8)
3097
integer, parameter, private :: BUD_ID_LEn = 36
3098
character(len=*), parameter, private :: &
3099
BUD_MOd = 'BUD_CC2(BUD_MOD,_)BUD_MOD_NAME'
3100
character(len=*), parameter, private :: &
3101
BUD_TYPe = "iD1D_z1D"
3103
module procedure get_elem1_
3107
module procedure get_elem1p_
3111
module procedure get_elem2_
3115
module procedure get_elem2p_
3118
interface dimensions
3119
module procedure dimensions_
3121
public :: dimensions
3122
interface distributed_index
3123
module procedure distributed_index_
3125
public :: distributed_index
3126
interface distribute
3127
module procedure distribute_
3129
public :: distribute
3131
module procedure new_dist_index_
3134
type(iD1D_z1D_), pointer :: D => null()
3135
integer :: error_ = 0
3139
type(zArray1D) :: e2
3140
integer :: refs_ = 0
3141
character(len=BUD_ID_LEN) :: id_ = "null_id"
3144
module procedure new_
3145
module procedure new_data_
3148
interface assignment(=)
3149
module procedure get_elem1_assign_
3150
module procedure get_elem2_assign_
3151
module procedure set_elem1_
3152
module procedure set_elem2_
3155
module procedure get_elem1_
3156
module procedure get_elem2_
3158
interface set_element
3159
module procedure set_elem1_
3160
module procedure set_elem2_
3163
module procedure get_elem1_
3166
interface set_element1
3167
module procedure set_elem1_
3169
public :: set_element1
3170
interface element1_p
3171
module procedure get_elem1p_
3173
public :: element1_p
3175
module procedure get_elem2_
3178
interface set_element2
3179
module procedure set_elem2_
3181
public :: set_element2
3182
interface element2_p
3183
module procedure get_elem2p_
3185
public :: element2_p
3187
private :: iD1D_z1D_
3188
interface assignment(=)
3189
module procedure common_assign_
3191
public :: assignment(=)
3192
private :: common_assign_
3193
interface initialize
3194
module procedure common_initialize_
3196
public :: initialize
3197
private :: common_initialize_
3198
interface is_initialized
3199
module procedure common_is_initialized_
3201
public :: is_initialized
3202
private :: common_is_initialized_
3203
interface initialized
3204
module procedure common_is_initialized_
3206
public :: initialized
3208
module procedure common_is_initialized_
3212
module procedure common_is_same_
3215
private :: common_is_same_
3217
module procedure common_is_same_
3221
module procedure common_delete_
3224
private :: common_delete_
3226
module procedure common_nullify_
3229
private :: common_nullify_
3231
module procedure copy_
3234
private :: common_copy_
3236
module procedure print_
3239
interface references
3240
module procedure common_references_
3242
public :: references
3243
private :: common_references_
3245
module procedure common_references_
3249
module procedure common_set_error_is_
3250
module procedure common_set_error_ii_
3251
module procedure common_set_error_il_
3254
private :: common_set_error_is_
3255
private :: common_set_error_ii_
3256
private :: common_set_error_il_
3258
module procedure common_error_
3261
private :: common_error_
3263
subroutine common_copy_(from, to)
3264
type(iD1D_z1D), intent(in) :: from
3265
type(iD1D_z1D), intent(inout) :: to
3266
call set_error(to, error(from))
3267
end subroutine common_copy_
3268
subroutine common_initialize_(this)
3269
type(iD1D_z1D), intent(inout) :: this
3272
allocate(this%D, stat=error)
3273
call set_error(this, error)
3274
if ( error /= 0 ) return
3276
call common_tag_object_(this)
3277
end subroutine common_initialize_
3278
pure function common_is_initialized_(this) result(init)
3279
type(iD1D_z1D), intent(in) :: this
3281
init = associated(this%D)
3282
end function common_is_initialized_
3283
elemental function common_is_same_(lhs, rhs) result(same)
3284
type(iD1D_z1D), intent(in) :: lhs, rhs
3286
same = is_initd(lhs) .and. is_initd(rhs)
3287
if ( .not. same ) return
3288
same = associated(lhs%D, target=rhs%D)
3289
end function common_is_same_
3290
subroutine common_delete_(this)
3291
type(iD1D_z1D), intent(inout) :: this
3293
call set_error(this, 0)
3294
if (.not. is_initd(this) ) return
3295
this%D%refs_ = this%D%refs_ - 1
3296
if ( 0 == this%D%refs_ ) then
3298
deallocate(this%D, stat=error)
3299
call set_error(this, error)
3302
end subroutine common_delete_
3303
elemental subroutine common_nullify_(this)
3304
type(iD1D_z1D), intent(inout) :: this
3305
if (.not. is_initd(this) ) return
3307
end subroutine common_nullify_
3308
subroutine common_assign_(lhs, rhs)
3309
type(iD1D_z1D), intent(inout) :: lhs
3310
type(iD1D_z1D), intent(in) :: rhs
3312
if ( .not. is_initd(rhs) ) return
3314
lhs%D%refs_ = rhs%D%refs_ + 1
3315
end subroutine common_assign_
3316
elemental function common_references_(this) result(refs)
3317
type(iD1D_z1D), intent(in) :: this
3319
if ( is_initd(this) ) then
3324
end function common_references_
3325
elemental function common_error_(this) result(error)
3326
type(iD1D_z1D), intent(in) :: this
3328
if ( is_initd(this) ) then
3333
end function common_error_
3334
elemental subroutine common_set_error_is_(this, error)
3335
type(iD1D_z1D), intent(inout) :: this
3336
integer(is_), intent(in) :: error
3338
end subroutine common_set_error_is_
3339
elemental subroutine common_set_error_ii_(this, error)
3340
type(iD1D_z1D), intent(inout) :: this
3341
integer(ii_), intent(in) :: error
3343
end subroutine common_set_error_ii_
3344
elemental subroutine common_set_error_il_(this, error)
3345
type(iD1D_z1D), intent(inout) :: this
3346
integer(il_), intent(in) :: error
3348
end subroutine common_set_error_il_
3349
elemental function common_id_(this) result(str)
3350
type(iD1D_z1D), intent(in) :: this
3351
character(len=BUD_ID_LEn) :: str
3353
end function common_id_
3354
subroutine common_tag_object_(this)
3355
type(iD1D_z1D), intent(inout) :: this
3356
end subroutine common_tag_object_
3357
subroutine delete_(this)
3358
type(iD1D_z1D), intent(inout) :: this
3359
call set_error(this, 0)
3360
call delete(this%D%e1)
3361
if ( 0 /= error(this%D%e1) ) &
3362
call set_error(this, error(this%D%e1))
3363
call delete(this%D%e2)
3364
if ( 0 /= error(this%D%e2) ) &
3365
call set_error(this, error(this%D%e2))
3366
end subroutine delete_
3367
subroutine copy_(from, to)
3368
type(iD1D_z1D), intent(in) :: from
3369
type(iD1D_z1D), intent(inout) :: to
3371
if ( .not. is_initd(from) ) return
3373
call common_copy_(from, to)
3374
call copy(from%D%e1, to%D%e1)
3375
call copy(from%D%e2, to%D%e2)
3376
end subroutine copy_
3377
subroutine new_data_(this, a, b &
3379
type(iD1D_z1D), intent(inout) :: this
3380
type(iDist1D), intent(inout) :: a
3381
type(zArray1D), intent(inout) :: b
3385
end subroutine new_data_
3386
subroutine new_(this)
3387
type(iD1D_z1D), intent(inout) :: this
3388
call initialize(this)
3390
subroutine get_elem1_(this, item)
3391
type(iD1D_z1D), intent(in) :: this
3392
type(iDist1D), intent(inout) :: item
3393
if ( .not. is_initd(this) ) then
3399
subroutine get_elem1_assign_(item, this)
3400
type(iDist1D), intent(inout) :: item
3401
type(iD1D_z1D), intent(in) :: this
3402
if ( .not. is_initd(this) ) then
3408
subroutine set_elem1_(this, item)
3409
type(iD1D_z1D), intent(inout) :: this
3410
type(iDist1D), intent(in) :: item
3411
if ( .not. is_initd(this) ) return
3414
function get_elem1p_(this) result(p)
3415
type(iD1D_z1D), intent(inout) :: this
3416
type(iDist1D), pointer :: p
3417
if ( .not. is_initd(this) ) then
3423
subroutine get_elem2_(this, item)
3424
type(iD1D_z1D), intent(in) :: this
3425
type(zArray1D), intent(inout) :: item
3426
if ( .not. is_initd(this) ) then
3432
subroutine get_elem2_assign_(item, this)
3433
type(zArray1D), intent(inout) :: item
3434
type(iD1D_z1D), intent(in) :: this
3435
if ( .not. is_initd(this) ) then
3441
subroutine set_elem2_(this, item)
3442
type(iD1D_z1D), intent(inout) :: this
3443
type(zArray1D), intent(in) :: item
3444
if ( .not. is_initd(this) ) return
3447
function get_elem2p_(this) result(p)
3448
type(iD1D_z1D), intent(inout) :: this
3449
type(zArray1D), pointer :: p
3450
if ( .not. is_initd(this) ) then
3456
subroutine print_(this, info, indent)
3457
type(iD1D_z1D), intent(in) :: this
3458
character(len=*), intent(in), optional :: info
3459
integer, intent(in), optional :: indent
3461
character(len=32) :: fmt
3462
character(len=256) :: name
3464
if ( present(info) ) name = info
3466
if ( present(indent) ) lindent = indent
3467
write(fmt, '(a,i0,a)') '(t',lindent,',3a)'
3468
if ( .not. is_initd(this) ) then
3469
write(*,fmt) "<", trim(name), " not initialized>"
3472
write(fmt, '(a,i0,a)') '(t',lindent,',3a)'
3473
lindent = lindent + 2 ! step indentation
3474
write(*,fmt) "<<", trim(name), " coll>"
3475
call print(this%D%e1, indent = lindent)
3476
call print(this%D%e2, indent = lindent)
3477
lindent = lindent - 2 ! go back to requested indentation
3478
write(fmt, '(a,i0,a)') '(t',lindent,',a,i0,a)'
3479
write(*,fmt) " <coll-refs: ", references(this), ">>"
3480
end subroutine print_
3481
subroutine new_dist_index_(this, dist, arr, dist_idx)
3482
type(iD1D_z1D), intent(inout) :: this
3483
type(iDist1D), intent(inout) :: dist
3484
type(zArray1D), intent(inout) :: arr
3485
integer, intent(in) :: dist_idx
3486
call new(this, dist, arr)
3487
end subroutine new_dist_index_
3488
function distributed_index_(this) result(idx)
3489
type(iD1D_z1D), intent(in) :: this
3491
if ( is_initd(this) ) then
3496
end function distributed_index_
3497
pure function dimensions_(this) result(d)
3498
type(iD1D_z1D), intent(in) :: this
3500
if ( is_initd(this) ) then
3505
end function dimensions_
3506
subroutine distribute_(this, parent, out_dist, out)
3507
type(iD1D_z1D), intent(inout) :: this
3508
type(MP_Comm), intent(inout) :: parent
3509
type(iDist1D), intent(inout) :: out_dist
3510
type(iD1D_z1D), intent(inout) :: out
3511
type(MP_Comm) :: comm, out_comm
3512
type(iDist1D) :: fake_dist, dist
3513
type(zArray1D) :: arr
3514
integer(ii_) :: ir, nranks, my_root, rank, in_rank
3515
logical :: is_distr, my_distr
3516
integer(ii_) :: dist_idx, dims
3517
integer(ii_) :: nl, ng
3518
integer(ii_) :: nout
3519
integer(ii_), allocatable :: ranks(:)
3520
integer(ii_), allocatable :: ashape(:), itmp1(:)
3521
if ( .not. is_communicator(parent) ) return
3522
rank = comm_rank(parent)
3523
nranks = comm_size(parent)
3525
in_rank = comm_rank(dist)
3526
if ( in_rank < 0 ) in_rank = in_rank - 1
3529
dims = dimensions(arr)
3530
call AllReduce_Max(dims, ir, parent)
3532
allocate(ashape(dims))
3533
if ( is_initd(arr) ) then
3534
dist_idx = distributed_index(this)
3536
ashape(ir) = size(arr, ir)
3544
call AllReduce_Max(dist_idx, ir, parent)
3546
allocate(itmp1(dims))
3547
call AllReduce_Max(ashape, itmp1, parent)
3549
if ( ir /= dist_idx ) then
3550
ashape(ir) = itmp1(ir)
3555
if ( is_communicator(out_comm) ) then
3556
if ( comm_rank(out_comm) == 0 ) then
3557
ir = comm_rank(parent)
3561
call AllReduce_Max(ir, my_root, out_comm)
3565
ng = size_global(dist)
3566
call AllReduce_Max(ng, nl, parent)
3568
nl = size_local(dist)
3569
do ir = 0 , nranks - 1
3570
if ( my_root == ir ) then
3575
call AllReduce_LOr(my_distr, is_distr, parent)
3576
if ( .not. is_distr ) cycle
3577
if ( my_distr ) then
3578
call new_remote(parent, out_dist)
3579
call create_ranks(out_dist)
3580
call sub_dist(out_dist)
3582
call new_remote(parent, fake_dist)
3583
call create_ranks(fake_dist)
3584
call sub_dist(fake_dist)
3585
call delete(fake_dist)
3592
call delete(out_comm)
3594
subroutine create_ranks(dist)
3595
type(iDist1D), intent(inout) :: dist
3596
type(MP_Comm) :: comm
3598
call child_Bcast(parent, comm, size=nout)
3599
allocate(ranks(-1:nout-1))
3601
call child_Bcast_ranks(parent, comm, nout, ranks(0:))
3603
end subroutine create_ranks
3604
subroutine sub_dist(out_dist)
3605
use bud_Transfer, only: transfer_dim
3606
type(iDist1D), intent(inout) :: out_dist
3607
type(MP_Comm) :: out_comm
3608
type(zArray1D) :: out_arr
3610
complex(rd_), pointer :: dat (:)
3611
complex(rd_), pointer :: odat (:)
3612
integer(ii_) :: il, ig, oil
3613
integer(ii_) :: out_nl
3615
integer :: send_R, recv_R
3616
integer(ii_), allocatable :: reqs(:), stats(:,:)
3617
integer(ii_) :: stat(MPI_STATUS_SIZE)
3619
if ( .not. run ) return
3621
out_nl = size_local(out_dist)
3622
if ( is_communicator(out_comm) ) then
3623
ashape(dist_idx) = out_nl
3624
call new(out_arr, ashape(:))
3625
call new(out, out_dist, out_arr)
3626
odat => array_p(out_arr)
3627
call delete(out_arr)
3629
if ( is_initd(dist) ) then
3630
allocate(reqs(nl), stats(MPI_STATUS_SIZE, nl))
3632
reqs(il) = MPI_REQUEST_NULL
3636
if ( dist_idx == dims ) then
3638
send_R = g2rank(dist, ig)
3639
recv_R = ranks(g2rank(out_dist, ig))
3640
if ( recv_R == rank .and. &
3641
send_R == in_rank ) then
3643
oil = g2l(out_dist, ig)
3645
else if ( recv_R == rank ) then
3646
oil = g2l(out_dist, ig)
3647
call Recv(odat(oil), MPI_ANY_SOURCE, ig, &
3649
else if ( send_R == in_rank ) then
3651
call ISSend(dat(il), recv_R, ig, &
3655
if ( allocated(reqs) ) &
3656
call WaitAll(nl, reqs, stats, parent)
3657
else if ( dist_idx == 1 ) then
3658
do i2 = 1 , ashape(2)
3660
send_R = g2rank(dist, ig)
3661
recv_R = ranks(g2rank(out_dist, ig))
3662
if ( recv_R == rank .and. &
3663
send_R == in_rank ) then
3665
oil = g2l(out_dist, ig)
3666
else if ( recv_R == rank ) then
3667
oil = g2l(out_dist, ig)
3668
else if ( send_R == in_rank ) then
3672
if ( allocated(reqs) ) &
3673
call WaitAll(nl, reqs, stats, parent)
3676
if ( allocated(reqs) ) deallocate(reqs)
3677
call Barrier(parent)
3678
call delete(out_comm)
3679
end subroutine sub_dist
3680
end subroutine distribute_
3681
subroutine write_(f, this)
3683
use bud_Transfer, only: transfer_dim
3684
type( File ), intent(inout) :: f
3685
type(iD1D_z1D), intent(in) :: this
3686
type(iDist1D) :: dist
3687
type(zArray1D) :: arr
3688
type( MP_Comm ) :: comm
3689
logical :: formatted, do_io
3690
integer :: iu, io_rank, dat_rank, rank
3691
character(len=64), parameter :: fmt_ = '(e20.16)'
3692
complex(rd_), pointer :: dat (:)
3693
complex(rd_), allocatable :: rdat(:)
3694
integer :: dist_idx, l, n, ndat
3696
integer :: status(MPI_STATUS_SIZE)
3697
if ( .not. is_initd(this) ) return
3701
rank = comm_rank(comm)
3702
if ( is_open(f) ) then
3707
call AllReduce_Max(io_rank, iu, comm)
3709
if ( io_rank < 0 ) then
3715
do_io = io_rank == rank
3717
formatted = is_formatted(f)
3723
dist_idx = distributed_index(this)
3724
if ( dist_idx == 1 ) then
3725
ndat = size_global(dist)
3730
allocate(rdat(ndat))
3731
if ( formatted ) then
3732
write(iu, '(i16)') 1
3733
write(iu, '(i16)') d1
3739
if ( dist_idx == 1 ) then
3741
do while ( i1 <= d1 )
3742
n = consecutive(dist, i1)
3743
dat_rank = global2rank(dist, i1)
3744
if ( do_io .and. rank == dat_rank ) then
3745
l = global2local(dist, i1)
3746
call transfer_dim(n, rdat(i1:), n, dat(l:))
3747
else if ( do_io ) then
3748
call Recv(rdat(i1), n, dat_rank, i1, comm, status)
3749
else if ( rank == dat_rank ) then
3750
l = global2local(dist, i1)
3751
call SSend(dat(l), n, io_rank, i1, comm)
3756
if ( formatted ) then
3757
write(iu, fmt_) rdat(:)
3763
if ( do_io ) deallocate(rdat)
3766
end subroutine write_
3767
subroutine read_(f, dist, this, dist_idx)
3769
use bud_Transfer, only: transfer_dim
3770
type( File ), intent(inout) :: f
3771
type(iDist1D), intent(inout) :: dist
3772
type(iD1D_z1D), intent(inout) :: this
3773
integer, intent(in), optional :: dist_idx
3774
type(zArray1D) :: arr
3775
type( MP_Comm ) :: comm
3776
logical :: formatted, do_io
3777
integer :: iu, io_rank, dat_rank, rank
3778
character(len=64), parameter :: fmt_ = '(e20.16)'
3779
integer(ii_) :: ashape(1)
3780
complex(rd_), pointer :: dat (:)
3781
complex(rd_), allocatable :: rdat(:)
3782
integer :: ldist_idx, l, n
3784
integer :: status(MPI_STATUS_SIZE)
3785
if ( .not. is_initd(this) ) return
3787
if ( present(dist_idx) ) ldist_idx = dist_idx
3789
rank = comm_rank(comm)
3790
if ( is_open(f) ) then
3795
call AllReduce_Max(io_rank, iu, comm)
3797
if ( io_rank < 0 ) then
3800
call set_error(this, -1)
3803
do_io = io_rank == rank
3805
formatted = is_formatted(f)
3807
if ( formatted ) then
3809
read(iu, '(i16)') ashape
3817
select case ( ldist_idx )
3819
ashape(1) = size_local(dist)
3821
call new(arr, ashape)
3823
call new(this, dist, arr, ldist_idx)
3829
if ( formatted ) then
3830
read(iu, fmt_) rdat(:)
3835
select case ( ldist_idx )
3838
do while ( i1 <= d1 )
3839
n = consecutive(dist, i1)
3840
dat_rank = global2rank(dist, i1)
3841
if ( do_io .and. rank == dat_rank ) then
3842
l = global2local(dist, i1)
3843
call transfer_dim(n, dat(l:), n, rdat(i1:))
3844
else if ( do_io ) then
3845
call SSend(rdat(i1), n, dat_rank, i1, comm)
3846
else if ( rank == dat_rank ) then
3847
l = global2local(dist, i1)
3848
call Recv(dat(l), n, io_rank, i1, comm, status)
3854
end subroutine read_