首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >OpenACC声明构造

OpenACC声明构造
EN

Stack Overflow用户
提问于 2020-09-11 06:11:58
回答 1查看 248关注 0票数 0

我用OpenACC编译器浏览了GPU2.6支持的特性,遇到了一个关于CPU和GPU之间内存管理的问题。

下面的Fortran代码是来自official document的修改版本

代码语言:javascript
运行
复制
module data
  integer, parameter :: maxl = 100000
  real, dimension(maxl) :: xstat
  real, dimension(:), allocatable :: yalloc
  !$acc declare create(xstat,yalloc)
end module

module useit
  use data
contains
  subroutine compute(n)
     integer :: n
     integer :: i
     !$acc parallel loop present(yalloc)
     do i = 1, n
        yalloc(i) = iprocess(i)
     enddo
  end subroutine
  real function iprocess(i)
     !$acc routine seq
     integer :: i
     iprocess = yalloc(i) + 2*xstat(i)
  end function
end module

program main

  use data
  use useit

  implicit none

  integer :: nSize = 100
  !---------------------------------------------------------------------------

  call allocit(nSize)
  call initialize

  call compute(nSize)

  !$acc update self(yalloc) 
  write(*,*) "yalloc(10)=",yalloc(10) ! should be 3

  call finalize
  
contains
  subroutine allocit(n)
    integer :: n
    allocate(yalloc(n))
  end subroutine allocit
  
  subroutine initialize
    xstat = 1.0
    yalloc = 1.0
    !$acc enter data copyin(xstat,yalloc)
  end subroutine initialize

  subroutine finalize

    deallocate(yalloc)
    
  end subroutine finalize
  
end program main

这段代码可以用nvfortran编译

代码语言:javascript
运行
复制
nvfortran -Minfo test.f90

它显示了CPU上的期望值:

代码语言:javascript
运行
复制
yalloc(10)=    3.000000

但是,在使用OpenACC编译时:

代码语言:javascript
运行
复制
nvfortran -add -Minfo test.f90

代码没有显示正确的输出:

代码语言:javascript
运行
复制
upload CUDA data  device=0 threadid=1 variable=descriptor bytes=128
upload CUDA data  device=0 threadid=1 variable=.attach. bytes=8
upload CUDA data  file=/home/yang/GPU-Collection/openacc/basics/globalArray.f90 function=initialize line=55 device=0 threadid=1 variable=.attach. bytes=8
launch CUDA kernel  file=/home/yang/GPU-Collection/openacc/basics/globalArray.f90 function=compute line=14 device=0 threadid=1 num_gangs=1 num_workers=1 vector_length=128 grid=1 block=128
download CUDA data  file=/home/yang/GPU-Collection/openacc/basics/globalArray.f90 function=main line=41 device=0 threadid=1 variable=yalloc bytes=400
 yalloc(10)=    0.000000

我试着在几个地方添加一些显式的内存移动,但都没有帮助。这真的让我很困惑。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-11 07:03:28

问题出在初始化例程中:

代码语言:javascript
运行
复制
  subroutine initialize
    xstat = 1.0
    yalloc = 1.0
    !acc enter data copyin(xstat,yalloc)
    !$acc update device(xstat,yalloc)
  end subroutine initialize

由于xstat和yalloc已经在一个数据区域( declare指令)中,第二个数据区域("enter data copyin in“)基本上被忽略(尽管引用计数器被更新)。相反,您需要使用update指令同步数据。

通过此更改,代码将获得正确的答案:

代码语言:javascript
运行
复制
% nvfortran test.f90 -acc -Minfo=accel; a.out
compute:
     14, Generating Tesla code
         15, !$acc loop gang, vector(128) ! blockidx%x threadidx%x
iprocess:
     19, Generating acc routine seq
         Generating Tesla code
main:
     41, Generating update self(yalloc(:))
initialize:
     56, Generating update device(yalloc(:),xstat(:))
 yalloc(10)=    3.000000
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63838328

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档