c++ - CudaMemCpy 在复制 vector<cv::Point3f> 时返回 cudaErrorInvalidValue

标签 c++ opencv cuda

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

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

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

}

最佳答案

是的,您可以使用 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 字节的分配中。

此外,您的函数参数似乎是指向 vector 的指针:

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

根据您显示的代码,这可能不是您想要的。您可能想要按值传递 vector :

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

或者更有可能,通过引用:

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

由于您还没有展示您打算如何调用此函数,因此无法完全确定此处的最佳方式。

关于c++ - CudaMemCpy 在复制 vector<cv::Point3f> 时返回 cudaErrorInvalidValue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30304764/

相关文章:

cuda使用常量内存作为二维数组

c++ - CUDA cudaMemcpy 数组结构

c++ - 通用 lambda 与标准模板函数(使用什么以及何时使用)

c++ - 服务器和客户端之间建立了连接,但无法通过 J2ME 中的 OutputStream 发送数据

c++ - OpenCV 中 1 平面图像的位平面仅适用于图像的 1/3

Python 使用正确的设备名称在 Windows 10 中显示 OpenCV 视频

c++ - CUDA: __device__ and __global__ error: expected constructor, destructor, or type conversion before "unsigned"/"void"”

c++ - C++中的纯虚析构函数

c++ - 如何返回目录的末尾

python - 执行 OCR 的技巧 - 没有得到想要的结果