CUDA独立上下文模块加载

news2024/11/17 11:50:01

CUDA独立上下文模块加载

在这里插入图片描述

大多数 CUDA 开发人员都熟悉 cuModuleLoad API 及其对应项,用于将包含设备代码的模块加载到 CUDA 上下文中。 在大多数情况下,您希望在所有设备上加载相同的设备代码。 这需要将设备代码显式加载到每个 CUDA 上下文中。 此外,不控制上下文创建和销毁的库和框架必须跟踪它们以显式加载和卸载模块。

这篇文章讨论了 CUDA 12.0 中引入的上下文独立加载,它解决了这些问题。

上下文相关的加载(Context-dependent loading)

传统上,模块加载总是与 CUDA 上下文相关联。 下面的代码示例显示了将相同的设备代码加载到两个设备然后在它们上启动内核的传统方法。

// Device 0
cuDeviceGet(&device0, 0);
cuDevicePrimaryCtxRetain(&ctx0, device0);
cuModuleLoad(&module0, “myModule.cubin”);
// Device 1
cuDeviceGet(&device1, 1);
cuDevicePrimaryCtxRetain(&ctx1, device1);
cuModuleLoad(&module1, “myModule.cubin”);

在每个设备上启动内核需要您检索每个模块的 CU 函数,如以下代码示例所示:

// Device 0
cuModuleGetFuntion(&function0, module0, “myKernel”);
cuLaunchKernel(function0,);
// Device 1
cuModuleGetFuntion(&function1, module1, “myKernel”);
cuLaunchKernel(function1,);

这会增加应用程序中的代码复杂性,因为您必须检索和跟踪每个上下文和每个模块的类型。 您还必须使用 cuModuleUnload API 显式卸载每个模块。

当库或框架主要使用 CUDA 驱动程序 API 来加载它们自己的模块时,问题会加剧。 他们可能无法完全控制应用程序拥有的上下文的生命周期。

// Application code

libraryInitialize();
cuDevicePrimaryCtxRetain(&ctx0, device0);
libraryFunc();
cuDevicePrimaryCtxRetain(&ctx0, device1);
libraryFunc();
libraryDeinitialize();

// Library code

libraryInitialize() {
  map<CUcontext, CUmodule> moduleContextMap;
}

libraryFunc() {
  cuCtxGetCurrent(&ctx);
  if (!moduleContextMap.contains(ctx)){
    cuModuleLoad(&module, “myModule.cubin”);
    moduleContextMap[ctx] = module;
  }
  else {
    module = moduleContextMap[ctx];
  }

  cuModuleGetFuntion(&function, module, “myKernel”);
  cuLaunchKernel(function,);
}

libraryDeinitialize() {
  moduleContextMap.clear();
}

在代码示例中,库必须检查新上下文并将模块显式加载到其中。 它还必须维护状态以检查模块是否已加载到上下文中。

理想情况下,状态可以在上下文被销毁后释放。 但是,如果库无法控制上下文的生命周期,这是不可能的。

这意味着资源的释放必须延迟到库取消初始化。 这不仅增加了代码的复杂性,而且还导致库占用资源的时间超过了它必须占用的时间,可能会拒绝应用程序的另一部分使用该内存。

另一种选择是让库和框架对用户施加额外的限制,以确保他们对资源分配和清理有足够的控制权。

上下文独立的加载(Context-independent loading)

CUDA 12.0 通过添加 cuLibrary* 和 cuKernel* API 引入了上下文无关加载,从而解决了这些问题。 通过上下文独立加载,在应用程序创建和销毁上下文时,CUDA 驱动程序会自动将模块加载和卸载到每个 CUDA 上下文中。

// Load library
cuLibraryLoadFromFile(&library,“myModule.cubin”, …);
cuLibraryGetKernel(&kernel, library, “myKernel”);

// Launch kernel on the primary context of device 0
cuDevicePrimaryCtxRetain(&ctx0, device0);
cuLaunchKernel((CUkernel)kernel, …);

// Launch kernel on the primary context of device 1
cuDevicePrimaryCtxRetain(&ctx1, device1);
cuLaunchKernel((CUkernel)kernel, …);

// Unload library
cuLibraryUnload(library);

如代码示例所示,cuLibraryLoadFromFile API 负责在创建或初始化上下文时加载模块。 在示例中,这是在 cuDevicePrimaryCtxRetain 期间完成的。

此外,您现在可以使用与上下文无关的句柄 CUkernel 启动内核,而不必维护每个上下文的 CUfunction。 cuLibraryGetKernel 检索设备函数 myKernel 的上下文无关句柄。 然后可以通过指定与上下文无关的句柄 CUkernel 来使用 cuLaunchKernel 启动设备功能。 CUDA 驱动程序负责根据此时处于活动状态的上下文在适当的上下文中启动设备功能。

库和框架现在可以分别在初始化和取消初始化期间简单地加载和卸载模块一次。

// Application code

libraryInitialize();
cuDevicePrimaryCtxRetain(&ctx0, device0);
libraryFunc();
cuDevicePrimaryCtxRetain(&ctx0, device1);
libraryFunc();
libraryDeinitialize();

