PageRenderTime 376ms CodeModel.GetById 111ms RepoModel.GetById 10ms app.codeStats 0ms

/wrfv2_fire/frame/module_machine.F

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