Cudnn v5.1與V 6.0的特性

V5.1

新增特性

  1. 針對3*3以及5*5de 卷積核,添加了新的Winograd卷積算法,提供前向和後向計算。可以通過使用CUDNN_CONVOLUTION_FWD_ALGO_WINOGRAD_NONFUSED,CUDNN_CONVOLUTION_BWD_DATA_ALGO_WINOGRAD_NONFUSED以及CUDNN_CONVOLUTION_BWD_FILTER_ALGO_WINOGRAD_NONFUSED觸發使用。
  2. cudnnConvolutionBackwardData以及cudnnConvolutionBackwardFilter擴展了針對FP16計算的支持
  3. 爲很多常用的例子優化了LRN的性能

cudnn5.1與cudnn5.0接口保持完全兼容

V6

新增特性

  1. 空洞卷積(也稱爲膨脹卷積)Dilated Convolutions。目前在Cudnn中添加了對Dilated Convolution的支持,這一支持並未改變API。之前在Convolution Descriptor中未使用的域“upscale”,被定義成允許用戶指定每個維度上的膨脹因子。當前對dilation的支持可以通過一下代碼路徑獲取,
  2. Forward:CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_GEMM
  3. Backward Data: CUDNN_CONVOLUTION_BWD_DATA_ALOGO_0
  4. Backward Filter: CUDNN_CONVOLUTION_BWD_FILTER_ALGO_0

  5. 新添加的接口cudnnConvolutionBiasActivationForward允許單個kernel中混合Convolution, bias以及activation操作。目前只支持單通道bias以及RELU激活函數。

  6. 支持8位整型數據的Inference,使用CUDA 6.1計算能力,以及Pascal GPU上4元素點乘指令IDP4A。有兩類Tensor的佈局類型能夠支持該特性,分別是Int8數據類型的CUDNN_TENSOR_NHWC以及Int8*4數據類型的CUDNN_TENSOR_NCHW_VECT.
  7. RNN現在支持3中算法,分別是
  8. CUDNN_RNN_ALGO_STANDARD: 與CUDNN v5.1具備同樣的功能
  9. CUDNN_RNN_ALGO_PERSIST_STATIC: 這個算法依賴於針對不同GPU預編譯的一致性CUDA kernel的使用
  10. CUDNN_RNN_ALGO_PERSIST_DYNAMIC:這個算法同樣依賴於一致性CUDA kernel的使用,但是這些kernel都是在運行時使用nvrtc編譯。在一些場景中,能夠獲得不錯的性能表現。另外這個算法只能運行在Pascal GPU上,以及Linux和windows系統上。
  11. 添加了對於一維FFT卷積的支持
  12. 添加cudnnReduceTensor接口,支持8路Reduce操作
  13. 支持CUDNN_ACTIVATION_ELU激活模式。
  14. 添加了一種deterministic max pooling mode: CUDNN_POOLING_MAX_DETERMINISTIC。
  15. 當使用low batch number時,在softmax層,使用CUDNN_SOFTMAX_MODE_CHANNEL模式獲得很大的性能提升。
  16. 當空間維度設置爲1時,cudnnAddTensor獲得很大的性能提升。

    6.0.21與6.0.20的差異

    1. Dilated Convolutions(dilation_h>1 or dilation_w>1) 在6.0.20版本基於Kepler GPU會參數不正確結果的問題修復。
    2. 在V6,第一次在CUDNN中提出vector數據類型的idea。具體參考cudnn user guide。

V6中被移除的API

  1. 以下方法被移除:
    o cudnnSetFilter4dDescriptor_v3
    o cudnnSetFilter4dDescriptor_v4
    o cudnnGetFilter4dDescriptor_v3
    o cudnnGetFilter4dDescriptor_v4
    o cudnnSetFilterNdDescriptor_v3
    o cudnnSetFilterNdDescriptor_v4
    o cudnnGetFilterNdDescriptor_v3
    o cudnnGetFilterNdDescriptor_v4
    o cudnnSetPooling2dDescriptor_v3
    o cudnnSetPooling2dDescriptor_v4
    o cudnnGetPooling2dDescriptor_v3
    o cudnnGetPooling2dDescriptor_v4
    o cudnnSetPoolingNdDescriptor_v3
    o cudnnSetPoolingNdDescriptor_v4
    o cudnnGetPoolingNdDescriptor_v3
    o cudnnGetPoolingNdDescriptor_v4
    o cudnnActivationForward_v3
    o cudnnActivationForward_v4
    o cudnnActivationBackward_v3
    o cudnnActivationBackward_v4

