From 6175e6d8cc039ba5dbd16251e28c9e38766c062b Mon Sep 17 00:00:00 2001 From: "Efimov Alexander/AI Tools Lab/./Samsung Electronics" Date: Wed, 19 Sep 2018 15:41:09 +0300 Subject: [PATCH] Add border type in pooling operation (#1579) * Add border type that describes content of pool input outside of it's shape * Support this property in importers * Fix warning in tflite_op_creator.cpp Signed-off-by: Efimov Alexander --- contrib/nnc/include/core/modelIR/operations/pool_op.h | 14 ++++++++++++-- contrib/nnc/passes/caffe_frontend/caffe_op_creator.cpp | 14 +++++++++++++- contrib/nnc/passes/tflite_frontend/tflite_op_creator.cpp | 8 +++++--- contrib/nnc/unittests/soft_backend/CPPOperations.cpp | 5 +++-- 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/contrib/nnc/include/core/modelIR/operations/pool_op.h b/contrib/nnc/include/core/modelIR/operations/pool_op.h index 4cb6d12..a0bc5b7 100644 --- a/contrib/nnc/include/core/modelIR/operations/pool_op.h +++ b/contrib/nnc/include/core/modelIR/operations/pool_op.h @@ -33,15 +33,24 @@ public: MIN }; + enum class BorderType + { + ZEROFILLED, // elements outside of input considered zero + EMPTY // Consider that there are no elements outside of input shape + }; + explicit PoolOp(const Shape &windowShape, const Shape &strides, PoolingType poolType, - PaddingType padding) - : OpDescription(1, 1), _padding(padding), _poolingType(poolType), _windowShape(windowShape), _strides(strides) + PaddingType padding, BorderType borderType) + : OpDescription(1, 1), _padding(padding), _poolingType(poolType), + _borderType(borderType), _windowShape(windowShape), _strides(strides) { _pads.resize(_windowShape.rank()); } PaddingType getPaddingType() const { return _padding; } + BorderType getBorderType() const { return _borderType; } + PoolingType getPoolingType() const { return _poolingType; } const Shape &getWindowShape() const { return _windowShape; } @@ -55,6 +64,7 @@ public: private: PaddingType _padding; PoolingType _poolingType; + BorderType _borderType; Shape _windowShape; Shape _strides; std::vector _pads; diff --git a/contrib/nnc/passes/caffe_frontend/caffe_op_creator.cpp b/contrib/nnc/passes/caffe_frontend/caffe_op_creator.cpp index 3e3b69b..7786384 100644 --- a/contrib/nnc/passes/caffe_frontend/caffe_op_creator.cpp +++ b/contrib/nnc/passes/caffe_frontend/caffe_op_creator.cpp @@ -340,8 +340,20 @@ std::vector OpCreator::createPool(InputOps inputs, InputParams param ops::PoolOp::PoolingType poolType = util::getPoolingType(opts); ops::PaddingType padType = ops::PaddingType::Custom; Shape stride = util::getPoolStride(opts); + ops::PoolOp::BorderType borderType; + switch (poolType) + { + case ops::PoolOp::PoolingType::AVG: + borderType = ops::PoolOp::BorderType::ZEROFILLED; + break; + case ops::PoolOp::PoolingType::MAX: + borderType = ops::PoolOp::BorderType::EMPTY; + break; + default: + throw PassException("Unsupported pooling type"); + } - auto pooling = createOp(inputs, windowShape, stride, poolType, padType); + auto pooling = createOp(inputs, windowShape, stride, poolType, padType, borderType); // Set pads auto op = static_cast(pooling[0]->getOperation()); diff --git a/contrib/nnc/passes/tflite_frontend/tflite_op_creator.cpp b/contrib/nnc/passes/tflite_frontend/tflite_op_creator.cpp index bbba2f6..80aa03f 100644 --- a/contrib/nnc/passes/tflite_frontend/tflite_op_creator.cpp +++ b/contrib/nnc/passes/tflite_frontend/tflite_op_creator.cpp @@ -62,7 +62,8 @@ std::vector OpCreator::createMaxPool(InputOps inputs, InputParams pa static_cast(opts->filter_width()), 1}, Shape{static_cast(opts->stride_h()), static_cast(opts->stride_w()), 1}, - ops::PoolOp::PoolingType::MAX, paddingMap[opts->padding()]); + ops::PoolOp::PoolingType::MAX, paddingMap[opts->padding()], + ops::PoolOp::BorderType::EMPTY); } std::vector OpCreator::createAvgPool(InputOps inputs, InputParams params, @@ -73,7 +74,8 @@ std::vector OpCreator::createAvgPool(InputOps inputs, InputParams pa static_cast(opts->filter_width()), 1}, Shape{static_cast(opts->stride_h()), static_cast(opts->stride_w()), 1}, - ops::PoolOp::PoolingType::AVG, paddingMap[opts->padding()]); + ops::PoolOp::PoolingType::AVG, paddingMap[opts->padding()], + ops::PoolOp::BorderType::EMPTY); } std::vector OpCreator::createSoftmax(InputOps inputs, InputParams params, @@ -143,7 +145,7 @@ void OpCreator::connectInputs(INode::Ref op, std::vector &inputs) // TODO: this part doesn't support the situation where an operator takes as input // some tensor that is not the 0th output of some other operator assert(inputs.size() == op->getOperation()->getNumInputs()); - for (int i = 0; i < inputs.size(); ++i) + for (size_t i = 0; i < inputs.size(); ++i) { op->connectInputTo(i, inputs[i]->getOutput(0)); } diff --git a/contrib/nnc/unittests/soft_backend/CPPOperations.cpp b/contrib/nnc/unittests/soft_backend/CPPOperations.cpp index 7867f2b..33dc795 100644 --- a/contrib/nnc/unittests/soft_backend/CPPOperations.cpp +++ b/contrib/nnc/unittests/soft_backend/CPPOperations.cpp @@ -410,11 +410,12 @@ static void genericPoolTest(Func testFunc) data::Shape windowShape{windowH, windowW, 1}; data::Shape strides{strideH, strideW, 1}; auto padT = IR::model::ops::PaddingType::Valid; + auto borderT = IR::model::ops::PoolOp::BorderType::EMPTY; Tensor aInputTensor; vector> inputNTensors(1); fillTensors(inputNTensors[0], aInputTensor, shapeData, 1.0f); - auto opGenerator = [windowShape, strides, padT](Graph &g) { - return g.create("y", windowShape, strides, poolT, padT); + auto opGenerator = [windowShape, strides, padT, borderT](Graph &g) { + return g.create("y", windowShape, strides, poolT, padT, borderT); }; createAndRunTestGraph(opGenerator, testFunc, inputNTensors, aInputTensor); -- 2.7.4