[2759] | 1 | !WRF:DRIVER_LAYER:DECOMPOSITION |
---|
| 2 | ! |
---|
| 3 | |
---|
| 4 | MODULE module_machine |
---|
| 5 | |
---|
| 6 | USE module_driver_constants |
---|
| 7 | |
---|
| 8 | ! Machine characteristics and utilities here. |
---|
| 9 | |
---|
| 10 | ! Tile strategy defined constants |
---|
| 11 | INTEGER, PARAMETER :: TILE_X = 1, TILE_Y = 2, TILE_XY = 3 |
---|
| 12 | |
---|
| 13 | TYPE machine_type |
---|
| 14 | INTEGER :: tile_strategy |
---|
| 15 | END TYPE machine_type |
---|
| 16 | |
---|
| 17 | TYPE (machine_type) machine_info |
---|
| 18 | |
---|
| 19 | CONTAINS |
---|
| 20 | |
---|
| 21 | RECURSIVE SUBROUTINE rlocproc(p,maxi,nproc,ml,mr,ret) |
---|
| 22 | IMPLICIT NONE |
---|
| 23 | INTEGER, INTENT(IN) :: p, maxi, nproc, ml, mr |
---|
| 24 | INTEGER, INTENT(OUT) :: ret |
---|
| 25 | INTEGER :: width, rem, ret2, bl, br, mid, adjust, & |
---|
| 26 | p_r, maxi_r, nproc_r, zero |
---|
| 27 | adjust = 0 |
---|
| 28 | rem = mod( maxi, nproc ) |
---|
| 29 | width = maxi / nproc |
---|
| 30 | mid = maxi / 2 |
---|
| 31 | IF ( rem>0 .AND. (((mod(rem,2).EQ.0).OR.(rem.GT.2)).OR.(p.LE.mid))) THEN |
---|
| 32 | width = width + 1 |
---|
| 33 | END IF |
---|
| 34 | IF ( p.LE.mid .AND. mod(rem,2).NE.0 ) THEN |
---|
| 35 | adjust = adjust + 1 |
---|
| 36 | END IF |
---|
| 37 | bl = max(width,ml) ; |
---|
| 38 | br = max(width,mr) ; |
---|
| 39 | IF (p<bl) THEN |
---|
| 40 | ret = 0 |
---|
| 41 | ELSE IF (p>maxi-br-1) THEN |
---|
| 42 | ret = nproc-1 |
---|
| 43 | ELSE |
---|
| 44 | p_r = p - bl |
---|
| 45 | maxi_r = maxi-bl-br+adjust |
---|
| 46 | nproc_r = max(nproc-2,1) |
---|
| 47 | zero = 0 |
---|
| 48 | CALL rlocproc( p_r, maxi_r, nproc_r, zero, zero, ret2 ) ! Recursive |
---|
| 49 | ret = ret2 + 1 |
---|
| 50 | END IF |
---|
| 51 | RETURN |
---|
| 52 | END SUBROUTINE rlocproc |
---|
| 53 | |
---|
| 54 | INTEGER FUNCTION locproc( i, m, numpart ) |
---|
| 55 | implicit none |
---|
| 56 | integer, intent(in) :: i, m, numpart |
---|
| 57 | integer :: retval, ii, im, inumpart, zero |
---|
| 58 | ii = i |
---|
| 59 | im = m |
---|
| 60 | inumpart = numpart |
---|
| 61 | zero = 0 |
---|
| 62 | CALL rlocproc( ii, im, inumpart, zero, zero, retval ) |
---|
| 63 | locproc = retval |
---|
| 64 | RETURN |
---|
| 65 | END FUNCTION locproc |
---|
| 66 | |
---|
| 67 | SUBROUTINE patchmap( res, y, x, py, px ) |
---|
| 68 | implicit none |
---|
| 69 | INTEGER, INTENT(IN) :: y, x, py, px |
---|
| 70 | INTEGER, DIMENSION(x,y), INTENT(OUT) :: res |
---|
| 71 | INTEGER :: i, j, p_min, p_maj |
---|
| 72 | DO j = 0,y-1 |
---|
| 73 | p_maj = locproc( j, y, py ) |
---|
| 74 | DO i = 0,x-1 |
---|
| 75 | p_min = locproc( i, x, px ) |
---|
| 76 | res(i+1,j+1) = p_min + px*p_maj |
---|
| 77 | END DO |
---|
| 78 | END DO |
---|
| 79 | RETURN |
---|
| 80 | END SUBROUTINE patchmap |
---|
| 81 | |
---|
| 82 | SUBROUTINE region_bounds( region_start, region_end, & |
---|
| 83 | num_p, p, & |
---|
| 84 | patch_start, patch_end ) |
---|
| 85 | ! 1-D decomposition routine: Given starting and ending indices of a |
---|
| 86 | ! vector, the number of patches dividing the vector, and the number of |
---|
| 87 | ! the patch, give the start and ending indices of the patch within the |
---|
| 88 | ! vector. This will work with tiles too. Implementation note. This is |
---|
| 89 | ! implemented somewhat inefficiently, now, with a loop, so we can use the |
---|
| 90 | ! locproc function above, which returns processor number for a given |
---|
| 91 | ! index, whereas what we want is index for a given processor number. |
---|
| 92 | ! With a little thought and a lot of debugging, we can come up with a |
---|
| 93 | ! direct expression for what we want. For time being, we loop... |
---|
| 94 | ! Remember that processor numbering starts with zero. |
---|
| 95 | |
---|
| 96 | IMPLICIT NONE |
---|
| 97 | INTEGER, INTENT(IN) :: region_start, region_end, num_p, p |
---|
| 98 | INTEGER, INTENT(OUT) :: patch_start, patch_end |
---|
| 99 | INTEGER :: offset, i |
---|
| 100 | patch_end = -999999999 |
---|
| 101 | patch_start = 999999999 |
---|
| 102 | offset = region_start |
---|
| 103 | do i = 0, region_end - offset |
---|
| 104 | if ( locproc( i, region_end-region_start+1, num_p ) == p ) then |
---|
| 105 | patch_end = max(patch_end,i) |
---|
| 106 | patch_start = min(patch_start,i) |
---|
| 107 | endif |
---|
| 108 | enddo |
---|
| 109 | patch_start = patch_start + offset |
---|
| 110 | patch_end = patch_end + offset |
---|
| 111 | RETURN |
---|
| 112 | END SUBROUTINE region_bounds |
---|
| 113 | |
---|
| 114 | SUBROUTINE least_aspect( nparts, minparts_y, minparts_x, nparts_y, nparts_x ) |
---|
| 115 | IMPLICIT NONE |
---|
| 116 | ! Input data. |
---|
| 117 | INTEGER, INTENT(IN) :: nparts, & |
---|
| 118 | minparts_y, minparts_x |
---|
| 119 | ! Output data. |
---|
| 120 | INTEGER, INTENT(OUT) :: nparts_y, nparts_x |
---|
| 121 | ! Local data. |
---|
| 122 | INTEGER :: x, y, mini |
---|
| 123 | mini = 2*nparts |
---|
| 124 | nparts_y = 1 |
---|
| 125 | nparts_x = nparts |
---|
| 126 | DO y = 1, nparts |
---|
| 127 | IF ( mod( nparts, y ) .eq. 0 ) THEN |
---|
| 128 | x = nparts / y |
---|
| 129 | IF ( abs( y-x ) .LT. mini & |
---|
| 130 | .AND. y .GE. minparts_y & |
---|
| 131 | .AND. x .GE. minparts_x ) THEN |
---|
| 132 | mini = abs( y-x ) |
---|
| 133 | nparts_y = y |
---|
| 134 | nparts_x = x |
---|
| 135 | END IF |
---|
| 136 | END IF |
---|
| 137 | END DO |
---|
| 138 | END SUBROUTINE least_aspect |
---|
| 139 | |
---|
| 140 | SUBROUTINE init_module_machine |
---|
| 141 | machine_info%tile_strategy = TILE_Y |
---|
| 142 | END SUBROUTINE init_module_machine |
---|
| 143 | |
---|
| 144 | END MODULE module_machine |
---|
| 145 | |
---|
| 146 | SUBROUTINE wrf_sizeof_integer( retval ) |
---|
| 147 | IMPLICIT NONE |
---|
| 148 | INTEGER retval |
---|
| 149 | ! IWORDSIZE is defined by CPP |
---|
| 150 | retval = IWORDSIZE |
---|
| 151 | RETURN |
---|
| 152 | END SUBROUTINE wrf_sizeof_integer |
---|
| 153 | |
---|
| 154 | SUBROUTINE wrf_sizeof_real( retval ) |
---|
| 155 | IMPLICIT NONE |
---|
| 156 | INTEGER retval |
---|
| 157 | ! RWORDSIZE is defined by CPP |
---|
| 158 | retval = RWORDSIZE |
---|
| 159 | RETURN |
---|
| 160 | END SUBROUTINE wrf_sizeof_real |
---|
| 161 | |
---|
| 162 | SUBROUTINE wrf_sizeof_doubleprecision( retval ) |
---|
| 163 | IMPLICIT NONE |
---|
| 164 | INTEGER retval |
---|
| 165 | ! DWORDSIZE is defined by CPP |
---|
| 166 | retval = DWORDSIZE |
---|
| 167 | RETURN |
---|
| 168 | END SUBROUTINE wrf_sizeof_doubleprecision |
---|
| 169 | |
---|
| 170 | SUBROUTINE wrf_sizeof_logical( retval ) |
---|
| 171 | IMPLICIT NONE |
---|
| 172 | INTEGER retval |
---|
| 173 | ! LWORDSIZE is defined by CPP |
---|
| 174 | retval = LWORDSIZE |
---|
| 175 | RETURN |
---|
| 176 | END SUBROUTINE wrf_sizeof_logical |
---|
| 177 | |
---|