// Library code

libraryInitialize() {
  cuLibraryLoadFromFile(&library,“myModule.cubin”,);
  cuLibraryGetKernel(&kernel, library, “myKernel”);
}

libraryFunc() {
  cuLaunchKernel((CUkernel)kernel,);
}

libraryDeinitialize() {
  cuLibraryUnload(library);
}

该库不再需要维护和跟踪每个上下文的状态。 context-independent loading的设计使得CUDA driver能够跟踪模块和context,进行加载和卸载模块的工作。

访问 __managed__ 变量

托管变量可以从设备和主机代码中引用。 例如,可以查询托管变量的地址,或者可以直接从设备或主机函数读取或写入它。 与具有创建它的 CUDA 上下文的生命周期的 __device__ 变量不同,属于模块的 __managed__ 变量指向跨所有 CUDA 上下文甚至设备的相同内存。

在 CUDA 12.0 之前,无法通过驱动程序 API 检索到跨 CUDA 上下文唯一的托管变量的句柄。 CUDA 12.0 引入了一个新的驱动程序 API cuLibraryGetManaged,这使得跨 CUDA 上下文获取唯一句柄成为可能。

开始使用与上下文无关的加载

在本文中,我们介绍了新的 CUDA 驱动程序 API,它们提供了独立于 CUDA 上下文加载设备代码的能力。 我们还讨论了用于启动内核的与上下文无关的句柄。 与传统的加载机制相比,它们共同提供了一种在 GPU 上加载和执行代码的更简单方法,从而降低了代码复杂性并避免了维护每个上下文状态的需要。

要开始使用这些 API,请下载 CUDA 驱动程序和工具包版本 12 或更高版本。 有关 cuLibrary* 和 cuKernel* API 的更多信息,请参阅 CUDA Driver API 文档。

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

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

相关文章

408总结-冲冲冲

数据结构 m阶B树除根节点外所有节点关键字范围⌈m/2⌉−1至m−1\lceil m/2\rceil-1至m-1⌈m/2⌉−1至m−1。所有叶节点都在同一层&#xff0c;且不带信息&#xff0c;代表查找失败的位置。是所有节点平衡因子都为0的多路平衡查找树完全二叉树的叶子结点只可能出现在最下面两层…

AndroidStudio使用maven-publish发布aar至mavencentral中央仓库

