File: C:\NOAA\NEMS_11731\src\chem\gocart\src\GMAO_Shared\GMAO_pilgrim\decompmodule.F90
1
2
3
4 MODULE decompmodule
5
6
7
8
9
10 #ifdef STAND_ALONE
11 # define iulog 6
12 #else
13 use cam_logfile, only: iulog
14 #endif
15 #include "debug.h"
16
17 IMPLICIT NONE
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108 PUBLIC DecompType, DecompCreate, DecompFree
109 PUBLIC DecompCopy, DecompPermute, DecompDefined
110 PUBLIC DecompGlobalToLocal, DecompLocalToGlobal, DecompInfo
111
112 INTERFACE DecompCreate
113 MODULE PROCEDURE DecompRegular1D
114 MODULE PROCEDURE DecompRegular2D
115 MODULE PROCEDURE DecompRegular3D
116 MODULE PROCEDURE DecompRegular3DOrder
117 MODULE PROCEDURE DecompRegular4D
118 MODULE PROCEDURE DecompCreateIrr
119 MODULE PROCEDURE DecompCreateTags
120 END INTERFACE
121
122 INTERFACE DecompGlobalToLocal
123 MODULE PROCEDURE DecompG2L
124 MODULE PROCEDURE DecompG2LVector
125 END INTERFACE
126
127 INTERFACE DecompLocalToGlobal
128 MODULE PROCEDURE DecompL2G
129 MODULE PROCEDURE DecompL2GVector
130 END INTERFACE
131
132
133
134 TYPE Lists
135 INTEGER, POINTER :: StartTags(:)
136 INTEGER, POINTER :: EndTags(:)
137 INTEGER, POINTER :: Offsets(:)
138 END TYPE Lists
139
140 TYPE DecompType
141 LOGICAL :: Defined
142 INTEGER :: GlobalSize
143 INTEGER, POINTER :: NumEntries(:)
144 TYPE(Lists), POINTER :: Head(:)
145 END TYPE DecompType
146
147
148 CONTAINS
149
150
151
152
153
154
155 LOGICAL FUNCTION DecompDefined ( Decomp )
156
157 IMPLICIT NONE
158
159
160 TYPE(DecompType), INTENT( IN ):: Decomp
161
162
163
164
165
166
167
168
169
170
171
172
173
174 CPP_ENTER_PROCEDURE( "DECOMPDEFINED" )
175 DecompDefined = Decomp%Defined
176 CPP_LEAVE_PROCEDURE( "DECOMPDEFINED" )
177
178 RETURN
179
180 END FUNCTION DecompDefined
181
182
183
184
185
186
187
188
189 SUBROUTINE DecompFree ( Decomp )
190
191 IMPLICIT NONE
192
193
194 TYPE(DecompType), INTENT( INOUT ):: Decomp
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210 INTEGER :: I, NPEs
211
212 CPP_ENTER_PROCEDURE( "DECOMPFREE" )
213
214 IF ( ASSOCIATED( Decomp%NumEntries ) ) &
215 DEALLOCATE( Decomp%NumEntries )
216 IF ( ASSOCIATED( Decomp%Head ) ) THEN
217 NPEs = SIZE( Decomp%Head )
218 DO I = 1, NPEs
219
220
221
222 IF ( ASSOCIATED( Decomp%Head(I)%StartTags ) ) &
223 DEALLOCATE( Decomp%Head(I)%StartTags )
224 IF ( ASSOCIATED( Decomp%Head(I)%EndTags ) ) &
225 DEALLOCATE( Decomp%Head(I)%EndTags )
226 IF ( ASSOCIATED( Decomp%Head(I)%Offsets ) ) &
227 DEALLOCATE( Decomp%Head(I)%Offsets )
228 ENDDO
229 DEALLOCATE( Decomp%Head )
230 ENDIF
231 Decomp%Defined = .FALSE.
232
233 CPP_LEAVE_PROCEDURE( "DECOMPFREE" )
234 RETURN
235
236 END SUBROUTINE DecompFree
237
238
239
240
241
242
243
244
245 SUBROUTINE DecompCopy ( DecompIn, DecompOut )
246
247 IMPLICIT NONE
248
249
250 TYPE(DecompType), INTENT( IN ) :: DecompIn
251
252
253 TYPE(DecompType), INTENT( OUT ) :: DecompOut
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270 INTEGER :: I, J, NDims, NPEs, NRuns
271
272 CPP_ENTER_PROCEDURE( "DECOMPCOPY" )
273
274
275
276 %GlobalSize = DecompIn%GlobalSize
277
278
279
280
281 = SIZE( DecompIn%NumEntries )
282 CPP_ASSERT_F90( SIZE( DecompIn%Head ) .EQ. NPEs )
283 ALLOCATE( DecompOut%NumEntries( NPEs ) )
284 ALLOCATE( DecompOut%Head( NPEs ) )
285
286 DO I = 1, NPEs
287
288
289
290 %NumEntries( I ) = DecompIn%NumEntries( I )
291 NRuns = SIZE( DecompIn%Head( I )%StartTags )
292 CPP_ASSERT_F90( SIZE( DecompIn%Head( I )%EndTags ) .EQ. NRuns )
293
294
295
296 ALLOCATE( DecompOut%Head(I)%StartTags( NRuns ) )
297 ALLOCATE( DecompOut%Head(I)%EndTags( NRuns ) )
298 ALLOCATE( DecompOut%Head(I)%Offsets( NRuns ) )
299 DO J = 1, NRuns
300 DecompOut%Head(I)%StartTags(J) = DecompIn%Head(I)%StartTags(J)
301 DecompOut%Head(I)%EndTags(J) = DecompIn%Head(I)%EndTags(J)
302 DecompOut%Head(I)%Offsets(J) = DecompIn%Head(I)%Offsets(J)
303 ENDDO
304 ENDDO
305 DecompOut%Defined = .TRUE.
306
307 CPP_LEAVE_PROCEDURE( "DECOMPCOPY" )
308 RETURN
309
310 END SUBROUTINE DecompCopy
311
312
313
314
315
316
317
318
319 SUBROUTINE DecompPermute ( Permutation, Decomp )
320
321 IMPLICIT NONE
322
323
324 INTEGER :: Permutation( : )
325
326
327 TYPE(DecompType), INTENT( INOUT ) :: Decomp
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352 INTEGER, POINTER :: NumEntries(:)
353 TYPE(Lists), POINTER :: Head(:)
354 INTEGER :: I, J, NPEs, NRuns, TruePE
355
356 CPP_ENTER_PROCEDURE( "DECOMPPERMUTE" )
357
358
359
360 = SIZE( Decomp%NumEntries )
361 ALLOCATE( NumEntries( NPEs ) )
362 DO I = 1, NPEs
363 TruePE = Permutation( I )
364 NumEntries( TruePE ) = Decomp%NumEntries( I )
365 ENDDO
366
367
368
369 DEALLOCATE( Decomp%NumEntries )
370 Decomp%NumEntries => NumEntries
371 NULLIFY( NumEntries )
372
373
374
375
376 ALLOCATE( Head( NPEs ) )
377 DO I = 1, NPEs
378 TruePE = Permutation( I )
379 NRuns = SIZE( Decomp%Head(I)%StartTags )
380 CPP_ASSERT_F90( SIZE( Decomp%Head(I)%EndTags ) .EQ. NRuns )
381
382
383
384 ALLOCATE( Head(TruePE)%StartTags(NRuns) )
385 ALLOCATE( Head(TruePE)%EndTags(NRuns) )
386 ALLOCATE( Head(TruePE)%Offsets(NRuns) )
387 DO J = 1, NRuns
388 Head(TruePE)%StartTags(J) = Decomp%Head(I)%StartTags(J)
389 Head(TruePE)%EndTags(J) = Decomp%Head(I)%EndTags(J)
390 Head(TruePE)%Offsets(J) = Decomp%Head(I)%Offsets(J)
391 ENDDO
392 ENDDO
393
394
395
396 DO I = 1, NPEs
397 DEALLOCATE( Decomp%Head(I)%StartTags )
398 DEALLOCATE( Decomp%Head(I)%EndTags )
399 DEALLOCATE( Decomp%Head(I)%Offsets )
400 ENDDO
401
402
403
404 DEALLOCATE( Decomp%Head )
405
406
407
408
409 %Head => Head
410
411 NULLIFY( Head )
412
413 CPP_LEAVE_PROCEDURE( "DECOMPPERMUTE" )
414 RETURN
415
416 END SUBROUTINE DecompPermute
417
418
419
420
421
422
423
424
425 SUBROUTINE DecompRegular1D ( NPEs, Dist, Decomp )
426
427 IMPLICIT NONE
428
429
430 INTEGER, INTENT( IN ) :: NPEs
431 INTEGER, INTENT( IN ) :: Dist(:)
432
433
434 TYPE(DecompType), INTENT( OUT ) :: Decomp
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456 INTEGER :: I, Counter
457
458 CPP_ENTER_PROCEDURE( "DECOMPREGULAR1D" )
459
460 CPP_ASSERT_F90( NPEs .EQ. SIZE( Dist ) )
461
462
463
464 %GlobalSize = SUM(Dist)
465 ALLOCATE( Decomp%NumEntries( NPEs ) )
466 ALLOCATE( Decomp%Head( NPEs ) )
467 Counter = 0
468 DO I = 1, NPEs
469 Decomp%NumEntries(I) = Dist(I)
470
471
472
473 NULLIFY( Decomp%Head(I)%StartTags )
474 NULLIFY( Decomp%Head(I)%EndTags )
475 NULLIFY( Decomp%Head(I)%Offsets )
476 ALLOCATE( Decomp%Head(I)%StartTags(1) )
477 ALLOCATE( Decomp%Head(I)%EndTags(1) )
478 ALLOCATE( Decomp%Head(I)%Offsets(1) )
479
480
481
482
483 %Head(I)%StartTags(1) = Counter+1
484 Counter = Counter + Dist(I)
485 Decomp%Head(I)%EndTags(1) = Counter
486 Decomp%Head(I)%Offsets(1) = 0
487 ENDDO
488
489 Decomp%Defined = .TRUE.
490
491 CPP_LEAVE_PROCEDURE( "DECOMPREGULAR1D" )
492 RETURN
493
494 END SUBROUTINE DecompRegular1D
495
496
497
498
499
500
501
502
503 SUBROUTINE DecompRegular2D( NPEsX, NPEsY, Xdist, Ydist, Decomp )
504
505 IMPLICIT NONE
506
507
508 INTEGER, INTENT( IN ) :: NPEsX
509 INTEGER, INTENT( IN ) :: NPEsY
510 INTEGER, INTENT( IN ) :: Xdist(:)
511 INTEGER, INTENT( IN ) :: Ydist(:)
512
513
514 TYPE(DecompType), INTENT( OUT ) :: Decomp
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548 INTEGER :: TruePE, I, J, K, Counter1, Counter2, SizeX, SizeY
549
550 CPP_ENTER_PROCEDURE( "DECOMPREGULAR2D" )
551
552
553
554 CPP_ASSERT_F90( NPEsX .EQ. SIZE( Xdist ) )
555 CPP_ASSERT_F90( NPEsY .EQ. SIZE( Ydist ) )
556
557
558
559 = SUM(Xdist)
560 SizeY = SUM(Ydist)
561 Decomp%GlobalSize = SizeX * SizeY
562 ALLOCATE( Decomp%NumEntries( NPEsX*NPEsY ) )
563 ALLOCATE( Decomp%Head( NPEsX*NPEsY ) )
564 Counter1 = 0
565 DO J = 1, NPEsY
566 DO I = 1, NPEsX
567
568
569
570 = ( J-1 ) * NPEsX + I
571
572
573
574
575 %NumEntries(TruePE) = Xdist(I)*Ydist(J)
576
577
578
579 NULLIFY( Decomp%Head(TruePE)%StartTags )
580 NULLIFY( Decomp%Head(TruePE)%EndTags )
581 NULLIFY( Decomp%Head(TruePE)%Offsets )
582 ALLOCATE( Decomp%Head(TruePE)%StartTags(Ydist(J)) )
583 ALLOCATE( Decomp%Head(TruePE)%EndTags(Ydist(J)) )
584 ALLOCATE( Decomp%Head(TruePE)%Offsets(Ydist(J)) )
585 Counter2 = Counter1
586 DO K = 1, Ydist(J)
587
588
589
590
591
592 %Head(TruePE)%StartTags(K) = Counter2 + 1
593 Decomp%Head(TruePE)%EndTags(K) = Counter2 + Xdist(I)
594 Counter2 = Counter2 + SizeX
595 ENDDO
596 Counter1 = Counter1 + Xdist(I)
597 ENDDO
598
599
600
601
602
603 = Counter1 + SizeX*(Ydist(J)-1)
604 ENDDO
605
606
607
608 DO I=1, NPEsX*NPEsY
609 IF ( SIZE(Decomp%Head(I)%StartTags) > 0 ) THEN
610 Decomp%Head(I)%Offsets(1) = 0
611 DO J=2, SIZE(Decomp%Head(I)%StartTags)
612 Decomp%Head(I)%Offsets(J) = Decomp%Head(I)%Offsets(J-1) + &
613 Decomp%Head(I)%EndTags(J-1) - Decomp%Head(I)%StartTags(J-1) + 1
614 ENDDO
615 ENDIF
616 ENDDO
617
618 Decomp%Defined = .TRUE.
619
620 CPP_LEAVE_PROCEDURE( "DECOMPREGULAR2D" )
621 RETURN
622
623 END SUBROUTINE DecompRegular2D
624
625
626
627
628
629
630
631
632 SUBROUTINE DecompRegular3D ( NPEsX, NPEsY, NPEsZ, &
633 Xdist, Ydist, Zdist, Decomp )
634
635 IMPLICIT NONE
636
637
638 INTEGER, INTENT( IN ) :: NPEsX
639 INTEGER, INTENT( IN ) :: NPEsY
640 INTEGER, INTENT( IN ) :: NPEsZ
641 INTEGER, INTENT( IN ) :: Xdist(:)
642 INTEGER, INTENT( IN ) :: Ydist(:)
643 INTEGER, INTENT( IN ) :: Zdist(:)
644
645
646 TYPE(DecompType), INTENT( OUT ) :: Decomp
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679 INTEGER :: TruePE, Counter1, Counter2, Counter3
680 INTEGER :: I, J, K, L, M, N, SizeX, SizeY, SizeZ
681
682 CPP_ENTER_PROCEDURE( "DECOMPREGULAR3D" )
683
684
685
686
687 CPP_ASSERT_F90( NPEsX .EQ. SIZE( Xdist ) )
688 CPP_ASSERT_F90( NPEsY .EQ. SIZE( Ydist ) )
689 CPP_ASSERT_F90( NPEsZ .EQ. SIZE( Zdist ) )
690 CPP_ASSERT_F90( .NOT. ASSOCIATED( Decomp%Head ) )
691
692
693
694 = SUM(Xdist)
695 SizeY = SUM(Ydist)
696 SizeZ = SUM(Zdist)
697 Decomp%GlobalSize = SizeX * SizeY * SizeZ
698 ALLOCATE( Decomp%NumEntries( NPEsX*NPEsY*NPEsZ ) )
699 ALLOCATE( Decomp%Head( NPEsX*NPEsY*NPEsZ ) )
700 Counter1 = 0
701 DO K = 1, NPEsZ
702 DO J = 1, NPEsY
703 DO I = 1, NPEsX
704
705
706
707 = (K-1)*NPEsX*NPEsY + (J-1)*NPEsX + I
708 NULLIFY( Decomp%Head(TruePE)%StartTags )
709 NULLIFY( Decomp%Head(TruePE)%EndTags )
710 NULLIFY( Decomp%Head(TruePE)%Offsets )
711
712
713
714 %NumEntries(TruePE) = Xdist(I)*Ydist(J)*Zdist(K)
715
716
717
718 ALLOCATE( Decomp%Head(TruePE)%StartTags(Ydist(J)*Zdist(K)) )
719 ALLOCATE( Decomp%Head(TruePE)%EndTags(Ydist(J)*Zdist(K)) )
720 ALLOCATE( Decomp%Head(TruePE)%Offsets(Ydist(J)*Zdist(K)) )
721 Counter2 = Counter1
722 L = 0
723 DO N = 1, Zdist(K)
724 Counter3 = Counter2
725 DO M = 1, Ydist(J)
726
727
728
729
730
731 = L + 1
732 Decomp%Head(TruePE)%StartTags(L) = Counter3 + 1
733 Decomp%Head(TruePE)%EndTags(L) = Counter3 + Xdist(I)
734 Counter3 = Counter3 + SizeX
735 ENDDO
736 Counter2 = Counter2 + SizeX*SizeY
737 ENDDO
738 Counter1 = Counter1 + Xdist(I)
739 ENDDO
740
741
742
743
744
745 = Counter1 + SizeX*(Ydist(J)-1)
746 ENDDO
747
748
749
750
751
752 = Counter1 + SizeX*SizeY*(Zdist(K)-1)
753 ENDDO
754
755
756
757 DO I=1, NPEsX*NPEsY*NPEsZ
758 IF ( SIZE(Decomp%Head(I)%StartTags) > 0 ) THEN
759 Decomp%Head(I)%Offsets(1) = 0
760 DO J=2, SIZE(Decomp%Head(I)%StartTags)
761 Decomp%Head(I)%Offsets(J) = Decomp%Head(I)%Offsets(J-1) + &
762 Decomp%Head(I)%EndTags(J-1) - Decomp%Head(I)%StartTags(J-1) + 1
763 ENDDO
764 ENDIF
765 ENDDO
766
767 Decomp%Defined = .TRUE.
768
769 CPP_LEAVE_PROCEDURE( "DECOMPREGULAR3D" )
770 RETURN
771
772 END SUBROUTINE DecompRegular3D
773
774
775
776
777
778
779
780
781 SUBROUTINE DecompRegular3Dorder( Order, NPEsX, NPEsY, NPEsZ, &
782 Xdist, Ydist, Zdist, Decomp )
783
784 IMPLICIT NONE
785
786
787 CHARACTER(3), INTENT( IN ) :: Order
788 INTEGER, INTENT( IN ) :: NPEsX
789 INTEGER, INTENT( IN ) :: NPEsY
790 INTEGER, INTENT( IN ) :: NPEsZ
791 INTEGER, INTENT( IN ) :: Xdist(:)
792 INTEGER, INTENT( IN ) :: Ydist(:)
793 INTEGER, INTENT( IN ) :: Zdist(:)
794
795
796 TYPE(DecompType), INTENT( OUT ) :: Decomp
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827 INTEGER :: TruePE, Counter1, Counter2, Counter3
828 INTEGER :: I, J, K, L, M, N, SizeX, SizeY, SizeZ
829 INTEGER :: Imult, Jmult, Kmult
830
831 CPP_ENTER_PROCEDURE( "DECOMPREGULAR3DORDER" )
832
833
834
835
836 CPP_ASSERT_F90( NPEsX .EQ. SIZE( Xdist ) )
837 CPP_ASSERT_F90( NPEsY .EQ. SIZE( Ydist ) )
838 CPP_ASSERT_F90( NPEsZ .EQ. SIZE( Zdist ) )
839 CPP_ASSERT_F90( .NOT. ASSOCIATED( Decomp%Head ) )
840
841 IF ( Order=="xyz" ) THEN
842
843 = 1
844 Jmult = NPEsX
845 Kmult = NPEsX*NPEsY
846 ELSE IF ( Order=="xzy" ) THEN
847
848 = 1
849 Jmult = NPEsX*NPEsZ
850 Kmult = NPEsX
851 ELSE IF ( Order=="yxz" ) THEN
852
853 = NPEsY
854 Jmult = 1
855 Kmult = NPEsX*NPEsY
856 ELSE IF ( Order=="yzx" ) THEN
857
858 = NPEsY*NPEsZ
859 Jmult = 1
860 Kmult = NPEsY
861 ELSE IF ( Order=="zxy" ) THEN
862
863 = NPEsZ
864 Jmult = NPEsX*NPEsZ
865 Kmult = 1
866 ELSE IF ( Order=="zyx" ) THEN
867
868 = NPEsY*NPEsZ
869 Jmult = NPEsZ
870 Kmult = 1
871 ELSE
872
873 write(iulog,*) "Warning: DecompCreate3Dorder", Order, "not supported"
874 write(iulog,*) " Continuing with XYZ ordering"
875 Imult = 1
876 Jmult = NPEsX
877 Kmult = NPEsX*NPEsY
878 ENDIF
879
880
881
882
883 = SUM(Xdist)
884 SizeY = SUM(Ydist)
885 SizeZ = SUM(Zdist)
886 Decomp%GlobalSize = SizeX * SizeY * SizeZ
887 ALLOCATE( Decomp%NumEntries( NPEsX*NPEsY*NPEsZ ) )
888 ALLOCATE( Decomp%Head( NPEsX*NPEsY*NPEsZ ) )
889 Counter1 = 0
890
891 DO K = 1, NPEsZ
892 DO J = 1, NPEsY
893 DO I = 1, NPEsX
894
895
896
897
898 = (I-1)*Imult + (J-1)*Jmult + (K-1)*Kmult + 1
899
900
901
902 %NumEntries(TruePE) = Xdist(I)*Ydist(J)*Zdist(K)
903
904
905
906 ALLOCATE( Decomp%Head(TruePE)%StartTags(Ydist(J)*Zdist(K)) )
907 ALLOCATE( Decomp%Head(TruePE)%EndTags(Ydist(J)*Zdist(K)) )
908 ALLOCATE( Decomp%Head(TruePE)%Offsets(Ydist(J)*Zdist(K)) )
909 Counter2 = Counter1
910 L = 0
911 DO N = 1, Zdist(K)
912 Counter3 = Counter2
913 DO M = 1, Ydist(J)
914
915
916
917
918
919 = L + 1
920 Decomp%Head(TruePE)%StartTags(L) = Counter3 + 1
921 Decomp%Head(TruePE)%EndTags(L) = Counter3 + Xdist(I)
922 Counter3 = Counter3 + SizeX
923 ENDDO
924 Counter2 = Counter2 + SizeX*SizeY
925 ENDDO
926 Counter1 = Counter1 + Xdist(I)
927 ENDDO
928
929
930
931
932
933 = Counter1 + SizeX*(Ydist(J)-1)
934 ENDDO
935
936
937
938
939
940 = Counter1 + SizeX*SizeY*(Zdist(K)-1)
941 ENDDO
942
943
944
945 DO I=1, NPEsX*NPEsY*NPEsZ
946 IF ( SIZE(Decomp%Head(I)%StartTags) > 0 ) THEN
947 Decomp%Head(I)%Offsets(1) = 0
948 DO J=2, SIZE(Decomp%Head(I)%StartTags)
949 Decomp%Head(I)%Offsets(J) = Decomp%Head(I)%Offsets(J-1) + &
950 Decomp%Head(I)%EndTags(J-1) - Decomp%Head(I)%StartTags(J-1) + 1
951 ENDDO
952 ENDIF
953 ENDDO
954
955 Decomp%Defined = .TRUE.
956
957 CPP_LEAVE_PROCEDURE( "DECOMPREGULAR3DORDER" )
958 RETURN
959
960 END SUBROUTINE DecompRegular3DOrder
961
962
963
964
965
966
967
968
969 SUBROUTINE DecompRegular4D ( NPEsX, NPEsY, NPEsZ, NPEsT, &
970 Xdist, Ydist, Zdist, Tdist, Decomp )
971
972 IMPLICIT NONE
973
974
975 INTEGER, INTENT( IN ) :: NPEsX
976 INTEGER, INTENT( IN ) :: NPEsY
977 INTEGER, INTENT( IN ) :: NPEsZ
978 INTEGER, INTENT( IN ) :: NPEsT
979 INTEGER, INTENT( IN ) :: Xdist(:)
980 INTEGER, INTENT( IN ) :: Ydist(:)
981 INTEGER, INTENT( IN ) :: Zdist(:)
982 INTEGER, INTENT( IN ) :: Tdist(:)
983
984
985 TYPE(DecompType), INTENT( OUT ) :: Decomp
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016 INTEGER :: TruePE, Counter1, Counter2, Counter3, Counter4
1017 INTEGER :: I, J, K, L, M, N, P, T, SizeX, SizeY, SizeZ, SizeT
1018
1019 CPP_ENTER_PROCEDURE( "DECOMPREGULAR4D" )
1020
1021
1022
1023
1024 CPP_ASSERT_F90( NPEsX .EQ. SIZE( Xdist ) )
1025 CPP_ASSERT_F90( NPEsY .EQ. SIZE( Ydist ) )
1026 CPP_ASSERT_F90( NPEsZ .EQ. SIZE( Zdist ) )
1027 CPP_ASSERT_F90( NPEsT .EQ. SIZE( Tdist ) )
1028 CPP_ASSERT_F90( .NOT. ASSOCIATED( Decomp%Head ) )
1029
1030
1031
1032 = SUM(Xdist)
1033 SizeY = SUM(Ydist)
1034 SizeZ = SUM(Zdist)
1035 SizeT = SUM(Tdist)
1036 Decomp%GlobalSize = SizeX * SizeY * SizeZ * SizeT
1037 ALLOCATE( Decomp%NumEntries( NPEsX*NPEsY*NPEsZ*NPEsT ) )
1038 ALLOCATE( Decomp%Head( NPEsX*NPEsY*NPEsZ*NPEsT ) )
1039 Counter1 = 0
1040 DO T = 1, NPEsT
1041 DO K = 1, NPEsZ
1042 DO J = 1, NPEsY
1043 DO I = 1, NPEsX
1044
1045
1046
1047 = (T-1)*NPEsX*NPEsY*NPEsZ + &
1048 (K-1)*NPEsX*NPEsY + (J-1)*NPEsX + I
1049 NULLIFY( Decomp%Head(TruePE)%StartTags )
1050 NULLIFY( Decomp%Head(TruePE)%EndTags )
1051 NULLIFY( Decomp%Head(TruePE)%Offsets )
1052
1053
1054
1055 %NumEntries(TruePE) = &
1056 Xdist(I)*Ydist(J)*Zdist(K)*Tdist(T)
1057
1058
1059
1060 ALLOCATE( Decomp%Head(TruePE)%StartTags(Ydist(J)*Zdist(K)*Tdist(T)) )
1061 ALLOCATE( Decomp%Head(TruePE)%EndTags(Ydist(J)*Zdist(K)*Tdist(T)) )
1062 ALLOCATE( Decomp%Head(TruePE)%Offsets(Ydist(J)*Zdist(K)*Tdist(T)) )
1063 Counter2 = Counter1
1064 = 0
1065 DO P = 1, Tdist(T)
1066 Counter3 = Counter2
1067 DO N = 1, Zdist(K)
1068 Counter4 = Counter3
1069 DO M = 1, Ydist(J)
1070
1071
1072
1073
1074
1075 = L + 1
1076 Decomp%Head(TruePE)%StartTags(L) = Counter4 + 1
1077 Decomp%Head(TruePE)%EndTags(L) = Counter4 + Xdist(I)
1078 Counter4 = Counter4 + SizeX
1079 ENDDO
1080 Counter3 = Counter3 + SizeX*SizeY
1081 ENDDO
1082 Counter2 = Counter2 + SizeX*SizeY*SizeZ
1083 ENDDO
1084 Counter1 = Counter1 + Xdist(I)
1085 ENDDO
1086
1087
1088
1089
1090
1091 = Counter1 + SizeX*(Ydist(J)-1)
1092 ENDDO
1093
1094
1095
1096
1097
1098 = Counter1 + SizeX*SizeY*(Zdist(K)-1)
1099 ENDDO
1100 Counter1 = Counter1 + SizeX*SizeY*SizeZ*(Tdist(T)-1)
1101 ENDDO
1102
1103
1104
1105 DO I=1, NPEsX*NPEsY*NPEsZ*NPEsT
1106 IF ( SIZE(Decomp%Head(I)%StartTags) > 0 ) THEN
1107 Decomp%Head(I)%Offsets(1) = 0
1108 DO J=2, SIZE(Decomp%Head(I)%StartTags)
1109 Decomp%Head(I)%Offsets(J) = Decomp%Head(I)%Offsets(J-1) + &
1110 Decomp%Head(I)%EndTags(J-1) - Decomp%Head(I)%StartTags(J-1) + 1
1111 ENDDO
1112 ENDIF
1113 ENDDO
1114
1115 Decomp%Defined = .TRUE.
1116
1117 CPP_LEAVE_PROCEDURE( "DECOMPREGULAR4D" )
1118 RETURN
1119
1120 END SUBROUTINE DecompRegular4D
1121
1122
1123
1124
1125
1126
1127
1128
1129 SUBROUTINE DecompCreateIrr( NPEs, Pe, TotalPts, Decomp )
1130
1131 IMPLICIT NONE
1132
1133
1134 INTEGER, INTENT( IN ) :: NPEs
1135 INTEGER, INTENT( IN ) :: Pe(:)
1136 INTEGER, INTENT( IN ) :: TotalPts
1137
1138
1139 TYPE(DecompType), INTENT( OUT ) :: Decomp
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166 INTEGER :: I, J, PEhold
1167 INTEGER :: Counter( NPEs )
1168
1169 CPP_ENTER_PROCEDURE( "DECOMPCREATEIRR" )
1170
1171 CPP_ASSERT_F90( TotalPts .LE. SIZE( PE ) )
1172 CPP_ASSERT_F90( .NOT. ASSOCIATED( Decomp%Head ) )
1173
1174
1175
1176
1177 %GlobalSize = TotalPts
1178 ALLOCATE( Decomp%NumEntries( NPEs ) )
1179 ALLOCATE( Decomp%Head( NPEs ) )
1180
1181
1182
1183 = -1
1184 Counter = 0
1185 Decomp%NumEntries = 0
1186 DO I=1, TotalPts
1187 CPP_ASSERT_F90( ( PE( I ) .LT. NPEs .AND. PE( I ) .GE. 0 ) )
1188 IF ( PE( I ) .NE. PEhold ) THEN
1189 PEhold = PE( I )
1190 Counter( PEhold+1 ) = Counter( PEhold+1 ) + 1
1191 ENDIF
1192 Decomp%NumEntries(PEHold+1) = Decomp%NumEntries(PEHold+1) + 1
1193 ENDDO
1194 DO I=1, NPEs
1195
1196
1197
1198
1199 ALLOCATE( Decomp%Head(I)%StartTags(Counter(I)) )
1200 ALLOCATE( Decomp%Head(I)%EndTags(Counter(I)) )
1201 ALLOCATE( Decomp%Head(I)%Offsets(Counter(I)) )
1202 ENDDO
1203
1204
1205
1206 = -1
1207 Counter = 0
1208 DO I=1, TotalPts
1209 IF ( PE( I ) .NE. PEhold ) THEN
1210
1211
1212
1213 IF ( I .GT. 1 ) THEN
1214 Decomp%Head(PEhold+1)%EndTags(Counter(PEhold+1)) = I-1
1215 ENDIF
1216 PEhold = PE( I )
1217 Counter( PEhold+1 ) = Counter( PEhold+1 ) + 1
1218 Decomp%Head(PEhold+1)%StartTags(Counter(PEhold+1)) = I
1219 ENDIF
1220 ENDDO
1221
1222
1223
1224 IF ( TotalPts .GT. 0 ) THEN
1225 Decomp%Head(PEhold+1)%EndTags(Counter(PEhold+1)) = TotalPts
1226 ENDIF
1227
1228
1229
1230
1231 DO I=1, NPEs
1232 IF ( Counter(I) > 0 ) THEN
1233 Decomp%Head(I)%Offsets(1) = 0
1234 DO J=2, Counter(I)
1235 Decomp%Head(I)%Offsets(J) = Decomp%Head(I)%Offsets(J-1) + &
1236 Decomp%Head(I)%EndTags(J-1) - Decomp%Head(I)%StartTags(J-1) + 1
1237 ENDDO
1238 ENDIF
1239 ENDDO
1240 Decomp%Defined = .TRUE.
1241
1242 CPP_LEAVE_PROCEDURE( "DECOMPCREATEIRR" )
1243 RETURN
1244
1245 END SUBROUTINE DecompCreateIrr
1246
1247
1248
1249
1250
1251
1252
1253
1254 SUBROUTINE DecompCreateTags(Npes, Pe, TotalPts, Tags, Decomp )
1255
1256 IMPLICIT NONE
1257
1258
1259 INTEGER, INTENT( IN ) :: NPEs
1260 INTEGER, INTENT( IN ) :: Pe(:)
1261 INTEGER, INTENT( IN ) :: TotalPts
1262 INTEGER, INTENT( IN ) :: Tags(:)
1263
1264
1265 TYPE(DecompType), INTENT( OUT ) :: Decomp
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286 INTEGER :: I, J, PEhold, LastTag
1287 INTEGER :: Counter( NPEs )
1288
1289 CPP_ENTER_PROCEDURE( "DECOMPCREATETAGS" )
1290
1291 CPP_ASSERT_F90( TotalPts .LE. SIZE( PE ) )
1292 CPP_ASSERT_F90( TotalPts .LE. SIZE( Tags ) )
1293 CPP_ASSERT_F90( .NOT. ASSOCIATED( Decomp%Head ) )
1294
1295
1296
1297
1298 %GlobalSize = TotalPts
1299 ALLOCATE( Decomp%NumEntries( NPEs ) )
1300 ALLOCATE( Decomp%Head( NPEs ) )
1301
1302
1303
1304 = -1
1305 LastTag = -999999999
1306 Counter = 0
1307 Decomp%NumEntries = 0
1308 DO I=1, TotalPts
1309 CPP_ASSERT_F90( PE( I ) .LT. NPEs .AND. PE( I ) .GE. 0 )
1310 IF ( LastTag==0 .OR. Tags(I)/=LastTag+1 .OR. PE(I)/=PEhold ) THEN
1311 PEhold = PE( I )
1312 Counter( PEhold+1 ) = Counter( PEhold+1 ) + 1
1313 ENDIF
1314 Decomp%NumEntries(PEHold+1) = Decomp%NumEntries(PEHold+1) + 1
1315 LastTag = Tags(I)
1316 ENDDO
1317
1318 DO I=1, NPEs
1319
1320
1321
1322
1323 ALLOCATE( Decomp%Head(I)%StartTags(Counter(I)) )
1324 ALLOCATE( Decomp%Head(I)%EndTags(Counter(I)) )
1325 ALLOCATE( Decomp%Head(I)%Offsets(Counter(I)) )
1326 ENDDO
1327
1328
1329
1330
1331 = -1
1332 LastTag = -999999999
1333 Counter = 0
1334 DO I=1, TotalPts
1335 IF ( LastTag==0 .OR. Tags(I)/=LastTag+1 .OR. PE(I)/=PEhold ) THEN
1336
1337
1338
1339 IF ( I .GT. 1 ) THEN
1340 Decomp%Head(PEhold+1)%EndTags(Counter(PEhold+1)) = LastTag
1341 ENDIF
1342 PEhold = PE( I )
1343 Counter( PEhold+1 ) = Counter( PEhold+1 ) + 1
1344 Decomp%Head(PEhold+1)%StartTags(Counter(PEhold+1)) = Tags(I)
1345 ENDIF
1346 LastTag = Tags(I)
1347 ENDDO
1348
1349
1350
1351 IF ( TotalPts .GT. 0 ) THEN
1352 Decomp%Head(PEhold+1)%EndTags(Counter(PEhold+1)) =Tags(TotalPts)
1353 ENDIF
1354
1355
1356
1357
1358 DO I=1, NPEs
1359 IF ( Counter(I) > 0 ) THEN
1360 Decomp%Head(I)%Offsets(1) = 0
1361 DO J=2, Counter(I)
1362 Decomp%Head(I)%Offsets(J) = Decomp%Head(I)%Offsets(J-1) + &
1363 Decomp%Head(I)%EndTags(J-1) - Decomp%Head(I)%StartTags(J-1) + 1
1364 ENDDO
1365 ENDIF
1366 ENDDO
1367 Decomp%Defined = .TRUE.
1368
1369 CPP_LEAVE_PROCEDURE( "DECOMPCREATETAGS" )
1370 RETURN
1371
1372 END SUBROUTINE DecompCreateTags
1373
1374
1375
1376
1377
1378
1379
1380
1381 SUBROUTINE DecompG2L ( Decomp, Global, Local, Pe )
1382
1383 IMPLICIT NONE
1384
1385
1386 TYPE(DecompType), INTENT( IN ) :: Decomp
1387 INTEGER, INTENT( IN ) :: Global
1388
1389
1390
1391 INTEGER, INTENT( OUT ) :: Local
1392 INTEGER, INTENT( OUT ) :: Pe
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421 INTEGER, SAVE :: Ipe = 0
1422 INTEGER, SAVE :: J = 0
1423 INTEGER :: Ipeold, Jold, PEsize, Jsize
1424
1425 CPP_ENTER_PROCEDURE( "DECOMPG2L" )
1426
1427
1428
1429
1430 = -1
1431 Local = 0
1432 IF ( Global == 0 ) RETURN
1433 = SIZE( Decomp%Head )
1434 IF ( Ipe >= PEsize ) Ipe = 0
1435 Ipeold= Ipe
1436 PEs: DO
1437 = SIZE( Decomp%Head(Ipe+1)%StartTags )
1438 IF ( J >= Jsize ) J = 0
1439 Jold = J
1440 Blocks: DO WHILE (Jsize > 0)
1441 IF ( Global >= Decomp%Head(Ipe+1)%StartTags(J+1) .AND. &
1442 Global <= Decomp%Head(Ipe+1)%EndTags(J+1) ) THEN
1443 Local = Decomp%Head(Ipe+1)%Offsets(J+1) + Global - &
1444 Decomp%Head(Ipe+1)%StartTags(J+1) + 1
1445 Pe = Ipe
1446 EXIT PEs
1447 ELSE
1448 J = MOD(J+1,Jsize)
1449 ENDIF
1450 IF ( J == Jold ) EXIT Blocks
1451 ENDDO Blocks
1452 Ipe = MOD(Ipe+1,PEsize)
1453 = 0
1454 IF ( Ipe == Ipeold ) EXIT PEs
1455 ENDDO PEs
1456
1457 CPP_ASSERT_F90( Local .LE. Decomp%NumEntries(Pe+1) )
1458
1459 CPP_LEAVE_PROCEDURE( "DECOMPG2L" )
1460 RETURN
1461
1462
1463 END SUBROUTINE DecompG2L
1464
1465
1466
1467
1468
1469
1470
1471
1472 SUBROUTINE DecompG2LVector ( Decomp, N, Global, Local, Pe )
1473
1474 IMPLICIT NONE
1475
1476
1477 TYPE(DecompType), INTENT( IN ):: Decomp
1478 INTEGER, INTENT( IN ) :: N
1479 INTEGER, INTENT( IN ) :: Global(:)
1480
1481
1482
1483 INTEGER, INTENT( OUT ) :: Local(:)
1484 INTEGER, INTENT( OUT ) :: Pe(:)
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513 INTEGER, SAVE :: J = 0
1514 INTEGER, SAVE :: Ipe = 0
1515 INTEGER :: I, Ipeold, Jold, PEsize, Jsize
1516
1517 CPP_ENTER_PROCEDURE( "DECOMPG2LVECTOR" )
1518
1519 PEsize = SIZE( Decomp%Head )
1520
1521
1522
1523 DO I=1, N
1524 Pe(I) = -1
1525 Local(I) = 0
1526 IF ( Global(I) == 0 ) CYCLE
1527 IF ( Ipe >= PEsize ) Ipe = 0
1528 Ipeold= Ipe
1529 PEs: DO WHILE ( PEsize > 0 )
1530 = SIZE( Decomp%Head(Ipe+1)%StartTags )
1531 IF ( J >= Jsize ) J = 0
1532 Jold = J
1533 Blocks: DO WHILE (Jsize > 0)
1534 IF ( Global(I) >= Decomp%Head(Ipe+1)%StartTags(J+1) .AND. &
1535 Global(I) <= Decomp%Head(Ipe+1)%EndTags(J+1) ) THEN
1536 Local(I) = Decomp%Head(Ipe+1)%Offsets(J+1) + Global(I) - &
1537 Decomp%Head(Ipe+1)%StartTags(J+1) + 1
1538 Pe(I) = Ipe
1539 EXIT PEs
1540 ELSE
1541 J = MOD(J+1,Jsize)
1542 ENDIF
1543 IF ( J == Jold ) EXIT Blocks
1544 ENDDO Blocks
1545 Ipe = MOD(Ipe+1,PEsize)
1546 = 0
1547 IF ( Ipe == Ipeold ) EXIT PEs
1548 ENDDO PEs
1549
1550 CPP_ASSERT_F90( Local(I) .LE. Decomp%NumEntries(Pe(I)+1) )
1551
1552 ENDDO
1553 CPP_LEAVE_PROCEDURE( "DECOMPG2LVECTOR" )
1554 RETURN
1555
1556
1557 END SUBROUTINE DecompG2LVector
1558
1559
1560
1561
1562
1563
1564
1565
1566 SUBROUTINE DecompL2G ( Decomp, Local, Pe, Global )
1567
1568 IMPLICIT NONE
1569
1570
1571 TYPE(DecompType), INTENT( IN ) :: Decomp
1572 INTEGER, INTENT( IN ) :: Local
1573 INTEGER, INTENT( IN ) :: Pe
1574
1575
1576 INTEGER, INTENT( OUT ) :: Global
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604 INTEGER :: J, Counter
1605 LOGICAL :: Found
1606
1607 CPP_ENTER_PROCEDURE( "DECOMPL2G" )
1608 CPP_ASSERT_F90( Pe .GE. 0 )
1609 CPP_ASSERT_F90( Pe .LT. SIZE(Decomp%Head) )
1610 CPP_ASSERT_F90( Local .GT. 0 )
1611 CPP_ASSERT_F90( Local .LE. Decomp%NumEntries(Pe+1) )
1612
1613 Counter = 0
1614 Found = .FALSE.
1615 J = 0
1616 DO WHILE ( .NOT. Found )
1617 J = J+1
1618 Counter = Counter + Decomp%Head(Pe+1)%EndTags(J) - &
1619 Decomp%Head(Pe+1)%StartTags(J) + 1
1620 IF ( Local .LE. Counter ) THEN
1621 Found = .TRUE.
1622
1623
1624
1625 = Local - Counter + Decomp%Head(Pe+1)%EndTags(J)
1626 Found = .TRUE.
1627 ELSEIF ( J .GE. SIZE( Decomp%Head(Pe+1)%StartTags ) ) THEN
1628
1629
1630
1631 = .TRUE.
1632 Global = 0
1633 ENDIF
1634 ENDDO
1635
1636 CPP_LEAVE_PROCEDURE( "DECOMPL2G" )
1637 RETURN
1638
1639
1640 END SUBROUTINE DecompL2G
1641
1642
1643
1644
1645
1646
1647
1648
1649 SUBROUTINE DecompL2GVector ( Decomp, N, Local, Pe, Global )
1650
1651 IMPLICIT NONE
1652
1653
1654 TYPE(DecompType), INTENT( IN ) :: Decomp
1655 INTEGER, INTENT( IN ) :: N
1656 INTEGER, INTENT( IN ) :: Local(:)
1657 INTEGER, INTENT( IN ) :: Pe(:)
1658
1659
1660 INTEGER, INTENT( OUT ) :: Global(:)
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688 INTEGER :: I, J, Counter
1689 LOGICAL :: Found
1690
1691 CPP_ENTER_PROCEDURE( "DECOMPL2GVECTOR" )
1692 DO I=1,N
1693 CPP_ASSERT_F90( Pe(I) .GE. 0 )
1694 CPP_ASSERT_F90( Pe(I) .LT. SIZE(Decomp%Head) )
1695 CPP_ASSERT_F90( Local(I) .GT. 0 )
1696 CPP_ASSERT_F90( Local(I) .LE. Decomp%NumEntries(Pe(I)+1) )
1697
1698 Counter = 0
1699 Found = .FALSE.
1700 J = 0
1701 DO WHILE ( .NOT. Found )
1702 J = J+1
1703 Counter = Counter + Decomp%Head(Pe(I)+1)%EndTags(J) - &
1704 Decomp%Head(Pe(I)+1)%StartTags(J) + 1
1705 IF ( Local(I) .LE. Counter ) THEN
1706 Found = .TRUE.
1707
1708
1709
1710 (I) = Local(I) - Counter + Decomp%Head(Pe(I)+1)%EndTags(J)
1711 Found = .TRUE.
1712 ELSEIF ( J .GE. SIZE( Decomp%Head(Pe(I)+1)%StartTags ) ) THEN
1713
1714
1715
1716 = .TRUE.
1717 Global(I) = 0
1718 ENDIF
1719 ENDDO
1720 ENDDO
1721
1722 CPP_LEAVE_PROCEDURE( "DECOMPL2GVECTOR" )
1723 RETURN
1724
1725
1726 END SUBROUTINE DecompL2GVector
1727
1728
1729
1730
1731
1732
1733
1734
1735 SUBROUTINE DecompInfo( Decomp, Npes, TotalPts )
1736
1737 IMPLICIT NONE
1738
1739
1740 TYPE(DecompType), INTENT( IN ):: Decomp
1741
1742
1743 INTEGER, INTENT( OUT ) :: Npes
1744 INTEGER, INTENT( OUT ) :: TotalPts
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760 CPP_ENTER_PROCEDURE( "DECOMPINFO" )
1761
1762 Npes = SIZE( Decomp%Head )
1763 TotalPts = Decomp%GlobalSize
1764
1765 CPP_LEAVE_PROCEDURE( "DECOMPINFO" )
1766 RETURN
1767
1768 END SUBROUTINE DecompInfo
1769
1770
1771 END MODULE decompmodule
1772
1773