在gfortran mac中运行openMP时出现非法指令错误

时间:2014-03-26 01:31:05

标签: macos fortran openmp gfortran

我是openMP的新手,所以请耐心等待。我使用带有OX Mavericks的macbook pro并安装了与我的操作系统兼容的gfortran版本。

我实现了一个非常简单的动态规划问题来解决经济学家称之为新古典增长模型的问题。

当我在没有openMP的情况下运行它时没有发现任何问题,但是当尝试使用-fopenmp选项编译程序时,我得到

非法指令:4或 分段错误:11

......可能我做错了。

我附上主程序,子程序,模块和.sh编译文件

PROGRAM prg_dp1

    ! PRG_DP1 SOLVES THE GROWTH MODEL BY VALUE FUNCTION ITERATION OVER A DISCRETE GRID
    ! WITHOUT INTERPOLATION. EVALUATION IS DONE OVER NEXT PERIOD CAPITAL

    ! PROBLEM: PROGRAMMED AS MATRICES IT LIMITS THE SIZE OF THE PROGRAM BEFORE !SEGMENTATION FAULTS OCCUR

    USE modvar

    IMPLICIT NONE
    REAL(DP), DIMENSION(nk) :: v,v0,kp,c
    REAL(DP), DIMENSION(nk,nk) :: cm,um,vm
    REAL(DP) :: kstar,tbegin,tend
    INTEGER :: it,ik1,ik2,ind(nk)

    ! INVOCATION OF THE OUTPUT FILES WHERE THE INFORMATION IS GOING TO BE WRITTEN
    CALL CPU_TIME(tbegin)


    ! DEFINITION OF THE PARAMETERS OF THE MODEL

    p(1)=1.0001     ! Intertemporal elasticity of substitution (SIGMA)
    p(2)=0.96       ! Intertemporal discount factor (BETA)
    p(3)=0.06       ! Depreciation rate (DELTA)
    p(4)=0.36       ! Share of capital in production (ALPHA)
    p(5)=0.00       ! (Parameter not needed)

    ! COMPUTATION OF THE STEADY STATE CAPITAL STOCK

    kstar=((1.0/p(2)-(1.0-p(3)))/p(4))**(1.0/(p(4)-1.0))

    ! FIRST I ALLOCATE AND CONSTRUCT THE GRID

    slope=1.0
    gkmin=0.0001
    gkmax=5.0*kstar
  !  ALLOCATE(gk(nk),ones(nk,nk))

    ALLOCATE(gk(nk))
!   ones=1.0
    CALL sub_grid_generation(gk,nk,slope,gkmin,gkmax)

    ! DEFINITION OF THE MATRICES OF CONSUMPTION AND UTILITY

    !$OMP PARALLEL  DEFAULT(SHARED) PRIVATE(ik1,ik2)
    !$OMP DO SCHEDULE(DYNAMIC)
    DO ik1=1,nk
        DO ik2=1,nk
            cm(ik1,ik2)=gk(ik1)**p(4)+(1.0-p(3))*gk(ik1)-gk(ik2)
        END DO
    END DO
    !$OMP END DO
    !$OMP END PARALLEL

   ! cm = gk**p(4)+(1.0-p(3))*gk-gk*ones


    WHERE (cm .le. 0.0)
        um=-1.0e+6
    ELSEWHERE
        um=(cm**(1.0-p(1))-1.0)/(1.0-p(1))
    END WHERE

    ! DINAMIC PROGRAMMING STEP

    ! I first initialize the value function to zeros

    v0=0.0

    ! Main do has to be done by master-thread ... can I parallelize more?

    DO
        !$OMP PARALLEL DO PRIVATE(ik2)
        DO ik2=1,nk
            vm(:,ik2)=um(:,ik2)+p(2)*v0(ik2)
        END DO
        !$OMP END PARALLEL DO
        v=MAXVAL(vm,DIM=2)
        print *, MAXVAL(ABS(v-v0))
        IF (MAXVAL(ABS(v-v0)) .le. dp_tol) THEN
            EXIT
        ELSE
            v0=v
        END IF
    END DO

    ind=MAXLOC(v,DIM=1)

    kp=gk(ind)
    c=gk**p(4)+(1.0-p(3))*gk-kp
    open(unit=1,file='output.txt')
    DO ik1=1,nk
        write(1,'(4F10.5)') gk(ik1),v(ik1),kp(ik1),c(ik1)
    END DO
    close(1)
    DEALLOCATE(gk)

    CALL CPU_TIME(tend)

    PRINT *, tend-tbegin

END PROGRAM prg_dp1

SUBROUTINE sub_grid_generation(grid,gsize,slope,gridmin,gridmax)
    USE nrtype
INTEGER, INTENT(IN) :: gsize
    REAL(DP), INTENT(IN) :: slope,gridmin,gridmax
REAL(DP), INTENT(OUT) :: grid(gsize)
    INTEGER :: ig   
grid(1)=gridmin
    DO ig=2,gsize
    grid(ig)=gridmin+((gridmax-gridmin)/dfloat(gsize)**slope)*dfloat(ig)**slope
    END DO

