我正在使用英特尔17编译器与Fortran 2008合作。 我在一个子程序中得到一个3D(x,y,z)假定的形状数组,并希望将xy切片作为一维数组传递给另一个将它与矩阵相乘的函数:
SUBROUTINE xy_gyro_average_3d(this,infield,barfield)
class(xy_GyroAverager_t) :: this
REAL,DIMENSION(:,:,:), INTENT(IN),contiguous,TARGET :: infield
REAL,DIMENSION(:,:,:,:,:), INTENT(OUT),contiguous,TARGET :: barfield
INTEGER :: n,m,k,li0,lj0
type(Error_t) :: err
REAL,DIMENSION(:),POINTER :: inptr,outptr
li0=SIZE(infield,1)
lj0=SIZE(infield,2)
DO n=1,this%ln0
DO m=1,this%lm0
DO k=1,this%lk0
inptr(1:li0*lj0) => infield(:,:,k)
outptr(1:li0*lj0) => barfield(:,:,k,m,n)
CALL this%gyromatrix(k,m,n)%multiply_with(invec=inptr,&
& outvec=outptr,err=err)
if (err%err) call write_err(err)
END DO ! k
END DO ! m
END DO ! n
END SUBROUTINE xy_gyro_average_3d
multiply_with例程看起来(简化)如下:
SUBROUTINE multiply_with(this,invec,outvec,err)
CLASS(Matrix_t) :: this
real, dimension(1:), intent(IN) :: invec
real, dimension(1:),intent(OUT) :: outvec
CLASS(Error_t),INTENT(OUT) :: err
CALL this%multiply_with__do(invec,outvec,err)
END SUBROUTINE multiply_with
我收到有关指针分配的警告,然后是关于不匹配的实际和伪参数类型的错误:
src/GyroAverager.F90(294): warning #8589: Fortran 2008 specifies that if a bound remapping list is specified, data target must be of rank one. [INFIELD]
inptr(1:SIZE(infield(:,:,k))) => infield(:,:,k)
----------------------------------------------^
src/GyroAverager.F90(295): warning #8589: Fortran 2008 specifies that if a bound remapping list is specified, data target must be of rank one. [BARFIELD]
outptr(1:li0*lj0) => barfield(:,:,k,m,n)
----------------------------------^
src/GyroAverager.F90(297): error #6633: The type of the actual argument differs from the type of the dummy argument. [INPTR]
CALL this%gyromatrix(k,m,n)%multiply_with(invec=inptr,&
-------------------------------------------------------------^
src/GyroAverager.F90(298): error #6633: The type of the actual argument differs from the type of the dummy argument. [OUTPTR]
& outvec=outptr,err=err)
现在我认为警告不应该是一个问题,只要数组内场和barfield标记为连续(有没有办法这样做以消除警告消息?)。 错误消息究竟出现了什么问题?指针inptr和outptr与伪参数invec和outvec具有相同的维度。 但我读到如果你传递一个指针但是没有把它作为指针接收它指向的数组会被传递。那么到底它仍然作为2D数组而不是1D传递或者是其他地方的问题?
当multiply_with例程的标题看起来像这样时,它正在工作:
SUBROUTINE multiply_with(this,invec,outvec,err)
CLASS(Matrix_t) :: this
class(*), dimension(1:),intent(IN) :: invec
class(*), dimension(1:),intent(OUT) :: outvec
CLASS(Error_t),INTENT(OUT) :: err
然后multiply_with调用的例程稍后将通过select类型获取类型。但我减少了代码,因为我们一直在使用真正的数组。
这样做的正确方法是什么?