在qtcreator中cuda驱动初始化和使用、上下文管理设置,使用驱动API进行内存分配

cuInit-驱动初始化

1.cuInit用于初始化驱动API,如果不执行,cuda的所有API都会返回错误,全局执行一次就行
2.不需要cuDestroy,程序会自动销毁并释放

获取驱动版本、设备名称

1.cuDriverGetVersion(&driver_version):运行cuDriverGetVersion,驱动版本赋值给driver_version
2.cuDeviceGetName(device_name, sizeof(device_name), device):运行cuDeviceGetName,即可设备名称

在qt中实战一

在pro中,

#cuda cudnn
INCLUDEPATH += /usr/local/cuda/include
LIBS += -L/usr/local/cuda/lib64
LIBS += -lcuda  #要添加这个哦,不然会出现error: undefined reference to `cuInit'的错误
  #include <stdio.h>
    #include <stdlib.h>
    #include <cuda.h>

    int main(int argc, char const *argv[])
    {
        // 1. 任何驱动API调用之前必须先初始化
        CUresult re = cuInit(0);
        if (re != CUDA_SUCCESS){
            printf("cuda设备初始化失败!\n");
            exit(EXIT_FAILURE);
        }
        printf("cuda设备初始化成功!\n");
        // 2. 获取版本
        int cu_version;
        re = cuDriverGetVersion (&cu_version);
        if(re == CUDA_SUCCESS){
            printf("获取版本是:%d\n", cu_version);
        }else{
            printf("获取版本失败!\n");
        }
        return 0;
    }

}

参考:https://www.jianshu.com/p/15dc69405791?from=timeline

上下文管理设置

1.context是一种上下文,管理对gpu上所有的操作
2.一般来说,一个线程基本固定访问一个显卡,且只使用一个context
3.使用cuDevicePrimaryCtxRetain,为设备关联主context,分配、释放、设置(第一次调用cuDevicePrimaryCtxRetain,则会生成新的context;往后的调用都会用第一次调用的context)

在qt中实战二

// CUDA驱动头文件cuda.h
#include <cuda.h>   // include <> 和 "" 的区别    
#include <stdio.h>  // include <> : 标准库文件 
#include <string.h> // include "" : 自定义文件  详细情况请查看 readme.md -> 5

#define checkDriver(op)  __check_cuda_driver((op), #op, __FILE__, __LINE__)

bool __check_cuda_driver(CUresult code, const char* op, const char* file, int line){
    if(code != CUresult::CUDA_SUCCESS){    // 如果 成功获取CUDA情况下的返回值 与我们给定的值(0)不相等, 即条件成立, 返回值为flase
        const char* err_name = nullptr;    // 定义了一个字符串常量的空指针
        const char* err_message = nullptr;  
        cuGetErrorName(code, &err_name);    
        cuGetErrorString(code, &err_message);   
        printf("%s:%d  %s failed. \n  code = %s, message = %s\n", file, line, op, err_name, err_message); //打印错误信息
        return false;
    }
    return true;
}

int main(){
     // 1. 任何驱动API调用之前必须先初始化
     CUresult re = cuInit(0);
     CUdevice device = 0;
    // 使用cuDevicePrimaryCtxRetain获取与设备关联的context
     CUcontext ctxA = nullptr;  
    checkDriver(cuDevicePrimaryCtxRetain(&ctxA, device));       // 在 device 上指定一个地址对ctxA进行管理
    printf("ctxA = %p\n", ctxA);
    checkDriver(cuDevicePrimaryCtxRelease(device));
    return 0;
}

使用驱动API进行内存分配

// CUDA驱动头文件cuda.h
#include <cuda.h>

#include <stdio.h>
#include <string.h>

#define checkDriver(op)  __check_cuda_driver((op), #op, __FILE__, __LINE__)

bool __check_cuda_driver(CUresult code, const char* op, const char* file, int line){

    if(code != CUresult::CUDA_SUCCESS){    
        const char* err_name = nullptr;    
        const char* err_message = nullptr;  
        cuGetErrorName(code, &err_name);    
        cuGetErrorString(code, &err_message);   
        printf("%s:%d  %s failed. \n  code = %s, message = %s\n", file, line, op, err_name, err_message);   
        return false;
    }
    return true;
}

