OpenACC:如何将 openacc pragma 应用于 "macro loops"

OpenACC: How to apply openacc pragma to "macro loops"

我定义了这些宏:

#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];
  }}

但我收到 错误:此处可能无法使用此类编译指示

有什么方法可以使这个循环与宏并行化?

首先,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 循环紧密嵌套.