哪个 OpenACC 指令将告诉编译器仅在设备上执行语句?
Posted
技术标签:
【中文标题】哪个 OpenACC 指令将告诉编译器仅在设备上执行语句?【英文标题】:Which OpenACC directive will tell compiler to execute a statement on device only? 【发布时间】:2021-01-19 11:08:11 【问题描述】:我正在学习使用 Fortran 的 OpenACC(使用 Nvidia 的一套工具),并通过将我的共轭梯度 (CG) 求解器的实现移植到 GPU 来做到这一点。
显然,我正在尝试使用以下命令在设备(GPU 内存)上保留尽可能多的数据:
27 ! Copy matrix (a_sparse), vectors (ax - b) and scalars (alpha - pap) to GPU
28 !$acc enter data copyin(a_sparse)
29 !$acc enter data copyin(a_sparse % row(:))
30 !$acc enter data copyin(a_sparse % col(:))
31 !$acc enter data copyin(a_sparse % val(:))
32 !$acc enter data copyin(ax(:), ap(:), x(:), p(:), r(:), b(:))
33 !$acc enter data copyin(alpha, beta, rho, rho_old, pap)
从那时起,构成 CG 求解器的求解算法的所有操作都通过 present
子句完成。对于 vector 操作,摘录如下:
49 !$acc parallel loop &
50 !$acc& present(r, b, ax)
51 do i = 1, n
52 r(i) = b(i) - ax(i)
53 end do
我用标量做同样的事情,例如:
87 !$acc kernels present(alpha, rho, pap)
88 alpha = rho / pap
89 !$acc end kernels
所有标量变量都在设备上。在第 87-89 行中,我尝试仅在设备上执行命令 alpha = rho / pap
,避免从主机传输任何数据或向主机传输任何数据,但 nsight-sys 分析器向我显示以下内容:
令我惊讶的是,第 87 行似乎有数据传输,在(红色“输入数据”方块)之前和之后(红色“退出数据”方块)计算构造(蓝色“Cg.f90:87”方块) )。
谁能告诉我这是怎么回事?第 87-89 行是否在设备上执行?此外,为什么这些“输入数据”和“退出数据”字段没有对应的 CUDA 命令?如果是这样,为什么主机和设备之间似乎有数据传输?如果没有,是否有一个 OpenACC 命令可以指示编译器仅在设备上执行一条不一定是循环的编程线?
我注意到数组操作也是如此,例如我在上面第 49-53 行中写的那些,那里也有一些数据传输,但我可以将其归因于应该传递给设备的变量 n
.
【问题讨论】:
【参考方案1】:它可以做一些事情。 Fortran 指定数组语法操作的右侧需要在赋值给左侧之前进行完全评估,因此编译器可能会分配一个临时数组来保存评估的结果。虽然编译器通常可以优化对临时的需求,但它可能是也可能不是问题。尝试将其设为显式循环,而不是使用数组语法来查看是否能解决问题。
第二种可能性是编译器需要复制数组描述符,因为它无法判断它们是否已更改。不过,我希望看到一些数据移动,而不仅仅是进入/退出区域。
第三种可能性是,这只是当前检查本身,它仍然调用进入/退出运行时调用。该调用不是复制数据,而是查找稍后传递给内核调用的设备指针,并且引用计数器递增/递减。
【讨论】:
以上是关于哪个 OpenACC 指令将告诉编译器仅在设备上执行语句?的主要内容,如果未能解决你的问题,请参考以下文章