这是我的代码,我想让它与OpenMP并行。我有一个主循环来制作并行和一些内循环。
p
,i
或Li
是私有还是共享? 您是否建议对此并行循环使用可分配变量?
!$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
答案 0 :(得分:-1)
Personally I would break this problem up a bit.
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
Basically moving the array to be inside of either an ELEMENTAL FUNCTION or a PURE SUBROUTINE. Then see what it does for speed with inlining and a single parallel do of some sort (OMP or other).
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
Etc... For other elemental functions or pure subroutines
R_xy = matmul(R_x,R_y)
R_xyz = matmul(R_xy,R_ ...