2.API修改
cudnnConvolutionFwdAlgoPerf_t,cudnnConvolutionBwdFilterAlgoPerf_t,
cudnnConvolutionBwdDataAlgoPerf_t結構都修改並添加了新的域以及保留域。使用這些結構體的用戶並不需要修改任何的代碼,,只需重新編譯其應用確保應用的正確性。
在cudnnSetConvolutionNdDescriptor中將保留域upscale用於讓用於指定每個維度的膨脹因子。這一修改並不會對先用的使用造成影響,因爲都被設置成1,。然而,現在這些域可以被設置成大於1,用於dilated convolution,並使用指定的算法。

修復的bug

  1. Dilated Convolution在之前版本使用Kepler出現不正確結果的bug。
  2. CUDNN_CONVOLUTION_BWD_FILTER_ALGO_WINOGRAD_NONFUSED算法cudnnConvolutionBackwardFilter中,當c>32但是c並不是32的倍數。
  3. 當filter大小小於stride時,會出現非法內存訪問(cudnnConvolutionBackwardData)

cudnn API向後兼容性以及棄用策略

當需要改變cudnn中已有的一個API函數foo時,通常是用於支持一些新的特性,首先會創建一個新的API入口 foo_v,其中n代表第一次提出該方法的cudnn版本號,保持foo不動。這樣就能夠保證向後與CUDNN n-1版本保持兼容。這時,foo是被考慮要移除的,對於cudnn的使用者而言也是如此。
1. 在n+1版本中,遺留的foo入口將被映射到foo_v,f是n版本之前的版本號。
2. 所以在n+1版本中,沒有前綴的API入口foo也將被修改成foo_。
3. 之前被放棄的API入口,並且含有老版本前綴_v以及新的API入口_v將保留。
4. 在n+2版本上,給定的前綴入口均被移除。
當入口出現兩種不同的形式,一個有前綴一個沒有,那麼沒前綴的將是被認爲棄用。這種情況強烈建議用戶遷移到最新前綴的API入口,保證後續cudnn版本能夠向後兼容。當一個入口具有多個前綴,沒前綴的API入口被映射到更高數字的前綴。這種情況強烈建議使用沒有前綴的API入口,保證向後的兼容。

移除策略如下:
按照 cuDNN API 的演化規則,隨着 cuDNN 版本的更新,同一個 API 會有越來越多帶後綴的版本,會使得 cuDNN 臃腫、維護變得困難。因此,還需要 Deprecation 策略。所謂 Deprecation 策略,即演化過程中,對某些帶後綴 API 捨棄的機制。

cuDNN 新版本會確保向後兼容兩個版本。上篇以 cuDNN 從 v2 演化到 v4 爲例,因此不涉及到 Deprecation 策略。在這一篇,進一步演化到 v5, 介紹 Deprecation 策略。

如上篇所述,從 v2 演化到 v4,某個 API cudnnMyName 在 cuDNN v4 有如下三個版本,分別爲

_v2 修飾,即 cudnnMyName_v2, 以支持 v2 版本
_v3 修飾,即 cudnnMyName_v3, 以支持 v3 版本
不帶任何修飾,即 cudnnMyName, 功能與帶 _v3 修飾的一樣
那麼演化到 v5 時,它們各自如何變化呢?記住,v5 版本只向後支持兩個版本,即支持到 v3 。所以,該 API 三個版本有如下變化

捨棄 _v2 修飾的版本
由於 _v3 修飾的版本與不帶修飾的版本功能相同。因此,捨棄帶 _v3 修飾的版本、保留不帶修飾的版本
此時,該 API 在 v5 中只有一個版本——不帶任何修飾。從 v2 到 v5,該 API 的經過一系列演化,名字又變爲原來的樣子,但接口已經發生了變化。

最後,用 cuDNN 中一個實際的例子說明它的演化策略:cudnnSetConvolutionNdDescriptor 的演化。

v2 中,它的名字如下

cudnnSetConvolutionNdDescriptor
v3 中,它的接口發生變化,導致有如下兩個版本

cudnnSetConvolutionNdDescriptor,對應 v2 中舊的版本
cudnnSetConvolutionNdDescriptor_v3,對應 v3 中新的版本
v4 中,有如下三個版本

cudnnSetConvolutionNdDescriptor_v2,對應 v2 中舊的版本
cudnnSetConvolutionNdDescriptor_v3,對應 v3 中新的版本
cudnnSetConvolutionNdDescriptor,對應 v3 中新的版本
v5 中, Deprecation 起作用,只保留一個不帶任何後綴修飾的版本

cudnnSetConvolutionNdDescriptor,對應 v3 中新的版本

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章