ArmNN  NotReleased
DeepSpeechV1InferenceTest.hpp
Go to the documentation of this file.
1 //
2 // Copyright © 2017 Arm Ltd. All rights reserved.
3 // SPDX-License-Identifier: MIT
4 //
5 #pragma once
6 
7 #include "InferenceTest.hpp"
9 
10 #include <boost/assert.hpp>
11 #include <boost/core/ignore_unused.hpp>
12 #include <boost/numeric/conversion/cast.hpp>
13 #include <boost/test/tools/floating_point_comparison.hpp>
14 
15 #include <vector>
16 
17 namespace
18 {
19 
20 template<typename Model>
21 class DeepSpeechV1TestCase : public InferenceModelTestCase<Model>
22 {
23 public:
24  DeepSpeechV1TestCase(Model& model,
25  unsigned int testCaseId,
26  const DeepSpeechV1TestCaseData& testCaseData)
28  testCaseId,
29  { testCaseData.m_InputData.m_InputSeq,
30  testCaseData.m_InputData.m_StateH,
31  testCaseData.m_InputData.m_StateC},
32  { k_OutputSize1, k_OutputSize2, k_OutputSize3 })
33  , m_FloatComparer(boost::math::fpc::percent_tolerance(1.0f))
34  , m_ExpectedOutputs({testCaseData.m_ExpectedOutputData.m_InputSeq, testCaseData.m_ExpectedOutputData.m_StateH,
35  testCaseData.m_ExpectedOutputData.m_StateC})
36  {}
37 
39  {
40  boost::ignore_unused(options);
41  const std::vector<float>& output1 = boost::get<std::vector<float>>(this->GetOutputs()[0]); // logits
42  BOOST_ASSERT(output1.size() == k_OutputSize1);
43 
44  const std::vector<float>& output2 = boost::get<std::vector<float>>(this->GetOutputs()[1]); // new_state_c
45  BOOST_ASSERT(output2.size() == k_OutputSize2);
46 
47  const std::vector<float>& output3 = boost::get<std::vector<float>>(this->GetOutputs()[2]); // new_state_h
48  BOOST_ASSERT(output3.size() == k_OutputSize3);
49 
50  // Check each output to see whether it is the expected value
51  for (unsigned int j = 0u; j < output1.size(); j++)
52  {
53  if(!m_FloatComparer(output1[j], m_ExpectedOutputs.m_InputSeq[j]))
54  {
55  ARMNN_LOG(error) << "InputSeq for Lstm " << this->GetTestCaseId() <<
56  " is incorrect at" << j;
58  }
59  }
60 
61  for (unsigned int j = 0u; j < output2.size(); j++)
62  {
63  if(!m_FloatComparer(output2[j], m_ExpectedOutputs.m_StateH[j]))
64  {
65  ARMNN_LOG(error) << "StateH for Lstm " << this->GetTestCaseId() <<
66  " is incorrect";
68  }
69  }
70 
71  for (unsigned int j = 0u; j < output3.size(); j++)
72  {
73  if(!m_FloatComparer(output3[j], m_ExpectedOutputs.m_StateC[j]))
74  {
75  ARMNN_LOG(error) << "StateC for Lstm " << this->GetTestCaseId() <<
76  " is incorrect";
78  }
79  }
80  return TestCaseResult::Ok;
81  }
82 
83 private:
84 
85  static constexpr unsigned int k_OutputSize1 = 464u;
86  static constexpr unsigned int k_OutputSize2 = 2048u;
87  static constexpr unsigned int k_OutputSize3 = 2048u;
88 
89  boost::math::fpc::close_at_tolerance<float> m_FloatComparer;
90  LstmInput m_ExpectedOutputs;
91 };
92 
93 template <typename Model>
94 class DeepSpeechV1TestCaseProvider : public IInferenceTestCaseProvider
95 {
96 public:
97  template <typename TConstructModelCallable>
98  explicit DeepSpeechV1TestCaseProvider(TConstructModelCallable constructModel)
99  : m_ConstructModel(constructModel)
100  {}
101 
102  virtual void AddCommandLineOptions(boost::program_options::options_description& options) override
103  {
104  namespace po = boost::program_options;
105 
106  options.add_options()
107  ("input-seq-dir,s", po::value<std::string>(&m_InputSeqDir)->required(),
108  "Path to directory containing test data for m_InputSeq");
109  options.add_options()
110  ("prev-state-h-dir,h", po::value<std::string>(&m_PrevStateHDir)->required(),
111  "Path to directory containing test data for m_PrevStateH");
112  options.add_options()
113  ("prev-state-c-dir,c", po::value<std::string>(&m_PrevStateCDir)->required(),
114  "Path to directory containing test data for m_PrevStateC");
115  options.add_options()
116  ("logits-dir,l", po::value<std::string>(&m_LogitsDir)->required(),
117  "Path to directory containing test data for m_Logits");
118  options.add_options()
119  ("new-state-h-dir,H", po::value<std::string>(&m_NewStateHDir)->required(),
120  "Path to directory containing test data for m_NewStateH");
121  options.add_options()
122  ("new-state-c-dir,C", po::value<std::string>(&m_NewStateCDir)->required(),
123  "Path to directory containing test data for m_NewStateC");
124 
125 
126  Model::AddCommandLineOptions(options, m_ModelCommandLineOptions);
127  }
128 
129  virtual bool ProcessCommandLineOptions(const InferenceTestOptions &commonOptions) override
130  {
131  if (!ValidateDirectory(m_InputSeqDir))
132  {
133  return false;
134  }
135 
136  if (!ValidateDirectory(m_PrevStateCDir))
137  {
138  return false;
139  }
140 
141  if (!ValidateDirectory(m_PrevStateHDir))
142  {
143  return false;
144  }
145 
146  if (!ValidateDirectory(m_LogitsDir))
147  {
148  return false;
149  }
150 
151  if (!ValidateDirectory(m_NewStateCDir))
152  {
153  return false;
154  }
155 
156  if (!ValidateDirectory(m_NewStateHDir))
157  {
158  return false;
159  }
160 
161  m_Model = m_ConstructModel(commonOptions, m_ModelCommandLineOptions);
162  if (!m_Model)
163  {
164  return false;
165  }
166  m_Database = std::make_unique<DeepSpeechV1Database>(m_InputSeqDir.c_str(), m_PrevStateHDir.c_str(),
167  m_PrevStateCDir.c_str(), m_LogitsDir.c_str(),
168  m_NewStateHDir.c_str(), m_NewStateCDir.c_str());
169  if (!m_Database)
170  {
171  return false;
172  }
173 
174  return true;
175  }
176 
177  std::unique_ptr<IInferenceTestCase> GetTestCase(unsigned int testCaseId) override
178  {
179  std::unique_ptr<DeepSpeechV1TestCaseData> testCaseData = m_Database->GetTestCaseData(testCaseId);
180  if (!testCaseData)
181  {
182  return nullptr;
183  }
184 
185  return std::make_unique<DeepSpeechV1TestCase<Model>>(*m_Model, testCaseId, *testCaseData);
186  }
187 
188 private:
189  typename Model::CommandLineOptions m_ModelCommandLineOptions;
190  std::function<std::unique_ptr<Model>(const InferenceTestOptions&,
191  typename Model::CommandLineOptions)> m_ConstructModel;
192  std::unique_ptr<Model> m_Model;
193 
194  std::string m_InputSeqDir;
195  std::string m_PrevStateCDir;
196  std::string m_PrevStateHDir;
197  std::string m_LogitsDir;
198  std::string m_NewStateCDir;
199  std::string m_NewStateHDir;
200 
201  std::unique_ptr<DeepSpeechV1Database> m_Database;
202 };
203 
204 } // anonymous namespace
#define ARMNN_LOG(severity)
Definition: Logging.hpp:163
The test completed without any errors.
const std::vector< TContainer > & GetOutputs() const
virtual TestCaseResult ProcessResult(const InferenceTestOptions &options)=0
armnn::Runtime::CreationOptions::ExternalProfilingOptions options
bool ValidateDirectory(std::string &dir)