int main(){

    // 检查cuda driver的初始化
    checkDriver(cuInit(0));

    // 创建上下文
    CUcontext context = nullptr;
    CUdevice device = 0;
    checkDriver(cuCtxCreate(&context, CU_CTX_SCHED_AUTO, device));
    printf("context = %p\n", context);

    // 输入device prt向设备要一个100 byte的线性内存,并返回地址
    CUdeviceptr device_memory_pointer = 0;
    checkDriver(cuMemAlloc(&device_memory_pointer, 100)); // 注意这是指向device的pointer, 
    printf("device_memory_pointer = %p\n", device_memory_pointer);

    // 输入二级指针向host要一个100 byte的锁页内存,专供设备访问
    float* host_page_locked_memory = nullptr;
    checkDriver(cuMemAllocHost((void**)&host_page_locked_memory, 100));
    printf("host_page_locked_memory = %p\n", host_page_locked_memory);

    // 向page-locked memory 里放数据(仍在CPU上),可以让GPU可快速读取
    host_page_locked_memory[0] = 123;
    printf("host_page_locked_memory[0] = %f\n", host_page_locked_memory[0]);

    
    float new_value = 555;
    checkDriver(cuMemsetD32((CUdeviceptr)host_page_locked_memory, *(int*)&new_value, 1)); 
    printf("host_page_locked_memory[0] = %f\n", host_page_locked_memory[0]);
    // 释放内存
    checkDriver(cuMemFreeHost(host_page_locked_memory));
    return 0;
}
### 回答1: Qt Creator是一个跨平台的集成开发环境(IDE),可以用于开发C++应用程序。而CUDA是一种用于在NVIDIA GPU上进行并行计算的平行计算平台和API模型。 要在Qt Creator使用CUDA,需要按照以下步骤进行设置: 1. 确保你已经正确安装了NVIDIA显卡驱动CUDA Toolkit。可以在NVIDIA官网下载并安装它们。 2. 打开Qt Creator,并创建一个新的Qt项目或者打开一个现有的项目。 3. 在项目文件(.pro)添加以下内容: ``` CUDA_SOURCES += your_cuda_file.cu CUDA_DIR = /path/to/cuda CUDA_ARCH = sm_35 ``` 其,`your_cuda_file.cu`是你的CUDA源文件的名称,`CUDA_DIR`是CUDA的安装路径,`CUDA_ARCH`是你的GPU架构版本。你可以根据自己的情况调整这些参数。 4. 在Qt Creator的项目设置,添加CUDA模块。选择“构建&运行” → “Kits” → “Qt” → “Add”,然后选择CUDA模块。 5. 在Qt Creator编写和调试CUDA代码。你可以使用CUDA C/C++语言编写CUDA核函数,并在主机代码调用它们。可以使用Qt Creator的调试器来进行调试和分析。 需要注意的是,Qt Creator本身并不提供CUDA的开发支持,但它可以与CUDA一起使用,以便在创建和管理CUDA项目时提供方便的开发环境。 ### 回答2: Qt Creator是一个集成开发环境,可以用于开发和调试Qt应用程序。它集成了众多开发工具和插件,使得开发者可以更加方便地进行程序开发和调试。 CUDA是NVIDIA推出的一种并行计算技术,主要适用于处理大规模的科学计算和图形处理任务。它利用GPU的并行计算能力,可以显著提高计算效率。 如果我们希望在Qt Creator使用CUDA进行开发,首先需要安装NVIDIA CUDA Toolkit。然后,在Qt Creator进行如下配置: 1. 打开Qt Creator,选择“菜单栏 -> 工具 -> 选项”,进入选项设置界面。 2. 在左侧边栏选择“建构和运行”选项。 3. 在右侧区域选择“Kits”选项卡,并点击“添加”按钮,添加一个新的Kit。 4. 在新弹出的对话框,选择“CUDA Application”作为新的Kit类型,并点击“下一步”按钮。 5. 在“名称”输入框输入Kit的名称,并选择已安装的CUDA版本。 6. 在“设备”区域,选择与您的CUDA版本和硬件兼容的设备。 7. 在“编译套件”区域,选择与您的CUDA版本兼容的编译器。 8. 点击“完成”按钮完成Kit的创建和配置。 配置完成后,您就可以在Qt Creator使用CUDA进行开发了。可以在Qt Creator的项目添加CUDA的源文件,并通过设置编译选项来指定CUDA的相关参数。然后,您可以编译和运行CUDA应用程序,并通过Qt Creator的调试工具来调试您的代码。 需要注意的是,使用CUDA进行开发需要具备一定的CUDA编程基础和GPU编程知识。此外,您还需要确保GPU驱动程序和CUDA Toolkit已正确安装和配置。因此,在使用Qt Creator进行CUDA开发之前,建议您先学习和了解CUDA的基本概念和编程技术,以充分发挥其在并行计算方面的优势。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值