最近在学习杜老师shouxieai的TensorRT,记一下笔记总结一下。
一、CUDA-DriverAPI介绍
- CUDA Driver是与GPU进行沟通的驱动级别底层API,了解DriverAPI有助于RuntimeAPI的学习。
- CUDA Driver是随显卡驱动发布,对应cuda.h和libcuda.so
二、驱动初始化culnit
-
culnit初始化CUDA-DriverAPI,若不执行,则所有API都返回错误,全局执行一次
-
没有对应cuDestroy,不需要释放,程序销毁自动释放
CUresult code=cuInit(0); //CUresult 类型:用于接收一些可能的错误代码
if(code != CUresult::CUDA_SUCCESS){
const char* err_message = nullptr;
cuGetErrorString(code, &err_message); // 获取错误代码的字符串描述
// cuGetErrorName (code, &err_message); // 获取错误代码的字符串
printf("Initialize failed. code = %d, message = %s\n", code, err_message);
return -1;
}
三、CUDA错误检查
#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;
}
三、CUcontext
1. context介绍
- context字面意思是上下文环境,是一个抽象类,定义很多应用程序环境中全局信息的接口。通俗点就是,当程序从一个位置调到另一个位置的时候就叫上下文切换(保存现场,进行压栈出栈),进程间的切换也叫上下文切换,保存现场,以便返回之前的线程。
- C++中context一般为一个结构体,用来存储一些关键信息,比如在上下文切换时,保存切换之前的状态和数据,需要一个结构体承担,然后将context中状态和数据重新赋值为新,实现切换,运行完后又切换回来,之前保存的状态和数据又重新使用。
2. CUcontext分类:
(1)手动管理context,cuCtxCreate(手动管理,堆栈方式push、pop)
(2)自动管理context,cuDevicePrimaryCtxRetain(runtime api的context以此为基础)
3. CUcontext介绍
(1)CUcontext关联对GPU的所有操作(所有经GPU的操作都必须使用CUcontext),其与一块显卡关联,一个显卡可以被多CUcontext关联,为了方便控制device
(2)每个线程都有一个栈结构体储存CUcontext,栈顶是当前使用的CUcontext,push、pop函数操作栈,所有api以当前CUcontext为操作目标,栈为了方便多个设备控制(递归调用)
//无context,一直带有device
cuMalloc(device, &ptr, 100);
cuFree(device, ptr);
cuMemcpy(device, dst, src, 100);
//有context
cuCreateContext(device, &context); //创建CUcontext,将context和device关联
cuPushCurrent(context);
cuMalloc(&ptr, 100);
cuFree(ptr);
cuMemcpy(dst, src. 100);
cuPopCurrent(context);
4.cuDevicePrimaryCtxRetain
- 一个线程基本固定访问一个显卡,且基本只使用一个context,进行CreateContext、PushCurrent、PopCurrent等多context管理很麻烦,nv封装cuDevicePrimaryCtxRetain,为设备关联主context(不需要管分配、释放、设置、栈)。
- 给device-id,cuDevicePrimaryCtxRetain帮你把context设备好,一个显卡对应一个primaryContext,不同线程,只要device-id一样,primaryContext就一样,线程安全。
- runtimeAPI自动使用cuDevicePrimaryCtxRetain
cuDevicePrimaryCtxRetain(device, &context);
cuMalloc(&ptr, 100);
cuFree(ptr);
cuMemcpy(dst, src, 100);