【问题标题】:How to pass dynamic Eigen vector to GPU using Cuda?如何使用 Cuda 将动态特征向量传递给 GPU?
【发布时间】:2021-03-24 13:06:24
【问题描述】:

我将学习如何将动态特征向量传输到 GPU 并将其取回。为此,我写了一段测试代码:

    using Vector = Eigen::Matrix<float, Eigen::Dynamic, 1, Eigen::ColMajor>;
    Vector vector;
    uint64_t size = 6;

    vector.resize(size);
    for (uint64_t i = 0; i < size; ++i)
        vector[i] = i;

    uint64_t sizeInBytes = size * sizeof (float) + sizeof (vector);

    Vector *vectorCuda;
    cudaMalloc((void**)&vectorCuda, sizeInBytes);
    cudaMemcpy(vectorCuda, &vector, sizeInBytes, cudaMemcpyKind::cudaMemcpyHostToDevice);

    Vector result;
    result.resize(size);
    cudaMemcpy(&result, vectorCuda, sizeInBytes, cudaMemcpyKind::cudaMemcpyDeviceToHost);

    cudaFree(vectorCuda);
    std::cout << "result: " << std::endl << result << std::endl;

输出是:

result: 
0
1
2
3
4
5
double free or corruption (fasttop)

所以我将数据传递给 GPU 并将其取回,但我收到了 SIGABRT 错误。错误发生在std::free(ptr):

1  __GI_raise                                                                      raise.c           50   0x7ffff660b18b 
2  __GI_abort                                                                      abort.c           79   0x7ffff65ea859 
3  __libc_message                                                                  libc_fatal.c      155  0x7ffff66553ee 
4  malloc_printerr                                                                 malloc.c          5347 0x7ffff665d47c 
5  _int_free                                                                       malloc.c          4266 0x7ffff665ede5 
6  Eigen::internal::aligned_free                                                   Memory.h          177  0x555555564e14 
7  Eigen::internal::conditional_aligned_free<true>                                 Memory.h          230  0x55555556601e 
8  Eigen::internal::conditional_aligned_delete_auto<float, true>                   Memory.h          416  0x555555565820 
9  Eigen::DenseStorage<float, -1, -1, 1, 0>::~DenseStorage                         DenseStorage.h    542  0x555555565281 
10 Eigen::PlainObjectBase<Eigen::Matrix<float, -1, 1, 0, -1, 1>>::~PlainObjectBase PlainObjectBase.h 98   0x5555555650be 
11 Eigen::Matrix<float, -1, 1, 0, -1, 1>::~Matrix                                  Matrix.h          178  0x5555555650de 
12 main                                                                            main.cpp          26   0x555555564b42 

我以为是因为在空对象上调用了析构函数,但是当我注释掉该行时

//    cudaMemcpy(&result, vectorCuda, sizeInBytes, cudaMemcpyKind::cudaMemcpyDeviceToHost);

错误消失了。

那么如何解决呢?

我最近也在用 Cuda 编写代码,我的代码中可能有一些不好的行。因此,如果有经验的人注意到可能导致未来错误的东西,我会很高兴。我想将开始和结束的动态特征向量存储在堆栈中。

【问题讨论】:

    标签: c++ cuda eigen eigen3 gpu


    【解决方案1】:

    解决此问题的最简单方法是使用 Eigen data() 函数将其转换为 float* 指针,该函数返回指向矩阵中数据的原始指针。您可以将数据传输到 GPU,在那里进行处理,然后将该数据复制回来并再次将其存储在一个不错的特征矩阵中。

    #include <iostream>
    #include <cuda_runtime.h>
    #include <eigen3/Eigen/Core>
    #include <eigen3/Eigen/Dense>
    
    using Vector = Eigen::Matrix<float, Eigen::Dynamic, 1, Eigen::ColMajor>;
    
    int main(){
    Vector vector;
    uint64_t size = 6;
    
    vector.resize(size);
    for (uint64_t i = 0; i < size; ++i)
        vector[i] = i;
    
    uint64_t sizeInBytes = size * sizeof (float);
    
    float *raw_vector = vector.data();
    float *vectorCuda;
    cudaMalloc((void**)&vectorCuda, sizeInBytes);
    cudaMemcpy(vectorCuda, raw_vector, sizeInBytes, cudaMemcpyKind::cudaMemcpyHostToDevice);
    
    Vector result;
    result.resize(size);
    cudaMemcpy(result.data(), vectorCuda, sizeInBytes, cudaMemcpyKind::cudaMemcpyDeviceToHost);
    
    cudaFree(vectorCuda);
    std::cout << "result: " << std::endl << result << std::endl;
    return 0;
    
     }
    

    【讨论】:

    • 感谢您的回答。也许我的问题并不完整。我正在寻找一种将动态特征向量发送到内核的方法,因为内核中的一些函数使用它。不幸的是,我得出的结论是,唯一的方法是将数据作为 float* 指针从 data() 传输到 GPU,然后使用 Eigen::Map 将其包装在内核中。
    • 这可能是一个很好的解决方案。也许不是最优雅的,但在内核(或调用函数)内调用 eigen::map 可能不会产生显着的开销。
    猜你喜欢
    • 2023-04-04
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    相关资源
    最近更新 更多