OpenACC:如何将 openacc pragma 应用于“宏循环”
Posted
技术标签:
【中文标题】OpenACC:如何将 openacc pragma 应用于“宏循环”【英文标题】:OpenACC: How to apply openacc pragma to "macro loops" 【发布时间】:2021-09-23 06:11:19 【问题描述】:我定义了这些宏:
#define I_LOOP(g, i) _ibeg = g->lbeg[IDIR]; _iend = g->lend[IDIR]; \
for (i = _ibeg; i <= _iend; i++)
#define J_LOOP(g, j) _jbeg = g->lbeg[JDIR]; _jend = g->lend[JDIR]; \
for (j = _jbeg; i <= _jend; j++)
我有这个循环我想并行化
#pragma acc parallel loop collapse(2)
I_LOOP(g, i)
J_LOOP(g, j)
U0[j][i] = Uc[j][i];
但我收到错误:此处可能无法使用这种编译指示。
有没有办法让这个循环与宏并行化?
【问题讨论】:
【参考方案1】:首先,OpenACC loop
要求 for
循环在其中紧密嵌套,即没有前面的 _ibeg
、_iend
分配。
其次,对于这种#define
的用法,你也许可以用_Pragma
做点什么(见https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html 等):
#define I_LOOP(g, i) _ibeg = g->lbeg[IDIR]; _iend = g->lend[IDIR]; \
_Pragma("acc parallel loop private(_jbeg, _jend") \
for (i = _ibeg; i <= _iend; i++)
#define J_LOOP(g, j) _jbeg = g->lbeg[JDIR]; _jend = g->lend[JDIR]; \
_Pragma(acc loop) \
for (j = _jbeg; j <= _jend; j++)
(未经测试;您没有提供独立示例。)
(请注意,我还修正了i <= _jend
错字。)
通过#define DO_PRAGMA(x) _Pragma(#x)
进行间接可能会很有用:
#define DO_PRAGMA(x) _Pragma(#x)
#define I_LOOP(g, i, pragma) _ibeg = g->lbeg[IDIR]; _iend = g->lend[IDIR]; \
DO_PRAGMA(pragma) \
for (i = _ibeg; i <= _iend; i++)
#define J_LOOP(g, j, pragma) _jbeg = g->lbeg[JDIR]; _jend = g->lend[JDIR]; \
DO_PRAGMA(pragma) \
for (j = _jbeg; j <= _jend; j++)
...,然后:
I_LOOP(g, i, "acc parallel loop private(_jbeg, _jend")
J_LOOP(g, j, "acc loop")
U0[j][i] = Uc[j][i];
使用collapse
子句需要更多代码重组,这又要求for
循环紧密嵌套。
【讨论】:
以上是关于OpenACC:如何将 openacc pragma 应用于“宏循环”的主要内容,如果未能解决你的问题,请参考以下文章