aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/contrib/lite/kernels/svdf_test.cc
diff options
context:
space:
mode:
authorGravatar Andrew Selle <aselle@google.com>2017-11-10 10:35:35 -0800
committerGravatar Andrew Selle <aselle@andyselle.com>2017-11-10 16:14:42 -0800
commit0b15439f8f0f2d4755587f4096c3ea04cb199d23 (patch)
tree9aa4fc8162bf9b4ee50112a7b85703f70ca4df08 /tensorflow/contrib/lite/kernels/svdf_test.cc
parent7ac140a5845553275427162aabd9d54987144b4a (diff)
Internal Change.
PiperOrigin-RevId: 175307445
Diffstat (limited to 'tensorflow/contrib/lite/kernels/svdf_test.cc')
-rw-r--r--tensorflow/contrib/lite/kernels/svdf_test.cc312
1 files changed, 312 insertions, 0 deletions
diff --git a/tensorflow/contrib/lite/kernels/svdf_test.cc b/tensorflow/contrib/lite/kernels/svdf_test.cc
new file mode 100644
index 0000000000..d956025e9d
--- /dev/null
+++ b/tensorflow/contrib/lite/kernels/svdf_test.cc
@@ -0,0 +1,312 @@
+/* Copyright 2017 The TensorFlow Authors. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+==============================================================================*/
+// Unit test for TFLite SVDF op.
+
+#include <vector>
+#include <iomanip>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+#include "tensorflow/contrib/lite/interpreter.h"
+#include "tensorflow/contrib/lite/kernels/register.h"
+#include "tensorflow/contrib/lite/kernels/test_util.h"
+#include "tensorflow/contrib/lite/model.h"
+
+namespace tflite {
+namespace {
+
+using ::testing::ElementsAreArray;
+
+static float svdf_input[] = {
+ 0.12609188, -0.46347019, -0.89598465,
+ 0.35867718, 0.36897406, 0.73463392,
+
+ 0.14278367, -1.64410412, -0.75222826,
+ -0.57290924, 0.12729003, 0.7567004,
+
+ 0.49837467, 0.19278903, 0.26584083,
+ 0.17660543, 0.52949083, -0.77931279,
+
+ -0.11186574, 0.13164264, -0.05349274,
+ -0.72674477, -0.5683046, 0.55900657,
+
+ -0.68892461, 0.37783599, 0.18263303,
+ -0.63690937, 0.44483393, -0.71817774,
+
+ -0.81299269, -0.86831826, 1.43940818,
+ -0.95760226, 1.82078898, 0.71135032,
+
+ -1.45006323, -0.82251364, -1.69082689,
+ -1.65087092, -1.89238167, 1.54172635,
+
+ 0.03966608, -0.24936394, -0.77526885,
+ 2.06740379, -1.51439476, 1.43768692,
+
+ 0.11771342, -0.23761693, -0.65898693,
+ 0.31088525, -1.55601168, -0.87661445,
+
+ -0.89477462, 1.67204106, -0.53235275,
+ -0.6230064, 0.29819036, 1.06939757,
+};
+
+static float svdf_golden_output_rank_1[] = {
+ 0.014899, -0.0517661, -0.143725, -0.00271883,
+ -0.03004015, 0.09565311, 0.1587342, 0.00784263,
+
+ 0.068281, -0.162217, -0.152268, 0.00323521,
+ 0.01582633, 0.03858774, -0.03001583, -0.02671271,
+
+ -0.0317821, -0.0333089, 0.0609602, 0.0333759,
+ -0.01432795, 0.05524484, 0.1101355, -0.02382665,
+
+ -0.00623099, -0.077701, -0.391193, -0.0136691,
+ -0.02333033, 0.02293761, 0.12338032, 0.04326871,
+
+ 0.201551, -0.164607, -0.179462, -0.0592739,
+ 0.01064911, -0.17503069, 0.07821996, -0.00224009,
+
+ 0.0886511, -0.0875401, -0.269283, 0.0281379,
+ -0.02282338, 0.09741908, 0.32973239, 0.12281385,
+
+ -0.201174, -0.586145, -0.628624, -0.0330412,
+ 0.24780814, -0.39304617, -0.22473189, 0.02589256,
+
+ -0.0839096, -0.299329, 0.108746, 0.109808,
+ 0.10084175, -0.06416984, 0.28936723, 0.0026358,
+
+ 0.419114, -0.237824, -0.422627, 0.175115,
+ -0.2314795, -0.18584411, -0.4228974, -0.12928449,
+
+ 0.36726, -0.522303, -0.456502, -0.175475,
+ 0.17012937, -0.34447709, 0.38505614, -0.28158101,
+};
+
+static float svdf_golden_output_rank_2[] = {
+ -0.09623547, -0.10193135, 0.11083051, -0.0347917,
+ 0.1141196, 0.12965347, -0.12652366, 0.01007236,
+
+ -0.16396809, -0.21247184, 0.11259045, -0.04156673,
+ 0.10132131, -0.06143532, -0.00924693, 0.10084561,
+
+ 0.01257364, 0.0506071, -0.19287863, -0.07162561,
+ -0.02033747, 0.22673416, 0.15487903, 0.02525555,
+
+ -0.1411963, -0.37054959, 0.01774767, 0.05867489,
+ 0.09607603, -0.0141301, -0.08995658, 0.12867066,
+
+ -0.27142537, -0.16955489, 0.18521598, -0.12528358,
+ 0.00331409, 0.11167502, 0.02218599, -0.07309391,
+
+ 0.09593632, -0.28361851, -0.0773851, 0.17199151,
+ -0.00075242, 0.33691186, -0.1536046, 0.16572715,
+
+ -0.27916506, -0.27626723, 0.42615682, 0.3225764,
+ -0.37472126, -0.55655634, -0.05013514, 0.289112,
+
+ -0.24418658, 0.07540751, -0.1940318, -0.08911639,
+ 0.00732617, 0.46737891, 0.26449674, 0.24888524,
+
+ -0.17225097, -0.54660404, -0.38795233, 0.08389944,
+ 0.07736043, -0.28260678, 0.15666828, 1.14949894,
+
+ -0.57454878, -0.64704704, 0.73235172, -0.34616736,
+ 0.21120001, -0.22927976, 0.02455296, -0.35906726,
+};
+
+// Derived class of SingleOpModel, which is used to test SVDF TFLite op.
+class SVDFOpModel : public SingleOpModel {
+ public:
+ SVDFOpModel(int batches, int units, int input_size, int memory_size, int rank)
+ : batches_(batches),
+ units_(units),
+ input_size_(input_size),
+ memory_size_(memory_size),
+ rank_(rank) {
+ input_ = AddInput(TensorType_FLOAT32);
+ weights_feature_ = AddInput(TensorType_FLOAT32);
+ weights_time_ = AddInput(TensorType_FLOAT32);
+ bias_ = AddNullInput();
+ state_ = AddOutput(TensorType_FLOAT32);
+ output_ = AddOutput(TensorType_FLOAT32);
+ SetBuiltinOp(
+ BuiltinOperator_SVDF, BuiltinOptions_SVDFOptions,
+ CreateSVDFOptions(builder_, rank, ActivationFunctionType_NONE).Union());
+ BuildInterpreter({
+ {batches_, input_size_}, // Input tensor
+ {units_ * rank, input_size_}, // weights_feature tensor
+ {units_ * rank, memory_size_}, // weights_time tensor
+ {units_} // bias tensor
+ });
+ }
+
+ // Populates the weights_feature tensor.
+ void SetWeightsFeature(std::initializer_list<float> f) {
+ PopulateTensor(weights_feature_, f);
+ }
+
+ // Populates the weights_time tensor.
+ void SetWeightsTime(std::initializer_list<float> f) {
+ PopulateTensor(weights_time_, f);
+ }
+
+ // Populates the input tensor.
+ void SetInput(int offset, float* begin, float* end) {
+ PopulateTensor(input_, offset, begin, end);
+ }
+
+ // Resets the state of SVDF op by filling it with 0's.
+ void ResetState() {
+ const int zero_buffer_size = rank_ * units_ * batches_ * memory_size_;
+ std::unique_ptr<float[]> zero_buffer(new float[zero_buffer_size]);
+ memset(zero_buffer.get(), 0, zero_buffer_size * sizeof(float));
+ PopulateTensor(state_, 0, zero_buffer.get(),
+ zero_buffer.get() + zero_buffer_size);
+ }
+
+ // Extracts the output tensor from the SVDF op.
+ std::vector<float> GetOutput() { return ExtractVector<float>(output_); }
+
+ int input_size() { return input_size_; }
+ int num_units() { return units_; }
+ int num_batches() { return batches_; }
+
+ private:
+ int input_;
+ int weights_feature_;
+ int weights_time_;
+ int bias_;
+ int state_;
+ int output_;
+
+ int batches_;
+ int units_;
+ int input_size_;
+ int memory_size_;
+ int rank_;
+};
+
+TEST(SVDFOpTest, BlackBoxTestRank1) {
+ SVDFOpModel svdf(/*batches=*/2, /*units=*/4, /*input_size=*/3,
+ /*memory_size=*/10, /*rank=*/1);
+ svdf.SetWeightsFeature({-0.31930989, -0.36118156, 0.0079667, 0.37613347,
+ 0.22197971, 0.12416199, 0.27901134, 0.27557442,
+ 0.3905206, -0.36137494, -0.06634006, -0.10640851});
+
+ svdf.SetWeightsTime(
+ {-0.31930989, 0.37613347, 0.27901134, -0.36137494, -0.36118156,
+ 0.22197971, 0.27557442, -0.06634006, 0.0079667, 0.12416199,
+
+ 0.3905206, -0.10640851, -0.0976817, 0.15294972, 0.39635518,
+ -0.02702999, 0.39296314, 0.15785322, 0.21931258, 0.31053296,
+
+ -0.36916667, 0.38031587, -0.21580373, 0.27072677, 0.23622236,
+ 0.34936687, 0.18174365, 0.35907319, -0.17493086, 0.324846,
+
+ -0.10781813, 0.27201805, 0.14324132, -0.23681851, -0.27115166,
+ -0.01580888, -0.14943552, 0.15465137, 0.09784451, -0.0337657});
+
+ svdf.ResetState();
+ const int svdf_num_batches = svdf.num_batches();
+ const int svdf_input_size = svdf.input_size();
+ const int svdf_num_units = svdf.num_units();
+ const int input_sequence_size =
+ sizeof(svdf_input) / sizeof(float) / (svdf_input_size * svdf_num_batches);
+ // Going over each input batch, setting the input tensor, invoking the SVDF op
+ // and checking the output with the expected golden values.
+ for (int i = 0; i < input_sequence_size; i++) {
+ float* batch_start = svdf_input + i * svdf_input_size * svdf_num_batches;
+ float* batch_end = batch_start + svdf_input_size * svdf_num_batches;
+ svdf.SetInput(0, batch_start, batch_end);
+
+ svdf.Invoke();
+
+ float* golden_start =
+ svdf_golden_output_rank_1 + i * svdf_num_units * svdf_num_batches;
+ float* golden_end = golden_start + svdf_num_units * svdf_num_batches;
+ std::vector<float> expected;
+ expected.insert(expected.end(), golden_start, golden_end);
+
+ EXPECT_THAT(svdf.GetOutput(), ElementsAreArray(ArrayFloatNear(expected)));
+ }
+}
+
+TEST(SVDFOpTest, BlackBoxTestRank2) {
+ SVDFOpModel svdf(/*batches=*/2, /*units=*/4, /*input_size=*/3,
+ /*memory_size=*/10, /*rank=*/2);
+ svdf.SetWeightsFeature({-0.31930989, 0.0079667, 0.39296314, 0.37613347,
+ 0.12416199, 0.15785322, 0.27901134, 0.3905206,
+ 0.21931258, -0.36137494, -0.10640851, 0.31053296,
+ -0.36118156, -0.0976817, -0.36916667, 0.22197971,
+ 0.15294972, 0.38031587, 0.27557442, 0.39635518,
+ -0.21580373, -0.06634006, -0.02702999, 0.27072677});
+
+ svdf.SetWeightsTime(
+ {-0.31930989, 0.37613347, 0.27901134, -0.36137494, -0.36118156,
+ 0.22197971, 0.27557442, -0.06634006, 0.0079667, 0.12416199,
+
+ 0.3905206, -0.10640851, -0.0976817, 0.15294972, 0.39635518,
+ -0.02702999, 0.39296314, 0.15785322, 0.21931258, 0.31053296,
+
+ -0.36916667, 0.38031587, -0.21580373, 0.27072677, 0.23622236,
+ 0.34936687, 0.18174365, 0.35907319, -0.17493086, 0.324846,
+
+ -0.10781813, 0.27201805, 0.14324132, -0.23681851, -0.27115166,
+ -0.01580888, -0.14943552, 0.15465137, 0.09784451, -0.0337657,
+
+ -0.14884081, 0.19931212, -0.36002168, 0.34663299, -0.11405486,
+ 0.12672701, 0.39463779, -0.07886535, -0.06384811, 0.08249187,
+
+ -0.26816407, -0.19905911, 0.29211238, 0.31264046, -0.28664589,
+ 0.05698794, 0.11613581, 0.14078894, 0.02187902, -0.21781836,
+
+ -0.15567942, 0.08693647, -0.38256618, 0.36580828, -0.22922277,
+ -0.0226903, 0.12878349, -0.28122205, -0.10850525, -0.11955214,
+
+ 0.27179423, -0.04710215, 0.31069002, 0.22672787, 0.09580326,
+ 0.08682203, 0.1258215, 0.1851041, 0.29228821, 0.12366763});
+
+ svdf.ResetState();
+ const int svdf_num_batches = svdf.num_batches();
+ const int svdf_input_size = svdf.input_size();
+ const int svdf_num_units = svdf.num_units();
+ const int input_sequence_size =
+ sizeof(svdf_input) / sizeof(float) / (svdf_input_size * svdf_num_batches);
+ // Going over each input batch, setting the input tensor, invoking the SVDF op
+ // and checking the output with the expected golden values.
+ for (int i = 0; i < input_sequence_size; i++) {
+ float* batch_start = svdf_input + i * svdf_input_size * svdf_num_batches;
+ float* batch_end = batch_start + svdf_input_size * svdf_num_batches;
+ svdf.SetInput(0, batch_start, batch_end);
+
+ svdf.Invoke();
+
+ float* golden_start =
+ svdf_golden_output_rank_2 + i * svdf_num_units * svdf_num_batches;
+ float* golden_end = golden_start + svdf_num_units * svdf_num_batches;
+ std::vector<float> expected;
+ expected.insert(expected.end(), golden_start, golden_end);
+
+ EXPECT_THAT(svdf.GetOutput(), ElementsAreArray(ArrayFloatNear(expected)));
+ }
+}
+
+} // namespace
+} // namespace tflite
+
+int main(int argc, char** argv) {
+ // On Linux, add: tflite::LogToStderr();
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}