我正在尝试使用OpenMP指令并行化FORTRAN90中编写的mex代码。当我不使用任何OpenMP时代码工作正常,但是当我并行化时,我会收到分段错误。我在调试器模式下调试了运行MATLAB的代码。它到达mex函数的末尾没有任何问题,并且当我将结果传递给MATLAB工作区时会产生这个错误。有没有人知道出现这种错误的可能原因?我用的是R2014a。这是代码:
subroutine qtest(srcRe,srcIm,nF,nS,freq,srcPos,nDim,lstPos,nL,c0,resp)
use omp_lib
implicit none
integer*4, intent(in) :: nF, nS, nDim, nL
real*8, intent(in) :: srcRe(nF,nS),srcIm(nF,nS),freq(nF)
real*8, intent(in) :: srcPos(nS,nDim), lstPos(nL,nDim), c0
real*8, intent(out) :: resp(nF,nL)
real*8 :: pi, k(nF), r(nS), x2(nS)
complex*16 :: icplx, G(nF), ikr(nF), p(nF)
integer*4 :: i,j,m
icplx = (0.d0,1.d0)
pi = 4.d0*datan(1.d0)
k = 2.d0*pi*freq/c0
resp = 0.d0
G = 0.d0
!$OMP PARALLEL
do i = 1,nL
!$OMP SINGLE
x2 = (lstPos(i,1) - srcPos(:,1))**2.d0
r = x2
do m = 2,nDim
r = r + (lstPos(i,m) - srcPos(:,m))**2.d0
enddo
r = dsqrt(r)
p = 0.d0
!$OMP END SINGLE
!$OMP DO PRIVATE(j,ikr,G) REDUCTION(+:p)
do j = 1,nS
ikr = icplx*k*r(j)
G = cdexp(-ikr)/(4.d0*pi*r(j))
p = p + (srcRe(:,j) + icplx*srcIm(:,j))*G
enddo
!$OMP END DO
!$OMP SINGLE
resp(:,i) = resp(:,i) + 20.d0*dlog10(cdabs(p)/20.d-6)
!$OMP END SINGLE
enddo
!$OMP END PARALLEL
end subroutine qtest
我用来从/向Matlab工作空间传输变量的函数是:
#include "fintrf.h"
!
SUBROUTINE MEXFUNCTION(NLHS, PLHS, NRHS, PRHS)
use mexf90
implicit none
integer*8, intent(in) :: PRHS(*) ! Pointers carrying the input data
integer*8, intent(out) :: PLHS(*) ! Pointers carrying the output data
integer*4, intent(in) :: NLHS,NRHS ! REMAINS THE SAME FOR 64BIT system
!-----------------------------------------------------------------------
integer*8 :: err, nF, nF1, nS, nS1, nDim, nDim1, nL
real*8 :: c0
integer*8, pointer :: srcRe, srcIm, freq, srcPos, lstPos, resp
character(200) :: errMsg
integer*4 :: txt, classId
integer*4, external :: mexprintf
! ASSIGN POINTERS TO THE VARIOUS PARAMETERS
srcRe =>MXGETPR(PRHS(1))
nF = MXGETM(PRHS(1))
nS = MXGETN(PRHS(1))
srcIm =>MXGETPR(PRHS(2))
freq =>MXGETPR(PRHS(3))
nF1 = MXGETM(PRHS(3))
srcPos =>MXGETPR(PRHS(4))
nS1 = MXGETM(PRHS(4))
nDim = MXGETN(PRHS(4))
lstPos =>MXGETPR(PRHS(5))
nL = MXGETM(PRHS(5))
nDim1 = MXGETN(PRHS(5))
c0 = MXGETSCALAR(PRHS(6))
plhs(1) = mxCreateDoubleMatrix(nF,nL,0)
resp =>mxGetPr(plhs(1))
call qtest(srcRe, srcIm,nF,nS,freq,srcPos,nDim,lstPos,nL,c0,resp)
END SUBROUTINE MEXFUNCTION
调试时,代码到达此行,之后我无法干预任何内容,Matlab进行转移。在Matlab方面,它只是一行调用此函数的代码。
aaa = qtest(srcRe,srcIm,freq,srcPos,lstPos,c0);
正如我上面提到的,如果我不使用任何并行化,这是有效的。
答案 0 :(得分:0)
子例程qtest
包含声明
integer*4, intent(in) :: nF, nS, nDim, nL
而mexfunction
包含
integer*8 :: err, nF, nF1, nS, nS1, nDim, nDim1, nL
就个人而言,我始终对变量进行一致的声明,看看会发生什么。