使用数组表达式在 FORTRAN 中编写最佳代码

Writing optimal code in FORTRAN using array expressions

我正在寻找一种方法来编写快速代码并能够使用内置向量运算(为了可读性)。

FORTRAN 似乎是不错的选择。然而,我在网上找到的几乎所有资源都是关于编写代码 没有 数组表达式的,并且只有简单的向量运算示例。

我强烈需要一些很好的资源,这些资源可以涵盖注意事项并提供一些关于使用向量表达式优化代码的见解。

示例: 目前我什至无法预测此类代码的行为:

! a = [0], indices = [1, 1]
a(indices) = a(indices) + 1

编译后得到a = [2],但这是正确的吗?如果我使用 openmp,它会这样吗?

就我个人而言,我很乐意在 numpy 上有类似以下示例的内容:

  1. 100 numpy excercises
  2. numpy: tips and tricks to work with data
  3. Getting the Best Performance out of NumPy

您的代码不符合标准:

Fortran 2008 6.5.3.3.2.3:

If a vector subscript has two or more elements with the same value, an array section with that vector subscript shall not appear in a variable definition context (16.6.7). NOTE 6.15

因此您的操作结果不是标准定义的。

您问题的其他部分似乎过于宽泛,无法在此处进行处理。有很多关于 Fortran 90 及更高版本的科学编程的书籍。

另请注意,矢量化 Fortran 和 C 或 C++ 中的大多数人指的是使用 SIMD 指令 而不是 NumPy 的矢量化表达式。这些只是 Fortran 中的数组表达式。

我扫描了很多资源(约 20 本书和几十个网页)。真倒霉,我错过了一些非常重要的事情。我发布的问题确实不正确,并且来自我最初对 fortran 中的数组操作的高期望。

我期望的答案是:没有工具可以用自动并行化的 Fortran 编写简短、可读的代码(更准确地说:有,但那些是专有库)。

fortran 中可用的内部函数列表非常短 (link),并且只包含容易映射到 SIMD 操作的函数。

有很多功能会被遗漏。

  • 虽然这可以通过单独的库解决,每个平台都有单独的实现,但 Fortran 不提供这样的功能。有商业选项(见this thread

缺失函数的简要示例:

  • 无内置数组 sortunique。建议的方式是使用this library,它提供单线程代码(忘记线程和CUDA)

  • 累计总和/运行总和。可以简单地实现它,但是生成的代码永远无法在 threads/CUDA/Xeon Phi/whatever 上正常工作。

  • bincount,numpy.ufunc.at,numpy.ufunc.reduceat(在很多应用中非常有用)

在大多数情况下,即使是简单的实现,fortran 也能提供 2 倍的加速,但编写的代码将始终是单线程的,而 matlab/numpy 函数可以在 GPU 或其他并行平台上重新实现,而无需用户付出任何努力侧面(偶尔发生在 MATLAB 中,另见 gnumpy,theano and parakeet

总而言之,这对我来说是个坏消息。 Fortran 开发人员现在真正关心的是拥有快速的程序,而不是将来。我也无法将我的代码锁定在专有软件上。我仍在寻找合适的工具。 (Julia 是当前候选人)

另请参阅: