如何将stl向量矩阵转换为2d阵列矩阵(或1d阵列)

问题描述:

我正在使用CUDA,但似乎我无法将STL向量作为参数传递,因此我需要将这些向量矩阵转换为动态数组。如何将stl向量矩阵转换为2d阵列矩阵(或1d阵列)

std::vector< std::vector<float> > some_matrix;float **f;

我试图用memcpy函数,但由于某种原因,如期望的那样,如果我尝试复制内容的简化版,工作,有的在原有的矩阵值的改变垃圾。 我避免使用循环,因为那会降低效率。

+0

你以前是怎么做的?您可以显示您的代码,并让其他人帮助修复这些错误(如果有的话)。 – kangshiyin

+0

std :: vector仅供主机使用。我会推荐使用推力库。 – JackO*

+0

好吧,我要试一试。 –

正如您发现的那样,不可能将std::vector传递给CUDA内核并在内核代码中使用它,并且不可能将您可能构建的简单的主机指针数组传递给也可以将CUDA内核编号为std::vector< std::vector<float> >

你需要做的是首先创建一个设备指针的主机数组(这样你复制到设备的每一行就有一个条目),并且复制指向设备的指针数组。这意味着您需要为复制到设备的每个矩阵行或列调用cudaMalloc和cudaMemcpy调用。你可以做这样的:

std::vector< std::vector<float> > some_matrix; 

float** f = new float*[some_matrix.size()]; 
for (int i = 0; i < some_matrix.size(); ++i) { 
    size_t szp = sizeof(float) * some_matrix[i].size(); 
    float* p; 
    cudaMalloc((void **)&p, sz); 
    cudaMemcpy(p, &some_matrix[i][0], szp, cudaMemcpyHostToDevice); 
    f[i] = p; 
} 

float** f_dev; 
size_t szf = sizeof(float*) * some_matrix.size(); 
cudaMalloc((void **)&f_dev, szf); 
cudaMemcpy(f_dev, f, szf, cudaMemcpyHostToDevice); 

[免责声明:写在浏览器中,从来没有编译或测试,使用风险自担]

在此之后f_dev可以安全地传递到CUDA内核和所使用的设备。

希望你能从上面的代码中看到为什么这种数据结构在GPU上不太容易使用。有很多API开销来设置并传输它,然后在设备上存在延迟惩罚,因为要将值提取到内存所需的双指针间接寻址。

对于源数据不是“锯齿状数组”的情况(即矩阵中所有行都是相同长度的情况),存储在线性存储器中的扁平列主要或行主要数组是更好的解决方案。如果源数组锯齿状,请考虑使用类似于CSR或CSC稀疏矩阵格式的结构。这些在设备上并没有提供太多的性能改进,但是它们减少了主机端API开销来管理它们。