目录AndroidStudio使用maven-publish发布aar至mavencentral中央仓库1、注册[【sonatype】](https://issues.sonatype.org/secure/Signup!default.jspa)2、创建Group ID3、下载安装[gnupg](https://www.gnupg.org/download/index.html)4、创建生成密钥5. 配置maven-publish打包推…

设计模式之访问者模式

Visitor design pattern 访问者模式的概念、访问者模式的结构、访问者模式的优缺点、访问者模式的使用场景、访问者模式实现示例、访问者模式的源码分析、双分派 1、访问者模式的概念 访问者模式&#xff0c;即在不改变聚合对象内元素的前提下&#xff0c;为聚合对象内每个元素…

STM32F103VET6基于STM32CubeMX RTC时钟报警中断使用示例

STM32F103VET6基于STM32CubeMX RTC时钟报警中断使用示例&#x1f4fa;STM32CubeMX配置RTC时钟报警中断演示过程&#xff1a; &#x1f4cc;相关篇《STM32F103VET6基于STM32CubeMX RTC时钟秒更新中断使用示例》&#x1f4cc;《STM32F103VET6基于STM32CubeMX RTC时钟使用示例》&a…

VUE-router

七.Vue-router 1、什么是vue-router vue-router是vue.js官方路由管理器。vue的单页应用是基于路由和组件的&#xff0c;路由用于设定访问路径&#xff0c;并将路径和组件映射起来。 传统页面切换是用超链接a标签进行切换。但vue里是用路由&#xff0c;因为我们用Vue做的都是…

K8s 前世今生与架构组件简析

k8s 前世 k8s 的前世是google 内部的Borg 系统&#xff0c;是一个作业调度平台&#xff0c;调度的对象是一个个进程。 Borg 本身也利用了容器化技术比如 Cgroups, Namespace 实现应用的隔离。 运行在线上的业务主要分为在线业务&#xff08;prod&#xff09;和离线业务(non-…

Netty实战与源码剖析(二)——Netty线程模型

1 线程模型基本介绍 不同的线程模式&#xff0c;对于程序的性能有很大的影响&#xff0c;Netty为何具有如此高的性能&#xff0c;很大程度上是得益于Netty采用的线程模型。 目前主流存在的线程模型有两种&#xff1a; 传统阻塞IO模型Reactor模型 然而根据Reactor的数量和处理…

零基础转行程序员,有哪些经验可以借鉴?

随着互联网行业的迅速发展&#xff0c;市场对于程序员的需求增大&#xff0c;越来越多的人开始转行到IT领域&#xff0c;程序员也不再基于计算机科学或软件工程等个别专业的毕业生&#xff0c;其他非计算机相关专业的&#xff0c;像学物理、数学、自动化&#xff0c;甚至英语、…

云原生丨DataX在数据迁移中的应用与实践

文章目录一、前言二、准备工作三、安装工具与数据迁移Demo安装工具与数据迁移三、使用Datax抽取移动云上的gauss数据库四、Datax工具逻辑说明整体框架核心模板介绍流程调度数据库类型插件读、写说明五、Datax工具参数说明SettingReader& writerjdbcUrlusernamepasswordtabl…

数据人PK也无人,为什么业务部门的数据需求都是急活?

**导读&#xff1a;**你是不是经常听到数据开发吐槽业务部门&#xff1a;我可以理解业务部门数据需求多&#xff0c;但为什么经常要得这么急呢&#xff1f; 作为一个数据开发者&#xff0c;可以回想一下&#xff0c;当初是怎么进入数据行业的。 是不是也是听一些大V忽悠&…

Java Swing JSlider:滑块组件

在前面的章节中&#xff0c;我们介绍了 Swing 设计简单界面所需的窗口、布局组件以及如何响应事件。Swing 还提供了很多高级组件&#xff0c;如菜单栏、工具栏、文件选择器、表格以及树等。使用这些高级组件可以实现更为复杂的布局&#xff0c;也可以使程序界面更加人性化&…

颜色分析.

介绍 宽光谱光源对许多光学系统都很重要&#xff0c;应用范围包括白光照明、分光计等。Fred中的颜色图像分析&#xff0c;是通过计算每个像素的色度坐标并在表面上显示生成的RGB值来生成颜色分布。此外&#xff0c;FRED还可以显示彩色色度图&#xff0c;并在用户移动光标时指…

CSS -- CSS选择器精讲(基础选择器,符合选择器,属性选择器,结构伪类选择器,伪选择器)

文章目录1 CSS基础选择器1.1 选择器的分类1.2 标签选择器1.3 类选择器1.4 id选择器1.5 通配符选择器1.6 基础选择器总结2 CSS的复合选择器2.1 什么是复合选择器2.2 后代选择器2.3 子选择器2.4 并集选择器2.5 伪类选择器2.6 链接伪类选择器2.7 :focus 伪类选择器2.8 复合选择器总…

正点原子-Linux嵌入式开发学习-第二期04

第十一讲&#xff1a;BSP工程管理 BSP管理其实就是以前学stm32一样的单独为led写.h和.c&#xff0c;并且文件夹有很多种 使用ubuntu的vscode创建bsp文件 第一步&#xff1a;新建bsp文件夹&#xff0c;在bsp文件夹新建各个外设或者功能的文件夹&#xff08;一定是在相应的文件夹…

nodejs+vue+elementui鲜花销售商城管理系统410

前台&#xff1a; (1) 用户注册&#xff1a;用户名&#xff0c;密码&#xff0c;确认密码&#xff0c;邮箱&#xff0c;手机号&#xff0c;真实姓名&#xff0c;收货地址 (2) 用户登录&#xff1a;用户名&#xff0c;密码&#xff0c;验证码 登录后在主页显示欢迎信息&am…

2022年保险行业和产品研究报告

第一章 行业概况 保险业是经营风险的特殊行业。保险是以契约形式确立双方经济关系&#xff0c;以缴纳保险费建立起来的保险基金&#xff0c;对保险合同规定范围内的灾害事故所造成的损失&#xff0c;进行经济补偿或给付的一种经济形式。 保险是专门以风险为经营对象、为人们提…

RK3568开发环境搭建

前面我给大家展示了RK3568的开发板&#xff0c;但是并没有对RK3568的芯片资源进行描述&#xff0c;这里简单给大家看下该芯片的资源&#xff0c;具体的请看瑞芯微官网https://www.rock-chips.com/ 对芯片有了写了解之后&#xff0c;下面就开始搭建开发环境&#xff0c;让我们早…

Databend 开源周报 #72

Databend 是一款强大的云数仓。专为弹性和高效设计&#xff0c;自由且开源。 即刻体验云服务&#xff1a;https://app.databend.com。 What’s New 探索 Databend 本周新进展&#xff0c;遇到更贴近你心意的 Databend 。 Features & Improvements Multiple Catalogs …

操作系统:虚拟存储器 练习题(带有答案和解析)

文章目录1.虚拟存储器概述1.1.常规存储管理方式的特征和局部性原理1.2.虚拟存储器的定义和特征1.3.虚拟存储器的实现方法2.请求分页存储管理方式2.1.请求分页中的硬件支持2.2.请求分页中的内存分配3.页面置换算法3.1.最佳置换算法和先进先出置换算法3.2.最近最久未使用和最少使…

Spring事件处理

在实际业务开发中&#xff0c;有时候复杂性的业务之间需要解耦&#xff0c;常用的方法&#xff1a;同步、异步、MQ。但 MQ 重啊&#xff0c;非必要不提升架构复杂度。 针对同步和异步使用方式&#xff1a;&#xff11;.定时器 &#xff12;.Spring Event. Spring Event: 观察者…