source: lmdz_wrf/trunk/WRFV3/frame/module_machine.F @ 354

Last change on this file since 354 was 1, checked in by lfita, 10 years ago
  • -- --- Opening of the WRF+LMDZ coupling repository --- -- -

WRF: version v3.3
LMDZ: version v1818

More details in:

File size: 5.1 KB
Line 
1!WRF:DRIVER_LAYER:DECOMPOSITION
2!
3
4MODULE 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
144END MODULE module_machine
145
146SUBROUTINE wrf_sizeof_integer( retval )
147  IMPLICIT NONE
148  INTEGER retval
149! IWORDSIZE is defined by CPP
150  retval = IWORDSIZE
151  RETURN
152END SUBROUTINE wrf_sizeof_integer
153
154SUBROUTINE wrf_sizeof_real( retval )
155  IMPLICIT NONE
156  INTEGER retval
157! RWORDSIZE is defined by CPP
158  retval = RWORDSIZE
159  RETURN
160END SUBROUTINE wrf_sizeof_real
161
162SUBROUTINE wrf_sizeof_doubleprecision( retval )
163  IMPLICIT NONE
164  INTEGER retval
165! DWORDSIZE is defined by CPP
166  retval = DWORDSIZE
167  RETURN
168END SUBROUTINE wrf_sizeof_doubleprecision
169
170SUBROUTINE wrf_sizeof_logical( retval )
171  IMPLICIT NONE
172  INTEGER retval
173! LWORDSIZE is defined by CPP
174  retval = LWORDSIZE
175  RETURN
176END SUBROUTINE wrf_sizeof_logical
177
Note: See TracBrowser for help on using the repository browser.