在cuDNN中简化Tensor Ops

在Tesla V100 GPU中引入神经网络模型以来,神经网络模型已迅速利用NVIDIA Tensor Cores进行深度学习。例如,基于Tensor Core的解决方案宣布了ResNet50训练的性能记录。

NVIDIA的cuDNN库 使CUDA程序员能够优化循环神经网络卷积神经网络,以实现GPU加速。概述了cuDNN用户使用Tensor Core 进行卷积的简便方法,并附有说明和示例代码。该文章为cuDNN应用提供了一些简单的规则:FP16数据规则,张量维数规则,ALGO_1的使用等。

cuDNN版本解除了大多数限制。cuDNN 7.2版本取消了FP16数据约束,而cuDNN 7.3删除了张量尺寸约束(对于打包的NCHW张量数据),直接进行改进。

将FP32数据用于Tensor Ops

关于在CUDA中使用Tensor Core的帖子讨论了将FP16输入用于张量操作,如图1所示。虽然张量操作仍然使用FP16数据,但卷积cuDNN API允许用户选择将FP32输入数据转换为FP16。如果需要,卷积的输出数据也将转换为FP32。

图1. FP32数据现在可以用作输入

CUDNN_TENSOR_OP_MATH_ALLOW_CONVERSION枚举值,在cuDNN 7.2,使cuDNN应用程序员选择转换FP32数据运算使用。该枚举值与枚举值一样传递给cudnnSetConvolutionMathType()调用CUDNN_TENSOR_OP_MATH。此代码段显示了如何执行此操作:

//设置数学类型以允许cuDNN使用Tensor Core:
checkCudnnErr(cudnnSetConvolutionMathType(cudnnConvDesc,CUDNN_TENSOR_OP_MATH_ALLOW_CONVERSION));

将在后面的部分中看到使用代码片段的上下文。

FP32数据也用于RNN

现在还为RNN启用了类似的FP32数据转换。只需将CUDNN_TENSOR_OP_MATH_ALLOW_CONVERSION枚举值传递给cudnnSetRNNMatrixMathType()调用,即可将FP32数据转换为在RNN中使用。如下使用:

//设置数学类型以允许cuDNN使用Tensor Core:
checkCudnnErr(cudnnSetRNNMatrixMathType(cudnnRnnDesc,CUDNN_TENSOR_OP_MATH_ALLOW_CONVERSION));

消除了NCHW张量尺寸约束

早期版本的cuDNN要求所有张量的通道维数必须为8的倍数。cuDNN可以根据需要自动填充张量。

CUDNN_TENSOR_OP_MATHCUDNN_TENSOR_OP_MATH_ALLOW_CONVERSION情况下,对于填充的NCHW数据,此填充都是自动的。发生填充时,性能损失可忽略不计。

//设置NCHW张量尺寸,不必设置为8的倍数(此处仅显示输入张量):
int dimA [] = {1,7,32,32};
int strideA [] = {7168,1024,32,1};

下一节中的示例代码演示了如何使用。

样例代码

将张量运算用于FP32数据和任何通道尺寸的逻辑类似于为cuDNN的早期版本编写时使用的逻辑。只有维度和数据类型发生了变化(以及使用CUDNN_TENSOR_OP_MATH_ALLOW_CONVERSION)

//创建一个cuDNN句柄:
checkCudnnErr(cudnnCreate(&handle_));
 
//创建张量描述符:
checkCudnnErr(cudnnCreateTensorDescriptor(&cudnnIdesc));
checkCudnnErr(cudnnCreateFilterDescriptor(&cudnnFdesc));
checkCudnnErr(cudnnCreateTensorDescriptor(&cudnnOdesc));
checkCudnnErr(cudnnCreateConvolutionDescriptor(&cudnnConvDesc));
 
//设置NCHW张量尺寸,不必设置为8的倍数(此处仅显示输入张量):
int dimA [] = {1,7,32,32};
int strideA [] = {7168,1024,32,1};
 
checkCudnnErr(cudnnSetTensorNdDescriptor(cudnnIdesc,CUDNN_DATA_FLOAT,
convDim + 2,dimA,strideA));
 
//分配和初始化张量(同样,仅显示输入张量): 
checkCudaErr(cudaMalloc((void **)&(devPtrI),(insize)* sizeof(devPtrI [0]))));;
hostI =(T_ELEM *)calloc(insize,sizeof(hostI [0]));
 
initImage(hostI,insize);
 
checkCudaErr(cudaMemcpy(devPtrI,hostI,sizeof(hostI [0])* insize,cudaMemcpyHostToDevice));
 
//设置计算数据类型(以下为CUDNN_DATA_FLOAT):
checkCudnnErr(cudnnSetConvolutionNdDescriptor(cudnnConvDesc,convDim,padA,convstrideA,dilationA,CUDNN_CONVOLUTION,CUDNN_DATA_FLOAT));;
 
//设置数学类型以允许cuDNN使用Tensor Core:
checkCudnnErr(cudnnSetConvolutionMathType(cudnnConvDesc,CUDNN_TENSOR_OP_MATH_ALLOW_CONVERSION));
 
//选择支持的算法:
cudnnConvolutionFwdAlgo_t算法= CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_PRECOMP_GEMM;
 
//分配的工作空间:
checkCudnnErr(cudnnGetConvolutionForwardWorkspaceSize(handle_,cudnnIdesc,
cudnnFdesc,cudnnConvDesc,
cudnnOdesc,algo,&workSpaceSize));
 
如果(workSpaceSize> 0){
   cudaMalloc(&workSpace,workSpaceSize);
}
 
//调用卷积: 
checkCudnnErr(cudnnConvolutionForward(handle_,(void *)(&alpha),cudnnIdesc,devPtrI,
cudnnFdesc,devPtrF,cudnnConvDesc,algo,
workSpace,workSpaceSize,(void *)(&beta),
cudnnOdesc,devPtrO));

