1 /* Copyright 2021 The TensorFlow Authors. All Rights Reserved. 2 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 ==============================================================================*/ 15 16 #ifndef TENSORFLOW_LITE_DELEGATES_XNNPACK_QUANTIZED_REDUCE_TESTER_H_ 17 #define TENSORFLOW_LITE_DELEGATES_XNNPACK_QUANTIZED_REDUCE_TESTER_H_ 18 19 #include <cstdint> 20 #include <unordered_set> 21 #include <vector> 22 23 #include <gtest/gtest.h> 24 #include "tensorflow/lite/c/common.h" 25 #include "tensorflow/lite/interpreter.h" 26 #include "tensorflow/lite/schema/schema_generated.h" 27 28 namespace tflite { 29 namespace xnnpack { 30 31 class QuantizedReduceTester { 32 public: 33 QuantizedReduceTester() = default; 34 QuantizedReduceTester(const QuantizedReduceTester&) = delete; 35 QuantizedReduceTester& operator=(const QuantizedReduceTester&) = delete; 36 InputShape(std::initializer_list<int32_t> shape)37 inline QuantizedReduceTester& InputShape( 38 std::initializer_list<int32_t> shape) { 39 for (auto it = shape.begin(); it != shape.end(); ++it) { 40 EXPECT_GT(*it, 0); 41 } 42 input_shape_ = std::vector<int32_t>(shape.begin(), shape.end()); 43 input_size_ = QuantizedReduceTester::ComputeSize(input_shape_); 44 return *this; 45 } 46 InputShape()47 inline const std::vector<int32_t>& InputShape() const { return input_shape_; } 48 InputSize()49 inline int32_t InputSize() const { return input_size_; } 50 Axes(std::initializer_list<int32_t> axes)51 inline QuantizedReduceTester& Axes(std::initializer_list<int32_t> axes) { 52 for (auto it = axes.begin(); it != axes.end(); ++it) { 53 EXPECT_GE(*it, 0); 54 } 55 axes_ = std::vector<int32_t>(axes.begin(), axes.end()); 56 return *this; 57 } 58 Axes()59 inline const std::vector<int32_t>& Axes() const { return axes_; } 60 KeepDims(bool keep_dims)61 inline QuantizedReduceTester& KeepDims(bool keep_dims) { 62 keep_dims_ = keep_dims; 63 return *this; 64 } 65 KeepDims()66 inline bool KeepDims() const { return keep_dims_; } 67 OutputShape()68 inline std::vector<int32_t> OutputShape() const { 69 std::vector<int32_t> output_shape; 70 output_shape.reserve(InputShape().size()); 71 std::unordered_set<int32_t> axes_set(Axes().cbegin(), Axes().cend()); 72 for (int32_t i = 0; i < InputShape().size(); i++) { 73 if (axes_set.count(i) != 0) { 74 if (KeepDims()) { 75 output_shape.push_back(1); 76 } 77 } else { 78 output_shape.push_back(InputShape()[i]); 79 } 80 } 81 return output_shape; 82 } 83 OutputSize()84 inline int32_t OutputSize() const { 85 int32_t output_size = 1; 86 std::unordered_set<int32_t> axes_set(Axes().cbegin(), Axes().cend()); 87 for (int32_t i = 0; i < InputShape().size(); i++) { 88 if (axes_set.count(i) == 0) { 89 output_size *= InputShape()[i]; 90 } 91 } 92 return output_size; 93 } 94 InputZeroPoint(int32_t input_zero_point)95 inline QuantizedReduceTester& InputZeroPoint(int32_t input_zero_point) { 96 input_zero_point_ = input_zero_point; 97 return *this; 98 } 99 InputZeroPoint()100 inline int32_t InputZeroPoint() const { return input_zero_point_; } 101 OutputZeroPoint(int32_t output_zero_point)102 inline QuantizedReduceTester& OutputZeroPoint(int32_t output_zero_point) { 103 output_zero_point_ = output_zero_point; 104 return *this; 105 } 106 OutputZeroPoint()107 inline int32_t OutputZeroPoint() const { return output_zero_point_; } 108 InputScale(float input_scale)109 inline QuantizedReduceTester& InputScale(float input_scale) { 110 input_scale_ = input_scale; 111 return *this; 112 } 113 InputScale()114 inline float InputScale() const { return input_scale_; } 115 OutputScale(float output_scale)116 inline QuantizedReduceTester& OutputScale(float output_scale) { 117 output_scale_ = output_scale; 118 return *this; 119 } 120 OutputScale()121 inline float OutputScale() const { return output_scale_; } 122 Unsigned(bool is_unsigned)123 inline QuantizedReduceTester& Unsigned(bool is_unsigned) { 124 unsigned_ = is_unsigned; 125 return *this; 126 } 127 Unsigned()128 inline bool Unsigned() const { return unsigned_; } 129 130 template <class T> 131 void Test(Interpreter* delegate_interpreter, 132 Interpreter* default_interpreter) const; 133 134 void Test(tflite::BuiltinOperator reduce_op, TfLiteDelegate* delegate) const; 135 136 private: 137 std::vector<char> CreateTfLiteModel(tflite::BuiltinOperator reduce_op) const; 138 139 static int32_t ComputeSize(const std::vector<int32_t>& shape); 140 141 std::vector<int32_t> input_shape_; 142 std::vector<int32_t> axes_; 143 int32_t input_size_; 144 bool keep_dims_ = true; 145 int32_t input_zero_point_ = 1; 146 int32_t output_zero_point_ = 2; 147 float input_scale_ = 1.25f; 148 float output_scale_ = 0.75f; 149 bool unsigned_ = false; 150 }; 151 152 } // namespace xnnpack 153 } // namespace tflite 154 155 #endif // TENSORFLOW_LITE_DELEGATES_XNNPACK_QUANTIZED_REDUCE_TESTER_H_ 156