我正在尝试编写与OpenACC并行化的面向对象的C++代码。
我可以找到一些关于OpenACC的stackoverflow问题和GTC谈话,但是找不到一些面向对象代码的真实示例。

this question中,显示了一个OpenACCArray的示例,该示例在后台执行一些内存管理(代码可在http://www.pgroup.com/lit/samples/gtc15_S5233.tar处找到)。
但是,我想知道是否有可能创建一个在更高级别上管理数组的类。例如。

struct Data
{

//    OpenACCArray<float> a;

    OpenACCArray<Vector3<float>> a3;

    Data(size_t len) {
#pragma acc enter data copyin(this)
//        a.resize(len);
        a3.resize(len);
    }
    ~Data() {
#pragma acc exit data delete(this)
    }
    void update_device() {
//        a.update_device();
        a3.update_device();
    }
    void update_host() {
//        a.update_host();
        a3.update_host();
    }
};

int main(int argc, char *argv[])
{
    const size_t len = 32*128;
    Data d(len);

    d.update_device();
 #pragma acc kernels loop independent present(d)
    for (int i=0; i < len; ++i) {
     float val = (float)i/(float)len;

     d.a3[i].x = val;
     d.a3[i].y = i;
     d.a3[i].z = d.a3[i].x / d.a3[i].y;
    }
    d.update_host();
    for (int i=0; i < len/128; ++i) {
       cout << i << ": " << d.a3[i].x << "," << d.a3[i].y << "," << d.a3[i].z << endl;
    }
    cout << endl;
    return 0;
}

有趣的是,该程序可以工作,但是一旦我取消注释OpenACCArray<float> a;,即在该Data结构中添加另一个成员,我就会遇到内存错误。FATAL ERROR: variable in data clause is partially present on the device

由于OpenACCArray结构是一个平面结构,可自行处理指针的间接调用,因此应将其复制为成员吗?
还是需要成为该结构的指针,并且这些指针必须与指令进行硬连线?
然后,我担心必须使用the above mentioned question的jeff larkin建议的别名指针的问题。
我不介意为此工作而工作,但是我找不到如何执行此操作的引用。
使用编译器指令keepgpu,keepptx可以帮助您了解编译器在做什么,但是我更喜欢使用反向工程来生成ptx代码。

任何指向有用的引用项目或文档的指针都将受到高度赞赏。

最佳答案

在OpenACCArray1.h header 中,删除两个“#pragma acc enter data create(this)”编译指示。发生的事情是“数据”构造函数正在设备上创建“a”和“a3”对象。因此,当在OpenACCArray构造函数中遇到第二个Enter数据区域时,该指针已经在设备中了。

由于“a3”和“数据”为此this指针共享相同的地址,因此仅存在一个数据成员时,此方法有效。因此,当遇到第二个Enter数据编译指示时,当前检查会发现它已经在设备上,因此不再创建它。当添加“a”时,“Data”的大小是“a”的两倍,因此,当前检查发现此指针已经存在,但是大小与以前不同。这就是“部分存在”错误的含义。数据在那里,但是大小与预期不同。

只有父类/结构才能在设备上创建this指针。

希望这可以帮助,

10-08 04:51