Leaky Relu in CuDNN

username: avyz
cooked: <p>Hi,</p>
<p>The pytorch pre-trained DNN that I am following uses leaky RELU as an activation function in its layers. I am building the inference network on local machine using CuDNN which doesn’t seem to support leaky RELU as an activation function.</p>
<p>Please share any ideas / examples on how to use leaky RELU in CuDNN?</p>
<p>Thanks!</p>

username: ptrblck
cooked: <p>You could either write a custom kernel (or take a look at what PyTorch might be using internally) and/or create a feature request for cudnn in their support board.</p>

username: avyz
cooked: <p>Thanks <a class="mention" href="/u/ptrblck">@ptrblck</a></p>
<p>I did collect the log for the network so as to see what activation function Pytorch is using internally, but it doesn’t provide any information about the activation layer. However, I also verified that the other network which uses only RELU activation, its activation details were available. So, not sure why it hided leaky RELU’s activation detail. Also, I am using Google Colab, so not sure if that’s causing any bottleneck.</p>
<p>Regarding creating own kernel to implement leaky RELU, does it have any performance impact? Does CuDNN creates any internal pipelines or buffers to speed up the process and introducing own kernel will impact it?</p>

username: ptrblck
cooked: <p>I’m not sure what kind of logging you are looking at and where it’s showing the activation and where it doesn’t. Could you explain it a bit more?</p>
<aside class="quote no-group" data-username="avyz" data-post="3" data-topic="116766">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/a/e99b99/48.png" class="avatar"> avyz:</div>
<blockquote>
<p>Regarding creating own kernel to implement leaky RELU, does it have any performance impact? Does CuDNN creates any internal pipelines or buffers to speed up the process and introducing own kernel will impact it?</p>
</blockquote>
</aside>
<p>I was thinking about reusing PyTorch’s internal kernel.<br>
Since there is no leaky ReLU kernel in cudnn, there wouldn’t be any performance impact, as there wouldn’t be a cudnn baseline to compare against.</p>

username: avyz
cooked: <p><a class="mention" href="/u/ptrblck">@ptrblck</a> I am using cudnn API logging to collect the log files. Previously, I designed LeNet for hand written digit classification in Pytorch, which uses RELU in all its layers and for that I can see the activation function logged in.<br>
Here is a snippet of log file showing RELU activation function-</p>
<blockquote>
<p>I! CuDNN (v7605) function cudnnActivationForward() called:<br>
i!     handle: type=cudnnHandle_t; streamId=0000000000000000 (defaultStream);<br>
i!     activationDesc: type=cudnnActivationDescriptor_t:<br>
i!         coef: type=double; val=0.000000;<br>
i!         mode: type=cudnnActivationMode_t; val=CUDNN_ACTIVATION_RELU (1);<br>
i!         reluNanOpt: type=cudnnNanPropagation_t; val=CUDNN_PROPAGATE_NAN (1);<br>
i!     alpha: type=CUDNN_DATA_FLOAT; val=1.000000;<br>
i!     srcDesc: type=cudnnTensorDescriptor_t:<br>
i!         dataType: type=cudnnDataType_t; val=CUDNN_DATA_FLOAT (0);<br>
i!         nbDims: type=int; val=4;<br>
i!         dimA: type=int; val=[1,500,1,1];<br>
i!         strideA: type=int; val=[500,1,1,1];<br>
i!     srcData: location=dev; addr=000000070D060E00;<br>
i!     beta: type=CUDNN_DATA_FLOAT; val=0.000000;<br>
i!     destDesc: type=cudnnTensorDescriptor_t:<br>
i!         dataType: type=cudnnDataType_t; val=CUDNN_DATA_FLOAT (0);<br>
i!         nbDims: type=int; val=4;<br>
i!         dimA: type=int; val=[1,500,1,1];<br>
i!         strideA: type=int; val=[500,1,1,1];<br>
i!     destData: location=dev; addr=000000070D061600;<br>
i! Time: 2021-03-30T10:41:47.544918 (0d+0h+0m+4s since start)<br>
i! Process=40584; Thread=38684; GPU=0; Handle=0000022AB3F7E7E0; StreamId=0000000000000000 (defaultStream).</p>
</blockquote>
<p>However, currently I am working on UNet architecture, which uses leaky RELU in all its layers. Hence, to know how Pytorch implements leaky RELU given CuDNN doesn’t support it, I collected the log files again using cudnn API logging, but this time the log files doesn’t contain any information about the activation function.</p>
<hr>
<p>Given leaky RELU kernel implementation is simple, I was thinking about writing my own kernel. But, you mentioned about reusing Pytorch’s internal kernel. Can you please suggest / refer to how to get access to Pytorch’s internal kernels?</p>
<p>Thanks!</p>

username: ptrblck
cooked: <p>It’s called from <a href="https://github.com/pytorch/pytorch/blob/593295daacc28ed016f1d7456bd2ecd21c786544/aten/src/ATen/native/cuda/Activation.cu#L374-L381">here</a> using the <code>TensorIterator</code>.</p>