1 !WRF:DRIVER_LAYER:DECOMPOSITION
6 USE module_driver_constants
8 ! Machine characteristics and utilities here.
10 ! Tile strategy defined constants
11 INTEGER, PARAMETER :: TILE_NONE = 0, TILE_X = 1, TILE_Y = 2, TILE_XY = 3
15 RECURSIVE SUBROUTINE rlocproc(p,maxi,nproc,ml,mr,ret)
17 INTEGER, INTENT(IN) :: p, maxi, nproc, ml, mr
18 INTEGER, INTENT(OUT) :: ret
19 INTEGER :: width, rem, ret2, bl, br, mid, adjust, &
20 p_r, maxi_r, nproc_r, zero
22 rem = mod( maxi, nproc )
25 IF ( rem>0 .AND. (((mod(rem,2).EQ.0).OR.(rem.GT.2)).OR.(p.LE.mid))) THEN
28 IF ( p.LE.mid .AND. mod(rem,2).NE.0 ) THEN
35 ELSE IF (p>maxi-br-1) THEN
39 maxi_r = maxi-bl-br+adjust
40 nproc_r = max(nproc-2,1)
42 CALL rlocproc( p_r, maxi_r, nproc_r, zero, zero, ret2 ) ! Recursive
46 END SUBROUTINE rlocproc
48 INTEGER FUNCTION locproc( i, m, numpart )
50 integer, intent(in) :: i, m, numpart
51 integer :: retval, ii, im, inumpart, zero
56 CALL rlocproc( ii, im, inumpart, zero, zero, retval )
61 SUBROUTINE patchmap( res, y, x, py, px )
63 INTEGER, INTENT(IN) :: y, x, py, px
64 INTEGER, DIMENSION(x,y), INTENT(OUT) :: res
65 INTEGER :: i, j, p_min, p_maj
67 p_maj = locproc( j, y, py )
69 p_min = locproc( i, x, px )
70 res(i+1,j+1) = p_min + px*p_maj
74 END SUBROUTINE patchmap
76 SUBROUTINE region_bounds( region_start, region_end, &
78 patch_start, patch_end )
79 ! 1-D decomposition routine: Given starting and ending indices of a
80 ! vector, the number of patches dividing the vector, and the number of
81 ! the patch, give the start and ending indices of the patch within the
82 ! vector. This will work with tiles too. Implementation note. This is
83 ! implemented somewhat inefficiently, now, with a loop, so we can use the
84 ! locproc function above, which returns processor number for a given
85 ! index, whereas what we want is index for a given processor number.
86 ! With a little thought and a lot of debugging, we can come up with a
87 ! direct expression for what we want. For time being, we loop...
88 ! Remember that processor numbering starts with zero.
91 INTEGER, INTENT(IN) :: region_start, region_end, num_p, p
92 INTEGER, INTENT(OUT) :: patch_start, patch_end
94 patch_end = -999999999
95 patch_start = 999999999
97 do i = 0, region_end - offset
98 if ( locproc( i, region_end-region_start+1, num_p ) == p ) then
99 patch_end = max(patch_end,i)
100 patch_start = min(patch_start,i)
103 patch_start = patch_start + offset
104 patch_end = patch_end + offset
106 END SUBROUTINE region_bounds
108 SUBROUTINE least_aspect( nparts, minparts_y, minparts_x, nparts_y, nparts_x )
111 INTEGER, INTENT(IN) :: nparts, &
112 minparts_y, minparts_x
114 INTEGER, INTENT(OUT) :: nparts_y, nparts_x
116 INTEGER :: x, y, mini
121 IF ( mod( nparts, y ) .eq. 0 ) THEN
123 IF ( abs( y-x ) .LT. mini &
124 .AND. y .GE. minparts_y &
125 .AND. x .GE. minparts_x ) THEN
132 END SUBROUTINE least_aspect
134 SUBROUTINE init_module_machine
136 END SUBROUTINE init_module_machine
138 END MODULE module_machine
140 SUBROUTINE wrf_sizeof_integer( retval )
143 ! IWORDSIZE is defined by CPP
146 END SUBROUTINE wrf_sizeof_integer
148 SUBROUTINE wrf_sizeof_real( retval )
151 ! RWORDSIZE is defined by CPP
154 END SUBROUTINE wrf_sizeof_real
156 SUBROUTINE wrf_sizeof_doubleprecision( retval )
159 ! DWORDSIZE is defined by CPP
162 END SUBROUTINE wrf_sizeof_doubleprecision
164 SUBROUTINE wrf_sizeof_logical( retval )
167 ! LWORDSIZE is defined by CPP
170 END SUBROUTINE wrf_sizeof_logical