【问题标题】:CudaMemCpy returns cudaErrorInvalidValue on copying vector<cv::Point3f>CudaMemCpy 在复制 vector<cv::Point3f> 时返回 cudaErrorInvalidValue
【发布时间】:2015-05-18 22:28:35
【问题描述】:

CudaMemCpy 在将向量复制到设备时返回 cudaErrorInvalidValue。我试过给 "&input", "&input[0]",... 我总是得到同样的错误但不明白为什么?

您可以使用 cudaMemcpy 复制一个向量,还是我需要先将该向量的内容复制到一个新数组中?

void computeDepthChangeMap(unsigned char* depthChangeMap, size_t size, std::vector<cv::Point3f>* input, float dcf, int width, int height)                                           {
    unsigned char* dev_depthChangeMap = 0;
    float* dev_dcf = 0;
    int* dev_wdt = 0;
    int arraySize = size;
    cv::Point3f* dev_input = 0;
    cudaError_t cudaStatus;

    cudaStatus = cudaSetDevice(0);
    cudaStatus = cudaMalloc((void**)&dev_depthChangeMap, size);
    cudaStatus = cudaMalloc((void**)&dev_input, size);
    cudaStatus = cudaMalloc((void**)&dev_dcf, sizeof(float));
    cudaStatus = cudaMalloc((void**)&dev_wdt, sizeof(int));

    cudaStatus = cudaMemcpy(dev_depthChangeMap, depthChangeMap, size, cudaMemcpyHostToDevice);
    cudaStatus = cudaMemcpy(dev_wdt, &width, sizeof(int), cudaMemcpyHostToDevice);
    cudaStatus = cudaMemcpy(dev_dcf, &dcf, sizeof(float), cudaMemcpyHostToDevice);
    cudaStatus = cudaMemcpy(dev_input, &input[0], sizeof(cv::Point3f)*size, cudaMemcpyHostToDevice);

    //cuaStatus returns cudaErrorInvalidValue >> PROBLEM HERE << 

    dim3 threadsPerBlock(8, 8); //init x, y
    dim3 numBlocks(width / threadsPerBlock.x, height / threadsPerBlock.y);

    addKernel <<<numBlocks, threadsPerBlock >>>(dev_depthChangeMap, dev_dcf, dev_input, dev_wdt);


    cudaStatus = cudaGetLastError();   
    cudaStatus = cudaDeviceSynchronize();
    cudaStatus = cudaMemcpy(depthChangeMap, dev_depthChangeMap, size, cudaMemcpyDeviceToHost);
}

__global__ void addKernel(unsigned char* dev_depthChangeMap, float* dcf, cv::Point3f* inp, int* wdt)
{
    register int row_idx = (blockIdx.x * blockDim.x) + threadIdx.x;
    register int col_idx = (blockIdx.y * blockDim.y) + threadIdx.y;
    register int idx = row_idx * (*wdt) + col_idx;

    register float depth = inp[idx].z;
    register float depthR = inp[idx + 1].z;
    register float depthD = inp[idx + *wdt].z;

    //and so on

}

【问题讨论】:

    标签: c++ opencv cuda


    【解决方案1】:

    是的,您可以使用cudaMemcpystd::vector 复制。

    您的尺寸设置不正确:

    void computeDepthChangeMap(unsigned char* depthChangeMap, size_t size, std::vector<cv::Point3f>* input, float dcf, int width, int height)                                           {
    
    ...
    cudaStatus = cudaMalloc((void**)&dev_input, size);
                                                ^^^^
    
    cudaStatus = cudaMemcpy(dev_input, &input[0], sizeof(cv::Point3f)*size, cudaMemcpyHostToDevice);
                                                         ^^^^^^^^^^^^^^^^^
    

    这些大小参数都应该以字节为单位。您不能将长度为 sizeof(cv::Point3f)*size 字节的数据复制到长度为 size 字节的分配中。

    另外,您的函数参数似乎是指向向量的指针:

    std::vector<cv::Point3f>* input,
    

    根据您显示的代码,这可能不是您想要的。您可能希望按值传递向量

    std::vector<cv::Point3f> input,
    

    或者更有可能,参考

    std::vector<cv::Point3f> &input,
    

    由于您尚未展示您打算如何调用此函数,因此无法完全确定这里最好的方法。

    【讨论】:

    • 谢谢;可能通过参考;否则我会无缘无故地创建一个新向量对吗?
    • 是的,按值传递向量涉及制作向量的副本以供函数使用。
    猜你喜欢
    • 1970-01-01
    • 2017-12-01
    • 2017-10-26
    • 1970-01-01
    • 1970-01-01
    • 2019-05-15
    • 2011-03-06
    • 2012-03-08
    • 2017-09-29
    相关资源
    最近更新 更多