27 #ifndef MAXPOOLLAYER_H_ 
   28 #define MAXPOOLLAYER_H_ 
   58 template <
typename Architecture_t>
 
   59 class TMaxPoolLayer : 
public VGeneralLayer<Architecture_t>  {
 
   62    using Tensor_t = 
typename Architecture_t::Tensor_t;
 
   63    using Matrix_t = 
typename Architecture_t::Matrix_t;
 
   64    using Scalar_t = 
typename Architecture_t::Scalar_t;
 
   66    using LayerDescriptor_t = 
typename Architecture_t::PoolingDescriptor_t;
 
   67    using WeightsDescriptor_t = 
typename Architecture_t::EmptyDescriptor_t;
 
   68    using HelperDescriptor_t = 
typename Architecture_t::DropoutDescriptor_t;
 
   71    using AlgorithmForward_t = 
typename Architecture_t::AlgorithmForward_t;   
 
   72    using AlgorithmBackward_t = 
typename Architecture_t::AlgorithmBackward_t; 
 
   73    using AlgorithmHelper_t = 
typename Architecture_t::AlgorithmHelper_t;     
 
   76    using AlgorithmDataType_t = 
typename Architecture_t::AlgorithmDataType_t;
 
   78    using ReduceTensorDescriptor_t = 
typename Architecture_t::ReduceTensorDescriptor_t; 
 
   88    size_t fNLocalViewPixels; 
 
   91    Scalar_t fDropoutProbability; 
 
   93    TDescriptors *fDescriptors = 
nullptr; 
 
   95    TWorkspace *fWorkspace = 
nullptr;
 
   98    Tensor_t fIndexTensor; 
 
  100    void InitializeDescriptors();
 
  101    void ReleaseDescriptors();
 
  102    void InitializeWorkspace();
 
  103    void FreeWorkspace();
 
  107    TMaxPoolLayer(
size_t BatchSize, 
size_t InputDepth, 
size_t InputHeight, 
size_t InputWidth, 
size_t FilterHeight,
 
  108                  size_t FilterWidth, 
size_t StrideRows, 
size_t StrideCols, Scalar_t DropoutProbability);
 
  111    TMaxPoolLayer(TMaxPoolLayer<Architecture_t> *layer);
 
  114    TMaxPoolLayer(
const TMaxPoolLayer &);
 
  117    virtual ~TMaxPoolLayer();
 
  125    void Forward(Tensor_t &input, 
bool applyDropout = 
true);
 
  131    void Backward(Tensor_t &gradients_backward, 
const Tensor_t &activations_backward);
 
  135    virtual void AddWeightsXMLTo(
void *parent);
 
  138    virtual void ReadWeightsFromXML(
void *parent);
 
  144    size_t GetFilterDepth()
 const { 
return fFilterDepth; }
 
  145    size_t GetFilterHeight()
 const { 
return fFilterHeight; }
 
  146    size_t GetFilterWidth()
 const { 
return fFilterWidth; }
 
  148    size_t GetStrideRows()
 const { 
return fStrideRows; }
 
  149    size_t GetStrideCols()
 const { 
return fStrideCols; }
 
  151    size_t GetNLocalViews()
 const { 
return fNLocalViews; }
 
  153    Scalar_t GetDropoutProbability()
 const { 
return fDropoutProbability; }
 
  155    const Tensor_t & GetIndexTensor()
 const { 
return fIndexTensor; }
 
  156    Tensor_t & GetIndexTensor() { 
return fIndexTensor; }
 
  159    TDescriptors *GetDescriptors() { 
return fDescriptors; }
 
  160    const TDescriptors *GetDescriptors()
 const { 
return fDescriptors; }
 
  162    TWorkspace *GetWorkspace() { 
return fWorkspace; }
 
  163    const TWorkspace *GetWorkspace()
 const { 
return fWorkspace; }
 
  167 template <
typename Architecture_t>
 
  168 TMaxPoolLayer<Architecture_t>::TMaxPoolLayer(
size_t batchSize, 
size_t inputDepth, 
size_t inputHeight, 
size_t inputWidth,
 
  169                                              size_t filterHeight, 
size_t filterWidth, 
size_t strideRows,
 
  170                                              size_t strideCols, Scalar_t dropoutProbability)
 
  171    : VGeneralLayer<Architecture_t>(
 
  172         batchSize, inputDepth, inputHeight, inputWidth, inputDepth,
 
  173         TConvLayer<Architecture_t>::calculateDimension(inputHeight, filterHeight, 0, strideRows),
 
  174         TConvLayer<Architecture_t>::calculateDimension(inputWidth, filterWidth, 0, strideCols), 0, 0, 0, 0, 0,
 
  176         batchSize, inputDepth,
 
  177         TConvLayer<Architecture_t>::calculateNLocalViews(inputHeight, filterHeight, 0, strideRows, inputWidth,
 
  178                                                          filterWidth, 0, strideCols),
 
  179         EInitialization::kZero),
 
  180      fFilterDepth(inputDepth), fFilterHeight(filterHeight), fFilterWidth(filterWidth), fStrideRows(strideRows),
 
  181      fStrideCols(strideCols),
 
  182      fNLocalViews(TConvLayer<Architecture_t>::calculateNLocalViews(inputHeight, filterHeight, 0, strideRows,
 
  183                                                                    inputWidth, filterWidth, 0, strideCols)),
 
  184      fDropoutProbability(dropoutProbability), fIndexTensor(batchSize, inputDepth, fNLocalViews)
 
  186    InitializeDescriptors();
 
  187    InitializeWorkspace();
 
  191 template <
typename Architecture_t>
 
  192 TMaxPoolLayer<Architecture_t>::TMaxPoolLayer(TMaxPoolLayer<Architecture_t> *layer)
 
  193    : VGeneralLayer<Architecture_t>(layer), fFilterDepth(layer->GetFilterDepth()),
 
  194      fFilterHeight(layer->GetFilterHeight()), fFilterWidth(layer->GetFilterWidth()),
 
  195      fStrideRows(layer->GetStrideRows()), fStrideCols(layer->GetStrideCols()), fNLocalViews(layer->GetNLocalViews()),
 
  196      fDropoutProbability(layer->GetDropoutProbability()), fIndexTensor(layer->GetIndexTensor().GetShape())
 
  198    InitializeDescriptors();
 
  199    InitializeWorkspace();
 
  203 template <
typename Architecture_t>
 
  204 TMaxPoolLayer<Architecture_t>::TMaxPoolLayer(
const TMaxPoolLayer &layer)
 
  205    : VGeneralLayer<Architecture_t>(layer), fFilterDepth(layer.fFilterDepth), fFilterHeight(layer.fFilterHeight),
 
  206      fFilterWidth(layer.fFilterWidth), fStrideRows(layer.fStrideRows), fStrideCols(layer.fStrideCols),
 
  207      fNLocalViews(layer.fNLocalViews), fDropoutProbability(layer.fDropoutProbability),
 
  208      fIndexTensor(layer.GetIndexTensor().GetShape())
 
  210    InitializeDescriptors();
 
  211    InitializeWorkspace();
 
  215 template <
typename Architecture_t>
 
  216 TMaxPoolLayer<Architecture_t>::~TMaxPoolLayer()
 
  219       ReleaseDescriptors();
 
  221       fDescriptors = 
nullptr;
 
  227       fWorkspace = 
nullptr;
 
  232 template <
typename Architecture_t>
 
  233 auto TMaxPoolLayer<Architecture_t>::Forward(Tensor_t &input, 
bool applyDropout) -> 
void 
  235    if (applyDropout && (this->GetDropoutProbability() != 1.0)) {
 
  236       Architecture_t::DropoutForward(input, fDescriptors, fWorkspace, this->GetDropoutProbability());
 
  239    Architecture_t::Downsample(
 
  240       this->GetOutput(), fIndexTensor, input, (TCNNDescriptors<TMaxPoolLayer<Architecture_t>> &)*fDescriptors,
 
  241       (TCNNWorkspace<TMaxPoolLayer<Architecture_t>> &)*fWorkspace, this->GetInputHeight(), this->GetInputWidth(),
 
  242       this->GetFilterHeight(), this->GetFilterWidth(), this->GetStrideRows(), this->GetStrideCols());
 
  246 template <
typename Architecture_t>
 
  247 auto TMaxPoolLayer<Architecture_t>::Backward(Tensor_t &gradients_backward, 
const Tensor_t &activations_backward) -> 
void 
  251    if (this->GetDropoutProbability() != 1.0) {
 
  252       Architecture_t::DropoutBackward(this->GetActivationGradients(), fDescriptors, fWorkspace);
 
  254    Architecture_t::MaxPoolLayerBackward(
 
  255       gradients_backward, this->GetActivationGradients(), fIndexTensor, activations_backward, this->GetOutput(),
 
  256       (TCNNDescriptors<TMaxPoolLayer<Architecture_t>> &)(*fDescriptors),
 
  257       (TCNNWorkspace<TMaxPoolLayer<Architecture_t>> &)(*fWorkspace), this->GetInputHeight(), this->GetInputWidth(),
 
  258       this->GetFilterHeight(), this->GetFilterWidth(), this->GetStrideRows(), this->GetStrideCols(),
 
  259       this->GetNLocalViews());
 
  263 template <
typename Architecture_t>
 
  264 auto TMaxPoolLayer<Architecture_t>::Print() const -> 
void 
  266    std::cout << 
" POOL Layer: \t";
 
  267    std::cout << 
"( W = " << this->GetWidth() << 
" , ";
 
  268    std::cout << 
" H = " << this->GetHeight() << 
" , ";
 
  269    std::cout << 
" D = " << this->GetDepth() << 
" ) ";
 
  271    std::cout << 
"\t Filter ( W = " << this->GetFilterWidth() << 
" , ";
 
  272    std::cout << 
" H = " << this->GetFilterHeight() << 
" ) ";
 
  274    if (this->GetOutput().GetSize() > 0) {
 
  275       std::cout << 
"\tOutput = ( " << this->GetOutput().GetFirstSize() << 
" , " << this->GetOutput().GetCSize()
 
  276                 << 
" , " << this->GetOutput().GetHSize() << 
" , " << this->GetOutput().GetWSize() << 
" ) ";
 
  278    std::cout << std::endl;
 
  282 template <
typename Architecture_t>
 
  283 void TMaxPoolLayer<Architecture_t>::AddWeightsXMLTo(
void *parent)
 
  285    auto layerxml = gTools().xmlengine().NewChild(parent, 0, 
"MaxPoolLayer");
 
  288    gTools().xmlengine().NewAttr(layerxml, 0, 
"FilterHeight", gTools().StringFromInt(this->GetFilterHeight()));
 
  289    gTools().xmlengine().NewAttr(layerxml, 0, 
"FilterWidth", gTools().StringFromInt(this->GetFilterWidth()));
 
  290    gTools().xmlengine().NewAttr(layerxml, 0, 
"StrideRows", gTools().StringFromInt(this->GetStrideRows()));
 
  291    gTools().xmlengine().NewAttr(layerxml, 0, 
"StrideCols", gTools().StringFromInt(this->GetStrideCols()));
 
  296 template <
typename Architecture_t>
 
  297 void TMaxPoolLayer<Architecture_t>::ReadWeightsFromXML(
void * )
 
  303 template <
typename Architecture_t>
 
  304 void TMaxPoolLayer<Architecture_t>::InitializeDescriptors() {
 
  305    Architecture_t::InitializePoolDescriptors(fDescriptors, 
this);
 
  308 template <
typename Architecture_t>
 
  309 void TMaxPoolLayer<Architecture_t>::ReleaseDescriptors() {
 
  310    Architecture_t::ReleasePoolDescriptors(fDescriptors);
 
  314 template <
typename Architecture_t>
 
  315 void TMaxPoolLayer<Architecture_t>::InitializeWorkspace() {
 
  325 template <
typename Architecture_t>
 
  326 void TMaxPoolLayer<Architecture_t>::FreeWorkspace() {