我正在寻找一种编写快速代码并能够使用内置向量操作的方法(为了便于阅读)。
FORTRAN似乎是个好人选。但是,我在网上找到的几乎所有资源都是关于编写代码而不是数组表达式,并且只有简单的向量操作示例。
我强烈需要一些可以涵盖警告的好资源,并对使用矢量表达式优化代码提供一些见解。
实施例: 目前我甚至无法预测此类代码的行为:
! a = [0], indices = [1, 1]
a(indices) = a(indices) + 1
编译完成后我得到a = [2]
,但这是正确的吗?如果我使用openmp,它会表现得像这样吗?
就个人而言,我很乐意在numpy上有类似下面的例子:
答案 0 :(得分:3)
您的代码不符合标准:
Fortran 2008 6.5.3.3.2.3:
如果向量下标包含两个或多个具有相同值的元素, 带有该向量下标的数组部分不得出现在 变量定义上下文(16.6.7)。注6.15
因此,您的操作结果不是由标准定义的。
您问题的其他部分似乎过于宽泛,无法在此处理。在Fortran 90及更高版本中有很多关于科学编程的书籍。
还要注意,通过 vectorization ,Fortran和C或C ++中的大多数人都意味着使用SIMD指令simd而不是NumPy中的矢量化表达式。这些只是Fortran中的数组表达式。
答案 1 :(得分:-1)
我扫描过很多来源(约20本书和几十个网页)。运气不好我错过了非常重要的事情。我发布的问题确实是错误的,并且来自我对fortran中阵列操作的最初期望。
我期望的答案是:没有工具可以在fortran中使用自动并行化编写简短易读的代码(更确切地说:有,但这些是专有库)。
fortran中可用的内部函数列表很短 (link),仅包含易于映射到SIMD操作的函数。
有很多功能会缺少一个。
缺少功能的简要示例:
没有内置数组sort
或unique
。建议的方法是使用this library,它提供单线程代码(忘记线程和CUDA)
累计金额/运行金额。一个人可以实现它,但结果代码永远不会在线程/ CUDA / Xeon Phi /接下来的任何东西上正常工作。
bincount,numpy.ufunc.at,numpy.ufunc.reduceat(在许多应用程序中非常有用)
在大多数情况下,即使使用简单的实现,fortran也能提供2倍的加速,但编写的代码将始终是单线程的,而matlab / numpy函数可以重新实现GPU或其他并行平台而无需用户端的任何努力(偶尔发生在MATLAB上,也见gnumpy,theano和parakeet)
总而言之,这对我来说是个坏消息。 Fortran开发人员非常关心今天的快速程序,而不是将来。我也无法将我的代码锁定在专有软件上。而且我还在寻找合适的工具。 (Julia是当前候选人)
另见:
STL analogue in fortran 需要准备使用的算法。
Numerical recipes: the art of parallel programming作者实现类似MATLAB的基本操作,以获得更具表现力的代码
我也发现有用的these notes可以看到推荐的代码优化方法(看不到向量操作的位置)
dicussion关于在fortran中实现独特功能,建议使用专有工具。