带有指针的嵌套类值得openACC

时间:2018-12-27 16:23:44

标签: gpu openacc pgi pgi-accelerator

我在C ++中有一个相当大的代码,我必须将一些新类集成到基类中,如下所示。

class A
    {
    int N;
    B  b;
    double *__restrict__ w;
    construct();
    }



  A::construct()
    {
    w=new double[N];

    #pragma acc data enter create(this)
    #pragma acc update device(this)
    #pragma acc data enter create(w)
    // allocate  class A
    b.construct()
    }



  class B
    {
    double *__restrict__ u;
    double *__restrict__ v;
    B(){};
    construct();
    }
    B::construct()
    {
    u=new double[N];
    v=new double[N];
    #pragma acc data enter create(this)
    #pragma acc update device(this)
    #pragma acc data enter create(u)
    #pragma acc data enter create(v)

    }

我认为我正在遇到深度复制问题,因为类B的指针无效,因此未定义GPU上代码的行为。 对于在不涉及深度复制问题的情况下如何将类包含在另一个类中的反馈,我将不胜感激。我怀疑更新设备(此)是由某种原因引起的。

1 个答案:

答案 0 :(得分:1)

您是否有完整的示例来重新创建所看到的错误?我使用您的代码片段编写了一个小测试示例,它工作正常。 (见下文)

如果要在创建数组后更新“ this”指针,那么这将是一个问题,因为您将使用主机指针覆盖设备指针。但是,正如您上面显示的那样,这不应该成为问题。

% cat test.cpp
#include <iostream>

class B
{
        public:
                int N;
                double *__restrict__ u;
                double *__restrict__ v;
                void construct(int);
};

void B::construct(int _N)
{
        N=_N;
        u=new double[N];
        v=new double[N];
#pragma acc enter data create(this)
#pragma acc update device(this)
#pragma acc enter data create(u[:N])
#pragma acc enter data create(v[:N])
}

class A
{
        public:
                int N;
                B  b;
                double *__restrict__ w;
                void construct(int);
};

void A::construct(int _N)
{
        N=_N;
        w=new double[N];
#pragma acc enter data create(this)
#pragma acc update device(this)
#pragma acc enter data create(w[:N])

        // allocate  class A
        b.construct(N);
}


int main() {

        A myA;
        int N=32;
        myA.construct(N);

#pragma acc parallel loop present(myA)
        for (int i=0; i<N; ++i) {
                myA.w[i] = i;
                myA.b.u[i] = i;
                myA.b.v[i] = i;
        }
#pragma acc update host( myA.w[:N], myA.b.u[:N], myA.b.v[:N])
        for (int i=0; i<N; ++i) {
                std::cout << myA.w[i] << ":" << myA.b.u[i] << ":" << myA.b.v[i] << std::endl;
        }
        return 0;
}
% pgc++ test.cpp -Minfo=accel -V18.10 -ta=tesla; a.out
main:
     49, Generating present(myA)
         Accelerator kernel generated
         Generating Tesla code
         52, #pragma acc loop gang, vector(32) /* blockIdx.x threadIdx.x */
     56, Generating update self(myA.b.u[:N],myA.w[:N],myA.b.v[:N])
B::construct(int):
     21, Generating update device(this[:1])
         Generating enter data create(this[:1],v[:N],u[:N])
A::construct(int):
     41, Generating update device(this[:1])
         Generating enter data create(w[:N],this[:1])
0:0:0
1:1:1
2:2:2
3:3:3
4:4:4
5:5:5
6:6:6
7:7:7
8:8:8
9:9:9
10:10:10
11:11:11
12:12:12
13:13:13
14:14:14
15:15:15
16:16:16
17:17:17
18:18:18
19:19:19
20:20:20
21:21:21
22:22:22
23:23:23
24:24:24
25:25:25
26:26:26
27:27:27
28:28:28
29:29:29
30:30:30
31:31:31