aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/contrib/lite/kernels/pad_test.cc
diff options
context:
space:
mode:
authorGravatar Suharsh Sivakumar <suharshs@google.com>2018-04-06 14:13:49 -0700
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2018-04-06 14:16:02 -0700
commit3745f2582daeae7a49a129e250cf0cc2d573924a (patch)
tree87f036afd0bd6ae32ac624d883adeac60a7e772a /tensorflow/contrib/lite/kernels/pad_test.cc
parent8413fb51307c0274ae4db31181c531de046eb309 (diff)
Pad support for quantized zero.
PiperOrigin-RevId: 191938267
Diffstat (limited to 'tensorflow/contrib/lite/kernels/pad_test.cc')
-rw-r--r--tensorflow/contrib/lite/kernels/pad_test.cc129
1 files changed, 111 insertions, 18 deletions
diff --git a/tensorflow/contrib/lite/kernels/pad_test.cc b/tensorflow/contrib/lite/kernels/pad_test.cc
index 28834ad071..c06237e572 100644
--- a/tensorflow/contrib/lite/kernels/pad_test.cc
+++ b/tensorflow/contrib/lite/kernels/pad_test.cc
@@ -22,6 +22,7 @@ namespace tflite {
namespace {
using ::testing::ElementsAreArray;
+using ::testing::Matcher;
class PadOpModel : public SingleOpModel {
public:
@@ -29,6 +30,10 @@ class PadOpModel : public SingleOpModel {
PopulateTensor<float>(input_, data);
}
+ void SetQuantizedInput(std::initializer_list<float> data) {
+ QuantizeAndPopulate<uint8_t>(input_, data);
+ }
+
void SetPaddings(std::initializer_list<int> paddings) {
PopulateTensor<int>(paddings_, paddings);
}
@@ -36,6 +41,11 @@ class PadOpModel : public SingleOpModel {
std::vector<float> GetOutput() { return ExtractVector<float>(output_); }
std::vector<int> GetOutputShape() { return GetTensorShape(output_); }
+ std::vector<float> GetDequantizedOutput() {
+ return Dequantize<uint8_t>(ExtractVector<uint8_t>(output_),
+ GetScale(output_), GetZeroPoint(output_));
+ }
+
protected:
int input_;
int output_;
@@ -50,16 +60,17 @@ class PadOpModel : public SingleOpModel {
// m.Invoke();
class PadOpConstModel : public PadOpModel {
public:
- PadOpConstModel(std::initializer_list<int> input_shape,
+ PadOpConstModel(const TensorData& input,
std::initializer_list<int> paddings_shape,
- std::initializer_list<int> paddings) {
- input_ = AddInput(TensorType_FLOAT32);
+ std::initializer_list<int> paddings,
+ const TensorData& output) {
+ input_ = AddInput(input);
paddings_ = AddConstInput(TensorType_INT32, paddings, paddings_shape);
- output_ = AddOutput(TensorType_FLOAT32);
+ output_ = AddOutput(output);
SetBuiltinOp(BuiltinOperator_PAD, BuiltinOptions_PadOptions,
CreatePadOptions(builder_).Union());
- BuildInterpreter({input_shape});
+ BuildInterpreter({input.shape});
}
};
@@ -72,40 +83,45 @@ class PadOpConstModel : public PadOpModel {
// m.Invoke();
class PadOpDynamicModel : public PadOpModel {
public:
- PadOpDynamicModel(std::initializer_list<int> input_shape,
- std::initializer_list<int> paddings_shape) {
- input_ = AddInput(TensorType_FLOAT32);
+ PadOpDynamicModel(const TensorData& input,
+ std::initializer_list<int> paddings_shape,
+ const TensorData& output) {
+ input_ = AddInput(input);
paddings_ = AddInput(TensorType_INT32);
- output_ = AddOutput(TensorType_FLOAT32);
+ output_ = AddOutput(output);
SetBuiltinOp(BuiltinOperator_PAD, BuiltinOptions_PadOptions,
CreatePadOptions(builder_).Union());
- BuildInterpreter({input_shape, paddings_shape});
+ BuildInterpreter({input.shape, paddings_shape});
}
};
TEST(PadOpTest, TooManyDimensions) {
EXPECT_DEATH(
- PadOpConstModel({1, 2, 3, 4, 5, 6, 7, 8, 9}, {9, 2},
- {1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9}),
+ PadOpConstModel({TensorType_FLOAT32, {1, 2, 3, 4, 5, 6, 7, 8, 9}}, {9, 2},
+ {1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9},
+ {TensorType_FLOAT32}),
"dims != 4");
}
TEST(PadOpTest, UnequalDimensions) {
- EXPECT_DEATH(PadOpConstModel({1, 1, 2, 1}, {3, 2}, {1, 1, 2, 2, 3, 3}),
+ EXPECT_DEATH(PadOpConstModel({TensorType_FLOAT32, {1, 1, 2, 1}}, {3, 2},
+ {1, 1, 2, 2, 3, 3}, {TensorType_FLOAT32}),
"3 != 4");
}
TEST(PadOpTest, InvalidPadValue) {
EXPECT_DEATH(
- PadOpConstModel({1, 1, 2, 1}, {4, 2}, {0, 0, 1, -1, 2, -1, 0, 0}),
+ PadOpConstModel({TensorType_FLOAT32, {1, 1, 2, 1}}, {4, 2},
+ {0, 0, 1, -1, 2, -1, 0, 0}, {TensorType_FLOAT32}),
"Pad value has to be greater than equal to 0.");
}
TEST(PadOpTest, SimpleConstTest) {
// Padding is represented as four 2-D lists representing above padding and
// below padding (i.e. {{0, 0}, {1, 1}, {1, 1}, {0, 0}}).
- PadOpConstModel m({1, 2, 2, 1}, {4, 2}, {0, 0, 1, 1, 1, 1, 0, 0});
+ PadOpConstModel m({TensorType_FLOAT32, {1, 2, 2, 1}}, {4, 2},
+ {0, 0, 1, 1, 1, 1, 0, 0}, {TensorType_FLOAT32});
m.SetInput({1, 2, 3, 4});
m.Invoke();
EXPECT_THAT(m.GetOutput(), ElementsAreArray({0, 0, 0, 0, 0, 1, 2, 0, 0, 3, 4,
@@ -114,7 +130,8 @@ TEST(PadOpTest, SimpleConstTest) {
}
TEST(PadOpTest, SimpleDynamicTest) {
- PadOpDynamicModel m({1, 2, 2, 1}, {4, 2});
+ PadOpDynamicModel m({TensorType_FLOAT32, {1, 2, 2, 1}}, {4, 2},
+ {TensorType_FLOAT32});
m.SetInput({1, 2, 3, 4});
m.SetPaddings({0, 0, 1, 1, 1, 1, 0, 0});
m.Invoke();
@@ -124,7 +141,8 @@ TEST(PadOpTest, SimpleDynamicTest) {
}
TEST(PadOpTest, AdvancedConstTest) {
- PadOpConstModel m({1, 2, 3, 1}, {4, 2}, {0, 0, 0, 2, 1, 3, 0, 0});
+ PadOpConstModel m({TensorType_FLOAT32, {1, 2, 3, 1}}, {4, 2},
+ {0, 0, 0, 2, 1, 3, 0, 0}, {TensorType_FLOAT32});
m.SetInput({1, 2, 3, 4, 5, 6});
m.Invoke();
EXPECT_THAT(m.GetOutput(),
@@ -134,7 +152,8 @@ TEST(PadOpTest, AdvancedConstTest) {
}
TEST(PadOpTest, AdvancedDynamicTest) {
- PadOpDynamicModel m({1, 2, 3, 1}, {4, 2});
+ PadOpDynamicModel m({TensorType_FLOAT32, {1, 2, 3, 1}}, {4, 2},
+ {TensorType_FLOAT32});
m.SetInput({1, 2, 3, 4, 5, 6});
m.SetPaddings({0, 0, 0, 2, 1, 3, 0, 0});
m.Invoke();
@@ -144,6 +163,80 @@ TEST(PadOpTest, AdvancedDynamicTest) {
EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({1, 4, 7, 1}));
}
+class QuantizedPadOpTest : public ::testing::Test {
+ protected:
+ std::vector<Matcher<float>> DequantizedArrayNear(
+ const std::vector<float>& values, const float min, const float max) {
+ const float quantization_tolerance = (max - min) / 255.0;
+ return ArrayFloatNear(values, quantization_tolerance);
+ }
+};
+
+TEST_F(QuantizedPadOpTest, ZeroNotInQuantizationRange) {
+ // The test_util and actual quantization code currently ensure that the range
+ // must include zero, but if that ever changes, this test will catch it.
+ EXPECT_DEATH(PadOpConstModel m({TensorType_UINT8, {1, 2, 2, 1}, 1.0, 2.0},
+ {4, 2}, {0, 0, 1, 1, 1, 1, 0, 0},
+ {TensorType_UINT8, {}, 1.0, 2.0}),
+ ".*Check failed: f_min <= 0.*");
+}
+
+TEST_F(QuantizedPadOpTest, SimpleConstTest) {
+ // Padding is represented as four 2-D lists representing above padding and
+ // below padding (i.e. {{0, 0}, {1, 1}, {1, 1}, {0, 0}}).
+ PadOpConstModel m({TensorType_UINT8, {1, 2, 2, 1}, -1.0, 1.0}, {4, 2},
+ {0, 0, 1, 1, 1, 1, 0, 0},
+ {TensorType_UINT8, {}, -1.0, 1.0});
+ m.SetQuantizedInput({-0.8, 0.2, 0.9, 0.7});
+ m.Invoke();
+ EXPECT_THAT(m.GetDequantizedOutput(),
+ ElementsAreArray(DequantizedArrayNear(
+ {0, 0, 0, 0, 0, -0.8, 0.2, 0, 0, 0.9, 0.7, 0, 0, 0, 0, 0},
+ -1.0, 1.0)));
+ EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({1, 4, 4, 1}));
+}
+
+TEST_F(QuantizedPadOpTest, SimpleDynamicTest) {
+ PadOpDynamicModel m({TensorType_UINT8, {1, 2, 2, 1}, -1.0, 1.0}, {4, 2},
+ {TensorType_UINT8, {}, -1.0, 1.0});
+ m.SetQuantizedInput({-0.8, 0.2, 0.9, 0.7});
+ m.SetPaddings({0, 0, 1, 1, 1, 1, 0, 0});
+ m.Invoke();
+ EXPECT_THAT(m.GetDequantizedOutput(),
+ ElementsAreArray(DequantizedArrayNear(
+ {0, 0, 0, 0, 0, -0.8, 0.2, 0, 0, 0.9, 0.7, 0, 0, 0, 0, 0},
+ -1.0, 1.0)));
+ EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({1, 4, 4, 1}));
+}
+
+TEST_F(QuantizedPadOpTest, AdvancedConstTest) {
+ PadOpConstModel m({TensorType_UINT8, {1, 2, 3, 1}, -1.0, 1.0}, {4, 2},
+ {0, 0, 0, 2, 1, 3, 0, 0},
+ {TensorType_UINT8, {}, -1.0, 1.0});
+ m.SetQuantizedInput({-0.8, 0.2, 0.9, 0.7, 0.1, -0.3});
+ m.Invoke();
+ EXPECT_THAT(m.GetDequantizedOutput(),
+ ElementsAreArray(DequantizedArrayNear(
+ {0, -0.8, 0.2, 0.9, 0, 0, 0, 0, 0.7, 0.1, -0.3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ -1.0, 1.0)));
+ EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({1, 4, 7, 1}));
+}
+
+TEST_F(QuantizedPadOpTest, AdvancedDynamicTest) {
+ PadOpDynamicModel m({TensorType_UINT8, {1, 2, 3, 1}, -1.0, 1.0}, {4, 2},
+ {TensorType_UINT8, {}, -1.0, 1.0});
+ m.SetQuantizedInput({-0.8, 0.2, 0.9, 0.7, 0.1, -0.3});
+ m.SetPaddings({0, 0, 0, 2, 1, 3, 0, 0});
+ m.Invoke();
+ EXPECT_THAT(m.GetDequantizedOutput(),
+ ElementsAreArray(DequantizedArrayNear(
+ {0, -0.8, 0.2, 0.9, 0, 0, 0, 0, 0.7, 0.1, -0.3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+ -1.0, 1.0)));
+ EXPECT_THAT(m.GetOutputShape(), ElementsAreArray({1, 4, 7, 1}));
+}
+
} // namespace
} // namespace tflite