END SUBROUTINE sub_grid_generation

MODULE nrtype
    INTEGER, PARAMETER :: I4B = SELECTED_INT_KIND(9)
    INTEGER, PARAMETER :: I2B = SELECTED_INT_KIND(4)
    INTEGER, PARAMETER :: I1B = SELECTED_INT_KIND(2)
    INTEGER, PARAMETER :: SP = KIND(1.0)
    INTEGER, PARAMETER :: DP = KIND(1.0D0)
    INTEGER, PARAMETER :: SPC = KIND((1.0,1.0))
    INTEGER, PARAMETER :: DPC = KIND((1.0D0,1.0D0))
    INTEGER, PARAMETER :: LGT = KIND(.true.)
    REAL(SP), PARAMETER :: PI=3.141592653589793238462643383279502884197_sp
    REAL(SP), PARAMETER :: PIO2=1.57079632679489661923132169163975144209858_sp
    REAL(SP), PARAMETER :: TWOPI=6.283185307179586476925286766559005768394_sp
    REAL(SP), PARAMETER :: SQRT2=1.41421356237309504880168872420969807856967_sp
    REAL(SP), PARAMETER :: EULER=0.5772156649015328606065120900824024310422_sp
    REAL(DP), PARAMETER :: PI_D=3.141592653589793238462643383279502884197_dp
    REAL(DP), PARAMETER :: PIO2_D=1.57079632679489661923132169163975144209858_dp
    REAL(DP), PARAMETER :: TWOPI_D=6.283185307179586476925286766559005768394_dp
    REAL(DP), PARAMETER :: gr=(5.0**0.5-1.0)/2.0
    TYPE sprs2_sp
        INTEGER(I4B) :: n,len
        REAL(SP), DIMENSION(:), POINTER :: val
        INTEGER(I4B), DIMENSION(:), POINTER :: irow
        INTEGER(I4B), DIMENSION(:), POINTER :: jcol
    END TYPE sprs2_sp
    TYPE sprs2_dp
        INTEGER(I4B) :: n,len
        REAL(DP), DIMENSION(:), POINTER :: val
        INTEGER(I4B), DIMENSION(:), POINTER :: irow
        INTEGER(I4B), DIMENSION(:), POINTER :: jcol
    END TYPE sprs2_dp
END MODULE nrtype

MODULE modvar
    USE nrtype
    IMPLICIT NONE
    REAL(DP), PARAMETER :: r_tol=1e-8
    REAL(DP), PARAMETER :: p_tol=1e-6

    REAL(DP), PARAMETER :: dp_tol=1e-6
    REAL(DP), PARAMETER :: c_tol=0.001
    REAL(DP), PARAMETER :: adj=0.5

    INTEGER, PARAMETER :: r_m=10000

    ! PARAMETER THAT DEFINE THE DIMENSION OF THE PROBLEM

    INTEGER, PARAMETER :: nk=5000
    INTEGER, PARAMETER :: nz=21
    INTEGER, PARAMETER :: np=20000
    INTEGER, PARAMETER :: nt=5000

    INTEGER, PARAMETER :: maxit=10000

    INTEGER, PARAMETER :: dist_maxit=5000

    ! POLICY PARAMETER, COMMON ENDOGENOUS VARIABLES AND OTHER ALLOCATABLE ARRAYS

    REAL(DP), PARAMETER :: nw=0.0
    REAL(DP), PARAMETER :: ft=0.33
    REAL(DP) :: p(5),gkmin,gkmax,slope
    REAL(DP), ALLOCATABLE :: gk(:),gz(:),m(:,:),mss(:),ones(:,:)
END MODULE modvar

和我用来编译的.sh文件

export OMP_NUM_THREADS=8
gfortran -O2 -fopenmp -c nrtype.f90 modvar.f90 sub_grid_generation.f90 prg_dp1.f90

gfortran -O2 -fopenmp -fcheck=bounds -o myprog nrtype.o modvar.o sub_grid_generation.o prg_dp1.o

我知道这很乏味但我会感激一些帮助

谢谢

2 个答案:

答案 0 :(得分:3)

其他选项是使全局数组cm,um,vm,也可能是较小的其他数组,可分配。当您更改问题大小,从某处读取并维护可执行文件时,这将变得很方便。

REAL(DP), DIMENSION(:,:),allocatable :: cm,um,vm

allocate(cm(nk,nk),um(nk,nk),vm(nk,nk))

答案 1 :(得分:2)

这是一个堆栈空间问题。我尝试使用ifort运行它,即使没有openmp我也得到非法指令,我必须指定-heap-arrays才能让它正常运行。一旦我添加了openmp,就会出现非法指令错误。 WHERE语句似乎是问题代码。在openmp和非openmp运行中都是导致它失败的部分

OS X堆栈空间相当有限,您正在创建大型数组。使用-heap-arrays有帮助,但是一旦你使用openmp不再可能,ulimit最多可以达到~64 MB。

我发现将此添加到您的编辑工作中:

-Wl,-stack_size,0x40000000,-stack_addr,0xf0000000

将堆栈大小增加到1GB。这可能是微调,但我尝试使用256 MB,但仍然不够。