VS2022+QT6.9配置ONNXruntime GPU、CUDA、cuDNN(附官网下载链接)(GPU开启代码示例)

本次教程就以本人电脑的RX2060举例,选择对应版本的ONNXruntime、CUDA、cuDNN,下面是具体版本和QT代码的开启GPU运行效果

一、第一步查询自己电脑显卡当前版本,查询到版本后如果不知道自己对应的ONNX、cuDNN、CUDA请拉到步骤八有对应表,然后按照步骤来,附官方下载链接

cmd命令:nvidia-smi

二、CUDA Version 11.2 兼容 ONNX Runtime v1.11.0

onnxruntime/releases

三、CUDA Version 11.2 对应 CUDA Toolkit 11.2

cuda-toolkit-archive

四、CUDA 11.2 兼容 cuDNN V8.2.0

cudnn-archive

五、下面的CUDA 11.2安装好后将cuDNN的bin 、include、lib等文件复制到 CUDA11.2中

cuda 11.2的安装路径:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2

为什么把cuDNN的这四个文件复制到CUDA中?

cuDNN(CUDA Deep Neural Network Library)是基于 CUDA 的专用加速库(专门优化深度学习算子),但它并不是 CUDA Toolkit 的默认组成部分,而是独立发布的。系统 / 框架调用 cuDNN 的前提是:CUDA Toolkit 能在其 "默认搜索路径" 中找到 cuDNN 的头文件、库文件,

六、cmd中验证CUDA是否安装成功 nvcc -V

七、新建QT项目,配置项目属性

添加包含目录:C:\Users\Administrator\Desktop\onnxruntime-win-x64-gpu-1.11.0\include

添加库目录:C:\Users\Administrator\Desktop\onnxruntime-win-x64-gpu-1.11.0\lib

链接器中输入:

onnxruntime.lib

onnxruntime_providers_cuda.lib

onnxruntime_providers_shared.lib

onnxruntime_providers_tensorrt.lib

还要把这4个dll组件放到项目根目录中

下面为验证代码,验证是否开启GPU:

QtWidgetsApplication2.h

cpp 复制代码
#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_QtWidgetsApplication2.h"
#include "onnxruntime_cxx_api.h"
#include "onnxruntime_c_api.h"
#include <QThread>
#include <vector>
#include <QTimer>

class SimpleGPUDetector;

class QtWidgetsApplication2 : public QMainWindow
{
    Q_OBJECT

public:
    QtWidgetsApplication2(QWidget *parent = nullptr);
    ~QtWidgetsApplication2();

private:
    Ui::QtWidgetsApplication2Class ui;
    SimpleGPUDetector* CUDA; // 对象
    QThread* CUDA_thread;    // 线程
};

class SimpleGPUDetector : public QObject
{
    Q_OBJECT

public:
    SimpleGPUDetector();

    // 检查CUDA是否可用的实现
    bool isCUDAAvailable() const;   

    // 检查是否有任意GPU支持的实现
    bool isAnyGPUAvailable() const; 

    // 获取可用提供者列表的实现
    std::vector<std::string> getAvailableProviders() const; 

public:
    // SessionOptions的实现
    void slotCreateGPUSessionOptions(int gpu_id);

    // 创建SessionOptions会话
    Ort::SessionOptions createGPUSessionOptionsSafe(int gpu_id) const;
    std::vector<std::string> availableProviders_; // 记录可用的执行提供者
    Ort::Env env_;                                // 环境对象
};

QtWidgetsApplication2.cpp

cpp 复制代码
#include "QtWidgetsApplication2.h"

QtWidgetsApplication2::QtWidgetsApplication2(QWidget* parent)
    : QMainWindow(parent)  
    , CUDA(nullptr)        
    , CUDA_thread(nullptr) 
{

    ui.setupUi(this);

    CUDA_thread = new QThread(this);
    CUDA = new SimpleGPUDetector();
    CUDA->moveToThread(CUDA_thread);    
    CUDA_thread->start();
}

QtWidgetsApplication2::~QtWidgetsApplication2()
{
    if (CUDA_thread && CUDA_thread->isRunning()) {
        CUDA_thread->quit();
        if (!CUDA_thread->wait(3000)) {
            CUDA_thread->terminate();
            CUDA_thread->wait();
        }
    }

    delete CUDA;
    CUDA = nullptr;
 
    delete CUDA_thread;
    CUDA_thread = nullptr;
}

// 初始化ONNX Runtime环境
SimpleGPUDetector::SimpleGPUDetector() : env_(ORT_LOGGING_LEVEL_WARNING, "GPUDetector")
{
    try {
        // 获取ONNX Runtime所有可用的执行提供者
        auto providers = Ort::GetAvailableProviders();

        // 转换为vector<string>存储
        availableProviders_ = std::vector<std::string>(providers.begin(), providers.end());

        // 遍历打印每个可用的执行提供者
        for (const auto& provider : availableProviders_) {
            qDebug() << "  - " << QString::fromStdString(provider);
        }

        // 打印CUDA和GPU可用性
        qDebug() << "CUDA可用: " << (isCUDAAvailable() ? "是" : "否");
        qDebug() << "任意GPU可用: " << (isAnyGPUAvailable() ? "是" : "否");

        // 创建SessionOptions的实现
        slotCreateGPUSessionOptions(0);
    }
    catch (const std::exception& e) {
        qCritical() << "初始化GPU检测器失败: " << e.what();
        availableProviders_.clear();
    }
}

