微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

OpenACC:如何将 openacc 编译指示应用于“宏循环”

如何解决OpenACC:如何将 openacc 编译指示应用于“宏循环”

我定义了这些宏:

#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,"acc parallel loop private(_jbeg,_jend"){
J_LOOP(g,"acc loop"){
  U0[j][i] = Uc[j][i];
}}

使用 collapse 子句需要更多的代码重组,这再次要求 for 循环紧密嵌套

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。