2 // Copyright 2016-2018 Intel Corporation.
4 // This software and the related documents are Intel copyrighted materials,
5 // and your use of them is governed by the express license under which they
6 // were provided to you (End User License Agreement for the Intel(R) Software
7 // Development Products (Version May 2017)). Unless the License provides
8 // otherwise, you may not use, modify, copy, publish, distribute, disclose or
9 // transmit this software or the related documents without Intel's prior
10 // written permission.
12 // This software and the related documents are provided as is, with no
13 // express or implied warranties, other than those that are expressly
14 // stated in the License.
19 #include <inference_engine/graph_tools.hpp>
20 #include "gtest/gtest.h"
21 #include "inference_engine.hpp"
22 #include "gna/gna_config.hpp"
23 #include "gna_plugin.hpp"
25 #include "test_irs.hpp"
29 #define withConfig(key, value) withGNAConfig(GNA_CONFIG_KEY(key), value)
30 #define ASSERT_NO_THROW_IE_EXCEPTION(expr) \
33 }catch(std::exception & e) {\
37 FAIL() << "unknown exception";\
41 * GNA unit tests environment
43 class GnaPluginTestEnvironment {
45 struct NnetPrecision {
46 InferenceEngine::Precision input_precision;
47 InferenceEngine::Precision output_precision;
48 InferenceEngine::Precision weights_precision;
49 InferenceEngine::Precision biases_precision;
58 matchMaxPoolingInserted,
59 matchPwlQuantizeMetrics,
61 matchDiagonalInserted,
65 matchAffineWeightsTranspose,
69 std::vector<MatchWhat> whatToMatch;
74 InferenceEngine::TargetDevice target_device =
75 InferenceEngine::TargetDevice::eGNA;
76 int matchQuantity = kUnset;
77 int numberOfStates = kUnset;
78 bool matchInserted = true;
79 NnetPrecision nnet_precision;
80 float quantization_presicion_threshold = 1.0f;
81 uint16_t quantization_segments_threshold = UINT16_MAX;
84 std::string exportedModelFileName;
85 bool exportNetworkOnly = false;
86 std::function<void (InferenceEngine::CNNNetwork &)> cb;
87 std::map<std::string, std::string> config;
88 GNAPluginNS::Policy policy;
89 bool matchThrows = false;
90 uint32_t proc_type = static_cast<intel_gna_proc_t>(GNA_SOFTWARE & GNA_HARDWARE);
91 std::string importedModelFileName;
92 bool is_profiling_enabled = false;
93 bool matchOutput = false;
94 bool is_setup_of_omp_theads_expected = false;
95 std::vector<int16_t> input_processed;
96 InferenceEngine::Precision input_precision = InferenceEngine::Precision::FP32;
97 std::map<std::string, std::vector<float>> input_init;
98 std::vector<float> expected_output;
99 int16_t fillValue = 0;
100 std::vector<float> weightsFillPattern;
101 std::pair<int, int> transposeArgs;
102 std::pair<int, int> transposedArgsForSaving;
103 std::vector<uint16_t>* transposedData;
108 virtual ~GNATestBase() = default;
112 class GNATestConfigurability : public GNATestBase{
114 bool needNextMatcher = true;
115 GnaPluginTestEnvironment _env;
116 GnaPluginTestEnvironment::MatchWhat & getMatcher() {
117 if (needNextMatcher) {
118 needNextMatcher = false;
119 _env.whatToMatch.push_back({});
121 return _env.whatToMatch.back();
124 GNATestConfigurability(GnaPluginTestEnvironment env) : _env(env) {
127 needNextMatcher = true;
128 return *dynamic_cast<T*>(this);
130 template <class VType>
131 T & withGNAConfig(const std::string &keyName, const VType &value) {
132 std::stringstream ss;
134 _env.config[keyName] = ss.str();
135 return *dynamic_cast<T*>(this);
137 T & withGNADeviceMode(std::string value) {
138 _env.config[GNA_CONFIG_KEY(DEVICE_MODE)] = value;
139 return *dynamic_cast<T*>(this);
141 T & withAcceleratorThreadsNumber(std::string value) {
142 _env.config[GNA_CONFIG_KEY(LIB_N_THREADS)] = value;
143 return *dynamic_cast<T*>(this);
146 _env.matchThrows = true;
147 return *dynamic_cast<T*>(this);
149 T & profiling_counters() {
150 _env.is_profiling_enabled = true;
151 _env.config[CONFIG_KEY(PERF_COUNT)] = InferenceEngine::PluginConfigParams::YES;
152 return *dynamic_cast<T*>(this);
155 T & enable_omp_multithreading() {
156 _env.is_setup_of_omp_theads_expected = true;
157 _env.config[CONFIG_KEY(SINGLE_THREAD)] = InferenceEngine::PluginConfigParams::NO;
158 return *dynamic_cast<T*>(this);
163 * @brief matches loadnetwork + infer + call to gna_api propagate
165 class GNAPropagateMatcher : public GNATestConfigurability<GNAPropagateMatcher> {
167 using base = GNATestConfigurability<GNAPropagateMatcher>;
169 using base::getMatcher;
171 ~GNAPropagateMatcher() {
175 GNAPropagateMatcher & called() {
176 // inserting default matcher that matches any propagate_forward call
181 GNAPropagateMatcher & returns() {
185 GNAPropagateMatcher & And() {
189 GNAPropagateMatcher & that() {
193 GNAPropagateMatcher & result() {
197 GNAPropagateMatcher & called_with() {
201 GNAPropagateMatcher & called_without() {
202 _env.matchInserted = false;
206 * @brief gna_propagate_forward will fill all output pointers of 16 bits with this value
208 GNAPropagateMatcher & filledWith(int16_t valueToFill) {
209 _env.fillValue = valueToFill;
210 getMatcher() = GnaPluginTestEnvironment::fillOutputValues;
214 GNAPropagateMatcher & equal_to(const std::vector<float>& expect) {
215 _env.matchOutput = true;
216 _env.expected_output = expect;
220 GNAPropagateMatcher & input(const std::string & inputName, const std::vector<float>& inputData) {
221 _env.input_init[inputName] = inputData;
225 GNAPropagateMatcher & inputScale(const std::string & inputName, float scaleFactor) {
226 _env.config[std::string(GNA_CONFIG_KEY(SCALE_FACTOR)) + "_" + inputName] = std::to_string(scaleFactor);
230 GNAPropagateMatcher & called_with_input_and_expected_output(const std::vector<float>& input_data,
231 const std::vector<float>& expect) {
232 _env.matchOutput = true;
233 _env.input_init["any_input_name"] = input_data;
234 _env.expected_output = expect;
238 GNAPropagateMatcher & once() {
239 _env.matchQuantity = 1;
243 GNAPropagateMatcher & twice() {
244 _env.matchQuantity = 2;
248 GNAPropagateMatcher & args(std::string args) {
252 GNAPropagateMatcher & exact_nnet_structure(intel_nnet_type_t * pNet) {
254 getMatcher() = GnaPluginTestEnvironment::exactNNetStructure;
255 original_nnet = pNet;
259 GNAPropagateMatcher & pwl_inserted_into_nnet() {
260 getMatcher() = GnaPluginTestEnvironment::matchPwlInserted;
264 GNAPropagateMatcher & max_pooling_inserted_into_nnet() {
265 getMatcher() = GnaPluginTestEnvironment::matchMaxPoolingInserted;
269 GNAPropagateMatcher & succeed() {
273 GNAPropagateMatcher & convolution_inserted_into_nnet() {
274 getMatcher() = GnaPluginTestEnvironment::matchConvInserted;
279 GNAPropagateMatcher & pwl_quantization_activation(uint32_t activation_type) {
280 getMatcher() = GnaPluginTestEnvironment::matchPwlQuantizeMetrics;
281 _env.type = activation_type;
285 GNAPropagateMatcher & pwl_quantization_precision_threshold(float threshold) {
286 getMatcher() = GnaPluginTestEnvironment::matchPwlQuantizeMetrics;
287 _env.quantization_presicion_threshold = threshold;
291 GNAPropagateMatcher & pwl_quantization_segments_threshold(uint16_t threshold) {
292 getMatcher() = GnaPluginTestEnvironment::matchPwlQuantizeMetrics;
293 _env.quantization_segments_threshold = threshold;
297 GNAPropagateMatcher & diagonal_inserted_into_nnet() {
298 getMatcher() = GnaPluginTestEnvironment::matchDiagonalInserted;
302 GNAPropagateMatcher &preprocessed_input_data(std::vector<float> input_init, std::vector<int16_t> input_processed,
303 InferenceEngine::Precision inputPrecision) {
304 getMatcher() = GnaPluginTestEnvironment::matchInputData;
305 _env.input_processed = std::move(input_processed);
306 _env.input_init["placeholder"] = std::move(input_init);
307 _env.input_precision = inputPrecision;
311 GNAPropagateMatcher & copy_inserted_into_nnet() {
312 getMatcher() = GnaPluginTestEnvironment::matchCopyInserted;
317 GNAPropagateMatcher & affine_weights_transpozed(std::pair<int, int> &&transpozedArgs) {
318 getMatcher() = GnaPluginTestEnvironment::saveAffineWeights;
319 _env.transposedArgsForSaving = std::move(transpozedArgs);
324 GNAPropagateMatcher & affine_weights() {
325 getMatcher() = GnaPluginTestEnvironment::saveAffineWeights;
329 GNAPropagateMatcher & affine_weights_eq(std::vector<uint16_t> & sourceWeights) {
330 getMatcher() = GnaPluginTestEnvironment::matchAffineWeights;
331 _env.transposedData = &sourceWeights;
336 GNAPropagateMatcher & affine_weights_transposed(std::vector<uint16_t> & sourceWeights, std::pair<int,int> transposeData) {
337 getMatcher() = GnaPluginTestEnvironment::matchAffineWeightsTranspose;
338 _env.transposeArgs = transposeData;
339 _env.transposedData = &sourceWeights;
343 GNAPropagateMatcher & nnet_input_precision(const InferenceEngine::Precision &precision) {
344 getMatcher() = GnaPluginTestEnvironment::matchPrecision;
345 _env.nnet_precision.input_precision = precision;
348 GNAPropagateMatcher & nnet_ouput_precision(const InferenceEngine::Precision &precision) {
349 getMatcher() = GnaPluginTestEnvironment::matchPrecision;
350 _env.nnet_precision.output_precision = precision;
353 GNAPropagateMatcher & nnet_weights_precision(const InferenceEngine::Precision &precision) {
354 getMatcher() = GnaPluginTestEnvironment::matchPrecision;
355 _env.nnet_precision.weights_precision = precision;
358 GNAPropagateMatcher & nnet_biases_precision(const InferenceEngine::Precision &precision) {
359 getMatcher() = GnaPluginTestEnvironment::matchPrecision;
360 _env.nnet_precision.biases_precision = precision;
364 GNAPropagateMatcher & proc_type(uint32_t proc_type) {
365 getMatcher() = GnaPluginTestEnvironment::matchProcType;
366 _env.proc_type = proc_type;
370 GNAPropagateMatcher & to(intel_nnet_type_t *savedNet) {
371 this->savedNet = savedNet;
375 GNAPropagateMatcher & to(std::vector<uint16_t> & sourceWeights) {
376 _env.transposedData = &sourceWeights;
382 GNAPropagateMatcher & onCPU() {
383 _env.target_device = InferenceEngine::TargetDevice::eCPU;
388 intel_nnet_type_t * original_nnet = nullptr;
389 intel_nnet_type_t * savedNet = nullptr;
394 * @brief GNAPlugin matches creation only case
396 class GNAPluginCreationMatcher : public GNATestConfigurability<GNAPluginCreationMatcher> {
398 using base = GNATestConfigurability<GNAPluginCreationMatcher>;
401 GNAPluginCreationMatcher & gna_plugin() {
404 ~GNAPluginCreationMatcher () {
412 * @brief GNAPlugin matches creation only case
414 class GNAPluginAOTMatcher : public GNATestConfigurability<GNAPluginAOTMatcher> {
416 using base = GNATestConfigurability<GNAPluginAOTMatcher>;
419 ~GNAPluginAOTMatcher() {
427 * @brief xnn api tests
429 class GNADumpXNNMatcher : public GNATestConfigurability<GNADumpXNNMatcher> {
431 using base = GNATestConfigurability<GNADumpXNNMatcher>;
434 ~GNADumpXNNMatcher() {
435 if (match_in_dctor) {
439 GNADumpXNNMatcher& called() {
444 bool match_in_dctor = true;
445 void load(GNAPluginNS::GNAPlugin & plugin);
450 * @brief xnn api tests
452 class GNAQueryStateMatcher : public GNADumpXNNMatcher {
454 using base = GNADumpXNNMatcher;
457 ~GNAQueryStateMatcher() {
458 if (match_in_dctor) {
460 match_in_dctor = false;
464 _env.numberOfStates = 0;
467 _env.numberOfStates = GnaPluginTestEnvironment::kAnyNotNull;
477 * @brief base for test fixture
479 class GNATest : public ::testing::Test, public GNATestConfigurability<GNATest> {
480 using base = GNATestConfigurability<GNATest>;
484 std::vector<uint8_t> data;
485 std::function<void (void *)> destroyer;
487 destroyer(&data.front());
490 std::list<XStorage> dataUsedInMatchers;
491 std::list<std::shared_ptr<GNATestBase>> returnedMatchers;
496 dataUsedInMatchers.push_back({std::vector<uint8_t >(sizeof(T)), [](void * toDestroy) {
497 reinterpret_cast<T*>(toDestroy)->~T();
500 auto ptr = reinterpret_cast<T*> (&dataUsedInMatchers.back().data.front());
501 // sad to say we are not using destructors here so data might leak
506 GNATest() : base(GnaPluginTestEnvironment()) {}
513 GNATest & assert_that() {
516 GNATest & export_network(std::string modelName) {
517 _env.model = modelName;
518 _env.exportNetworkOnly = true;
521 GNATest & save_args() {
522 getMatcher() = GnaPluginTestEnvironment::saveArgs;
529 GNATest & onInfer1AFModel() {
530 _env.model = GNATestIRs::Fc2DOutputModel();
533 GNATest & onLoad(std::string _model) {
537 GNATest & afterLoadingModel(std::string _model) {
542 GNAQueryStateMatcher & queryState() {
543 returnedMatchers.push_back(std::make_shared<GNAQueryStateMatcher>(_env));
545 _env = GnaPluginTestEnvironment();
546 return dynamic_cast<GNAQueryStateMatcher&>(*returnedMatchers.back());
549 /**importing indicates no infer happened ata all **/
550 GNAPropagateMatcher & importingModelFrom(std::string fileName) {
551 _env.importedModelFileName = fileName;
552 returnedMatchers.push_back(std::make_shared<GNAPropagateMatcher>(_env));
554 _env = GnaPluginTestEnvironment();
555 return dynamic_cast<GNAPropagateMatcher&>(*returnedMatchers.back());
557 GNATest & importedFrom(std::string fileName) {
558 _env.importedModelFileName = fileName;
561 GNATest & onInferModel(std::string _model = "",
562 std::function<void (InferenceEngine::CNNNetwork &)> _cb = [](InferenceEngine::CNNNetwork & net){}) {
567 GNATest & withWeigthsPattern(std::vector<float> && initializer) {
568 _env.weightsFillPattern = std::move(initializer);
577 GNATest & inNotCompactMode() {
578 _env.config[GNA_CONFIG_KEY(COMPACT_MODE)] = CONFIG_VALUE(NO);
581 GNATest & withUniformPWLAlgo() {
582 base::_env.config[GNA_CONFIG_KEY(PWL_UNIFORM_DESIGN)] = CONFIG_VALUE(YES);
585 GNAPropagateMatcher& propagate_forward() {
586 returnedMatchers.push_back(std::make_shared<GNAPropagateMatcher>(_env));
588 _env = GnaPluginTestEnvironment();
589 return dynamic_cast<GNAPropagateMatcher&>(*returnedMatchers.back());
591 GNADumpXNNMatcher& dumpXNN() {
592 returnedMatchers.push_back(std::make_shared<GNADumpXNNMatcher>(_env));
594 _env = GnaPluginTestEnvironment();
595 return dynamic_cast<GNADumpXNNMatcher&>(*returnedMatchers.back());
597 GNATest & withNanScaleFactor() {
598 base::_env.config[GNA_CONFIG_KEY(SCALE_FACTOR)] = std::to_string(std::numeric_limits<float>::quiet_NaN());
601 GNATest & withInfScaleFactor() {
602 base::_env.config[GNA_CONFIG_KEY(SCALE_FACTOR)] = std::to_string(std::numeric_limits<float>::infinity());
605 GNAPluginCreationMatcher creating() {
609 GNAPluginAOTMatcher & to (std::string fileName) {
610 _env.exportedModelFileName = fileName;
611 returnedMatchers.push_back(std::make_shared<GNAPluginAOTMatcher>(_env));
613 _env = GnaPluginTestEnvironment();
614 return dynamic_cast<GNAPluginAOTMatcher&>(*returnedMatchers.back());
617 static void fillWeights(InferenceEngine::Blob::Ptr weights, std::vector<float> pattern = {1.f}) {
618 float * p = weights->buffer().as<float *>();
619 float * pEnd = p + weights->byteSize() / sizeof(float);
622 for (int i = 0; i != (weights->byteSize() / sizeof(float) / 3) + 1; i++) {
623 for (int j = 0; j != pattern.size() && p != pEnd; j++, p++) {