繁体   English   中英

如何在CUDA内核中使用Eigen

[英]How to work with Eigen in CUDA kernels

本征是C ++线性代数库http://eigen.tuxfamily.org

使用基本数据类型(例如基本浮点数组)很容易,只需将其复制到设备内存中,然后将指针传递给cuda内核即可。 但是本征矩阵是复杂的类型,那么如何将其复制到设备内存中并让cuda内核对其进行读写操作?

自2016年11月(发行Eigen 3.3)以来,存在一个新选项: 直接在CUDA内核中使用Eigen-请参阅此问题

链接问题的示例:

__global__ void cu_dot(Eigen::Vector3f *v1, Eigen::Vector3f *v2, double *out, size_t N)
{
    int idx = blockIdx.x * blockDim.x + threadIdx.x;
    if(idx < N)
    {
        out[idx] = v1[idx].dot(v2[idx]);
    }
    return;
}

Eigen::Vector3f数组复制到设备:

Eigen::Vector3f *host_vectors = new Eigen::Vector3f[N];
Eigen::Vector3f *dev_vectors;
cudaMalloc((void **)&dev_vectors, sizeof(Eigen::Vector3f)*N)
cudaMemcpy(dev_vectors, host_vectors, sizeof(Eigen::Vector3f)*N, cudaMemcpyHostToDevice)

如果只需要通过原始C指针访问Eigen::Matrix的数据,则可以使用.data()函数。 默认情况下,系数按列主顺序或行主顺序顺序存储在内存中,如果您要求:

MatrixXd A(10,10);
double *A_data = A.data();

除了重写和修改代码外,还有一个与Eigen兼容的库,该库是作为研究项目的副产品编写的,可以在GPU上执行矩阵计算,并且可以使用多个后端: https : //github.com/rudaoshi/gpumatrix

我不能保证,但是如果它起作用了,那可能正是您要寻找的。

如果您想要一个更通用的解决方案,则该线程似乎包含非常有用的信息

有两种方法。

使本征在GPU上工作,这可能很困难,而且效果不佳。 至少如果在GPU上工作意味着只能让其编译并产生结果。 Eigen实际上是针对现代CPU进行手工优化的。 在内部,Eigen使用自己的分配器和内存布局,这些分配器和内存布局很可能在CUDA上无法正常工作。

第二种方法更容易实现,并且不应该破坏传统的Eigen代码,并且Probaly是唯一适合您的情况。 使用Eigen::Map将基础矩阵切换为普通矩阵(即double** )。 这样,您将拥有用于普通数据类型的Eigen接口,因此代码不会中断,并且可以像通常那样将矩阵作为常规c数组发送到GPU。 缺点是您可能不会充分利用Eigen的潜力,但是如果您将大部分工作转移到GPU上就可以了。

它实际上在扭转一些事情。 除了让Eigen数组在CUDA上工作外,您还可以让Eigen在普通数组上工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM