gpt4 book ai didi

fortran - ifort 中的 "In call to DSYEV, an array temporary was created for argument"但相关维度仅为 1

转载 作者:行者123 更新时间:2023-12-05 03:28:57 25 4
gpt4 key购买 nike

相关问题Temporary array creation and routine GEMM Warning message (402) : An array temporary created for argument

对于以下 Fortran 代码(修改自 dsyev in fortran 90 )

program test_dsyev   
implicit none
integer, parameter :: dp = selected_real_kind(15, 307)
real(dp), allocatable :: A(:,:), A2(:,:,:), work (:), w(:)
real(dp) :: c1
integer :: i, j
integer :: lwork, info, n, lda
character :: jobz, UPLO

n=5
allocate(A(n,n))
allocate(A2(1,n,n))

A = 0.0_dp
c1 = 1.0_dp
do i = 1, n
do j = 1, n
A(i, j) = i * c1 + j * c1
end do
end do
A2(1,:,:) = A

lda = n
lwork = 10 * n

jobz = 'N'
UPLO = 'U'
allocate(work(lwork))
allocate(w(n))
call dsyev(jobz,uplo,n,A,lda,w,work,lwork,info)
write (*,*) w

call dsyev(jobz,uplo,n,A2(1,:,:),lda,w,work,lwork,info)
write (*,*) w
end program test_dsyev

调用了 d.f90ifort -mkl -warn all -check all d.f90 给我

 -1.58312395177700      -1.465651932086313E-015  8.229374109843719E-018
4.803282588162841E-016 31.5831239517770
forrtl: warning (406): fort: (1): In call to DSYEV, an array temporary was created for argument #4

Image PC Routine Line Source
a.out 0000000000408E86 Unknown Unknown Unknown
a.out 000000000040580B Unknown Unknown Unknown
a.out 0000000000403812 Unknown Unknown Unknown
libc-2.17.so 00002B10A2A31555 __libc_start_main Unknown Unknown
a.out 0000000000403729 Unknown Unknown Unknown
-1.58312395177700 -1.465651932086313E-015 8.229374109843719E-018

似乎警告消息与A2(1,:,:) 和内存不连续有关。是的,Fortran 是专栏专业的。但是,A2 的第一个维度是 1。A2 应该跟在 A2(1,1,1) 之后,A2(1, 2,1),...,我的意思是,A2的第一个索引在内存分配中没有起到作用。还是我完全错了?

最佳答案

让我们考虑一个更简单的程序来查看发生了什么:

  implicit none

integer i(1,1)
call s(i(1,:))

contains

subroutine s(j)
integer j(*)
end subroutine s

end program

使用 -check 编译以启用临时复制检查,我们可以看到完全相同的警告:

forrtl: warning (406): fort: (1): In call to S, an array temporary was created for argument #1

与问题示例一样,虚拟参数假定大小,实际参数是相同等级的数组部分,但比整个数组小一级。

数组部分 i(1,:) 实际参数是连续的,所以也许不需要为虚拟 j 临时复制?看看这个,当 i 不是简单地连续时,ifort 会制作一个临时副本,即使它“显然”是连续的。1

但是,因为伪参数 j 是假设大小的,我们不需要担心传递数组部分 i(1,:):我们可以传递整个数组 i,或简单连续的部分 i(:,:)。我们可以这样做,因为当虚拟参数为假定大小(或显式大小)时,实际参数和虚拟参数的等级不需要匹配。

请注意,如果假定虚拟对象为 shape,则秩确实需要匹配,但编译器可能会通过传递数组描述符/dope 来处理参数关联,而不是制作临时副本:与假设大小和显式大小的数组参数不同,假设形状的虚拟对象不必是连续的。 (编译器可能仍然会制作一个临时副本,并在它认为有益时警告制作临时副本,但这并不总是会发生。)

最后,我推测警告的触发器是简单的连续性(很高兴有人确认/争论),但有一些证据表明您可以使用此处的简单替代方法避免运行时检查警告。 (如果不是简单地连续,那么制作副本是完全有意义的:简单连续性以一种易于检查的方式定义。)


1 i(1,:) 不是简单连续的,即使第一个范围是 1,因为简单连续的规则(F2018,9.5.4 ):

no subscript-triplet is preceded by a section-subscript that is a subscript.

第二位的:是下标三元组,而第一位的1是下标。

关于fortran - ifort 中的 "In call to DSYEV, an array temporary was created for argument"但相关维度仅为 1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71129629/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com