text: #ifndef CAFFE_CUDNN_CONV_LAYER_HPP_
  #define CAFFE_CUDNN_CONV_LAYER_HPP_
  
  #include <vector>
  
  #include "caffe/blob.hpp"
  #include "caffe/layer.hpp"
  #include "caffe/proto/caffe.pb.h"
  
  #include "caffe/layers/conv_layer.hpp"
  
  namespace caffe {
  
  #ifdef USE_CUDNN
  /*
   * @brief cuDNN implementation of ConvolutionLayer.
   *        Fallback to ConvolutionLayer for CPU mode.
   *
   * cuDNN accelerates convolution through forward kernels for filtering and bias
   * plus backward kernels for the gradient w.r.t. the filters, biases, and
   * inputs. Caffe + cuDNN further speeds up the computation through forward
   * parallelism across groups and backward parallelism across gradients.
   *
   * The CUDNN engine does not have memory overhead for matrix buffers. For many
   * input and filter regimes the CUDNN engine is faster than the CAFFE engine,
   * but for fully-convolutional models and large inputs the CAFFE engine can be
   * faster as long as it fits in memory.
  */
  template <typename Dtype>
  class CuDNNConvolutionLayer : public ConvolutionLayer<Dtype> {
   public:
    explicit CuDNNConvolutionLayer(const LayerParameter& param)
        : ConvolutionLayer<Dtype>(param), handles_setup_(false) {}
    virtual void LayerSetUp(const vector<Blob<Dtype>*>& bottom,
        const vector<Blob<Dtype>*>& top);
    virtual void Reshape(const vector<Blob<Dtype>*>& bottom,
        const vector<Blob<Dtype>*>& top);
    virtual ~CuDNNConvolutionLayer();
  
   protected:
    virtual void Forward_gpu(const vector<Blob<Dtype>*>& bottom,
        const vector<Blob<Dtype>*>& top);
    virtual void Backward_gpu(const vector<Blob<Dtype>*>& top,
        const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom);
  
    bool handles_setup_;
    cudnnHandle_t* handle_;
    cudaStream_t*  stream_;
    vector<cudnnTensorDescriptor_t> bottom_descs_, top_descs_;
    cudnnTensorDescriptor_t    bias_desc_;
    cudnnFilterDescriptor_t      filter_desc_;
    vector<cudnnConvolutionDescriptor_t> conv_descs_;
    int bottom_offset_, top_offset_, weight_offset_, bias_offset_;
    size_t workspaceSizeInBytes;
    void *workspace;
  };
  #endif
  
  }  // namespace caffe
  
  #endif  // CAFFE_CUDNN_CONV_LAYER_HPP_
  