// 检查CUDA是否可用的实现
bool SimpleGPUDetector::isCUDAAvailable() const
{
    for (const auto& provider : availableProviders_) {
        if (provider.find("CUDA") != std::string::npos) {
            return true;
        }
    }
    return false;
}

// 检查是否有任意GPU支持的实现
bool SimpleGPUDetector::isAnyGPUAvailable() const
{
    const std::vector<std::string> gpu_providers = { "CUDA", "DML", "TensorRT", "CoreML", "ROCm" };
    for (const auto& provider : availableProviders_) {
        for (const auto& gpu_p : gpu_providers) {
            if (provider.find(gpu_p) != std::string::npos) {
                return true;
            }
        }
    }
    return false;
}

// 获取可用提供者列表的实现
std::vector<std::string> SimpleGPUDetector::getAvailableProviders() const
{
    return availableProviders_;
}

// 创建SessionOptions会话
Ort::SessionOptions SimpleGPUDetector::createGPUSessionOptionsSafe(int gpu_id) const
{
    // 创建默认的SessionOptions对象:ONNX Runtime的会话配置
    Ort::SessionOptions session_options;

    //  设置图优化级别为基础级:降低优化级别,减少初始化崩溃概率
    session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_BASIC);

    // 检查CUDA是否可用
    if (isCUDAAvailable()) {
        try {
            qDebug() << "[线程" << QThread::currentThreadId() << "] 尝试配置CUDA执行提供者(GPU ID:" << gpu_id << ")";

            OrtCUDAProviderOptions cuda_options{};
            cuda_options.device_id = gpu_id;

            session_options.AppendExecutionProvider_CUDA(cuda_options);
            qDebug() << "[线程" << QThread::currentThreadId() << "] CUDA执行提供者配置成功";
        }
        catch (const Ort::Exception& e) {
            qCritical() << "配置CUDA失败: " << e.what() << "(错误码:" << e.GetOrtErrorCode() << ")";
            qWarning() << "降级为CPU执行提供者";
        }
        catch (const std::exception& e) {
            qCritical() << "配置CUDA时发生异常: " << e.what();
        }
    }
    else if (isAnyGPUAvailable()) {
        qDebug() << "[线程" << QThread::currentThreadId() << "] 使用其他GPU执行提供者";
    }
    else {
        qDebug() << "[线程" << QThread::currentThreadId() << "] 无GPU支持,使用CPU执行提供者";
    }

    return session_options;
}

// 在线程中创建SessionOptions的实现
void SimpleGPUDetector::slotCreateGPUSessionOptions(int gpu_id)
{
    bool success = false;
    try {
        // 1. 安全创建GPU版本的SessionOptions
        Ort::SessionOptions opt = createGPUSessionOptionsSafe(gpu_id);
        // 标记成功
        success = true;

        // 示例:加载模型(可选,替换为你的模型路径)
        // if (success) {
        //     Ort::Session session(env_, "your_model.onnx", opt);
        //     qDebug() << "模型加载成功";
        // }
    }
    // 捕获所有异常:避免加载模型/创建配置时崩溃
    catch (const std::exception& e) {
        qCritical() << "创建SessionOptions/加载模型失败: " << e.what();
        success = false;
    }
}

运行效果:开启GPU成功,在会话中添加模型即可使用GPU加速

八、对应表

需要注意的是CUDA Toolkit 的版本就是cmd命令 nvidia-smi 查询的 CUDA Version的版本 他们是对应的,CUDA Toolkit 是完整工具包

CUDA Toolkit 11.2 是完整安装包,其核心版本就是 11.2 ,你看到的 "CUDA Version: 11.2" 本质就是这个 Toolkit 的版本标识

相关推荐
chen_22717 小时前
动态桌面方案
c++·qt·ffmpeg·kanzi
雒珣1 天前
Qt简单任务的多线程操作(无需创建类)
开发语言·qt
qq_401700411 天前
QT C++ 好看的连击动画组件
开发语言·c++·qt
m0_635647481 天前
Qt使用第三方组件库新手教程(一)
开发语言·c++·qt
雒珣1 天前
控制QT生成目录
开发语言·qt
嘿嘿潶黑黑1 天前
Linux 安装 Qt
linux·qt
Tianwen_Burning1 天前
点云在qt的QVTKOpenGLNativeWidget控件上显示
qt·halcon3d
南桥几晴秋2 天前
QT按钮控件
开发语言·qt
Eloudy2 天前
模板函数动态库与头文件设计示例
算法·cuda