Optimization 在forall循环中使用用户定义的函数

Optimization 在forall循环中使用用户定义的函数,optimization,error-handling,compiler-errors,fortran,gfortran,Optimization,Error Handling,Compiler Errors,Fortran,Gfortran,我有一个pde要解决。为了优化,我使用forall循环,在循环内部,变量使用用户定义的函数按以下方式更改 forall(i=2:n-1,j=2:n-1, w(i,j).gt.wmax/1000) k3(i,j)=w(i,j)+h*k(x(i),t) end forall 这里,k(x,t)是我前面定义的一个外部定义的函数 错误来自: Reference to impure function ‘k’ at (1) inside a FORALL block 我正在使用gfortran

我有一个pde要解决。为了优化,我使用forall循环,在循环内部,变量使用用户定义的函数按以下方式更改

forall(i=2:n-1,j=2:n-1, w(i,j).gt.wmax/1000)
    k3(i,j)=w(i,j)+h*k(x(i),t)
end forall
这里,k(x,t)是我前面定义的一个外部定义的函数

错误来自:

 Reference to impure function ‘k’ at (1) inside a FORALL block

我正在使用gfortran。如果在forall循环中需要用户定义的函数,那么解决方案是什么?有没有可能在一个论坛内,或者我需要做一些其他的事情,这也将优化?如果有其他可能的话,也请解释一下。

问题是您在FORALL块中引用了一个名为k的不纯函数。为了在编写函数时实现这一点,您必须使其成为纯函数,并且在循环中调用它时在作用域中有一个接口-纯函数是一种断言,即函数不会(除其他外)更改其参数,如果发生这种情况,可能会使Forall构造的并行处理给出错误的答案。如果你给出了一个完整的,最小的程序来显示你的问题,我会告诉你你需要做的改变,但是你没有,我不能


但事实上,这是顺便提一下。不要使用FORALL。几乎可以肯定的是,您的程序不会比使用简单的do循环运行得更快,而且很可能运行得更慢。福尔在当时似乎是个好主意,但由于种种原因,它并没有真正起作用——我注意到,在梅特卡夫、里德和科恩的最新版《现代Fortran解释》中,他们将其标记为过时。相反,我将研究更现代的Do Concurrent,或者,也许是最好的,学习如何使用OpenMP并行化循环。

问题是,您在FORALL块中引用了一个名为k的不纯函数。为了在编写函数时实现这一点,您必须使其成为纯函数,并且在循环中调用它时在作用域中有一个接口-纯函数是一种断言,即函数不会(除其他外)更改其参数,如果发生这种情况,可能会使Forall构造的并行处理给出错误的答案。如果你给出了一个完整的,最小的程序来显示你的问题,我会告诉你你需要做的改变,但是你没有,我不能


但事实上,这是顺便提一下。不要使用FORALL。几乎可以肯定的是,您的程序不会比使用简单的do循环运行得更快,而且很可能运行得更慢。福尔在当时似乎是个好主意,但由于种种原因,它并没有真正起作用——我注意到,在梅特卡夫、里德和科恩的最新版《现代Fortran解释》中,他们将其标记为过时。相反,我会研究更现代的Do Concurrent,或者,也许是最好的,学习如何使用OpenMP并行化循环。

正如Ian所说,forall不会使代码更快。如果有什么不同的话,它可以使速度变慢。只需使用do循环。正如Ian所说,forall不会使您的代码更快。如果有什么不同的话,它可以使速度变慢。只需使用do循环即可。Fortran 2018在第B.3.13节中将
for all
标记为已过时。在本节的讨论中,建议改用
DO CURRENT
。无论是在FORALL、WHERE还是DO循环中,函数都应该追求纯或基本。Fortran 2018在第B.3.13节中将
FORALL
标记为过时。在本节的讨论中,建议改为使用
DO CURRENT
。无论是在FORALL、WHERE还是DO循环中,函数都应该追求纯或基本。