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

使用ONNX Runtime C++ API能否在GPU内将cudaArray转为Ort::Value?

可行,可通过ONNX Runtime CUDA执行提供者(EP)结合CUDA内存互操作实现全程GPU内数据流转
  • 前提准备
    确保你使用的ONNX Runtime是编译/安装了CUDA EP的版本,这是实现GPU内存直接复用的基础。

  • cudaArray转CUDA线性设备内存
    ONNX Runtime的Ort::Value更适配线性CUDA设备内存,而cudaArray属于二维纹理内存,需要先在GPU内部完成格式转换:通过cudaMemcpy2DFromArray将cudaArray的数据复制到预分配的CUDA线性内存中,这个操作全程在GPU上执行,不会将数据传输到CPU。
    示例代码:

    // 已知cudaArray、图像宽高、数据格式(如RGB uint8)
    int img_width = ...;
    int img_height = ...;
    size_t linear_pitch;
    uint8_t* d_linear_buf;
    
    // 分配CUDA线性设备内存(带对齐处理)
    cudaMallocPitch(&d_linear_buf, &linear_pitch, img_width * 3, img_height);
    // GPU内数据拷贝:cudaArray -> 线性内存
    cudaMemcpy2DFromArray(d_linear_buf, linear_pitch, cudaArray, 0, 0, img_width * 3, img_height, cudaMemcpyDeviceToDevice);
    
  • 基于CUDA内存创建Ort::Value
    利用ONNX Runtime的CUDA内存信息对象,直接绑定已有的CUDA线性内存来构建Ort::Value,无需数据回传CPU:
    示例代码:

    // 创建CUDA内存信息,指定内存来自CUDA设备
    auto cuda_mem_info = Ort::MemoryInfo::CreateCuda(OrtDeviceAllocator, OrtMemTypeDefault);
    // 定义模型输入张量的形状(示例为NHWC格式:batch=1, 高, 宽, 通道数3)
    std::vector<int64_t> input_shape = {1, img_height, img_width, 3};
    // 直接基于CUDA设备指针创建Ort::Value
    Ort::Value input_tensor = Ort::Value::CreateTensor<uint8_t>(
        cuda_mem_info,
        d_linear_buf,
        img_height * linear_pitch, // 按实际分配的内存字节数传入
        input_shape.data(),
        input_shape.size()
    );
    
  • 关键注意事项

    • 内存生命周期:ONNX Runtime默认不会自动释放你手动分配的CUDA线性内存,因此在Ort::Value不再使用后,需要自行调用cudaFree(d_linear_buf)释放内存;若希望由ONNX Runtime接管内存管理,可以改用ONNX Runtime提供的CUDA内存分配接口来申请线性内存。
    • 数据格式匹配:确保cudaArray转换后的线性内存数据格式(通道顺序、数据类型、对齐方式)与ONNX模型的输入要求完全一致,否则会导致推理结果异常。
    • CUDA上下文一致性:要保证DX11-CUDA互操作使用的CUDA上下文,与ONNX Runtime CUDA EP使用的上下文为同一个,避免出现内存访问权限错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 17:20:02