C++11+fortran+OpenACC移植程序从核报错



  • 求大神指点~~

    程序概况

    我目前移植的应用是c++11编写的, 规模在数十万行,数值计算密集部分使用fortran编写,该程序在x86机器上使用valgrind检测没有内存泄漏。现在程序在主核上c++11使用gcc530, fortran用swafort -host编译然后链接,可以正常运行。

    编译配置:

    C++11部分采用module load sw提供的mpiswg++编译器, 开启-std=gnu++11-mhybrid选项。
    fortran部分采用系统默认的swafort编译器, 开启-fpe3

    链接选项:

    "\
     -L/usr/sw-mpp/mpi2/mpiswgcc/lib -L/usr/sw-mpp/lib \
     -lmpifort -lgfortran -lgfortran_slave -lslave -lathread -lmaster -lc_slave -lglibc_slave \
     -L/usr/sw-mpp/swacc/swacc-2.0.0-1458-fix-1473/lib/sw5 \
     -Wl,-zmuldefs -static -lswacc_host -lswacc_slave -lm_slave \
     -L/usr/sw-mpp/swcc/swgcc530-tools/usr_sw5/lib -lslave \
     -L/usr/sw-mpp/swcc/lib/gcc-lib/sw_64-swcc-linux/5.421-sw-500/lib \
     -lfortran_slave -lfortran -lffio -lffio_slave "
    

    错误信息

    在fortran中加入OpenACC指导语句之后, 程序会报各种问题, 比如在一个完美嵌套循环上加一个OpenACC, 程序就会报段错误, 循环代码和报错信息如附录所示。
    示例代码:

    c$acc parallel loop copyout(dux)
          DO K=ifirst1,ilast1
            DO J=ifirst0,ilast0
              DO L=1,4
                 DUX(J,K,L)= 0.0
             ENDDO
            ENDDO
          ENDDO
    c$acc end parallel loop
    

    其中一种错误:

    CATCHSIG: Myid = 0(CPU    8,CG 0), si_signo = 11(Segmentation Fault: PC = 0x4ff04642f8)
    [vn000008:mpi_rank_0][MPIDI_CH3_Abort] application called MPI_Abort(MPI_COMM_WORLD, 1000) - process 0: Invalid argument (22)
    

    目前的尝试

    我做过一些尝试:

    • 在主核的c++代码上添加一些打印语句也会影响报错类型,目前发现的报错包括:

      1. SPDE Error
      2. Fload Point Exception
      3. Segmentation Fault
      4. DMA descriptor examination
    • 有时在完美嵌套循环上加collapse可以使原本报spde error的程序正常运行, 但有些代码段不加collapse可以正常运行但加了collapse反而会报错。

    • 尝试使用swacc生成中间代码, 然后用gcc530编译主从核代码, 问题依然存在, 与用swacc编译产生的结果一致。

    • 在已经出错(比如FPE)的acc加速区内, 添加打印语句, 从核没有打印输出, 但程序可以正常运行了。

    • 尝试将fortran的数值内核单独摘出来,使用简单的c++11代码(约70行)调用数值内核,使用与主程序相同的链接脚本和编译器套件, acc加速部分工作正常且有加速, 从核可以正常打印, 添加的各种copyin、local、collapse等均可以正常工作。


    2020/07/24更新:
    * 使用athread重新改写从核代码, 从核直接访问主存程序可以运行,直接访问主存可以正确赋值, 但在调试过程中发现, 添加打印语句write(*,*) my_id会报SDLB错。报错信息如下:

    +------------------------------------------------------------------------------+
    |                           CPE Exception Encountered                          |
    +------------------------------------------------------------------------------+
    SDLB Exception Happended
    +------------------------------------------------------------------------------+
    |                              Decoding CPE spots                              |
    +------------------------------------------------------------------------------+
    Last function spawned 4ff04109c0
    +------------------------------------------------------------------------------+
    |                               Decode of CPE PCs                              |
    +------------------------------------------------------------------------------+
      0:  4ff0444bf0   1:  4ff0436758   2:  4ff0436758   3:  4ff0436758   4:  4ff0436758   5:  4ff0436758   6:  4ff0436758   7:  4ff0436758
      8:  4ff0436760   9:  4ff0436760  10:  4ff0436760  11:  4ff0436758  12:  4ff0436758  13:  4ff0436758  14:  4ff0436760  15:  4ff0436760
     16:  4ff0436758  17:  4ff0436760  18:  4ff0436758  19:  4ff0436760  20:  4ff0436758  21:  4ff0436760  22:  4ff0436758  23:  4ff0436760
     24:  4ff0436760  25:  4ff0436758  26:  4ff0436760  27:  4ff0436758  28:  4ff0436758  29:  4ff0436758  30:  4ff0436760  31:  4ff0436758
     32:  4ff0436758  33:  4ff0436758  34:  4ff0436760  35:  4ff0436758  36:  4ff0436760  37:  4ff0436760  38:  4ff0436758  39:  4ff0436758
     40:  4ff0436758  41:  4ff0436760  42:  4ff0436760  43:  4ff0436758  44:  4ff0436760  45:  4ff0436758  46:  4ff0436760  47:  4ff0436760
     48:  4ff0436760  49:  4ff0436758  50:  4ff0436758  51:  4ff0436758  52:  4ff0436760  53:  4ff0436760  54:  4ff0436760  55:  4ff0436758
     56:  4ff0436758  57:  4ff0436760  58:  4ff0436758  59:  4ff0436758  60:  4ff0436758  61:  4ff0436760  62:  4ff0436758  63:  4ff0436758
    +------------------------------------------------------------------------------+
    |                           Decode of SDLB error spot                          |
    +------------------------------------------------------------------------------+
    TC_SDLB_ERR_SPOT: 2c0200700001c920
    REQ_TYPE: read
    TC_SDLB_REQ_ADDR: 700001c920
    SRC_PE: 0
    GRAIN: 1
    SRC_TYPE: cpe
    OUT_OF_RANGE: yes
    OUT_OF_PERM: no
    

    2020/07/25更新:

    • 在程序中只对一个fortran的赋值循环添加openacc指导语句并不添加任何copy操作(没有DMA?)程序可以运行, 但赋的值与主核运行时的赋值不一致: 下文中的循环是将tracergt0tracelft0赋值为1.0, 主核使用swafort -host编译打印得到的结果均是1.0, 但打开openacc之后, 用swafort编译, 得到两个数组在赋值之后得到的数组内有大量其他不正常数字, 如8.33833108929440958E-2等。
    c$acc parallel loop
          do  ic2=ifirst2-FACEG,ilast2+FACEG
             do  ic1=ifirst1-FACEG,ilast1+FACEG
               ie0=ifirst0-FACEG
               tracergt0(ie0,ic1,ic2)=1.0
               tracelft0(ie0,ic1,ic2)=1.0
    
    
               do  ie0=ifirst0+1-FACEG,ilast0+FACEG
                 tracelft0(ie0,ic1,ic2)=1.0
                 tracergt0(ie0,ic1,ic2)=1.0
               enddo
    
               ie0=ilast0+FACEG+1
               tracelft0(ie0,ic1,ic2)=1.0
               tracergt0(ie0,ic1,ic2)=1.0
             enddo
          enddo
    c$acc end parallel loop
    


  • 代码好长,我有阅读Fortran恐惧症,建议是你首先在逻辑上研究一下有没有并行写,就是最外层循环的两个下标有对数组同一个位置的更新。
    另外你刚开始那个代码我觉得珠海要是循环顺序的问题。考虑试一下:

    DO L=1,4
    c$acc parallel loop
      DO K=ifirst1,ilast1
    c$acc data copyout(dux(:, k, l))
        DO J=ifirst0,ilast0
          DUX(J,K,L)= 0.0
        ENDDO
    c$acc end data
      ENDDO
    c$acc end parallel loop
    ENDDO
    


  • loop不能和copy配合


登录后回复