a2db98670a
Signed-off-by: Micaela Verucchi <micaelaverucchi@gmail.com>
128 lines
3.2 KiB
C++
128 lines
3.2 KiB
C++
#include <iostream>
|
|
|
|
#include "Layer.h"
|
|
#include "kernels.h"
|
|
|
|
namespace tk { namespace dnn {
|
|
|
|
Pooling::Pooling( Network *net, int winH, int winW, int strideH, int strideW,
|
|
int paddingH, int paddingW,
|
|
tkdnnPoolingMode_t pool_mode) :
|
|
Layer(net) {
|
|
|
|
this->winH = winH;
|
|
this->winW = winW;
|
|
this->strideH = strideH;
|
|
this->strideW = strideW;
|
|
this->pool_mode = pool_mode;
|
|
this->paddingH = paddingH;
|
|
this->paddingW = paddingW;
|
|
|
|
checkCUDNN( cudnnCreatePoolingDescriptor(&poolingDesc) );
|
|
|
|
int n = input_dim.n;
|
|
int c = input_dim.c;
|
|
int h = input_dim.h;
|
|
int w = input_dim.w;
|
|
int l = input_dim.l;
|
|
|
|
printf("before: %d %d\n", h, w);
|
|
|
|
|
|
poolOn3d = false;
|
|
|
|
if(l > 1) {
|
|
poolOn3d = true;
|
|
|
|
if(n != 1)
|
|
FatalError("N value on 3d pool must be 1");
|
|
|
|
//use batch as l
|
|
n = l;
|
|
}
|
|
|
|
|
|
|
|
checkCUDNN( cudnnSetPooling2dDescriptor(poolingDesc, cudnnPoolingMode_t(pool_mode),
|
|
CUDNN_NOT_PROPAGATE_NAN, winH, winW, paddingH, paddingW, strideH, strideW) );
|
|
|
|
checkCUDNN( cudnnSetTensor4dDescriptor(srcTensorDesc,
|
|
net->tensorFormat, net->dataType, n, c, h, w) );
|
|
|
|
//get out dim
|
|
// checkCUDNN( cudnnGetPooling2dForwardOutputDim(poolingDesc, srcTensorDesc, &n, &c, &h, &w));
|
|
|
|
//compute w and h as in darknet
|
|
|
|
int padH = paddingH == 0? winH -1 : paddingH;
|
|
int padW = paddingW == 0? winW -1 : paddingW;
|
|
|
|
h = (h + padH - winH)/strideH +1;
|
|
w = (w + padW - winW)/strideW +1;
|
|
|
|
// h = (h + winH*this->paddingH)/strideH;
|
|
// w = (w + winW*this->paddingW)/strideW;
|
|
|
|
checkCUDNN( cudnnSetTensor4dDescriptor(dstTensorDesc,
|
|
net->tensorFormat, net->dataType, n, c, h, w) );
|
|
|
|
printf("after: %d %d\n", h, w);
|
|
|
|
output_dim.n = n;
|
|
output_dim.c = c;
|
|
output_dim.h = h;
|
|
output_dim.w = w;
|
|
output_dim.l = l;
|
|
|
|
checkCuda( cudaMalloc(&dstData, output_dim.tot()*sizeof(dnnType)) );
|
|
|
|
//pool on 3d data need transposition at the enter and on the exit
|
|
//allocate for initial and final transposition
|
|
if(poolOn3d) {
|
|
output_dim.n = 1;
|
|
|
|
checkCuda( cudaMalloc(&tmpInputData, input_dim.tot()*sizeof(dnnType)) );
|
|
checkCuda( cudaMalloc(&tmpOutputData, output_dim.tot()*sizeof(dnnType)) );
|
|
}
|
|
|
|
}
|
|
|
|
Pooling::~Pooling() {
|
|
|
|
if(poolOn3d) {
|
|
checkCuda( cudaFree(tmpInputData) );
|
|
checkCuda( cudaFree(tmpOutputData) );
|
|
}
|
|
|
|
checkCUDNN( cudnnDestroyPoolingDescriptor(poolingDesc) );
|
|
checkCuda( cudaFree(dstData) );
|
|
}
|
|
|
|
dnnType* Pooling::infer(dataDim_t &dim, dnnType* srcData) {
|
|
|
|
dnnType *poolSrc = srcData;
|
|
dnnType *poolDst = dstData;
|
|
|
|
if(poolOn3d) {
|
|
matrixTranspose(net->cublasHandle, srcData, tmpInputData, dim.h*dim.w*dim.c, dim.l);
|
|
poolSrc = tmpInputData;
|
|
poolDst = tmpOutputData;
|
|
}
|
|
|
|
dnnType alpha = dnnType(1);
|
|
dnnType beta = dnnType(0);
|
|
checkCUDNN( cudnnPoolingForward(net->cudnnHandle, poolingDesc,
|
|
&alpha, srcTensorDesc, poolSrc,
|
|
&beta, dstTensorDesc, poolDst) );
|
|
|
|
//update dim
|
|
dim = output_dim;
|
|
|
|
if(poolOn3d)
|
|
matrixTranspose(net->cublasHandle, tmpOutputData, dstData, dim.l, dim.h*dim.w*dim.c);
|
|
|
|
return dstData;
|
|
}
|
|
|
|
}}
|