我已经有了当前的代码,但它仍然无效。如果代码正确,请帮助我编译它。我曾尝试过这样编译:
gfortran trap.f -fopenmp
PROGRAM TRAP
USE OMP_LIB
DOUBLE PRECISION INTEG, TMPINT
DOUBLE PRECISION A, B
PARAMETER (A=3.0, B=7.0)
INTEGER N
PARAMETER (N=10)
DOUBLE PRECISION H
DOUBLE PRECISION X
INTEGER I
DOUBLE PRECISION F
H = (B-A)/N
INTEG = 0.0
TMPINT = 0.0
!$omp parallel firstprivate(X, TMPINT) shared(INTEG)
!$omp do
DO 10 I=1,N-1,1
X=A+I*H
TMPINT = TMPINT + F(X)
10 CONTINUE
!$omp end do
!$omp critical
INTEG = INTEG + TMPINT
!$omp end critical
!$omp end parallel
NTEG = (INTEG+(F(A)+F(B))/2.0)*H
PRINT *, "WITH N=", N, "INTEGRAL=", INTEG
END
FUNCTION F(X)
DOUBLE PRECISION X
F = X / (X + 1) * EXP(-X + 2)
END
编译器提出以下问题:
答案 0 :(得分:1)
你的程序有一个后缀.f
,所以gfortran假定代码是固定格式的,并且抱怨许多语句都是"无法分类"。要解决此问题,请将文件名更改为trap.f90
并编译为gfortran -fopenmp trap.f90
以采用自由格式。还有其他问题:一个是函数F(X)
的返回类型与主程序中声明的类型不匹配,因此F(X)
需要修改为
FUNCTION F(X)
implicit none !<--- this is always recommended
DOUBLE PRECISION X, F !<--- add F here
F = X / (X + 1) * EXP(-X + 2)
END
另一个问题是NTEG
可能是INTEG
的拼写错误,因此应将其修改为
INTEG = (INTEG+(F(A)+F(B))/2.0)*H
(如果我们在主程序中有implicit none
,则自动检测到这一点)。现在运行代码,例如8个线程,给出
$ OMP_NUM_THREADS=8 ./a.out
WITH N= 10 INTEGRAL= 0.28927708626319770
虽然exact result是0.28598 ...增加N
的价值,我们可以确认协议变得更好:
WITH N= 100 INTEGRAL= 0.28602065571967972
WITH N= 1000 INTEGRAL= 0.28598803555916535
WITH N= 10000 INTEGRAL= 0.28598770935198736
WITH N= 100000 INTEGRAL= 0.28598770608991503
顺便说一下,使用reduction子句来做同样的事情可能更容易,例如:
INTEG = 0.0
!$omp parallel do reduction(+ : integ) private(x)
DO I = 1, N-1
X = A + I * H
INTEG = INTEG + F( X )
ENDDO
!$omp end parallel do
INTEG = (INTEG+(F(A)+F(B))/2.0)*H
答案 1 :(得分:0)
您的代码采用固定格式(.f
)。因此,您必须按固定格式的规则进行编码:每行的前六个字符具有特殊含义,除非您在第一个位置,行继续(第六个位置)或语句标签{中指定注释,否则应为空白{1}}。
如果您相应地格式化代码,编译器会抱怨10
的返回值不匹配。由于您不使用F(X)
,因此类型由函数的第一个字母定义,implicit none
映射到(单精度)实数。因此,您需要明确指定返回类型。
然后代码如下:
F
[请注意,我也将 PROGRAM TRAP
USE OMP_LIB
DOUBLE PRECISION INTEG, TMPINT
DOUBLE PRECISION A, B
PARAMETER (A=3.0, B=7.0)
INTEGER N
PARAMETER (N=10)
DOUBLE PRECISION H
DOUBLE PRECISION X
INTEGER I
DOUBLE PRECISION F
H = (B-A)/N
INTEG = 0.0
TMPINT = 0.0
c$omp parallel firstprivate(X, TMPINT) shared(INTEG)
c$omp do
DO 10 I=1,N-1,1
X=A+I*H
TMPINT = TMPINT + F(X)
10 CONTINUE
c$omp end do
c$omp critical
INTEG = INTEG + TMPINT
c$omp end critical
c$omp end parallel
INTEG = (INTEG+(F(A)+F(B))/2.0)*H
PRINT *, "WITH N=", N, "INTEGRAL=", INTEG
END
DOUBLE PRECISION FUNCTION F(X)
DOUBLE PRECISION X
F = X / (X + 1) * EXP(-X + 2)
END
行修改为NTAG =
,因为我认为这是有意的。我没有检查代码的有效性。 ]