FP32性能

图2显示了将Tensor Core用于FP32张量数据时卷积的比较性能。该图表将V100张量运算与V100 FMA运算进行了比较,因此,其增益并不像以前的将V100性能与P100 FMA进行比较的图表那样明显。但是,与使用FMA ops相比,与FP32输入一起使用的Tensor ops仍然代表了可观的收益。

图2.具有Tensor Core的Tesla V100(Volta)与Tesla V100(Volta)的卷积性能比较。比较是在每个神经网络的卷积层运行时间的几何方法之间进行的。两种情况都使用FP32输入/输出数据和FP32计算。一种使用Tensor Core,另一种使用FP32融合乘加(FMA)。

剩余约束

尽管解除了在cuDNN中使用张量运算的主要限制,但仍然存在一些次要限制。一个限制是使用ALGO_1(IMPLICIT_PRECOMP_GEMM用于转发)。cuDNN中还没有其他卷积算法使用张量运算。

另一个较小的限制是卷积滤波器的大小,特别是空间尺寸(r和s)。但是,用于卷积的FFT算法非常适合于滤波器尺寸较大的用例。只需在超出张量运算滤波器限制以达到最佳性能之前就将卷积切换为使用FFT算法即可。

在cuDNN中简化Tensor Ops的更多相关文章

  1. 在PHP应用中简化OAuth2.0身份验证集成:OAuth 2.0 Client

    在PHP应用中简化OAuth2.0身份验证集成:OAuth 2.0 Client   阅读目录 验证代码流程 Refreshing a Token Built-In Providers 这个包能够让你 ...

  2. TensorFlow中的 tensor 张量到底是什么意思?

    详见[Reference]: TensorFlow中的“Tensor”到底是什么? 以下摘录一些要点: 这个图好生动呀!~ 标量和向量都是张量(tensor).

  3. tensorflow中张量(tensor)的属性——维数(阶)、形状和数据类型

    tensorflow的命名来源于本身的运行原理,tensor(张量)意味着N维数组,flow(流)意味着基于数据流图的计算,所以tensorflow字面理解为张量从流图的一端流动到另一端的计算过程. ...

  4. EL和 JSTL? 在JSP中简化 java代码的写法!

    一.servlet部分 package com.aaa.servlet; import com.aaa.dao.IStudentDAO; import com.aaa.dao.Impl.Student ...

  5. pytorch 中改变tensor维度的几种操作

    具体示例如下,注意观察维度的变化 #coding=utf-8 import torch """改变tensor的形状的四种不同变化形式""" ...

  6. Python中简化的验证码功能实现

    #!/usr/bin/env python # _*_ encoding:utf-8 _*_ # author:snate import random def generate_auth_code() ...

  7. Pytorch中ndarray tensor list互转

    1.ndarray->tensor : b=torch.from_numpy(a) 2.tensor->ndarray: b=a.numpy() ''' 但这么写会报错-- Runtime ...

  8. python中简化的验证码功能

    验证码一般用来验证登陆.交易等行为,减少对端为机器操作的概率,python中可以使用random模块,char()内置函数来实现一个简单的验证码功能. import random def veri_c ...

  9. VIM中简化删除,光标移动和查找操作

    # 一.命令行模式下简化删除 1. 向后删除单个字符:[x] 2. 向前删除单个字符:[X] 3. 删除从光标开始到单词结尾:[dw] 删除从光标后的2个单词:[d2w] 4. 删除整个单词:[daw ...

随机推荐

  1. animation几个比较好玩的属性(alternate,及animation-fill-mode)

    <!DOCTYPE html> <html> <head> <style> div { width:100px; height:100px; backg ...

  2. hdu4560 不错的建图,二分最大流

    题意: 我是歌手 Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Subm ...

  3. hdu3234 带权并查集(XOR)

    题意:       给你n个未知的正整数,有三总操作       I P V            P的值是V       I P Q V          P XOR Q = V       Q K ...

  4. Idea一直卡在loading archetype list问题解决(或者报Unable to import maven project: See logs for details)

    暂时没有测试成功 https://blog.csdn.net/calo_missile/article/details/95898519

  5. Activity,Tasks

    常见的一些Activity的打开方式: //1.拨打电话 // 给移动客服10086拨打电话 Uri uri = Uri.parse("tel:10086"); Intent in ...

  6. 【SpringMVC】数据校验时,抛出javax.validation.UnexpectedTypeException: HV000030: No validator could be found for type: java.util.Date.

    老魏原创,转载请留言. 原因:给Javabean中的字段注解多余或者错误导致. @NotEmpty @Past @DateTimeFormat(pattern="yyyy-MM-dd&quo ...

  7. windows下使用dos命令手工与ntp服务器同步系统时间

    管理员模式的命令窗口 net stop w32time &w32tm /unregister &w32tm /register &net start w32time & ...

  8. 初探MFC

    MFC MFC(Microsoft Foundation Classes) 是微软基础类库,也就是用c++类将win32API封装起来. 应用程序对象 MFC程序都是以应用程序对象为核心,且程序中只有 ...

  9. Kubernetes入门,使用minikube 搭建本地k8s 环境

    这是一篇 K8S 的 HelloWorld,在学习K8S官方文档时搭建环境搭建的一个记录,照着文档下来还是比较顺利的. 一.安装kubectl 下载 kubectl curl -LO "ht ...

  10. MzzTxx——团队贡献分分配方案

    项目 内容 这个作业属于哪个课程 2021春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 团队贡献分分配规则制定 我在这个课程的目标是 进一步提升工程化开发能力,积累团队协作经验,熟悉全栈 ...