我想把一个指向复杂Fortran数组虚部的“指针”传递给一个只操作实数的BLAS函数。我指的是C语言意义上的“指针”,因为我不想涉及任何数据复制。
例如,考虑下面的简单代码(我的实际代码稍微复杂一些):
function foo(c1, c2, n) result(r)
complex, dimension(:), intent(in) :: c1, c2
integer, intent(in) :: n
real :: r
real, external :: SDOT
r = SDOT(n, c1(1)%re, 2, c2(1)%im, 2)
end function foo不幸的是,%re和%im仅在Fortran2008中指定。此外,我不确定标准是否允许将复杂的部分选择器应用于数组的各个元素,因为我的两个编译器都不支持这一点。
gfortran报告“非派生类型变量的意外‘%’”。
有没有其他方法可以实现我需要的东西?
发布于 2016-12-02 00:56:27
我要做的是首先创建一个具有显式形状或假定大小实参的子例程,并添加一个大小为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保存在不同的源文件中,并使用隐式接口,这样编译器就不会报错。有关其有效性的讨论,请参阅Is the storage of COMPLEX in fortran guaranteed to be two REALs?
不幸的是,它仍然会创建数组的临时副本。只有当你在SDOT中使用假定的形状参数,并且有明确的接口时,它才能真正帮助避免复制。
即使您为实部和虚部创建了Fortran实数指针,如果您将其传递给外部函数,仍然会创建一个临时副本。
发布于 2016-12-02 04:13:57
根据@Vladimir F的suggestion,我最终得到了以下代码。
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 barfoo.F文件:
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发布于 2016-12-02 21:39:27
function foo(c1, c2, n) result(r)
complex, dimension(:), intent(in) :: c1, c2
integer, intent(in) :: n
real :: r
REAL, DIMENSION(n) :: reality, dreamy
real, external :: SDOT
Reality = REAL(c1)
DReamy = IMAG(c2)
r = SDOT(n, Reality, 1, Dreamy, 1)
end function foo由于AIMAG和REAL是基本的,您应该能够将它们放在SDOT调用中,因为它们是堆栈上的临时向量。
https://stackoverflow.com/questions/40916015
复制相似问题