集群(ifort)上奇怪的 omp_get_wtime() 行为

问题描述 投票:0回答:2

我在本地 Windows 计算机和集群上运行相同的 Fortran 代码。

代码如下:

program mwe

use omp_lib    
implicit none
    


integer :: indx
integer :: indy
integer :: indz
integer :: total_z = 1000000
integer :: total_x = 200
integer :: total_y = 100

real, allocatable :: output(:,:), grid_x(:), grid_y(:)
real :: startTime, midTime, totalTime

allocate(output(total_x, total_y))
allocate(grid_x(total_x))
allocate(grid_y(total_y))



do indx = 1, total_x
    grid_x(indx) = indx * 2
end do 

do indy = 1, total_y
    grid_y(indy) = indy / 3
end do 


output = 0.0

startTime = omp_get_wtime()
do indz = 1,total_z
do indy = 1,total_y
!$omp parallel do default(private) shared(indy, total_y, indz, total_z, total_x, output, startTime)    
do indx = 1,total_x  
    
    output(indx,indy) = output(indx,indy) + grid_x(indx)/grid_y(indy) 
    if ((mod(indz, 100000) .eq. 0) .and. (indx .eq. 1) .and. (indy .eq. 1)) then 
            midTime = omp_get_wtime()
            write(*,"(A,F15.1,A)") "Total time elapsed",midTime-startTime," seconds." 
    end if 
    
    
    
end do
!$omp end parallel do  
end do
end do

    
end program

在 Windows 上我将代码编译为:

ifort /O2 /c /Qopenmp main.f90
ifort /o main.out /O2 /Qopenmp main.f90 /link /STACK:999999999,999999999

main.out

输出为:

总时间经过119.4秒。

总时间经过237.8秒。

总时间经过357.7秒。

总时间经过474.1秒。

总时间经过588.7秒。

总时间经过730.1秒。

总时间经过 873.0 秒。

总时间经过1015.4秒。

总时间经过1159.6秒。

在集群(linux)上我将代码编译为:

#!/bin/bash
#SBATCH -e error_file.err
#SBATCH -p common
#SBATCH -c 40
#SBATCH --job-name==mwe
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
export OMP_STACKSIZE=512mb
source /opt/apps/rhel8/intel-2020/compilers_and_libraries/linux/bin/compilervars.sh intel64

ifort -O2 -c -qopenmp main.f90
ifort -o main.out -O2 -qopenmp main.f90

./main.out

输出为:

总时间已过 0.0 秒。

总时间已过 0.0 秒。

总时间已过 128.0 秒。

总时间已过 128.0 秒。

总时间已过 128.0 秒。

总时间已过去 256.0 秒。

总时间已过去 256.0 秒。

总时间已过去 384.0 秒。

总时间已过去 384.0 秒。

总时间已过去 384.0 秒。

fortran openmp intel-fortran
2个回答
0
投票

这是 Linux 上

ifort
的编译器错误。
omp_get_wtime()
是一个
double precision
函数,并且您将其输出分配给
real
变量:这应该没问题,在 Fortran 中像往常一样进行隐式转换,但是
ifort
在这里搞砸了。

声明

double precision :: startTime, midTime, totalTime

解决了问题。

此外,您的 MRE 中有一个不相关的错误:

grid_x
grid_y
应在 OpenMP 区域中声明为
shared


0
投票

您正在计算两个大数的差异。但使用默认的实数,您无法获得足够的精度。

Compare

Total time elapsed   1717144796.8   1717144796.7 seconds.
Total time elapsed   1717144797.0   1717144796.7 seconds.
Total time elapsed   1717144797.1   1717144796.7 seconds.
Total time elapsed   1717144797.2   1717144796.7 seconds.
Total time elapsed   1717144797.4   1717144796.7 seconds.
Total time elapsed   1717144797.5   1717144796.7 seconds.
Total time elapsed   1717144797.6   1717144796.7 seconds.
Total time elapsed   1717144797.8   1717144796.7 seconds.
Total time elapsed   1717144797.9   1717144796.7 seconds.
Total time elapsed   1717144798.1   1717144796.7 seconds.
Total time elapsed   1717144798.2   1717144796.7 seconds.
Total time elapsed   1717144798.3   1717144796.7 seconds.
Total time elapsed   1717144798.5   1717144796.7 seconds.
Total time elapsed   1717144798.6   1717144796.7 seconds.
Total time elapsed   1717144798.7   1717144796.7 seconds.
Total time elapsed   1717144798.9   1717144796.7 seconds.

双精度

© www.soinside.com 2019 - 2024. All rights reserved.