通过a";指针;到BLAS例程的复Fortran数组的虚部

通过a";指针;到BLAS例程的复Fortran数组的虚部,fortran,blas,fortran2008,Fortran,Blas,Fortran2008,我想把一个指向复Fortran数组虚部的“指针”传递给一个只对实数运算的BLAS函数。我指的是C语言意义上的“指针”,因为我不希望涉及任何数据复制 例如,考虑下面的简单代码(我的实际代码稍微复杂一些): 不幸的是,%re和%im仅在Fortran 2008中指定。此外,我不确定该标准是否允许将复杂部分选择器应用于数组的各个元素,因为我的编译器都不支持这一点 gfortran对未派生的类型变量抱怨“意外“%” 有没有其他方法来实现我所需要的?我要做的是首先创建一个具有显式形状或假定大小实数参数的子

我想把一个指向复Fortran数组虚部的“指针”传递给一个只对实数运算的BLAS函数。我指的是C语言意义上的“指针”,因为我不希望涉及任何数据复制

例如,考虑下面的简单代码(我的实际代码稍微复杂一些):

不幸的是,
%re
%im
仅在Fortran 2008中指定。此外,我不确定该标准是否允许将复杂部分选择器应用于数组的各个元素,因为我的编译器都不支持这一点

gfortran
对未派生的类型变量抱怨“意外“%”


有没有其他方法来实现我所需要的?

我要做的是首先创建一个具有显式形状或假定大小实数参数的子例程,并添加一个大小为2的列组:

function foo(c1, c2, n) result(r)
  complex, dimension(:), intent(in) :: c1, c2
  integer, intent(in) :: n
  real :: r

  real, external :: bar

  r = bar(c1, c2, n)
end function foo

function bar(c1, c2, n) result(r)
  real, dimension(2,n), intent(in) :: c1, c2
  integer, intent(in) :: n
  real :: r

  r = SDOT(n, c1(1,:), 2, c2(2,:), n)
end function
bar
保存在不同的源文件中,并使用隐式接口,以便编译器不会抱怨。有关此方法有效性的讨论,请参见

不幸的是,它仍然会创建阵列的临时副本。只有在
SDOT
中使用了假定的形状参数,并且有明确的接口,才有助于避免复制

即使您为实部和虚部创建了Fortran实指针,但如果您将其传递给外部函数,仍然会生成一个临时副本。

根据,我最终得到以下代码

bar.F
文件:

function bar(c1, c2, n) result(r)
  real, intent(in) :: c1(*), c2(*)
  integer, intent(in) :: n
  real :: r

  r = SDOT(n, c1(1), 2, c2(2), 2)
end function bar
function foo(c1, c2, n) result(r)
  complex, dimension(:), intent(in) :: c1, c2
  integer, intent(in) :: n
  real :: r

  real, external :: bar

  r = bar(c1, c2, n)
end function foo
foo.F
文件:

function bar(c1, c2, n) result(r)
  real, intent(in) :: c1(*), c2(*)
  integer, intent(in) :: n
  real :: r

  r = SDOT(n, c1(1), 2, c2(2), 2)
end function bar
function foo(c1, c2, n) result(r)
  complex, dimension(:), intent(in) :: c1, c2
  integer, intent(in) :: n
  real :: r

  real, external :: bar

  r = bar(c1, c2, n)
end function foo

由于AIMAG和REAL是基本的,您应该能够将它们放在SDOT调用中,因为它们是堆栈上的临时向量。

Fortran也有指针。但是,您的示例不使用它们。你真的需要一个指针还是只想传递一个参数?另请看,
c1(1)%re
是完全有效的,但不是数组,所以我不确定这部分问题的意思。我想他希望c1(:)%re在end@VladimirF,这确实是我的猜测(甚至是
c1%re
)。这也很有道理。(对于asker:)它不会是简单的连续的,因此可能最终还是一个副本(只是由编译器而不是由用户显式地完成)。是的,实际上它应该可以工作。我试图避免它,因为在面向矩阵的BLAS例程中,2D复杂数组非常复杂。@Vladimir F,谢谢你的提示。我想把
c1
c2
作为
realc1(*)、c2(*)中的
bar()
。因此,我们可以调用
r=SDOT(n,c1(1),2,c2(2),n)
并避免复制。