fortran - 如何为假定的形状数组使用 optional 属性

标签 fortran optional

我在使用 Fortran 时遇到以下情况 optional 属性
对于假定的形状数组并试图找出最佳(在性能方面)解决方案。
如果有人能给我一个好的提示,我会很高兴。
请注意,我对我可以获得的每一个性能提升都很感兴趣,因为我的数组很大,循环的数量和周期甚至更大。

我的情况是,计算是使用 optional 参数完成的,或者如果它不存在,它会在其位置使用另一个数组。

  subroutine compute(tmat,av,av2)
  implicit none
  complex,intent(out)           :: tmat(:)   
  complex,intent(in)             :: av(:)      
  complex,intent(in),optional    :: av2(:)     

  if(present(av2)) then
      tmat = av *av2
  else
      tmat = av *av
  end if

  end subroutine compute_transition_matrices_bosonic

在这个简单的例子中,上面的解决方案就可以了。然而,我真正的代码要复杂得多。
这意味着例程的内部块可能非常大(数百行),最重要的是包含许多嵌套循环。
人们可以想象它是这样的:
  if(present(av2)) then
      tmat = "function"(av,av2)
  else
      tmat = "function"(av,av)
  end if

其中“函数”代表许多操作和循环(因此是“”)。关键是对于这两种情况,这些操作是相同的
if 语句使我需要编写两次代码。另一种解决方案是检查是否 av2出现在使用位置
代码会产生一些开销,因为此检查将非常(非常)频繁地进行。

我想知道是否有更聪明的解决方案来解决这样的问题。首先,人们可能会想到使用临时变量
  complex,                :: phi_tmp(:)

  if(present(av2)) then
      phi_tmp = av2
  else
      phi_tmp = av
  end if

  tmat = "function"(av,phi_tmp)

这通常在使用 optional 参数时完成。但这会复制数据,在我的情况下这是一个非常大的数组。
因此,我在考虑使用指针
  complex,intent(in),target             :: av(:)      
  complex,intent(in),optional,target    :: av2(:)   
  complex,pointer                :: phi_tmp(:)

  if(present(av2)) then
      phi_tmp => av2
  else
      phi_tmp => av
  end if

  tmat = "function"(av,phi_tmp)

但这需要TARGET av 的属性和 av2 .在这里我不确定这是否会导致性能下降,因为编译器
不能再假设 avav2在它的优化过程中没有别名,即使这里都有 INTENT(IN)属性
这样就不会出现混叠问题。此外,如果调用例程时输入中的参数是什么意思?
没有TARGET属性? (这编译和工作!)

有没有人对这些问题有一些经验?
有“标准”的解决方案吗? (我没找到)
最终的最佳解决方案是什么?

最佳答案

一种方法是针对当前和不存在的情况使用不同的子程序。

subroutine compute1(tmat,av)
  implicit none
  complex,intent(out)           :: tmat(:)   
  complex,intent(in)            :: av(:)      

  call compute2(tmat, av, av)  ! Ensure there is an explicit interface for compute2 here
end subroutine

subroutine compute2(tmat,av,av2)
  implicit none
  complex,intent(out)           :: tmat(:)   
  complex,intent(in)            :: av(:)      
  complex,intent(in)            :: av2(:)     

  tmat = "function"(av,av2)
end subroutine

其中两者都没有 optional 参数。

这可以添加到制作 compute这两者的泛型。

当然,这不会在所有情况下都有效,但这里使用 intent(in) av 上的属性和 av2compute2我们不必担心混叠。

关于fortran - 如何为假定的形状数组使用 optional 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32582929/

相关文章:

dll - Compaq Visual Fortran 6.6、动态链接库 (DLL) 和模块

fortran - 我声明了一个字符变量,但被告知我选择的符号不能有类型,我尝试过其他符号,但得到相同的错误

Clojure:将 'expanded' optional 参数传递给函数

java - 关于效率: .filter(Optional::isPresent).map(Optional::get) 不是比 .flatmap(Optional::stream) 更好吗?

foreign-keys - 使用 Entity Framework 7 的流体 API 创建 optional 外键

python - 在 Fortran 中实现像快速插值一样的 numpy

python - 使用 F2PY 处理 Python 中的 Fortran 字符数组

linux - 错误 : undefined reference to NetCDF functions

Python argparse : how to detect duplicated optional argument?

rust - 如何在HashMap <Option <String>,V>中查找值而不进行复制?