Advertisement
Guest User

Untitled

a guest
Apr 10th, 2020
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module Task
  2.   use :: mpi
  3.   implicit none
  4.   contains
  5.  
  6.   subroutine GetMaxCoordinates(A, x1, y1, x2, y2)
  7.     implicit none
  8.     integer(4), intent(out) :: x1, y1, x2, y2
  9.     integer(4) :: n, L, R, Up, Down, m,  new_x1, new_x2, new_y1, new_y2, calls
  10.     real(8), intent(in), dimension(:,:) :: A
  11.     real(8), allocatable :: current_column(:)
  12.     real(8) :: current_sum, max_sum, new_sum
  13.    
  14.     integer(4) :: mpiErr, mpiRank, mpiSize  
  15.     integer(4), dimension(MPI_STATUS_SIZE) :: status
  16.  
  17.     m = size(A, dim=1)
  18.     n = size(A, dim=2)
  19.  
  20.     allocate(current_column(m))
  21.  
  22.     x1=1
  23.     y1=1
  24.     x2=1
  25.     y2=1
  26.     max_sum = A(1,1)
  27.  
  28.     call MPI_Comm_size(MPI_COMM_WORLD, mpiSize, mpiErr)
  29.     call MPI_Comm_rank(MPI_COMM_WORLD, mpiRank, mpiErr)
  30.    
  31.     do L = mpiRank+1, n, mpiSize
  32.       current_column = A(:, L)
  33.       do R = L, n
  34.         if (R .gt. L) then
  35.           current_column = current_column + A(:, R)
  36.         endif
  37.  
  38.         call FindMaxInArray(current_column, current_sum, Up, Down)
  39.        
  40.         if (current_sum .gt. max_sum) then
  41.           max_sum = current_sum
  42.           x1 = Up
  43.           x2 = Down
  44.           y1 = L
  45.           y2 = R
  46.         endif
  47.  
  48.       end do
  49.     end do
  50.  
  51.     if (mpiRank /= 0) then
  52.       call MPI_Send(max_sum, 1, MPI_REAL8, 0, mpiRank+mpiSize, MPI_COMM_WORLD, mpiErr)
  53.       call MPI_Send(x1, 1, MPI_INTEGER4, 0, mpiRank+mpiSize, MPI_COMM_WORLD, mpiErr)    
  54.       call MPI_Send(x2, 1, MPI_INTEGER4, 0, mpiRank+mpiSize, MPI_COMM_WORLD, mpiErr)
  55.       call MPI_Send(y1, 1, MPI_INTEGER4, 0, mpiRank+mpiSize, MPI_COMM_WORLD, mpiErr)
  56.       call MPI_Send(y2, 1, MPI_INTEGER4, 0, mpiRank+mpiSize, MPI_COMM_WORLD, mpiErr)
  57.     else
  58.     calls = 0
  59.     do while (calls /= mpiSize-1)
  60.       call MPI_Recv(new_sum, 1, MPI_REAL8, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, status, mpiErr)
  61.       call MPI_Recv(new_x1, 1, MPI_INTEGER4, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, status, mpiErr)
  62.       call MPI_Recv(new_x2, 1, MPI_INTEGER4, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, status, mpiErr)
  63.       call MPI_Recv(new_y1, 1, MPI_INTEGER4, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, status, mpiErr)
  64.       call MPI_Recv(new_y2, 1, MPI_INTEGER4, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, status, mpiErr)
  65.       calls = calls + 1
  66.        
  67.       if (new_sum .gt. max_sum) then
  68.         max_sum = new_sum
  69.         x1 = new_x1
  70.         x2 = new_x2
  71.         y1 = new_y1
  72.         y2 = new_y2
  73.        endif
  74.     enddo  
  75.     endif
  76.    
  77.     call MPI_Bcast(x1, 1, MPI_INTEGER4, 0, MPI_COMM_WORLD, mpiErr)
  78.     call MPI_Bcast(x2, 1, MPI_INTEGER4, 0, MPI_COMM_WORLD, mpiErr)
  79.     call MPI_Bcast(y1, 1, MPI_INTEGER4, 0, MPI_COMM_WORLD, mpiErr)
  80.     call MPI_Bcast(y2, 1, MPI_INTEGER4, 0, MPI_COMM_WORLD, mpiErr)
  81.        
  82.     deallocate(current_column)
  83.   end subroutine
  84.  
  85.   subroutine FindMaxInArray(A, Summ, Up, Down)
  86.     implicit none
  87.     real(8), intent(in), dimension(:) :: A
  88.     integer(4), intent(out) :: Up, Down
  89.     real(8), intent(out) :: Summ
  90.     real(8) :: cur_sum
  91.     integer(4) :: minus_pos, i
  92.  
  93.     Summ = A(1)
  94.     Up = 1
  95.     Down = 1
  96.     cur_sum = 0
  97.     minus_pos = 0
  98.  
  99.     do i=1, size(A)
  100.       cur_sum = cur_sum + A(i)
  101.       if (cur_sum .gt. Summ) then
  102.         Summ = cur_sum
  103.         Up = minus_pos + 1
  104.         Down = i
  105.       endif
  106.    
  107.       if (cur_sum .lt. 0) then
  108.         cur_sum = 0
  109.         minus_pos = i
  110.       endif
  111.     enddo
  112.  
  113.   end subroutine
  114.  
  115. end module
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement