精简CUDA教程——CUDA Driver API

精简CUDA教程——CUDA Driver API

tensorRT从零起步迈向高性能工业级部署(就业导向) 课程笔记,讲师讲的不错,可以去看原视频支持下。

Driver API概述

CUDA 的多级 API

CUDA 的 API 有多级(下图),详细可参考:CUDA环境详解。

  • CUDA Driver API 是 CUDA 与 GPU 沟通的驱动级底层 API。早期 CUDA 与 GPU 沟通都是直接通过 Driver API。cuCtxCreate()cu 开头的基本都是 Driver API。我们熟悉的 nvidia-smi 命令就是调用的 Driver API。
  • 后来发觉 Driver API 太过底层,细节太过复杂,故演变出了 Runtime API,Runtime API 是基于 Driver API 开发的,常见的 cudaMalloc() 等 API 都是 Runtime API。

在这里插入图片描述

CUDA Driver

环境相关

CUDA Driver 是随着显卡驱动发布,要与 cudatoolkit 分开看

CUDA Driver 对应于 cuda.hlibcuda.so 两个文件。注意 cuda.h 会在安装 cudatoolkit 时包含,但是 libcuda.so 是随着显卡驱动安装的我们的系统中的(而不是也跟着 cudatooklit 安装)。因此,如果要直接复制移动 libcuda.so 文件时要注意驱动版本需要与之适配。

如何了解CUDA Driver

本精简课程对于底层的 Driver API 的理解,是为了有利于后续的 Runtime API 的学习与错误调试。Driver API 是理解 cudaRuntime 中上下文的关键。因此,本精简课程在 CUDA Driver 这部分的主要的知识点是:

  • Context 的管理机制
  • CUDA 系列接口的开发习惯(错误检查方法)
  • 内存模型

关于context和内存的分类

关于context,有两种:

  1. 手动管理的 contextcuCtxCreate ,手动管理,以堆栈的方式 push/pop
  2. 自动管理的 contextcuDevicePrimaryCtxRetain,自动管理,Runtime API 以此为基础

关于内存,有两大类:

  1. CPU 内存,称之为 Host Memory
    • Pageable Memory:可分页内存
    • Page-Locked Memory:页锁定内存
  2. GPU 内存(显存),称之为 Device Memory
    • Global Memory:全局内存
    • Shared Memory:共享内存
    • … 其他

以上内容之后会展开介绍。

cuIint 驱动初始化

  1. cuInit 的意义是,初始化驱动 API,全局执行一次即可,如果不执行,则所有 API 都将返回错误。
  2. 没有对应的 cuDestroy,不需要释放,程序销毁自动释放。

返回值检查

版本一

正确友好地检查 cuda 函数的返回值,有利于程序的组织结构,使得代码的可读性更好,错误更容易发现。

我们知道 cuInit 返回的类型是 CUresult,该返回值会告诉程序员函数成功还是失败,失败的原因是什么。

官方版本的检查的逻辑,如下:

// 使用有参宏定义检查cuda driver是否被正常初始化, 并定位程序出错的文件名、行数和错误信息
// 宏定义中带do...while循环可保证程序的正确性
#define checkDriver(op)    \do{                    \auto code = (op);  \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 -1;   \}                \}while(0)

是一个宏定义,我们在调用其他 API 的时候,对函数的返回值进行检查,并在出错时将错误码和报错信息打印出来,方便调试。比如:

checkDriver(cuDeviceGetName(device_name, sizeof(device_name), device));

如果有未初始化等错误,报错信息会被清晰地打印出来。

这个版本一也是 Nvidia 官方使用的版本,但是存在一些问题,比如代码可读性较差,直接返回 int 型错误码等。推荐使用版本二。

版本二

// 很明显,这种代码封装方式,更加的便于使用
//宏定义 #define <宏名>(<参数表>) <宏体>
#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;
}

很明显的,版本二的返回值、代码可读性、封装性等都相较版本一好了很多。使用的方式是一样的:

checkDriver(cuDeviceGetName(device_name, sizeof(device_name), device));
// 或加一个判断,遇到错误即退出
if (!checkDriver(cuDeviceGetName(device_name, sizeof(device_name), device))) {return -1;
}

CUcontext

手动上下文管理

  • context 是一种上下文,关联对 GPU 的所有操作。

  • 一个 context 与一块显卡关联,一块显卡可以被多个 context 关联。

  • 每个线程都有一个栈结构存储 context,栈顶是当前使用的 context,对应有 push/pop 函数操作 context 的栈,所有 API 都以当前 context 为操作目标

试想一下,如果执行任何操作你都需要传递一个 device 决定送到哪个设备执行,得多麻烦。context 就是为了方便管理当前 API 是在哪个 device 上执行而提出的一种手段,而栈结构的使用则是为了保存之前的上下文中的 device,从而方便控制多个设备。

在这里插入图片描述

自动上下文管理

  • 由于高频操作都是一个线程固定访问一个 device 不变,不经常会有同一个线程来回多次访问不同 device 的情况,且只会使用到一个 context,很少用到多 context。
  • 即在多数情况下, CreateContextPushCurrentPopCurrent 这种多 context 管理就显得很麻烦
  • 因此就推出了 cuDevicePrimaryCtxRetain ,为设备关联主 context,这样分配、设置、释放、栈都不需要我们再去手动管理,是一种自动管理 context 的方式
  • primaryContext :给我设备 id,给你 context 并设置好,此时一个 device 对应一个 primary context。不同线程,只要设备 id 相同,primary context 就相同,且 context 是线程安全的。
  • 在之后要介绍的 CUDA Runtime API 中,就是自动使用 cuDevicePrimaryCtxRetain 的。

在这里插入图片描述

DriverAPI 内存管理

  1. host memory 是计算机本身的内存,可以用 CUDA Driver API 来申请和释放,也可以用 C/C++ 的 malloc/freenew/delete 来申请和释放。
  2. device memory 是显卡上的内存,即显存,有专用的 Driver API 来进行申请和释放。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/532486.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CUDA编程入门极简教程

CUDA编程入门极简教程 转自&#xff1a;CUDA编程入门极简教程 作者&#xff1a;小小将 前言 2006年&#xff0c;NVIDIA公司发布了CUDA&#xff0c;CUDA是建立在NVIDIA的CPUs上的一个通用并行计算平台和编程模型&#xff0c;基于CUDA编程可以利用GPUs的并行计算引擎来更加高效地…

精简CUDA教程——CUDA Runtime API

精简CUDA教程——CUDA Runtime API tensorRT从零起步迈向高性能工业级部署&#xff08;就业导向&#xff09; 课程笔记&#xff0c;讲师讲的不错&#xff0c;可以去看原视频支持下。 Runtime API 概述 环境 图中可以看到&#xff0c;Runtime API 是基于 Driver API 之上开发的…

TensorRT ONNX 基础

TensorRT ONNX 基础 tensorRT从零起步迈向高性能工业级部署&#xff08;就业导向&#xff09; 课程笔记&#xff0c;讲师讲的不错&#xff0c;可以去看原视频支持下。 概述 TensorRT 的核心在于对模型算子的优化&#xff08;合并算子、利用当前 GPU 特性选择特定的核函数等多种…

mmdetection tools工具梳理

mmdetection tools工具梳理 mmdetection 是一个非常好用的开源目标检测框架&#xff0c;我们可以用它方便地训练自己的目标检测模型&#xff0c;mmdetection 项目仓库提供许多实用的工具来实现帮助我们进行各种测试。本篇将梳理以下 mmdetection 项目仓库 tools 目录下的各种实…

TensorRT ONNX 基础(续)

TensorRT ONNX 基础&#xff08;续&#xff09; PyTorch正确导出ONNX 几条推荐的原则&#xff0c;可以减少潜在的错误&#xff1a; 对于任何使用到 shape、size 返回值的参数时&#xff0c;例如 tensor.view(tensor.size(0), -1) 这类操作&#xff0c;避免直接使用 tensor.s…

frp实现内网穿透极简教程

frp实现内网穿透极简教程 本文是内网穿透极简教程&#xff0c;为求简洁&#xff0c;我们不介绍为什么内网穿透也不介绍其原理&#xff0c;这里假设各位读者都已经明确的知道自己的目的&#xff0c;本文仅介绍如何安装配置 frp 实现内网穿透。 简单来说&#xff0c;内网穿透就…

图像预处理之warpaffine与双线性插值及其高性能实现

图像预处理之warpaffine与双线性插值及其高性能实现 视频讲解&#xff1a;https://www.bilibili.com/video/BV1ZU4y1A7EG 代码Repo&#xff1a;https://github.com/shouxieai/tensorRT_Pro 本文为视频讲解的个人笔记。 warpaffine矩阵变换 对于坐标点的变换&#xff0c;我们通…

sed 简明教程

sed 简明教程 转自&#xff1a;https://coolshell.cn/articles/9104.html awk于1977年出生&#xff0c;今年36岁本命年&#xff0c;sed比awk大2-3岁&#xff0c;awk就像林妹妹&#xff0c;sed就是宝玉哥哥了。所以 林妹妹跳了个Topless&#xff0c;他的哥哥sed坐不住了&#xf…

[深度][PyTorch] DDP系列第一篇:入门教程

[深度][PyTorch] DDP系列第一篇&#xff1a;入门教程 转自&#xff1a;[原创][深度][PyTorch] DDP系列第一篇&#xff1a;入门教程 概览 想要让你的PyTorch神经网络在多卡环境上跑得又快又好&#xff1f;那你definitely需要这一篇&#xff01; No one knows DDP better than I…

