ПАРАЛЛЕЛЬНОЕ ПРОГРАММИРОВАНИЕ
          
        
        
          
            96
          
        
        
          Parameter(Nm=100)
        
        
          Double Precision A(Nm,Nm), B(Nm,Nm),
        
        
          $    Ac(Nm,Nm), Bc(Nm,Nm), C(Nm,Nm), Cc(Nm,Nm)
        
        
          Integer Counts(0:Nm), Shifts(0:Nm),
        
        
          $    Counts2(0:Nm), Shifts2(0:Nm)
        
        
          Call MPI_INIT(Ierr)
        
        
          Call MPI_COMM_SIZE(MPI_COMM_WORLD, Size, Ierr)
        
        
          Call MPI_COMM_RANK(MPI_COMM_WORLD, Rank, Ierr)
        
        
          C Задаются начальные значения матриц А и В
        
        
          If (Rank.eq.0) Then
        
        
          Do I = 1,Nm
        
        
          Do J = 1,Nm
        
        
          A(I,J) = I*J
        
        
          B(I,J) = 1/A(I,J)
        
        
          End Do
        
        
          End Do
        
        
          End If
        
        
          C Каждый процесC определяет первый и последний
        
        
          C столбец своих расчетов
        
        
          BCol = Rank*Nm/Size+1
        
        
          ECol = (Rank+1)*Nm/Size
        
        
          C Каждый процесc определяет свои массивы размера
        
        
          C полоc и их положение
        
        
          Do I = 0,Size-1
        
        
          Counts(I) = ((I+1)*Nm/Size-I*Nm/Size)*Nm
        
        
          Shifts(I) = I*Nm/Size*Nm
        
        
          End Do
        
        
          Do I = 0,Size-1
        
        
          Shifts2(I) = Shifts(Rank)
        
        
          Counts2(I) = Counts(Rank)
        
        
          End Do
        
        
          C «0» посылает всем процессам
        
        
          C соответствующие полосы матриц A и В
        
        
          Call MPI_SCATTERV(A(1,1), Counts, Shifts,
        
        
          $    MPI_DOUBLE_PRECISION, Ac(1,1), Counts(Rank),
        
        
          $    MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, Ierr)
        
        
          Call MPI_SCATTERV(B(1,1), Counts, Shifts,
        
        
          $    MPI_DOUBLE_PRECISION, Bc(1,1), Counts(Rank),
        
        
          $    MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD, Ierr)
        
        
          Do K = BCol,ECol
        
        
          Do I = 1,Nm
        
        
          C(I,K) = Ac(I,K-BCol+1)+Bc(I,K-BCol+1)
        
        
          End Do
        
        
          End Do
        
        
          C Каждый процесс отправляет свою рассчитанную полосу С
        
        
          C и заполняет недостающие полосы данными, поступающими от
        
        
          C других процессов
        
        
          Call MPI_ALLTOALLV(C(1,1), Counts2, Shifts2,
        
        
          $    MPI_DOUBLE_PRECISION, Cc(1,1), Counts,
        
        
          $    Shifts, MPI_DOUBLE_PRECISION,
        
        
          $    MPI_COMM_WORLD, Ierr)
        
        
          if (Rank.eq.0) write(6,*) "A=",A