OpenACC:具有私有变量的嵌套循环

时间:2020-07-24 12:56:43

标签: openacc

我想加速这些嵌套循环。由于v的维数(NMAX = MAX(NX1,NX2,NX3)),我知道这可能是两个外部循环并行化的冲突。我尝试使用 private 子句:

  static double **v;

  if (v == NULL) {
    v = ARRAY_2D(NMAX_POINT, NVAR, double);
  }
  
  #pragma acc parallel loop present(V, U) private(v[:NMAX_POINT][:NVAR])
  for (k = kbeg; k <= kend; k++){ g_k = k;
  #pragma acc loop
  for (j = jbeg; j <= jend; j++){ g_j = j;

    #pragma acc loop collapse(2)
    for (i = ibeg; i <= iend; i++) {  
    for (nv = 0; nv < NVAR; nv++){ 
      v[i][nv] = V[nv][k][j][i];
    }}

    #pragma acc routine(PrimToCons) seq
    PrimToCons (v, U[k][j], ibeg, iend);
  }}

我得到这些错误:

Generating present(V[:][:][:][:],U[:][:][:][:])

     Generating Tesla code

    144, #pragma acc loop seq

    146, #pragma acc loop seq

    151, #pragma acc loop gang, vector(128) collapse(2) /* blockIdx.x threadIdx.x */

    154,   /* blockIdx.x threadIdx.x collapsed */

144, Accelerator restriction: induction variable live-out from loop: g_k

     Complex loop carried dependence of v->-> prevents parallelization

146, Accelerator restriction: induction variable live-out from loop: g_j

     Loop carried dependence due to exposed use of v prevents parallelization

     Complex loop carried dependence of V->->->->,v->-> prevents parallelization

g_k g_j extern int 。我以前从未见过消息“ 归纳变量从循环中退出”。

编辑: 我按照建议修改了循环,但它仍然无法工作

#pragma acc parallel loop collapse(2) present(U, V) private(v[:NMAX_POINT][:NVAR])
  for (k = kbeg; k <= kend; k++){
  for (j = jbeg; j <= jend; j++){

    #pragma acc loop collapse(2)
    for (i = ibeg; i <= iend; i++) {  
    for (nv = 0; nv < NVAR; nv++){ 
      v[i][nv] = V[nv][k][j][i];
    }}
    PrimToCons (v, U[k][j], ibeg, iend, g_gamma);
  }}

我收到此错误:

Failing in Thread:1
call to cuStreamSynchronize returned error 700: Illegal address during kernel execution

好像编译器找不到v,U或V,但是在主函数中我使用了以下指令:

#pragma acc enter data copyin(data)
 #pragma acc enter data copyin(data.Vc[:NVAR][:NX3_TOT][:NX2_TOT][NX1_TOT], data.Uc[:NX3_TOT][:NX2_TOT][NX1_TOT][:NVAR])

data.Vc和data.Uc是我要并行化的例程中的V和U。

1 个答案:

答案 0 :(得分:0)

g_k和g_j是extern int。我从未看过“归纳 变量从循环中退出”。

并行运行时,执行循环迭代的顺序是不确定的。因此,一旦退出循环,g_k和g_j的值就是发生在最后的迭代。这会产生依赖性,因为为了获得正确的答案(即与串行运行时的答案一致的答案),必须依次运行“ k”和“ j”循环。

如果“ g_k”和“ g_j”是局部变量,则编译器将隐式私有化它们以消除此依赖性。但是,由于它们是全局变量,因此必须假定代码的其他部分使用结果,因此不能假定可以将它们设为私有。如果您知道这些变量未在其他地方使用,则可以通过将其添加到“ private”子句中来解决此问题。请注意,这些变量似乎并没有在循环本身中使用,因此可以将其删除,而在循环外部仅为其分配值“ kend”和“ jend”。

除非在“ PrimToCons”子例程中使用了“ g_k”和“ g_j”?在那种情况下,您有一个更大的问题,因为这将导致争用情况,因为变量值可能会被其他线程更新,而不再是子例程期望的值。在这种情况下,解决方法是将“ k”和“ j”作为参数传递给“ PrimToCons”,而不使用“ g_k”和“ g_j”。

至于“ v”,它也应该对“ j”循环专用,而不仅仅是“ k”循环。要解决此问题,我建议在“ k”循环的编译指示中添加“ collapse(2)”子句,并删除有关“ j”循环的循环指令。

相关问题