我是Eigen和CUDA的初学者。
我正在尝试使用Eigen Sparse Matrix在CUDA中工作,特别是我想将指向不等于0的值的指针传递给内核。
该代码有效,但输出不正确。应该是这样的
0.3 0.3 0.3
0.3 0.3 0.3
0 0 0
但我得到类似的东西:0.3 0.3 0.3 0 0 4.94066e-324 0
0.3 0.3 1.63042e-322
0 0 0
我的第二个问题是:如何仅将非0的值复制到内核中?这是代码:
#include <chrono>
#include <iomanip>
#include <iostream>
#include <random>
#include <Eigen/SparseCore>
#include <Eigen/Core>
const int BLOCK_DIM = 8;
__global__ void cu_fun(double *input, double *out, int N){
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if(idx < N){
out[idx] = input[idx]/10;
}
}
int main(){
int n = 3;
int nrow = n;
int ncol = n;
Eigen::SparseMatrix <double> spMat(n,n);
Eigen::SparseMatrix <double> out(n,n);
for(int i = 0; i < 2; i++){
for(int j = 0; j<3; j++){
spMat.insert(i,j) = 3;
}
}
const int non0 = spMat.nonZeros();
std::vector <double> value(non0);
double *dev_in = new double[non0];
double *dev_ret = new double[non0];
cudaMalloc((void **)&dev_in, sizeof(double)*non0);
cudaMalloc((void **)&dev_ret, sizeof(double)*non0);
cudaMemcpy(dev_in, spMat.valuePtr(), sizeof(double) * non0, cudaMemcpyHostToDevice);
cu_fun<<< 8,1>>>(dev_in, dev_ret, non0);
cudaMemcpy(value.data(), dev_ret, sizeof(double) * non0, cudaMemcpyDeviceToHost);
Eigen::Map<Eigen::SparseMatrix<double>> mat_map(nrow, ncol, non0, spMat.outerIndexPtr(), spMat.innerIndexPtr(), value.data());
out = mat_map.eval();
std::cout << spMat
<< "\n"
<< out;
}
最佳答案
从本征documentation报价为Eigen::SparseMatrix
您的代码假定spMat
中的所有非零条目都在spMat.valuePtr()
到spMat.valuePtr()+spMat.nonZeros()
的范围内。仅当矩阵被压缩时才会如此。您的矩阵未压缩。如果在赋值后添加对spMat.makeCompressed()
的调用,则应该发现该代码可以正常工作。修改数组构造并将其复制为非零值:
Eigen::SparseMatrix <double> spMat(n,n);
for(int i = 0; i < 2; i++){
for(int j = 0; j<3; j++){
spMat.insert(i,j) = 3;
}
}
spMat.makeCompressed();
const int non0 = spMat.nonZeros();
std::vector <double> value(non0);
double *dev_in; cudaMalloc((void **)&dev_in, sizeof(double)*non0);
double *dev_ret; cudaMalloc((void **)&dev_ret, sizeof(double)*non0);
cudaMemcpy(dev_in, spMat.valuePtr(), sizeof(double) * non0, cudaMemcpyHostToDevice);
[请注意,您包含并分配给new
和dev_in
的dev_out
调用是多余的,仅用于泄漏内存]给我这个:
$ nvcc -arch=sm_53 -std=c++11 -o eigennono -I $EIGENPATH eigennono.cu
$ ./eigennono
Nonzero entries:
(3,0) (3,1) (3,0) (3,1) (3,0) (3,1)
Outer pointers:
0 2 4 $
3 3 3
3 3 3
0 0 0
Nonzero entries:
(0.3,0) (0.3,1) (0.3,0) (0.3,1) (0.3,0) (0.3,1)
Outer pointers:
0 2 4 $
0.3 0.3 0.3
0.3 0.3 0.3
0 0 0
关于c++ - 如何在GPU内核中使用Eigen稀疏矩阵,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63174892/