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

时间:2013-10-02 14:17:39

标签: c++ arrays vector stl cuda

我正在使用CUDA,但似乎我无法将STL向量作为参数传递,因此我需要将这些向量矩阵转换为动态数组。

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

我试图使用memcpy函数但由于某种原因它没有按预期工作,如果我尝试复制内容,原始矩阵中的一些值被更改为垃圾。 我正在避免使用循环,因为这会降低效率。

1 个答案:

答案 0 :(得分:2)

正如您所知,不可能将std::vector传递给CUDA内核并在内核代码中使用它,并且不可能传递一个简单的主机指针数组。从std::vector< std::vector<float> >构建到CUDA内核。

您需要做的是首先创建一个设备指针的主机数组(因此您复制到设备的每一行都有一个条目)以及指向该设备的指针数组的副本。这意味着您需要在复制到设备的每个矩阵行或列中调用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开销来管理它们。