Fortran forall 限制

Posted

技术标签:

【中文标题】Fortran forall 限制【英文标题】:Fortran forall restrictions 【发布时间】:2011-12-22 10:33:36 【问题描述】:

我尝试使用forall 分配动态数组,但 gfortran 不喜欢这样。我还发现write 语句在forall 块中是被禁止的,我怀疑read 语句也是如此。

forall 块中不允许有哪些其他功能/操作?

除了在顺序无关紧要时有时替换do 循环之外,这个构造究竟是什么?我认为它会使编码更加清晰和优雅,尤其是在操作顺序不重要的情况下显示出来,但是对于可以在 forall 中完成的操作似乎非常有限制。

这些限制的原因是什么,即它们保护/防止用户搞砸的原因是什么?使用forall 是个好主意吗?如果是这样,出于什么目的?

现在在我正在处理的代码中只有一个forall 块,如果我在do 循环中将其全部翻译出来,它将产生四个嵌套循环。哪种方式更好?

【问题讨论】:

FORALL 不需要 PURE 程序和函数吗? 【参考方案1】:

现在已经不需要FORALLWHERE 构造了。它们是作为 Fortran 95(Fortran 90 的小扩展)的一部分引入的,主要是为了优化,当时代码矢量化是 HPC 中的主要内容。 FORALL 在应用中如此受限的原因正是因为它是为循环优化而设计的。另请注意,FORALL 不是循环构造,而是赋值。因此,块内只允许赋值语句。理论上,DO 循环给出了关于处理器将循环遍历的索引顺序的明确说明。 FORALL 构造允许编译器根据数组在内存中的存储方式选择最佳顺序。然而,随着时间的推移,这已经失去了意义,因为现代编译器非常擅长 DO 循环向量化,并且您可能不会注意到使用 FORALL 的任何改进。

查看关于 FORALLWHERE here 的精彩讨论

如果您担心代码性能,您可能更愿意考虑使用不同的编译器 - PGI 或 ifort。根据我自己的经验,gfortran 适合开发,但不适合 HPC。您会注意到使用 pgf90 或 ifort 编译的代码的执行速度提高了几倍。

【讨论】:

【参考方案2】:

Forall 构造被证明确实过于严格,并且仅对数组​​操作有用。有关确切限制,请参阅IBM Fortran - FORALL。限制较少的是 Fortran 2008 的 do concurrent 构造。即使是 readwrite 语句也是允许的。请参阅Intel Fortran - DO CONCURRENT 和New features of Fortran 2008。

【讨论】:

不过,还没有多少编译器支持 Fortran 2008。我正在使用 gfortran,最新的稳定版本(4.6?) Gfortran 4.6 部分支持 fortranwiki.org/fortran/show/Fortran+2008+status 和 gcc.gnu.org/onlinedocs/gfortran/Fortran-2008-status.html,声称在最新的 gfortran 中支持 do concurrent

以上是关于Fortran forall 限制的主要内容,如果未能解决你的问题,请参考以下文章

Fortran `forall` 或 `do concurrent` 中的临时变量

继续在教堂的 FORALL 循环之外

如何在 Fortran 程序中设置内部挂钟?

fortran acos 函数参数稳健性

如何从一个Fortran整数转换为一个较小的整数?

Fortran如何编写非零元素