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

时间:2015-10-19 17:09:04

标签: fortran vectorization fortran90

我正在寻找一种编写快速代码并能够使用内置向量操作的方法(为了便于阅读)。

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

2 个答案:

答案 0 :(得分:3)

您的代码不符合标准:

Fortran 2008 6.5.3.3.2.3:

  

如果向量下标包含两个或多个具有相同值的元素,   带有该向量下标的数组部分不得出现在   变量定义上下文(16.6.7)。注6.15

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

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

还要注意,通过 vectorization ,Fortran和C或C ++中的大多数人都意味着使用SIMD指令而不是NumPy中的矢量化表达式。这些只是Fortran中的数组表达式。

答案 1 :(得分:-1)

我扫描过很多来源(约20本书和几十个网页)。运气不好我错过了非常重要的事情。我发布的问题确实是错误的,并且来自我对fortran中阵列操作的最初期望。

我期望的答案是:没有工具可以在fortran中使用自动并行化编写简短易读的代码(更确切地说:有,但这些是专有库)。

fortran中可用的内部函数列表很短 (link),仅包含易于映射到SIMD操作的函数。

有很多功能会缺少一个。

  • 虽然这可以通过单独的库解决,每个平台都有单独的实现,但fortran并没有提供这样的解决方案。有商业选择(见this thread

缺少功能的简要示例:

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

  • 累计金额/运行金额。一个人可以实现它,但结果代码永远不会在线程/ CUDA / Xeon Phi /接下来的任何东西上正常工作。

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

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

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

另见: