OpenACC和GNU Scientific Library - gsl_matrix的数据移动

时间:2016-10-03 02:12:24

标签: gsl openacc

我已经观看了录制的openacc概述课程视频,直到第3讲,其中讨论了表达数据移动。如何使用gsl_matrix*copy_in()从cpu移动到gpu。例如,在CPU上我可以做类似的事情,

gsl_matrix *Z = gsl_matrix_calloc(100, 100),

这将给我一个100x100的零矩阵。现在Z是指向gsl_matrix结构的指针,看起来像

typedef struct{
  size_t size1;
  size_t size2;
  size_t tda;
  double * data;
  gsl_block * block;
  int owner;
  } gsl_matrix;

如何使用copyin()表示从CPU到GPU的Z(这是一个指针)的数据移动?

1 个答案:

答案 0 :(得分:1)

我无法直接谈论在OpenACC数据和计算区域内使用GSL,但可以为您提供有关动态数据成员的聚合类型的一般答案。

假设您使用PGI编译器和更新的NVIDIA设备,首先要尝试的是CUDA统一内存(UVM)。使用标志" -ta = tesla:managed"进行编译,所有动态分配的数据都将由CUDA运行时管理,因此您不需要自己管理数据移动。有涉及的开销和警告,但它使事情更容易上手。请注意,PGI 16.9或更高版本附带的CUDA 8.0可提高UVM性能。

如果没有UVM,您需要执行数据的手动深层复制。以下是您首先在设备上创建父结构并执行浅表复制的基本概念。接下来创建动态数组" data"在设备上,将初始值复制到数组,然后将数据的设备指针附加到设备结构的数据指针。因为"阻止"它本身就是一个包含动态数据成员的结构数组,您需要遍历数组,在设备上创建它的数据数组。

    matrix * mat = (matrix*) malloc(sizeof(matrix));
    #pragma acc enter data copyin(mat)
// Change this to the correct size of "data" and blocks
    #pragma acc enter data copyin(mat.data[0:dataSize]);
    #pragma acc enter data copyin(mat.block[0:blockSize]);
    for (i=0; i < blockSize; ++i) {
       #pragma acc enter data copyin(mat.block[i].data[0:mat.block[i].size])
    }

要删除,请再次走结构,从下往上删除

for (i=0; i < blockSize; ++i) {
   #pragma acc exit data delete(mat.block[i].data)
}
#pragma acc exit data delete(mat.block);
#pragma acc exit data delete(mat.data);
#pragma acc exit data delete(mat);

更新时,请务必仅更新基本数据类型的标量或数组。即更新&#34;数据&#34;但不是&#34;阻止&#34;。更新执行浅拷贝,因此更新&#34;阻止&#34;会更新导致非法地址的主机或设备指针。

最后,一定要把矩阵变量放在&#34; present&#34;在计算区域中使用它时的子句。

#pragma acc parallel loop present(mat)