【发布时间】:2020-05-24 05:45:44
【问题描述】:
我正在尝试并行化包含嵌套 do 循环的部分代码。嵌套循环中有一个“READ”操作。我正在尝试使用 openMP 来减少计算的墙时间。
我有一个包含可分配指针的类型。我不确定如何处理错误消息,当我尝试使用时,我收到“当指针 CellArr 未与目标关联时尝试使用它”
P_ph(iph,iel)%cellArr(igp)%arr 在这个嵌套循环之外。
OPEN (24, FILE=TRIM(ADJUSTL(InpFile))//"_GSP.dat", STATUS='OLD', ACTION='READ', &
ACCESS='DIRECT', FORM='FORMATTED', RECL=600*nel)
!$omp parallel private(id,iel,iph,igp,igp1,tmpP,lineNo,isegel,iSegEls,ngp,ngp1,P_ph, &
isegelTmp, igpTmp, phPolVec, integrand) shared(ShapeFunc_P, ElConn, nph)
id=omp_get_thread_num()
!$omp do
DO iel = 1, nel
ngp = elConn(iel)%ngp
DO iph = 1, nph
ALLOCATE( P_ph(iph, iel)%cellArr(ngp) )
END DO
DO igp = 1, ngp
lineNo = SUM( elConn(1:iel-1)%ngp ) + igp
READ(24,FMT=101,REC=lineNo ) isegelTmp, igpTmp, phPolVec
DO iph = 1, nph
ALLOCATE( P_ph(iph,iel)%cellArr(igp)%arr(ndim,ndim) )
tmpP = 0.d0
DO isegels = 1, Seg_P(iph)%segSize
isegel = Seg_P(iph)%els(isegels)
ngp1 = elConn(isegel)%ngp
ALLOCATE( integrand(ngp1) )
!Retrieve the PhP function from .dat file
phP = RESHAPE( SOURCE = phPolVec((isegel-1)*ndim*ndim+ &
1:isegel*ndim*ndim ),SHAPE=(/ndim,ndim/) ) / elConn(isegel)%vol
DO igp1 = 1, ngp1
ALLOCATE( integrand(igp1)%arr(ndim,ndim) )
integrand(igp1)%arr = phP*ShapeFunc_P(isegel)
END DO
CALL INTEGRAL( tmpP, integrand, elConn(isegel)%jacobian, ngp, nsd, ndim)
DO igp1=1, ngp1
DEALLOCATE( integrand(igp1)%arr )
END DO
DEALLOCATE(integrand)
END DO
P_ph(iph,iel)%cellArr(igp)%arr = tmpP
END DO
END DO
END DO
!$omp end do
!$omp end parallel
CLOSE (24)
种类如下:
TYPE CELL
REAL*8, POINTER :: arr(:,:)
END TYPE CELL
TYPE CELL2
TYPE (CELL), POINTER :: CellArr(:)
END TYPE CELL2
TYPE (CELL2) :: P_ph(nph, nel)
此代码作为顺序程序运行良好。
【问题讨论】:
-
P_ph应该共享,因为您可以从所有数组中访问其元素。 -
Fortran I/O 是否保证是线程安全的?我肯定会在更进一步之前检查一下 - 我的猜测不是
-
还要检查 SHARED (nel, ndim, nsd, P_ph, Seg_P) PRIVATE (phP)。 DEFAULT (NONE) 是一个很好的诊断。 P_ph 随着 ALLOCATE 不断增长
-
@PierredeBuyl:谢谢。根据您的建议,我不再收到错误消息。但是,结果似乎不是线程安全的。
-
我没有这方面的直接来源,但我想 OpenMP 区域中的文件 I/O 无论如何都是一个坏的想法。可以提前读取数据吗?
标签: fortran openmp intel-fortran