在cuDNN中簡化Tensor Ops

2022-02-03 10:36:06 字數 4480 閱讀 7612

在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張量資料),直接進行改進。

關於在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));
將在後面的部分中看到使用**片段的上下文。

現在還為rnn啟用了類似的fp32資料轉換。只需將cudnn_tensor_op_math_allow_conversion列舉值傳遞給cudnnsetrnnmatrixmathtype()呼叫,即可將fp32資料轉換為在rnn中使用。如下使用:

//設定數學型別以允許cudnn使用tensor core:
checkcudnnerr(cudnnsetrnnmatrixmathtype(cudnnrnndesc,cudnn_tensor_op_math_allow_conversion));
早期版本的cudnn要求所有張量的通道維數必須為8的倍數。cudnn可以根據需要自動填充張量。

cudnn_tensor_op_mathcudnn_tensor_op_math_allow_conversion情況下,對於填充的nchw資料,此填充都是自動的。發生填充時,效能損失可忽略不計。

//設定nchw張量尺寸,不必設定為8的倍數(此處僅顯示輸入張量):
intdima  = ;
intstridea  = ;
下一節中的示例**演示了如何使用。

將張量運算用於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的倍數(此處僅顯示輸入張量):
intdima  = ;
intstridea  = ;
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)
//呼叫卷積:
checkcudnnerr(cudnnconvolutionforward(handle_,(void*)(&alpha),cudnnidesc,devptri,
cudnnfdesc,devptrf,cudnnconvdesc,algo,
workspace,workspacesize,(void*)(&beta),
cudnnodesc,devptro));
圖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演算法即可。

在PyTorch中Tensor的查詢和篩選例子

本文原始碼基於版本1.0,互動介面基於0.4.1 import torch 按照指定軸上的座標進行過濾 index select 沿著某tensor的乙個軸dim篩選若干個座標 x torwww.cppcns.comch.randn 3,4 目標矩陣 x tensor 0.1427,0.0231,0...

驗證cuDNN在Linux上的安裝

驗證cudnn在linux上的安裝 要驗證cudnn是否已安裝並正常執行,請編譯位於以下位置的mnistcudnn示例 usr src cudnn samples v7 debian檔案中的目錄。將cudnn示例複製到可寫路徑。cp r usr src cudnn samples v7 home 轉...

pytorch中tensor型別轉換

tensor轉numpy tensor.numpy numpy轉tensor torch.from numpy 2 tensor與list tensor轉list tensor.tolist list轉tensor torch.tensor 3 tensor型別轉換 tensor torch.ten...