如何在CUDA内核中使用Eigen

时间:2014-05-22 09:00:11

标签: c++ cuda eigen

Eigen是一个c ++线性代数库http://eigen.tuxfamily.org

使用基本数据类型(如基本浮点数组)很容易,只需将其复制到设备内存并将指针传递给cuda内核即可。但是Eigen矩阵是复杂的类型,那么如何将它复制到设备内存并让cuda内核用它来读/写呢?

4 个答案:

答案 0 :(得分:14)

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

链接问题的示例:

__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)

答案 1 :(得分:7)

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

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

答案 2 :(得分:4)

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

我无法保证它,但如果它有效,它可能正是你正在寻找的。

如果您想要更通用的解决方案,this thread似乎包含非常有用的信息

答案 3 :(得分:3)

有两种方式。

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

第二种方式更容易做,不应该破坏遗留的本征代码,而probaly是唯一适用于您的情况。将基础矩阵切换为纯矩阵(即double**)使用Eigen::Map。通过这种方式,您将拥有到普通数据类型的Eigen接口,因此代码不会中断,您可以像通常那样将矩阵作为普通的c-array发送到GPU。缺点是你可能不会充分利用Eigen,但是如果你将大部分工作卸载到GPU上就可以了。

实际上它正在扭转局面。而不是让Eigen数组在CUDA上工作,你可以让Eigen在普通数组上工作。