2017-08-04 11 views
0

これは私のコードです。OpenMPと並列化したいのですが。私は並列といくつかの内部ループを作るために1つのメインループを持っています。内部ループのインデックス、プライベートまたは共有?

  1. piまたはプライベートまたは共有Liのように、内部ループのインデックスはありますか?
  2. 変数をプライベートまたは共有として宣言しないとどうなりますか?
  3. この並列ループに割り当て可能な変数を使用することをお勧めしますか?

    !$OMP PARALLEL DO 
        do l = 1,n_rep  
        do p = 1,n_l - 1 
        do q = 1,n_l - 1 
        do r = 1,n_l - 1 
         Li = (p - 1)*(n_l - 1)**2 + (q - 1)*(n_l - 1) + r 
    
         alpha(Li) = pi*rand() 
         gamma(Li) = pi*rand() 
         beta(Li) = pi/2*rand() 
    
         R_x(1,1) = 1.d0 
         R_x(1,2) = 0.d0 
         R_x(1,3) = 0.d0 
    
         R_x(2,1) = 0.d0 
         R_x(2,2) = cos(alpha(Li)) 
         R_x(2,3) = sin(alpha(Li)) 
    
         R_x(3,1) = 0.d0 
         R_x(3,2) = -sin(alpha(Li)) 
         R_x(3,3) = cos(alpha(Li)) 
    
         R_y(1,1) = cos(beta(Li)) 
         R_y(1,2) = 0.d0 
         R_y(1,3) = -sin(beta(Li)) 
    
         R_y(2,1) = 0.d0 
         R_y(2,2) = 1.d0 
         R_y(2,3) = 0.d0 
    
         R_y(3,1) = sin(beta(Li)) 
         R_y(3,2) = 0.d0 
         R_y(3,3) = cos(beta(Li)) 
    
         R_z(1,1) = cos(gamma(Li)) 
         R_z(1,2) = sin(gamma(Li)) 
         R_z(1,3) = 0.d0 
    
         R_z(2,1) = -sin(gamma(Li)) 
         R_z(2,2) = cos(gamma(Li)) 
         R_z(2,3) = 0.d0 
    
         R_z(3,1) = 0.d0 
         R_z(3,2) = 0.d0 
         R_z(3,3) = 1.d0 
    
         R_xy = matmul(R_x,R_y) 
         R_xyz = matmul(R_xy,R_z) 
    
    
         do i = 1,n_f - 1 
         do j = 1,n_f - 1 
         do k = 1,n_f - 1 
         Li = (i - 1)*(n_f - 1)**2 + (j - 1)*(n_f - 1) + k 
    
         cf_x(i) = x_f(i) + (p - 1)*d_l - x_c(p) 
         cf_y(j) = y_f(j) + (q - 1)*d_l - y_c(q) 
         cf_z(k) = z_f(k) + (r - 1)*d_l - z_c(r) 
    
         x_rotated = R_xyz(1,1)*cf_x(i) + R_xyz(1,2)*cf_y(j)  & 
            + R_xyz(1,3)*cf_z(k) 
         y_rotated = R_xyz(2,1)*cf_x(i) + R_xyz(2,2)*cf_y(j)  & 
            + R_xyz(2,3)*cf_z(k) 
         z_rotated = R_xyz(3,1)*cf_x(i) + R_xyz(3,2)*cf_y(j)  & 
            + R_xyz(3,3)*cf_z(k) 
    
         enddo 
         enddo 
         enddo 
    
    
        enddo 
        enddo 
        enddo 
        enddo 
    
    !$OMP END PARALLEL DO 
    
+3

OpenMPのは、デフォルトではプライベートループインデックスを行います。それらを共有すると、予期しない結果が生じる競合状態が発生します。おそらく割り当て可能な配列を含む、プライベートにする必要がある多くの変数があります。 – tim18

+0

投稿した内容の一部が不完全であるようです。 – tim18

+0

多くの未使用の結果があります。 – tim18

答えて

-1

個人的に私は少しこの問題を破るだろう。

Size_of_Array = n_l * n_l * n_l 
IF(ALLOCATED(Li))  DEALLOCATE( Li ) 
ALLOCATE( Li  (Size_of_Array)) 
IF(ALLOCATED(Alpha)) DEALLOCATE( Alpha) 
ALLOCATE (Alpha (Size_of_Array)) 
IF(ALLOCATED(Beta)) DEALLOCATE( Beta) 
ALLOCATE( Beta (Size_of_Array)) 
IF(ALLOCATED(Gamma)) DEALLOCATE( Gamma) 
ALLOCATE( Gamma (Size_of_Array)) 

indexer = 0 
do l = 1,n_rep  
    do p = 1,n_l - 1 
    do q = 1,n_l - 1 
     do r = 1,n_l - 1 
     indexer = indexer + 1 
     Li(Indexer) = (p - 1)*(n_l - 1)**2 + (q - 1)*(n_l - 1) + r 
     ENDDO 
    ENDDO 
    ENDDO 
ENDDO 

alpha = pi*rand() 
gamma = pi*rand() 
beta = pi/2*rand() 
!?OMP DO PARALLEL 
DO I= 1, SIZE(Li) 
    CALL Make_Array(Alpha(I), Beta(I), Gamma(I), MyArray(:,:,I)) 
ENDDO 
!etc 

基本的要素関数またはPURE SUBROUTINEのいずれかの内側になるように配列を移動させます。次に、インライン展開のスピードと何らかの並べ替え(OMPなど)の並行処理を確認します。

PURE SUBROUTINE Make_Array(Alpha, Beta, Gamma, MyArray) 
IMPLICIT NONE 
DOUBLE,    INTENT(IN ) :: Alpha 
DOUBLE,    INTENT(IN ) :: Beta 
DOUBLE,    INTENT(IN ) :: Gamma 
DOUBLE, DIMENSION(3,3) INTENT(INOUT) :: MyArray ! Maybe just intent(OUT)? 

    R_x(:,:) = 0.d0 
    R_x(1,1) = 1.d0 
    R_x(2,2) = cos(alpha) 
    R_x(2,3) = sin(alpha) 

    R_x(3,2) = -sin(alpha) 
    R_x(3,3) = cos(alpha) 

    R_y(1,1) = cos(beta) 
    R_y(1,3) = -sin(beta) 

    R_y(2,1) = 0.d0 
    R_y(2,2) = 1.d0 
    R_y(2,3) = 0.d0 

    R_y(3,1) = sin(beta(Li)) 
    R_y(3,2) = 0.d0 
    R_y(3,3) = cos(beta(Li)) 

    R_z(1,1) = cos(gamma(Li)) 
    R_z(1,2) = sin(gamma(Li)) 
    R_z(1,3) = 0.d0 

    R_z(2,1) = -sin(gamma(Li)) 
    R_z(2,2) = cos(gamma(Li)) 

    END SUBROUTINE Make_Array 

等...他の要素関数または純粋サブルーチンの

R_xy = matmul(R_x,R_y) 
    R_xyz = matmul(R_xy,R_ ... 
+1

これはどのようにして質問に答えますか?つまり、回答している質問から1と2と3へのあなたの反応は何ですか? –

+1

これは答えではないアドバイスです。 –

関連する問題