You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CUDA调用OpenCV图像处理核函数遇非法内存访问错误求助

问题原因及修复方案

你代码的核心错误出在核函数参数使用了引用类型,不符合CUDA核函数的参数传递规则。

错误原因

CUDA核函数的所有参数默认会拷贝到设备端的专属参数内存中,若将参数声明为引用类型,实际传递给核函数的是主机侧变量的内存地址:

  • 你传入的dimage是主机栈上存储的设备指针变量,unsigned char *&pimage相当于引用主机侧的dimage变量本身
  • const int &cn、const size_t &total同理,引用的是主机栈上的cn、total变量

设备代码没有权限访问主机端的虚拟地址空间,所以内核一启动就触发非法内存访问,直接执行失败,这也是你看不到内核printf输出、后续cudaMemcpy、cudaFree操作都跟着报错的原因。

修复方案

把核函数的所有参数改为值传递即可,修改后的核函数代码如下:

__global__ void makeGrey(
    unsigned char *pimage,
    const int cn,
    const size_t total)
{
    unsigned i = blockDim.x * blockIdx.x + threadIdx.x;
    unsigned icn = i * cn;

    printf("%u\n", i);

    if (i < total)
    {
        float result = pimage[icn + 0] * .114 +
                       pimage[icn + 1] * .587 +
                       pimage[icn + 2] * .299;
        pimage[icn + 0] = result; //B
        pimage[icn + 1] = result; //G
        pimage[icn + 2] = result; //R
        // pimage[icn + 3] *= result; //A 4通道图像可取消该注释
    }
}

额外注意事项

  • 如果输入图像是带alpha通道的4通道图,记得取消alpha通道赋值的注释,避免alpha通道保留原值导致输出图像和预期不符
  • CUDA核函数仅支持传入设备侧变量的引用,主机侧变量一律使用值传递,或者先把变量拷贝到设备内存再传设备指针

内容的提问来源于stack exchange,提问作者Hakan Demir

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 15:36:02