From 516a914c7307d52d16d525b93af8014f7301b32c Mon Sep 17 00:00:00 2001 From: chxin66 <57057788+chxin66@users.noreply.github.com> Date: Wed, 10 Nov 2021 20:07:06 +0800 Subject: [PATCH] Mapped Erf operation & unit tests (#211) Signed-off-by: Chen Xin Co-authored-by: Chen Xin --- include/tim/vx/ops.h | 2 + include/tim/vx/ops/erf.h | 53 ++++++++++++++++ src/tim/vx/ops/README.md | 2 +- src/tim/vx/ops/erf.cc | 42 +++++++++++++ src/tim/vx/ops/erf_test.cc | 124 +++++++++++++++++++++++++++++++++++++ 5 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 include/tim/vx/ops/erf.h create mode 100644 src/tim/vx/ops/erf.cc create mode 100644 src/tim/vx/ops/erf_test.cc diff --git a/include/tim/vx/ops.h b/include/tim/vx/ops.h index ac7b90f..e9b378f 100644 --- a/include/tim/vx/ops.h +++ b/include/tim/vx/ops.h @@ -38,6 +38,7 @@ #include "tim/vx/ops/depth2space.h" #include "tim/vx/ops/dropout.h" #include "tim/vx/ops/elementwise.h" +#include "tim/vx/ops/erf.h" #include "tim/vx/ops/fullyconnected.h" #include "tim/vx/ops/gather.h" #include "tim/vx/ops/gathernd.h" @@ -75,6 +76,7 @@ #include "tim/vx/ops/squeeze.h" #include "tim/vx/ops/stack.h" #include "tim/vx/ops/stridedslice.h" +#include "tim/vx/ops/svdf.h" #include "tim/vx/ops/tile.h" #include "tim/vx/ops/transpose.h" #include "tim/vx/ops/unidirectional_sequence_lstm.h" diff --git a/include/tim/vx/ops/erf.h b/include/tim/vx/ops/erf.h new file mode 100644 index 0000000..2aabeb5 --- /dev/null +++ b/include/tim/vx/ops/erf.h @@ -0,0 +1,53 @@ +/**************************************************************************** +* +* Copyright (c) 2021 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. +* +*****************************************************************************/ +#ifndef TIM_VX_OPS_ERF_H_ +#define TIM_VX_OPS_ERF_H_ + +#include "tim/vx/operation.h" +#include "tim/vx/types.h" + +namespace tim { +namespace vx { +namespace ops { + +/** + * ## Erf + * + * Computes the Gauss error function of x element-wise. + * + * - no parameters + */ + +class Erf : public Operation { + public: + Erf(Graph* graph); + std::shared_ptr Clone(std::shared_ptr& graph) const override; + }; + +} // namespace ops +} // namespace vx +} // namespace tim + +#endif /* TIM_VX_OPS_ERF_H_ */ + diff --git a/src/tim/vx/ops/README.md b/src/tim/vx/ops/README.md index ccd6000..8746aa5 100644 --- a/src/tim/vx/ops/README.md +++ b/src/tim/vx/ops/README.md @@ -100,10 +100,10 @@ SpatialTransformer|SPATIAL_TRANSFORMER|Mapped|[SpatialTransformer](https://githu shuffle_channel|SHUFFLECHANNEL|Mapped|[ANEURALNETWORKS_CHANNEL_SHUFFLE](https://developer.android.com/ndk/reference/group/neural-networks#group___neural_networks_1ggaabbe492c60331b13038e39d4207940e0a5b993c1211c4b1bc52fb595a3025251d) Gelu|GELU|Mapped|[tf.nn.gelu](https://tensorflow.google.cn/api_docs/python/tf/nn/gelu) Svdf|SVDF|Mapped|[ANEURALNETWORKS_SVDF](https://developer.android.com/ndk/reference/group/neural-networks#group___neural_networks_1ggaabbe492c60331b13038e39d4207940e0a7096de21038c1ce49d354a00cba7b552) +Erf|ERF|Mapped|[tf.math.erf](https://tensorflow.google.cn/api_docs/python/tf/math/erf) ||PROPOSAL| TBD |[Faster-RCNN Proposal Layer](https://github.com/intel/caffe/blob/master/examples/faster-rcnn/lib/rpn/proposal_layer.py) ||ROI_POOL|Planned 22Q1 |[ANEURALNETWORKS_ROI_POOLING](https://developer.android.com/ndk/reference/group/neural-networks#group___neural_networks_1ggaabbe492c60331b13038e39d4207940e0a6736198af337b2efbdb0b6b64dee7fe4) ||ROI_ALIGN| TBD |[ANEURALNETWORKS_ROI_ALIGN](https://developer.android.com/ndk/reference/group/neural-networks#group___neural_networks_1ggaabbe492c60331b13038e39d4207940e0a2848b39dd4bfba78f2438fda0d9397a4) -||SHUFFLECHANNEL|Mapped|[ANEURALNETWORKS_CHANNEL_SHUFFLE](https://developer.android.com/ndk/reference/group/neural-networks#group___neural_networks_1ggaabbe492c60331b13038e39d4207940e0a5b993c1211c4b1bc52fb595a3025251d) ||SIGNAL_FRAME|Planned 21Q3|[tf.signal.frame](https://tensorflow.google.cn/api_docs/python/tf/signal/frame) ||TOPK|Planned 21Q4|[tf.math.top_k](https://tensorflow.google.cn/api_docs/python/tf/math/top_k) |GRUCell|GRUCELL_OVXLIB|Planned 21Q3|[tf.keras.layers.GRUCell](https://tensorflow.google.cn/api_docs/python/tf/keras/layers/GRUCell?hl=en) diff --git a/src/tim/vx/ops/erf.cc b/src/tim/vx/ops/erf.cc new file mode 100644 index 0000000..40c737f --- /dev/null +++ b/src/tim/vx/ops/erf.cc @@ -0,0 +1,42 @@ +/**************************************************************************** +* +* Copyright (c) 2021 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. +* +*****************************************************************************/ +#include "tim/vx/ops/erf.h" + +#include "operation_private.h" +#include "type_utils.h" +#include "vsi_nn_pub.h" + +namespace tim { +namespace vx { +namespace ops { + +Erf::Erf(Graph* graph) : Operation(graph, VSI_NN_OP_ERF) {} + +std::shared_ptr Erf::Clone(std::shared_ptr& graph) const { + return graph->CreateOperation(); +} + +} // namespace ops +} // namespace vx +} // namespace tim \ No newline at end of file diff --git a/src/tim/vx/ops/erf_test.cc b/src/tim/vx/ops/erf_test.cc new file mode 100644 index 0000000..84b5b75 --- /dev/null +++ b/src/tim/vx/ops/erf_test.cc @@ -0,0 +1,124 @@ +/**************************************************************************** +* +* Copyright (c) 2021 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. +* +*****************************************************************************/ +#include "tim/vx/context.h" +#include "tim/vx/graph.h" +#include "tim/vx/ops/erf.h" + +#include "gtest/gtest.h" +#include "test_utils.h" + +TEST(Erf, shape_3_2_fp32) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType in_shape({3, 2}); + tim::vx::ShapeType out_shape({3, 2}); + tim::vx::TensorSpec in_spec(tim::vx::DataType::FLOAT32, in_shape, + tim::vx::TensorAttribute::INPUT); + tim::vx::TensorSpec out_spec(tim::vx::DataType::FLOAT32, out_shape, + tim::vx::TensorAttribute::OUTPUT); + + auto in_tensor = graph->CreateTensor(in_spec); + auto out_tensor = graph->CreateTensor(out_spec); + + std::vector in_data = { + 1, 2, 3, + 0,-1,-2}; + std::vector golden = { + 0.8427007, 0.9953223, 0.999978, + 0 ,-0.8427007,-0.9953223}; + + EXPECT_TRUE(in_tensor->CopyDataToTensor(in_data.data(), + in_data.size() * sizeof(float))); + auto op = graph->CreateOperation(); + (*op).BindInput(in_tensor).BindOutput(out_tensor); + + EXPECT_TRUE(graph->Compile()); + EXPECT_TRUE(graph->Run()); + + std::vector output(golden.size()); + EXPECT_TRUE(out_tensor->CopyDataFromTensor(output.data())); + EXPECT_TRUE(ArraysMatch(golden, output, 1e-2f)); +} + +TEST(Erf, shape_3_2_uint8_Quantized) { + auto ctx = tim::vx::Context::Create(); + auto graph = ctx->CreateGraph(); + + tim::vx::ShapeType in_shape({3, 2}); + tim::vx::ShapeType out_shape({3, 2}); + + const float InputMin = -128, InputMax = 127, OutputMin = -128, + OutputMax = 127; + + std::pair scalesAndZp; + + scalesAndZp = QuantizationParams(InputMin, InputMax); + std::vector scalesInput = {scalesAndZp.first}; //scale + std::vector zeroPointsInput = {scalesAndZp.second}; //zero point + + scalesAndZp = QuantizationParams(OutputMin, OutputMax); + std::vector scalesOutput = {scalesAndZp.first}; + std::vector zeroPointsOutput = {scalesAndZp.second}; + + tim::vx::Quantization quantInput(tim::vx::QuantType::ASYMMETRIC, 1, + scalesInput, zeroPointsInput); + tim::vx::Quantization quantOutput(tim::vx::QuantType::ASYMMETRIC, 1, + scalesOutput, zeroPointsOutput); + + tim::vx::TensorSpec input_spec(tim::vx::DataType::UINT8, in_shape, + tim::vx::TensorAttribute::INPUT, quantInput); + + tim::vx::TensorSpec output_spec(tim::vx::DataType::UINT8, out_shape, + tim::vx::TensorAttribute::OUTPUT, + quantOutput); + + auto input_tensor = graph->CreateTensor(input_spec); + auto output_tensor = graph->CreateTensor(output_spec); + + std::vector in_data_float = { + 1, 2, 3, + 0,-1,-2}; + std::vector golden_float = { + 0.8427007, 0.9953223, 0.999978, + 0 ,-0.8427007,-0.9953223}; + + std::vector input_data = + Quantize(in_data_float, scalesInput[0], + zeroPointsInput[0]); //Quantification process + std::vector golden = + Quantize(golden_float, scalesOutput[0], zeroPointsOutput[0]); + + EXPECT_TRUE( + input_tensor->CopyDataToTensor(input_data.data(), input_data.size() * 4)); + auto op = graph->CreateOperation(); + (*op).BindInput(input_tensor).BindOutput(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); +} \ No newline at end of file