Publishing R3
[platform/upstream/dldt.git] / inference-engine / tests / helpers / tests_common.hpp
1 // Copyright (C) 2018 Intel Corporation
2 //
3 // SPDX-License-Identifier: Apache-2.0
4 //
5
6 #pragma once
7 #include <cctype>
8 #include <gtest/gtest.h>
9 #include <gmock/gmock.h>
10
11 #include "inference_engine.hpp"
12 #include "test_model_path.hpp"
13 #include <tests_file_utils.hpp>
14 #include <cctype>
15 #include <chrono>
16
17 #ifdef WIN32
18 #define UNUSED
19 #else
20 #define UNUSED  __attribute__((unused))
21 #endif
22
23 #include "stdlib.h"
24 #include "stdio.h"
25 #include "string.h"
26 #ifdef _WIN32
27         #include "Psapi.h"
28 #endif
29
30 class TestsCommon : public ::testing::Test {
31 public:
32     static size_t parseLine(char* line) {
33         // This assumes that a digit will be found and the line ends in " Kb".
34         size_t i = strlen(line);
35         const char* p = line;
36         while (*p <'0' || *p > '9') p++;
37         line[i-3] = '\0';
38         i = (size_t)atoi(p);
39         return i;
40     }
41
42     static size_t getVmSizeInKB(){
43         FILE* file = fopen("/proc/self/status", "r");
44         size_t result = 0;
45         if (file != nullptr) {
46             char line[128];
47
48             while (fgets(line, 128, file) != NULL) {
49                 if (strncmp(line, "VmSize:", 7) == 0) {
50                     result = parseLine(line);
51                     break;
52                 }
53             }
54             fclose(file);
55         }
56         return result;
57     }
58 #ifdef _WIN32
59         static size_t getVmSizeInKBWin() {
60                 PROCESS_MEMORY_COUNTERS pmc;
61                 pmc.cb = sizeof(PROCESS_MEMORY_COUNTERS);
62                 GetProcessMemoryInfo(GetCurrentProcess(),&pmc, pmc.cb);
63                 return pmc.WorkingSetSize;
64         }
65 #endif
66
67  public:
68 #ifdef _WIN32
69     static std::string library_path() {return ".";};
70 #else
71     static std::string library_path() { return "./lib";};
72 #endif  // _WIN32
73
74     static std::string archPath() {
75         if (sizeof(void*) == 8) {
76             return  "../../lib/intel64";
77         } else {
78             return  "../../lib/ia32";
79         }
80     }
81
82     protected:
83     void TearDown() override {}
84
85     void SetUp() override {
86         auto memsize = getVmSizeInKB();
87         if (memsize != 0) {
88             std::cout << "\nMEM_USAGE=" << getVmSizeInKB() << "KB\n";
89         }
90     }
91     public:
92
93
94     inline std::string get_mock_engine_name() {
95         return make_plugin_name("mock_engine");
96     }
97
98     inline std::string get_mock_extension_name() {
99         return make_plugin_name("mock_extensions");
100     }
101     static std::string get_data_path(){
102         const char* data_path = std::getenv("DATA_PATH");
103
104         if (data_path == NULL){
105             if(DATA_PATH != NULL){
106                 data_path = DATA_PATH;
107             } else{
108                 ::testing::AssertionFailure()<<"DATA_PATH not defined";
109             }
110         }
111         return std::string(data_path);
112     }
113
114     static std::string make_so_name(const std::string & input) {
115 #ifdef _WIN32
116     #ifdef __MINGW32__
117         return "lib" + input + ".dll";
118     #else
119         return input + ".dll";
120     #endif
121 #elif __APPLE__
122         return "lib" + input + ".dylib";
123 #else
124         return "lib" + input + ".so";
125 #endif
126     }
127
128     static std::string make_plugin_name(const std::string & input) {
129         return make_so_name(input);
130     }
131
132     static void fill_data(InferenceEngine::Blob::Ptr blob) {
133         fill_data(blob->buffer().as<float*>(), blob->size());
134     }
135
136     static void fill_data(float *data, size_t size, size_t duty_ratio = 10) {
137         for (size_t i = 0; i < size; i++) {
138             if ( ( i / duty_ratio)%2 == 1) {
139                 data[i] = 0.0;
140             } else {
141                 data[i] = sin((float)i);
142             }
143         }
144     }
145
146     void compare(InferenceEngine::Blob &res, InferenceEngine::Blob &ref, float max_diff = 0.01f) {
147
148         float *res_ptr = res.buffer().as<float*>();
149         size_t res_size = res.size();
150
151         float *ref_ptr = ref.buffer().as<float*>();
152         size_t ref_size = ref.size();
153
154         ASSERT_EQ(res_size, ref_size);
155
156         for (size_t i = 0; i < ref_size; i++) {
157             ASSERT_NEAR(res_ptr[i], ref_ptr[i], max_diff);
158         }
159     }
160
161     void compare(float* res, float* ref, size_t size, float max_diff = 0.01f) {
162         for (size_t i = 0; i < size; i++) {
163             ASSERT_NEAR(res[i], ref[i], max_diff);
164         }
165     }
166
167     void replace(std::string& str, const std::string& from, const std::string& to)
168     {
169         std::string::size_type pos = 0;
170
171         while((pos = str.find(from, pos)) != std::string::npos) {
172             str.replace(pos, from.length(), to);
173             pos += to.length();
174         }
175     }
176
177     std::string replace(std::string& str, const std::string& from, const int& to) {
178         replace(str, from, std::to_string(to));
179         return str;
180     }
181
182     std::string replace(std::string& str, const std::string& from, const size_t& to) {
183         replace(str, from, std::to_string(to));
184         return str;
185     }
186
187     std::string replace(std::string& str, const std::string& from, const float& to) {
188         replace(str, from, std::to_string(to));
189         return str;
190     }
191     // trim from both ends (in place)
192     static inline std::string &trim(std::string &s) {
193         s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
194         s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
195         return s;
196     }
197
198
199     template <class T>
200     static InferenceEngine::StatusCode measurePerformance(const T & callInfer) {
201         bool isPerformance = nullptr != getenv("DLSDK_performance_test");
202         if (!isPerformance) {
203             return callInfer();
204         }
205
206         typedef std::chrono::high_resolution_clock Time;
207         typedef std::chrono::nanoseconds ns;
208         typedef std::chrono::duration<float> fsec;
209
210         size_t niter = atoi(getenv("DLSDK_ITER_NUM"));
211         std::vector<double> times(niter);
212         InferenceEngine::StatusCode sts = InferenceEngine::OK;
213
214         for (size_t i = 0; i < niter; ++i)
215         {
216             auto t0 = Time::now();
217             sts = callInfer();
218             auto t1 = Time::now();
219             fsec fs = t1 - t0;
220             ns d = std::chrono::duration_cast<ns>(fs);
221             double total = static_cast<double>(d.count());
222
223             times[i] = total*0.000001;
224         }
225
226         for (size_t i = 0; i < times.size(); i++)
227             std::cout << "Iteration: " << i << " | infer time: " << times[i] << " ms" << std::endl;
228
229         std::sort(times.begin(), times.end());
230
231         size_t first_index = (size_t)floor(times.size() * 0.25);
232         size_t last_index = (size_t)floor(times.size() * 0.75);
233         size_t num = last_index - first_index;
234
235         std::cout << "Q25: " << times[first_index] << std::endl;
236         std::cout << "Q75: " << times[last_index]  << std::endl;
237
238         if (niter < 4)
239         {
240             first_index = 0;
241             last_index = times.size();
242             num = times.size();
243         }
244
245         std::vector<double> clipped_times;
246         double mean = 0;
247         for (auto i = first_index; i < last_index; i++)
248         {
249             clipped_times.push_back(times[i]);
250             mean += times[i];
251         }
252
253         mean = mean/clipped_times.size();
254
255         double median = 0;
256         if (clipped_times.size()%2 != 0)
257             median = clipped_times[int(clipped_times.size()/2)];
258         else median = (clipped_times[int(clipped_times.size()/2)] + clipped_times[int(clipped_times.size()/2)-1])/2;
259
260         std::cout << "mean: " << mean << std::endl;
261         std::cout << "median: " << median << std::endl;
262
263         times.clear();
264         clipped_times.clear();
265
266         return sts;
267     }
268
269 };
270
271
272 // Check bitness
273 #include <stdint.h>
274 #if UINTPTR_MAX == 0xffffffff
275     /* 32-bit */
276     #define ENVIRONMENT32
277 #elif UINTPTR_MAX == 0xffffffffffffffff
278     /* 64-bit */
279     #define ENVIRONMENT64
280 #else
281     # error Unsupported architecture
282 #endif
283
284
285 template <typename T,typename S>
286 std::shared_ptr<InferenceEngine::TBlob<T>> to_tblob(const std::shared_ptr<S> &obj)
287 {
288     return std::dynamic_pointer_cast<InferenceEngine::TBlob<T>>(obj);
289 }
290
291 inline InferenceEngine::InputInfo::Ptr getFirstInput(InferenceEngine::ICNNNetwork *pNet)
292 {
293     InferenceEngine::InputsDataMap inputs;
294     pNet->getInputsInfo(inputs);
295     //ASSERT_GT(inputs.size(), 0);
296     return inputs.begin()->second;
297 }
298
299 using OptionsMap = std::map<std::string, std::string>;