diff --git a/include/tim/vx/ops/max_pool3d.h b/include/tim/vx/ops/max_pool3d.h new file mode 100644 index 0000000..75f00f1 --- /dev/null +++ b/include/tim/vx/ops/max_pool3d.h @@ -0,0 +1,77 @@ +/**************************************************************************** +* +* Copyright (c) 2022 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ +#ifdef VSI_FEAT_OP_MAX_POOL3D +#ifndef TIM_VX_OPS_MAX_POOL3D_H_ +#define TIM_VX_OPS_MAX_POOL3D_H_ + +#include "tim/vx/builtin_op.h" +#include "tim/vx/types.h" +#include +namespace tim { +namespace vx { +namespace ops { + +/** + * ## Max_pool3d + * + * Applies a 3D max pooling over an input Tensor which can be regarded as a composition of 3D planes. + * + * Input: + * - input [WHDCN] + * - kernel [ WHD ] + * + * Attribute: + * - round_type : CEILING or FLOOR + * - ksize : the height and width for kernel tensor. + * - stride : stride along each spatial axis. + * - pad : pad value for each spatial axis. (left, right, top, bottom, front, rear). + * - pad_type : AUTO, VALID or SAME. + * + */ + +class MaxPool3d : public BuiltinOp { + public: + MaxPool3d(Graph* Graph, RoundType round_type, + const std::array& ksize, + const std::array& stride, + const std::array& pad, + PadType pad_type, + DataLayout layout = DataLayout::WHDCN); + + std::shared_ptr Clone(std::shared_ptr& graph) const override; + + protected: + const RoundType round_type_; + const std::array ksize_; + const std::array stride_; + const std::array pad_; + const PadType pad_type_; +}; + +} // namespace ops +} // namespace vx +} // namespace tim + +#endif /* TIM_VX_OPS_MAX_POOL3D_H_ */ +#endif //(VSI_FEAT_OP_MAX_POOL3D) \ No newline at end of file diff --git a/src/tim/vx/ops/README.md b/src/tim/vx/ops/README.md index 295b214..b988ab7 100644 --- a/src/tim/vx/ops/README.md +++ b/src/tim/vx/ops/README.md @@ -113,10 +113,11 @@ GroupedConv1d|GROUPED_CONV1D|Mapped|[tf.keras.layers.Conv1D](https://tensorflow. |TopK|TOPK|Mapped (limited support)|[tf.math.top_k](https://tensorflow.google.cn/api_docs/python/tf/math/top_k) |GRUCell|GRUCELL_OVXLIB|Mapped|[tf.keras.layers.GRUCell](https://tensorflow.google.cn/api_docs/python/tf/keras/layers/GRUCell?hl=en) |UnidirectionalSequenceGRU|GRU_OVXLIB|Mapped|[tf.keras.layers.GRU](https://tensorflow.google.cn/api_docs/python/tf/keras/layers/GRUCell?hl=en) -Mod|MOD|Mapped|[Onnx.mod](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Mod) +Mod|MOD|Mapped|[Onnx.Mod](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Mod) Selu|SELU|Mapped|[tf.keras.activations.selu](https://www.tensorflow.org/api_docs/python/tf/keras/activations/selu) Celu|CELU|Mapped|[Onnx.celu](https://github.com/onnx/onnx/blob/main/docs/Operators.md#Celu) Rcp|RCP|Mapped|[tf.math.reciprocal](https://www.tensorflow.org/api_docs/python/tf/math/reciprocal) +MaxPool3d|MAX_POOL3D|Mapped|[Onnx.MaxPool](https://github.com/onnx/onnx/blob/main/docs/Operators.md#MaxPool) |UnidirectionalSequenceRNN|UNIDIRECTIONAL_SEQUENCE_RNN|Planned 22Q3|[ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_RNN](https://developer.android.com/ndk/reference/group/neural-networks#group___neural_networks_1ggaabbe492c60331b13038e39d4207940e0ae11aa1d461d2abaa117f6ee2cb503dd8) |BidirectionalSequenceRNN|BIDIRECTIONAL_SEQUENCE_RNN|Planned 22Q3|[ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_RNN](https://developer.android.com/ndk/reference/group/neural-networks#group___neural_networks_1ggaabbe492c60331b13038e39d4207940e0a487fc5ae247de828f13e62b99f259f3c) |BidirectionalSequenceLSTM|BIDIRECTIONAL_SEQUENCE_LSTM|Mapped|[ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_LSTM](https://developer.android.com/ndk/reference/group/neural-networks#group___neural_networks_1ggaabbe492c60331b13038e39d4207940e0a492a71cb7aa50b9a1a834a3cb269d778) diff --git a/src/tim/vx/ops/max_pool3d.cc b/src/tim/vx/ops/max_pool3d.cc new file mode 100644 index 0000000..0f63cb3 --- /dev/null +++ b/src/tim/vx/ops/max_pool3d.cc @@ -0,0 +1,65 @@ +/**************************************************************************** +* +* Copyright (c) 2022 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ +#ifdef VSI_FEAT_OP_MAX_POOL3D +#include "tim/vx/ops/max_pool3d.h" +#include "type_utils.h" +#include "builtin_op_impl.h" +#include "vsi_nn_pub.h" + +namespace tim { +namespace vx { +namespace ops { +MaxPool3d::MaxPool3d(Graph* Graph, RoundType round_type, + const std::array& ksize, + const std::array& stride, + const std::array& pad, + PadType pad_type, + DataLayout layout) + : BuiltinOp(Graph, VSI_NN_OP_MAX_POOL3D, 1, 1, layout), + round_type_(round_type), + ksize_(ksize), + stride_(stride), + pad_(pad), + pad_type_(pad_type){ + this->impl()->node()->nn_param.max_pool3d.round_type = TranslateRoundType(round_type_); + this->impl()->node()->nn_param.max_pool3d.ksize[0] = ksize_[0]; + this->impl()->node()->nn_param.max_pool3d.ksize[1] = ksize_[1]; + this->impl()->node()->nn_param.max_pool3d.ksize[2] = ksize_[2]; + this->impl()->node()->nn_param.max_pool3d.stride[0] = stride_[0]; + this->impl()->node()->nn_param.max_pool3d.stride[1] = stride_[1]; + this->impl()->node()->nn_param.max_pool3d.stride[2] = stride_[2]; + for (int i = 0; i < 6; i++){this->impl()->node()->nn_param.max_pool3d.pad[i] = pad_[i];} + this->impl()->node()->nn_param.max_pool3d.pad_type = TranslatePadType(pad_type_); +} + +std::shared_ptr MaxPool3d::Clone(std::shared_ptr& graph) const { + return graph->CreateOperation( + this->round_type_, this->ksize_, this->stride_, this->pad_, this->pad_type_); +} + +} // namespace ops +} // namespace vx +} // namespace tim + +#endif //(VSI_FEAT_OP_MAX_POOL3D) \ No newline at end of file diff --git a/src/tim/vx/ops/max_pool3d_test.cc b/src/tim/vx/ops/max_pool3d_test.cc new file mode 100644 index 0000000..8a416b1 --- /dev/null +++ b/src/tim/vx/ops/max_pool3d_test.cc @@ -0,0 +1,119 @@ +/**************************************************************************** +* +* Copyright (c) 2022 Vivante Corporation +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +*****************************************************************************/ +#ifdef VSI_FEAT_OP_MAX_POOL3D + +#include "tim/vx/ops/max_pool3d.h" +#include "tim/vx/context.h" +#include "tim/vx/graph.h" +#include "gtest/gtest.h" + +TEST(MaxPool3d, shape_3_2_2_2_1_fp32_kernel_2_2_2_stride_1_1_1_VALID) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType in_shape({3, 2, 2, 2, 1});//whdcn + tim::vx::ShapeType out_shape({2, 1, 1, 2, 1});//whdcn + tim::vx::TensorSpec input_spec(tim::vx::DataType::FLOAT32, in_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec output_spec(tim::vx::DataType::FLOAT32, out_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto input_tensor = graph->CreateTensor(input_spec); + auto output_tensor = graph->CreateTensor(output_spec); + + std::vector in_data = { + 0, 1, 2, + 3, 4 ,5, // depth0 channel0 + 6, 7, 8, + 9, 10, 11, // depth1 channel0 + 12, 13, 14, + 15, 16, 17,// depth0 channel1 + 18, 19, 20, + 21, 22, 23 // depth1 channel1 + }; + std::vector golden = { + 10,11, + 22,23 + }; + + EXPECT_TRUE(input_tensor->CopyDataToTensor(in_data.data(), in_data.size() * 4)); + + auto round_type = tim::vx::RoundType::FLOOR; + std::array ksize = {2, 2, 2}; //whd + std::array stride = {1, 1, 1}; //whd + std::array pad = {0, 0, 0, 0, 0, 0}; + + auto op = graph->CreateOperation( + round_type, ksize, stride, pad, tim::vx::PadType::VALID); + (*op).BindInputs({input_tensor}).BindOutputs({output_tensor}); + + EXPECT_TRUE(graph->Compile()); + EXPECT_TRUE(graph->Run()); + + std::vector output(golden.size()); + EXPECT_TRUE(output_tensor->CopyDataFromTensor(output.data())); + EXPECT_EQ(golden, output); +} + +TEST(MaxPool3d, shape_4_2_2_1_1_fp32_kernel_2_2_2_stride_1_1_1_SAME) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType in_shape({4,2,2,1,1}); //whdcn + tim::vx::ShapeType out_shape({4,2,2,1,1}); //whdcn + tim::vx::TensorSpec input_spec(tim::vx::DataType::FLOAT32, in_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec output_spec(tim::vx::DataType::FLOAT32, out_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto input_tensor = graph->CreateTensor(input_spec); + auto output_tensor = graph->CreateTensor(output_spec); + + std::vector in_data = { + 0, 6, 2, 4, 2, 5, 4, 3, 3, 2, 10, 7, 3, 2, 2, 4 + }; + std::vector golden = { + 6, 10, 10, 7, 5, 5, 4, 4, 3, 10, + 10, 7, 3, 2, 4, 4 + }; + EXPECT_TRUE(input_tensor->CopyDataToTensor(in_data.data(), in_data.size() * 4)); + + auto round_type = tim::vx::RoundType::FLOOR; + std::array ksize = {2, 2, 2}; + std::array stride = {1, 1, 1}; + std::array pad = {0, 0, 0, 0, 0, 0}; + + auto op = graph->CreateOperation( + round_type, ksize, stride, pad, tim::vx::PadType::SAME); + (*op).BindInputs({input_tensor}).BindOutputs({output_tensor}); + + EXPECT_TRUE(graph->Compile()); + EXPECT_TRUE(graph->Run()); + + std::vector output(golden.size()); + EXPECT_TRUE(output_tensor->CopyDataFromTensor(output.data())); + EXPECT_EQ(golden, output); +} + +# endif //(VSI_FEAT_OP_MAX_POOL3D) \ No newline at end of file