CUDNN 9 (2) Graph API

cuDNN 库提供了一个声明性编程模型,用于将计算描述为操作图。Graph API 是在 cuDNN 8.0 中引入的,以提供更灵活的 API,尤其是在操作融合(operation fusion)日益重要的情况下。

用户首先构建操作图。在较高的层次上,用户描述张量操作的数据流图。给定最终的图(finalized graph),用户然后选择并配置可以执行该图的引擎(engine)。有多种选择和配置引擎的方法,这些方法在易用性、运行时开销和引擎性能方面需要权衡。

注:算子和操作在文中大部分情况下意思相同,都对应Operation。

Graph API 有两个调用方式:

其中,cuDNN frontend API更加简单易用,并且在Github上开源,相当于对底层级的graph API做了warp。

关键概念

Operations and Operation Graphs

Operation Graphs是张量操作的数据流图。它是一种数学规范,并且与可以实现它的底层Engines分离,因为给定的图可能有多个Engine可用。

I/O 张量隐式地连接operation,例如,operation A 可能会产生张量 X,然后由operation B 消耗,这意味着operation B 依赖于operation A。

Engines and Engine Configurations

cuDNN Engines 是预编译的、针对特定深度学习操作优化的计算引擎,它们可以直接在 NVIDIA GPU 上运行,无需在每次调用时都重新编译或解释代码。这些Engines覆盖了深度学习中的常见操作,如卷积、矩阵乘法、激活函数等。通过使用这些Engines,开发者可以显著提高神经网络训练和推理的速度。

对于给定的Operation Graph,有一些Engines是实现该Graph的候选Engines。查询候选Engines列表的典型方法是通过启发式查询(heuristics query);Engine能够配置相关属性,比如tile size等。

Heuristics

启发式(heuristic)是一种获取引擎配置列表的方法,这些引擎配置旨在针对给定的操作图从性能最高到性能最低进行排序。有以下三种模式:

  • CUDNN_HEUR_MODE_A - 旨在快速并能够处理大多数操作图模式。它返回按预期性能排名的Engines配置列表。
  • CUDNN_HEUR_MODE_B - 旨在比模式 A 更准确,但会以更高的 CPU 延迟为代价返回Engines配置列表。在知道模式 A 可以做得更好的情况下,底层实现可能会退回到模式 A 启发式。
  • CUDNN_HEUR_MODE_FALLBACK - 旨在快速并提供功能回退(fallback),而不期望获得最佳性能。

通常使用modeA或者modeB,找到的第一个支持的Engine预计会有最佳的性能。

Graph API Example with Operation Fusion

以下示例实现了卷积(convolution)、偏置(bias)和激活(activation)的算子融合,三个算子如下图所示。

1. Creating Operation and Tensor Descriptors to Specify the Graph Dataflow

第一步,需要创建相应的三个backend operation descriptors。

在上图中,指定了一个前向卷积算子、一个用于偏置加法的逐点(Pointwise)算子以及一个用于 ReLU 激活的逐点算子。

然后,需要为图中所有操作的输入和输出创建tensor descriptors。图数据流是通过张量的分配来隐含的,例如,通过指定后端张量Tmp0既作为卷积运算的输出又作为偏置运算的输入,cuDNN推断数据流从卷积运行到偏置。这同样适用于张量Tmp1。如果用户不需要中间结果 Tmp0Tmp1 用于任何其他用途,则用户可以将它们指定为虚拟张量(virtual tensors),以便可以优化内存 I/O。

2. Finalizing The Operation Graph

第二步,确定operation graph。作为最终确定的一部分,cuDNN 执行数据流分析以建立操作之间的依赖关系并连接边缘,如下图所示。在此步骤中,cuDNN 执行各种检查以确认graph的有效性。

3. Configuring An Engine That Can Execute The Operation Graph

第三步,给定最终确定的操作图,用户必须选择并配置Engine来执行该图,从而产生执行计划(execution plan)。可以直接指定,也可以通过启发式寻找性能最优的Engine,执行启发式操作的典型方法是:

  • 查询启发式模式 A 或 B。
  • 寻找第一个具有功能支持的Engine config(或自动调整所有具有功能支持的引擎配置)。
  • 如果未找到Engine config,尝试查询回退启发式。

4. Executing The Engine

最后,构建execution plan并在运行它时,应通过提供工作区指针(workspace pointer)、UID 数组和设备指针(device pointers)数组来构建后端变体包(backend variant pack)。 UID 和指针应按相应的顺序排列。有了handle, execution plan 和 variant pack,就可以调用执行API并在GPU上进行计算。

下一篇文章会分析这一过程的cuDNN frontend API代码实现。

相关推荐
paopaokaka_luck4 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
码农小旋风5 小时前
详解K8S--声明式API
后端
Peter_chq5 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml46 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~6 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616886 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
睡觉谁叫~~~7 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
2401_865854889 小时前
iOS应用想要下载到手机上只能苹果签名吗?
后端·ios·iphone
AskHarries9 小时前
Spring Boot集成Access DB实现数据导入和解析
java·spring boot·后端
2401_8576226610 小时前
SpringBoot健身房管理:敏捷与自动化
spring boot·后端·自动化