【问题标题】:Is it possible to get pointers to the real and imaginary parts of a cuDoubleComplex?是否有可能获得指向 cuDoubleComplex 的实部和虚部的指针?
【发布时间】:2018-08-27 02:28:00
【问题描述】:

考虑设备内存中的cuDoubleComplex 数组a。是否有可能获得指向a 的实部和虚部的指针,而无需分配并执行深度复制到两个新的double 数组中?

类似这样的:

real_a = //points to real part of a
imag_a = //points to imaginary part of a

而不是类似的东西:

/*allocate real_a and imag_a here */
    for(int j=0; j<numElements; j++){
        real_a[j]= a[j].x;
        imag_a[j]= a[j].y;
}

CUDA does have something like this for numbers,但不适用于数组/指针。

原因是我希望能够分别在实部和虚部上调用 cuBLAS D 而不是 Z 函数。例如,

cublasDgemm(...,real_a,...,somearray,...,anotherarray,...)

【问题讨论】:

  • 嗯...所有虚部(同样是实部)都应该以固定的步幅间隔开,因此理论上您可以将每个虚部的地址计算为 base + index * stride 用于迭代器...也许如果您告诉我们为什么需要将复数数组的组件分成两个数组,而不是将它们留在a[] 中并根据需要访问,我们可以提供更好的帮助。
  • 好的,我实际上需要它们作为连续块,因为我将在它们上调用 cuBLAS 函数。根据您的建议,我已在问题中添加了更多详细信息。
  • 请注意,您链接到的是 JCUDA 文档,这基本上只是为了实现 java 和 CUBLAS/CUFFT 使用的 C 类型之间的互操作性

标签: cuda


【解决方案1】:

是否有可能获得指向实部和虚部的指针 没有分配和做一个深拷贝到两个新的双数组?

这是可以做到的:

double* real_a = reinterpret_cast<double*>(&a[0].x); //points to real part of a
double* imag_a = reinterpret_cast<double*>(&a[0].y); //points to imaginary part of a

但请注意,在访问指针以获取正确的实部或虚部时,您需要使用 2 的步幅。

原因是我希望能够调用 cuBLAS D 而不是 比 Z 函数分别作用于实部和虚部。

这将适用于将实指针或虚指针作为向量进行操作的 BLAS 函数,因为这些 BLAS 例程允许传递一个步幅(在这种情况下必须是两个)。

例如,

cublasDgemm(...,real_a,...,somearray,...,anotherarray,...)

这不适用于您可以直接获得的指针,如我在此处所示。将数组视为矩阵的 BLAS 函数确实支持跨步的源数据和目标数据,但是跨步应用于具有展平矩阵的每一列的开头,而不是应用于列中的元素,这是您需要做的这工作正常。

【讨论】:

  • 很好的建议。我想对于 3 级 BLAS 函数,唯一的选择是深拷贝?
  • 如果您要使用以传统 BLAS 为模型的封闭源代码库(如 CUBLAS),那么深拷贝可能是唯一的方法。如果您愿意修改 DGEMM 内核的源代码以使用跨步指针类而不是指向 double 的普通指针,那么您可能会做您想做的事。那么问题将是性能之一。是一个简单的 GEMM,它比具有深拷贝的最佳 GEMM 更快地访问内存。基准测试可以回答这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-23
  • 1970-01-01
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多