首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将指向复杂Fortran数组虚部的“指针”传递给BLAS例程

将指向复杂Fortran数组虚部的“指针”传递给BLAS例程
EN

Stack Overflow用户
提问于 2016-12-02 00:43:43
回答 3查看 305关注 0票数 1

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

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

代码语言:javascript
复制
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报告“非派生类型变量的意外‘%’”。

有没有其他方法可以实现我需要的东西?

EN

回答 3

Stack Overflow用户

发布于 2016-12-02 00:56:27

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

代码语言:javascript
复制
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实数指针,如果您将其传递给外部函数,仍然会创建一个临时副本。

票数 1
EN

Stack Overflow用户

发布于 2016-12-02 04:13:57

根据@Vladimir Fsuggestion,我最终得到了以下代码。

bar.F文件:

代码语言:javascript
复制
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

foo.F文件:

代码语言:javascript
复制
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
票数 0
EN

Stack Overflow用户

发布于 2016-12-02 21:39:27

代码语言:javascript
复制
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调用中,因为它们是堆栈上的临时向量。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40916015

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档