数据子句(当我使用 OpenACC 时输出为零)

Data Clauses (output is zero when i use OpenACC)

我想通过使用 OpenACC 来减少代码的运行时间,但不幸的是,当我使用 OpenACC 时,输出变为零。

萨贾德。**

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <openacc.h>
#include<time.h>
#include <string.h>
#include <malloc.h>

#define NX 201
#define NY 101
#define NZ 201
int main(void)
{
    int  i, j, k, l, m;
    static double   tr, w;
    static double  dt = 9.5e-9, t;
    static double cu[NZ];
    static double AA[NX][NY][NZ] , CC[NX][NY][NZ] , BB[NX][NY][NZ] ;
    static double A[NX][NY][NZ] , B[NX][NY][NZ] , C[NX][NY][NZ] ;
    FILE *file;
    file = fopen("BB-and-A.csv", "w");
    t = 0.;
    #pragma acc  data  copyin( tr, w,dt, t),copy(B ,A , C,AA , CC,BB,cu )
    {
        for (l = 1; l < 65; l++) {
            #pragma acc kernels loop private(i, j,k)
            for (i = 1; i < NX - 1; i++) {
                for (j = 0; j < NY - 1; j++) {
                    for (k = 1; k < NZ - 1; k++) {
                        A[i][j][k] = A[i][j][k]
                        + 1. * (B[i][j][k] - AA[i][j][k - 1]);
                    }
                }
            }
            #pragma acc kernels loop private(i, j,k)
            for (i = 1; i < NX - 1; i++) { /* BB */
                for (j = 1; j < NY - 1; j++) {
                    for (k = 0; k < NZ - 1; k++) {
                        B[i][j][k] =  B[i][j][k]
                        + 1.* (BB[i][j][k] - A[i - 1][j][k]);

                    }
                }
            }
            #pragma acc kernels
            for (m = 1; m < NZ - 1; m++) {
                tr = t - (double)(m)*5 / 1.5e8;
                if (tr <= 0.)
                    cu[m] = 0.;
                else {
                    w = (tr / 0.25e-6)*(tr / 0.25e-6);
                    cu[m] =1666*w / (w + 1.)*exp(-tr / 2.5e-6) ;
                    cu[m] = 2*cu[m];
                }
                A[10][60][m] = -cu[m];
            }
            #pragma acc update self(B)
            fprintf(file, "%e, %e \n", t*1e6,  -B[22][60][10] );
            t = t + dt;
        }
    }
    fclose(file);
}

这里的问题是 "copyin( tr, w,dt, t)",尤其是 "t" 变量。通过将这些标量放在数据子句中,您需要管理作为设备副本的主机之间的同步。因此,当您更新主机上的变量(即 "t = t + dt;")时,您需要使用新值更新设备副本。

此外,"tr" 上存在潜在的竞争条件,因为设备代码现在将成为共享设备变量而不是私有副本。

不过,最简单的方法就是不要将这些标量放在数据子句中。默认情况下,OpenACC 将标量私有化,因此无需自行管理它们。在 t 的情况下,它的值将作为参数传递给 CUDA 内核。

修复您的代码更改:

#pragma acc  data  copyin( tr, w,dt, t),copy(B ,A , C,AA , CC,BB,cu ) 

至:

#pragma acc  data  copy(B ,A , C,AA , CC,BB,cu )  

请注意,没有必要将循环索引放在私有子句中,因为它们是隐式私有的。