[深度][PyTorch] DDP系列第二篇:实现原理与源代码解析

[深度][PyTorch] DDP系列第二篇&#xff1a;实现原理与源代码解析 转自&#xff1a;https://zhuanlan.zhihu.com/p/187610959 概览 想要让你的PyTorch神经网络在多卡环境上跑得又快又好&#xff1f;那你definitely需要这一篇&#xff01; No one knows DDP better than I do! …

[深度][PyTorch] DDP系列第三篇:实战与技巧

[深度][PyTorch] DDP系列第三篇&#xff1a;实战与技巧 转自&#xff1a;https://zhuanlan.zhihu.com/p/250471767 零. 概览 想要让你的PyTorch神经网络在多卡环境上跑得又快又好&#xff1f;那你definitely需要这一篇&#xff01; No one knows DDP better than I do! – – …

机器学习:系统设计与实现 分布式训练

机器学习系统:设计与实现 分布式训练 转自&#xff1a;https://openmlsys.github.io/chapter_distributed_training/index.html 随着机器学习的进一步发展&#xff0c;科学家们设计出更大型&#xff0c;更多功能的机器学习模型&#xff08;例如说&#xff0c;GPT-3&#xff09;…

从零Makefile落地算法大项目,完整案例教程

从零Makefile落地算法大项目&#xff0c;完整案例教程 转自&#xff1a;从零Makefile落地算法大项目&#xff0c;完整案例教程 作者&#xff1a;手写AI 前言 在这里&#xff0c;你能学到基于Makefile的正式大项目的使用方式和考虑&#xff0c;相信我&#xff0c;其实可以很简单…

PyTorch扩展自定义PyThonC++(CUDA)算子的若干方法总结

PyTorch扩展自定义PyThon/C(CUDA)算子的若干方法总结 转自&#xff1a;https://zhuanlan.zhihu.com/p/158643792 作者&#xff1a;奔腾的黑猫 在做毕设的时候需要实现一个PyTorch原生代码中没有的并行算子&#xff0c;所以用到了这部分的知识&#xff0c;再不总结就要忘光了 &a…

给 Python 算法插上性能的翅膀——pybind11 落地实践

给 Python 算法插上性能的翅膀——pybind11 落地实践 转自&#xff1a;https://zhuanlan.zhihu.com/p/444805518 作者&#xff1a;jesonxiang&#xff08;向乾彪&#xff09;&#xff0c;腾讯 TEG 后台开发工程师 1. 背景 目前 AI 算法开发特别是训练基本都以 Python 为主&…

chrome自动提交文件_收集文档及提交名单统计

知乎文章若有排版问题请见谅&#xff0c;原文放在个人博客中【欢迎互踩&#xff01;】文叔叔文档收集使用动机在我们的学习工作中&#xff0c;少不了要让大家集体提交文件的情况&#xff0c;举个最简单的例子&#xff1a;收作业。 传统的文件收集流程大致是&#xff1a;群内发出…

惠普800g1支持什么内存_惠普黑白激光打印机哪种好 惠普黑白激光打印机推荐【图文详解】...

打印机的出现让我们在生活和日常工作中变得越来越方便&#xff0c;不过随着科技的发展&#xff0c;打印机的类型也变得非常多&#xff0c;其中就有黑白激光打印机&#xff0c;而黑白激光打印机的品牌也有很多&#xff0c;比如我们的惠普黑白激光打印机&#xff0c;今天小编就给…

控制台输出颜色控制

控制台输出颜色控制 转自&#xff1a;https://cloud.tencent.com/developer/article/1142372 前端时间&#xff0c;写了一篇 PHP 在 Console 模式下的进度显示 &#xff0c;正好最近的一个数据合并项目需要用到控制台颜色输出&#xff0c;所以就把相关的信息整理下&#xff0c;…

idea连接跳板机_跳板机服务(jumpserver)

一、跳板机服务作用介绍1、有效管理用户权限信息2、有效记录用户登录情况3、有效记录用户操作行为二、跳板机服务架构原理三、跳板机服务安装过程第一步&#xff1a;安装跳板机依赖软件yum -y install git python-pip mariadb-devel gcc automake autoconf python-devel readl…

【详细图解】再次理解im2col

【详细图解】再次理解im2col 转自&#xff1a;https://mp.weixin.qq.com/s/GPDYKQlIOq6Su0Ta9ipzig 一句话&#xff1a;im2col是将一个[C,H,W]矩阵变成一个[H,W]矩阵的一个方法&#xff0c;其原理是利用了行列式进行等价转换。 为什么要做im2col? 减少调用gemm的次数。 重要…