blob: 4d66b14d6798cb3cc26382959291f574d8733a07 [file] [log] [blame]
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +01001/*
Georgios Pinitas7f152512019-12-16 19:59:52 +00002 * Copyright (c) 2017-2020 ARM Limited.
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#include "Framework.h"
25
Pablo Tello4e0ac6f2018-10-01 14:31:11 +010026#include "arm_compute/runtime/Scheduler.h"
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +010027#include "support/ToolchainSupport.h"
Pablo Tellodb8485a2019-09-24 11:03:47 +010028#include "tests/framework/ParametersLibrary.h"
29
Gian Marco Iodiced30ed112018-05-16 12:01:14 +010030#ifdef ARM_COMPUTE_CL
Pablo Tellodb8485a2019-09-24 11:03:47 +010031#include "arm_compute/runtime/CL/CLRuntimeContext.h"
Gian Marco Iodiced30ed112018-05-16 12:01:14 +010032#include "arm_compute/runtime/CL/CLScheduler.h"
Pablo Tellodb8485a2019-09-24 11:03:47 +010033
Gian Marco Iodiced30ed112018-05-16 12:01:14 +010034#endif /* ARM_COMPUTE_CL */
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +010035
36#include <chrono>
37#include <iostream>
38#include <sstream>
39#include <type_traits>
40
41namespace arm_compute
42{
43namespace test
44{
Pablo Tellodb8485a2019-09-24 11:03:47 +010045std::unique_ptr<ParametersLibrary> parameters;
46
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +010047namespace framework
48{
Georgios Pinitas12833d02019-07-25 13:31:10 +010049std::unique_ptr<InstrumentsInfo> instruments_info;
50
Moritz Pflanzera4f711b2017-07-05 11:02:23 +010051Framework::Framework()
52{
Anthony Barbier72f4ae52018-11-07 17:33:54 +000053 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMESTAMPS, ScaleFactor::NONE), Instrument::make_instrument<WallClockTimestamps, ScaleFactor::NONE>);
54 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMESTAMPS, ScaleFactor::TIME_MS),
55 Instrument::make_instrument<WallClockTimestamps, ScaleFactor::TIME_MS>);
56 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMESTAMPS, ScaleFactor::TIME_S),
57 Instrument::make_instrument<WallClockTimestamps, ScaleFactor::TIME_S>);
Giorgio Arenace58a9f2017-10-31 17:59:17 +000058 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMER, ScaleFactor::NONE), Instrument::make_instrument<WallClockTimer, ScaleFactor::NONE>);
59 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMER, ScaleFactor::TIME_MS), Instrument::make_instrument<WallClockTimer, ScaleFactor::TIME_MS>);
60 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::WALL_CLOCK_TIMER, ScaleFactor::TIME_S), Instrument::make_instrument<WallClockTimer, ScaleFactor::TIME_S>);
Anthony Barbier72f4ae52018-11-07 17:33:54 +000061 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::SCHEDULER_TIMESTAMPS, ScaleFactor::NONE), Instrument::make_instrument<SchedulerTimestamps, ScaleFactor::NONE>);
62 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::SCHEDULER_TIMESTAMPS, ScaleFactor::TIME_MS),
63 Instrument::make_instrument<SchedulerTimestamps, ScaleFactor::TIME_MS>);
64 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::SCHEDULER_TIMESTAMPS, ScaleFactor::TIME_S),
65 Instrument::make_instrument<SchedulerTimestamps, ScaleFactor::TIME_S>);
Anthony Barbiere8a49832018-01-18 10:04:05 +000066 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::SCHEDULER_TIMER, ScaleFactor::NONE), Instrument::make_instrument<SchedulerTimer, ScaleFactor::NONE>);
67 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::SCHEDULER_TIMER, ScaleFactor::TIME_MS), Instrument::make_instrument<SchedulerTimer, ScaleFactor::TIME_MS>);
68 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::SCHEDULER_TIMER, ScaleFactor::TIME_S), Instrument::make_instrument<SchedulerTimer, ScaleFactor::TIME_S>);
Moritz Pflanzera4f711b2017-07-05 11:02:23 +010069#ifdef PMU_ENABLED
Giorgio Arenace58a9f2017-10-31 17:59:17 +000070 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::PMU, ScaleFactor::NONE), Instrument::make_instrument<PMUCounter, ScaleFactor::NONE>);
71 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::PMU, ScaleFactor::SCALE_1K), Instrument::make_instrument<PMUCounter, ScaleFactor::SCALE_1K>);
72 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::PMU, ScaleFactor::SCALE_1M), Instrument::make_instrument<PMUCounter, ScaleFactor::SCALE_1M>);
Moritz Pflanzera4f711b2017-07-05 11:02:23 +010073#endif /* PMU_ENABLED */
Moritz Pflanzer45634b42017-08-30 12:48:18 +010074#ifdef MALI_ENABLED
Giorgio Arenace58a9f2017-10-31 17:59:17 +000075 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::MALI, ScaleFactor::NONE), Instrument::make_instrument<MaliCounter, ScaleFactor::NONE>);
76 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::MALI, ScaleFactor::SCALE_1K), Instrument::make_instrument<MaliCounter, ScaleFactor::SCALE_1K>);
77 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::MALI, ScaleFactor::SCALE_1M), Instrument::make_instrument<MaliCounter, ScaleFactor::SCALE_1M>);
Moritz Pflanzer45634b42017-08-30 12:48:18 +010078#endif /* MALI_ENABLED */
Anthony Barbiere8895f82017-11-23 16:58:52 +000079#ifdef ARM_COMPUTE_CL
Anthony Barbier72f4ae52018-11-07 17:33:54 +000080 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMESTAMPS, ScaleFactor::NONE), Instrument::make_instrument<OpenCLTimestamps, ScaleFactor::NONE>);
81 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMESTAMPS, ScaleFactor::TIME_US), Instrument::make_instrument<OpenCLTimestamps, ScaleFactor::TIME_US>);
82 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMESTAMPS, ScaleFactor::TIME_MS), Instrument::make_instrument<OpenCLTimestamps, ScaleFactor::TIME_MS>);
83 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMESTAMPS, ScaleFactor::TIME_S), Instrument::make_instrument<OpenCLTimestamps, ScaleFactor::TIME_S>);
Giorgio Arenace58a9f2017-10-31 17:59:17 +000084 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMER, ScaleFactor::NONE), Instrument::make_instrument<OpenCLTimer, ScaleFactor::NONE>);
85 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMER, ScaleFactor::TIME_US), Instrument::make_instrument<OpenCLTimer, ScaleFactor::TIME_US>);
86 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMER, ScaleFactor::TIME_MS), Instrument::make_instrument<OpenCLTimer, ScaleFactor::TIME_MS>);
87 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_TIMER, ScaleFactor::TIME_S), Instrument::make_instrument<OpenCLTimer, ScaleFactor::TIME_S>);
Anthony Barbier35aa6a32018-04-23 16:12:12 +010088 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_MEMORY_USAGE, ScaleFactor::NONE), Instrument::make_instrument<OpenCLMemoryUsage, ScaleFactor::NONE>);
89 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_MEMORY_USAGE, ScaleFactor::SCALE_1K),
90 Instrument::make_instrument<OpenCLMemoryUsage, ScaleFactor::SCALE_1K>);
91 _available_instruments.emplace(std::pair<InstrumentType, ScaleFactor>(InstrumentType::OPENCL_MEMORY_USAGE, ScaleFactor::SCALE_1M),
92 Instrument::make_instrument<OpenCLMemoryUsage, ScaleFactor::SCALE_1M>);
Anthony Barbiere8895f82017-11-23 16:58:52 +000093#endif /* ARM_COMPUTE_CL */
Georgios Pinitas12833d02019-07-25 13:31:10 +010094
95 instruments_info = support::cpp14::make_unique<InstrumentsInfo>();
Moritz Pflanzera4f711b2017-07-05 11:02:23 +010096}
97
Giorgio Arenace58a9f2017-10-31 17:59:17 +000098std::set<InstrumentsDescription> Framework::available_instruments() const
Moritz Pflanzera4f711b2017-07-05 11:02:23 +010099{
Giorgio Arenace58a9f2017-10-31 17:59:17 +0000100 std::set<InstrumentsDescription> types;
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100101
102 for(const auto &instrument : _available_instruments)
103 {
104 types.emplace(instrument.first);
105 }
106
107 return types;
108}
109
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100110std::map<TestResult::Status, int> Framework::count_test_results() const
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100111{
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100112 std::map<TestResult::Status, int> counts;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100113
114 for(const auto &test : _test_results)
115 {
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100116 ++counts[test.second.status];
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100117 }
118
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100119 return counts;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100120}
121
122Framework &Framework::get()
123{
124 static Framework instance;
125 return instance;
126}
127
Georgios Pinitas7f152512019-12-16 19:59:52 +0000128void Framework::init(const FrameworkConfig &config)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100129{
Georgios Pinitas7f152512019-12-16 19:59:52 +0000130 _test_filter = TestFilter(config.mode, config.name_filter, config.id_filter);
131 _num_iterations = config.num_iterations;
132 _log_level = config.log_level;
133 _cooldown_sec = config.cooldown_sec;
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100134
Georgios Pinitas7f152512019-12-16 19:59:52 +0000135 _instruments = std::set<framework::InstrumentsDescription>(std::begin(config.instruments), std::end(config.instruments));
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100136}
137
138std::string Framework::current_suite_name() const
139{
140 return join(_test_suite_name.cbegin(), _test_suite_name.cend(), "/");
141}
142
143void Framework::push_suite(std::string name)
144{
145 _test_suite_name.emplace_back(std::move(name));
146}
147
148void Framework::pop_suite()
149{
150 _test_suite_name.pop_back();
151}
152
Moritz Pflanzerc7d15032017-07-18 16:21:16 +0100153void Framework::add_test_info(std::string info)
154{
155 _test_info.emplace_back(std::move(info));
156}
157
158void Framework::clear_test_info()
159{
160 _test_info.clear();
161}
162
163bool Framework::has_test_info() const
164{
165 return !_test_info.empty();
166}
167
168void Framework::print_test_info(std::ostream &os) const
169{
Moritz Pflanzer8df3faf2017-07-28 13:57:53 +0100170 if(!_test_info.empty())
Moritz Pflanzerc7d15032017-07-18 16:21:16 +0100171 {
Moritz Pflanzer8df3faf2017-07-28 13:57:53 +0100172 os << "CONTEXT:\n";
173
174 for(const auto &str : _test_info)
175 {
176 os << " " << str << "\n";
177 }
Moritz Pflanzerc7d15032017-07-18 16:21:16 +0100178 }
179}
180
Giorgio Arena2d099932017-10-25 15:47:08 +0100181template <typename F>
182void Framework::func_on_all_printers(F &&func)
183{
184 std::for_each(std::begin(_printers), std::end(_printers), func);
185}
186
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100187void Framework::log_test_start(const TestInfo &info)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100188{
Giorgio Arena2d099932017-10-25 15:47:08 +0100189 if(_log_level >= LogLevel::TESTS)
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100190 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100191 func_on_all_printers([&](Printer * p)
192 {
193 p->print_test_header(info);
194 });
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100195 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100196}
197
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100198void Framework::log_test_skipped(const TestInfo &info)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100199{
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100200 static_cast<void>(info);
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100201}
202
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100203void Framework::log_test_end(const TestInfo &info)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100204{
Giorgio Arena2d099932017-10-25 15:47:08 +0100205 if(_log_level >= LogLevel::MEASUREMENTS)
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100206 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100207 func_on_all_printers([&](Printer * p)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100208 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100209 p->print_measurements(_test_results.at(info).measurements);
210 });
211 }
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100212
Giorgio Arena2d099932017-10-25 15:47:08 +0100213 if(_log_level >= LogLevel::TESTS)
214 {
215 func_on_all_printers([](Printer * p)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100216 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100217 p->print_test_footer();
218 });
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100219 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100220}
221
Moritz Pflanzer24a82462017-08-04 11:34:44 +0100222void Framework::log_failed_expectation(const TestError &error)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100223{
Moritz Pflanzer0ce08442017-09-16 11:11:27 +0100224 ARM_COMPUTE_ERROR_ON(_current_test_info == nullptr);
225 ARM_COMPUTE_ERROR_ON(_current_test_result == nullptr);
226
227 const bool is_expected_failure = _current_test_info->status == TestCaseFactory::Status::EXPECTED_FAILURE;
228
Giorgio Arena2d099932017-10-25 15:47:08 +0100229 if(_log_level >= error.level())
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100230 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100231 func_on_all_printers([&](Printer * p)
232 {
233 p->print_error(error, is_expected_failure);
234 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100235 }
Moritz Pflanzere1103a82017-07-18 12:20:45 +0100236
Moritz Pflanzer0ce08442017-09-16 11:11:27 +0100237 _current_test_result->status = TestResult::Status::FAILED;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100238}
239
steniu01172c58d2017-08-31 13:49:08 +0100240void Framework::log_info(const std::string &info)
241{
Giorgio Arena2d099932017-10-25 15:47:08 +0100242 if(_log_level >= LogLevel::DEBUG)
steniu01172c58d2017-08-31 13:49:08 +0100243 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100244 func_on_all_printers([&](Printer * p)
245 {
246 p->print_info(info);
247 });
steniu01172c58d2017-08-31 13:49:08 +0100248 }
249}
250
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100251int Framework::num_iterations() const
252{
253 return _num_iterations;
254}
255
256void Framework::set_num_iterations(int num_iterations)
257{
258 _num_iterations = num_iterations;
259}
260
261void Framework::set_throw_errors(bool throw_errors)
262{
263 _throw_errors = throw_errors;
264}
265
266bool Framework::throw_errors() const
267{
268 return _throw_errors;
269}
270
Moritz Pflanzerfa811652017-07-26 17:00:37 +0100271void Framework::set_stop_on_error(bool stop_on_error)
272{
273 _stop_on_error = stop_on_error;
274}
275
276bool Framework::stop_on_error() const
277{
278 return _stop_on_error;
279}
280
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100281void Framework::set_error_on_missing_assets(bool error_on_missing_assets)
282{
283 _error_on_missing_assets = error_on_missing_assets;
284}
285
286bool Framework::error_on_missing_assets() const
287{
288 return _error_on_missing_assets;
289}
290
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100291void Framework::run_test(const TestInfo &info, TestCaseFactory &test_factory)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100292{
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100293 if(test_factory.status() == TestCaseFactory::Status::DISABLED)
294 {
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100295 log_test_skipped(info);
296 set_test_result(info, TestResult(TestResult::Status::DISABLED));
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100297 return;
298 }
299
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100300 log_test_start(info);
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100301
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100302 Profiler profiler = get_profiler();
Moritz Pflanzere33eb642017-07-31 14:48:45 +0100303 TestResult result(TestResult::Status::NOT_RUN);
Moritz Pflanzere1103a82017-07-18 12:20:45 +0100304
Moritz Pflanzer0ce08442017-09-16 11:11:27 +0100305 _current_test_info = &info;
Moritz Pflanzere1103a82017-07-18 12:20:45 +0100306 _current_test_result = &result;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100307
Giorgio Arena2d099932017-10-25 15:47:08 +0100308 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer24a82462017-08-04 11:34:44 +0100309 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100310 func_on_all_printers([](Printer * p)
311 {
312 p->print_errors_header();
313 });
Moritz Pflanzer24a82462017-08-04 11:34:44 +0100314 }
315
Moritz Pflanzer0ce08442017-09-16 11:11:27 +0100316 const bool is_expected_failure = info.status == TestCaseFactory::Status::EXPECTED_FAILURE;
Moritz Pflanzer5b61fd32017-09-12 15:51:33 +0100317
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100318 try
319 {
320 std::unique_ptr<TestCase> test_case = test_factory.make();
321
322 try
323 {
Anthony Barbier9fb0cac2018-04-20 15:46:21 +0100324 profiler.test_start();
325
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100326 test_case->do_setup();
327
328 for(int i = 0; i < _num_iterations; ++i)
329 {
Anthony Barbier61941452017-11-21 17:49:07 +0000330 //Start the profiler if:
331 //- there is only one iteration
332 //- it's not the first iteration of a multi-iterations run.
333 //
334 //Reason: if the CLTuner is enabled then the first run will be really messy
335 //as each kernel will be executed several times, messing up the instruments like OpenCL timers.
336 if(_num_iterations == 1 || i != 0)
Anthony Barbier2f8e0772017-11-15 13:06:46 +0000337 {
338 profiler.start();
339 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100340 test_case->do_run();
Joel Liang1c5ffd62017-12-28 10:09:51 +0800341 test_case->do_sync();
Anthony Barbier61941452017-11-21 17:49:07 +0000342 if(_num_iterations == 1 || i != 0)
Anthony Barbier2f8e0772017-11-15 13:06:46 +0000343 {
344 profiler.stop();
345 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100346 }
347
348 test_case->do_teardown();
Moritz Pflanzere33eb642017-07-31 14:48:45 +0100349
Anthony Barbier9fb0cac2018-04-20 15:46:21 +0100350 profiler.test_stop();
351
Moritz Pflanzere33eb642017-07-31 14:48:45 +0100352 // Change status to success if no error has happend
353 if(result.status == TestResult::Status::NOT_RUN)
354 {
355 result.status = TestResult::Status::SUCCESS;
356 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100357 }
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100358 catch(const FileNotFound &error)
359 {
Pablo Tello21eaefe2018-10-10 14:38:35 +0100360 profiler.test_stop();
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100361 if(_error_on_missing_assets)
362 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100363 if(_log_level >= LogLevel::ERRORS)
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100364 {
365 TestError test_error(error.what(), LogLevel::ERRORS);
Giorgio Arena2d099932017-10-25 15:47:08 +0100366 func_on_all_printers([&](Printer * p)
367 {
368 p->print_error(test_error, is_expected_failure);
369 });
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100370 }
371
372 result.status = TestResult::Status::FAILED;
373
374 if(_throw_errors)
375 {
376 throw;
377 }
378 }
379 else
380 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100381 if(_log_level >= LogLevel::DEBUG)
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100382 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100383 func_on_all_printers([&](Printer * p)
384 {
385 p->print_info(error.what());
386 });
Anthony Barbierf6705ec2017-09-28 12:01:10 +0100387 }
388
389 result.status = TestResult::Status::NOT_RUN;
390 }
391 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100392 catch(const TestError &error)
393 {
Pablo Tello21eaefe2018-10-10 14:38:35 +0100394 profiler.test_stop();
Giorgio Arena2d099932017-10-25 15:47:08 +0100395 if(_log_level >= error.level())
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100396 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100397 func_on_all_printers([&](Printer * p)
398 {
399 p->print_error(error, is_expected_failure);
400 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100401 }
402
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100403 result.status = TestResult::Status::FAILED;
404
405 if(_throw_errors)
406 {
407 throw;
408 }
409 }
Moritz Pflanzer47752c92017-07-18 13:38:47 +0100410#ifdef ARM_COMPUTE_CL
411 catch(const ::cl::Error &error)
412 {
Pablo Tello21eaefe2018-10-10 14:38:35 +0100413 profiler.test_stop();
Giorgio Arena2d099932017-10-25 15:47:08 +0100414 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100415 {
Moritz Pflanzer24a82462017-08-04 11:34:44 +0100416 std::stringstream stream;
417 stream << "Error code: " << error.err();
Moritz Pflanzer5b61fd32017-09-12 15:51:33 +0100418 TestError test_error(error.what(), LogLevel::ERRORS, stream.str());
Giorgio Arena2d099932017-10-25 15:47:08 +0100419 func_on_all_printers([&](Printer * p)
420 {
421 p->print_error(test_error, is_expected_failure);
422 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100423 }
424
Moritz Pflanzer47752c92017-07-18 13:38:47 +0100425 result.status = TestResult::Status::FAILED;
426
427 if(_throw_errors)
428 {
429 throw;
430 }
431 }
432#endif /* ARM_COMPUTE_CL */
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100433 catch(const std::exception &error)
434 {
Pablo Tello21eaefe2018-10-10 14:38:35 +0100435 profiler.test_stop();
Giorgio Arena2d099932017-10-25 15:47:08 +0100436 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100437 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100438 func_on_all_printers([&](Printer * p)
439 {
440 p->print_error(error, is_expected_failure);
441 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100442 }
443
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100444 result.status = TestResult::Status::CRASHED;
445
446 if(_throw_errors)
447 {
448 throw;
449 }
450 }
451 catch(...)
452 {
Pablo Tello21eaefe2018-10-10 14:38:35 +0100453 profiler.test_stop();
Giorgio Arena2d099932017-10-25 15:47:08 +0100454 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100455 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100456 func_on_all_printers([&](Printer * p)
457 {
458 p->print_error(TestError("Received unknown exception"), is_expected_failure);
459 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100460 }
461
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100462 result.status = TestResult::Status::CRASHED;
463
464 if(_throw_errors)
465 {
466 throw;
467 }
468 }
469 }
470 catch(const std::exception &error)
471 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100472 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100473 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100474 func_on_all_printers([&](Printer * p)
475 {
476 p->print_error(error, is_expected_failure);
477 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100478 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100479
Moritz Pflanzere33eb642017-07-31 14:48:45 +0100480 result.status = TestResult::Status::CRASHED;
481
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100482 if(_throw_errors)
483 {
484 throw;
485 }
486 }
487 catch(...)
488 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100489 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100490 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100491 func_on_all_printers([&](Printer * p)
492 {
493 p->print_error(TestError("Received unknown exception"), is_expected_failure);
494 });
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100495 }
496
Moritz Pflanzere1103a82017-07-18 12:20:45 +0100497 result.status = TestResult::Status::CRASHED;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100498
499 if(_throw_errors)
500 {
501 throw;
502 }
503 }
504
Giorgio Arena2d099932017-10-25 15:47:08 +0100505 if(_log_level >= LogLevel::ERRORS)
Moritz Pflanzer24a82462017-08-04 11:34:44 +0100506 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100507 func_on_all_printers([](Printer * p)
508 {
509 p->print_errors_footer();
510 });
Moritz Pflanzer24a82462017-08-04 11:34:44 +0100511 }
512
Moritz Pflanzer0ce08442017-09-16 11:11:27 +0100513 _current_test_info = nullptr;
Moritz Pflanzere1103a82017-07-18 12:20:45 +0100514 _current_test_result = nullptr;
515
Moritz Pflanzerfa811652017-07-26 17:00:37 +0100516 if(result.status == TestResult::Status::FAILED)
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100517 {
Moritz Pflanzerfa811652017-07-26 17:00:37 +0100518 if(info.status == TestCaseFactory::Status::EXPECTED_FAILURE)
519 {
520 result.status = TestResult::Status::EXPECTED_FAILURE;
521 }
Moritz Pflanzere33eb642017-07-31 14:48:45 +0100522 }
523
524 if(result.status == TestResult::Status::FAILED || result.status == TestResult::Status::CRASHED)
525 {
526 if(_stop_on_error)
Moritz Pflanzerfa811652017-07-26 17:00:37 +0100527 {
528 throw std::runtime_error("Abort on first error.");
529 }
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100530 }
531
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100532 result.measurements = profiler.measurements();
533
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100534 set_test_result(info, result);
535 log_test_end(info);
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100536}
537
538bool Framework::run()
539{
540 // Clear old test results
541 _test_results.clear();
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100542
Giorgio Arena2d099932017-10-25 15:47:08 +0100543 if(_log_level >= LogLevel::TESTS)
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100544 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100545 func_on_all_printers([](Printer * p)
546 {
547 p->print_run_header();
548 });
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100549 }
550
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100551 const std::chrono::time_point<std::chrono::high_resolution_clock> start = std::chrono::high_resolution_clock::now();
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100552
Gian Marco Iodiced30ed112018-05-16 12:01:14 +0100553 int id = 0;
554 int id_run_test = 0;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100555
556 for(auto &test_factory : _test_factories)
557 {
558 const std::string test_case_name = test_factory->name();
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100559 const TestInfo test_info{ id, test_case_name, test_factory->mode(), test_factory->status() };
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100560
Moritz Pflanzerec2de0f2017-07-27 14:43:46 +0100561 if(_test_filter.is_selected(test_info))
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100562 {
Gian Marco Iodiced30ed112018-05-16 12:01:14 +0100563#ifdef ARM_COMPUTE_CL
Georgios Pinitasf5ec9812018-10-26 14:07:56 +0100564 // Every 100 tests, reset the OpenCL context to release the allocated memory
565 if(opencl_is_available() && (id_run_test % 100) == 0)
Gian Marco Iodiced30ed112018-05-16 12:01:14 +0100566 {
Georgios Pinitasc9f163b2019-11-18 14:25:45 +0000567 auto ctx_properties = CLScheduler::get().context().getInfo<CL_CONTEXT_PROPERTIES>(nullptr);
568 auto queue_properties = CLScheduler::get().queue().getInfo<CL_QUEUE_PROPERTIES>(nullptr);
569
570 cl::Context new_ctx = cl::Context(CL_DEVICE_TYPE_DEFAULT, ctx_properties.data());
571 cl::CommandQueue new_queue = cl::CommandQueue(new_ctx, CLKernelLibrary::get().get_device(), queue_properties);
572
Georgios Pinitasdf473ea2018-05-31 18:53:52 +0100573 CLKernelLibrary::get().clear_programs_cache();
Georgios Pinitasc9f163b2019-11-18 14:25:45 +0000574 CLScheduler::get().set_context(new_ctx);
575 CLScheduler::get().set_queue(new_queue);
Gian Marco Iodiced30ed112018-05-16 12:01:14 +0100576 }
577#endif // ARM_COMPUTE_CL
Pablo Tellodb8485a2019-09-24 11:03:47 +0100578
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100579 run_test(test_info, *test_factory);
Gian Marco Iodiced30ed112018-05-16 12:01:14 +0100580
581 ++id_run_test;
Georgios Pinitas7f152512019-12-16 19:59:52 +0000582
583 // Run test delay
584 sleep_in_seconds(_cooldown_sec);
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100585 }
586
587 ++id;
588 }
589
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100590 const std::chrono::time_point<std::chrono::high_resolution_clock> end = std::chrono::high_resolution_clock::now();
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100591
Giorgio Arena2d099932017-10-25 15:47:08 +0100592 if(_log_level >= LogLevel::TESTS)
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100593 {
Giorgio Arena2d099932017-10-25 15:47:08 +0100594 func_on_all_printers([](Printer * p)
595 {
596 p->print_run_footer();
597 });
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100598 }
599
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100600 auto runtime = std::chrono::duration_cast<std::chrono::seconds>(end - start);
601 std::map<TestResult::Status, int> results = count_test_results();
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100602
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100603 if(_log_level > LogLevel::NONE)
604 {
Moritz Pflanzer8df3faf2017-07-28 13:57:53 +0100605 std::cout << "Executed " << _test_results.size() << " test(s) ("
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100606 << results[TestResult::Status::SUCCESS] << " passed, "
607 << results[TestResult::Status::EXPECTED_FAILURE] << " expected failures, "
608 << results[TestResult::Status::FAILED] << " failed, "
609 << results[TestResult::Status::CRASHED] << " crashed, "
610 << results[TestResult::Status::DISABLED] << " disabled) in " << runtime.count() << " second(s)\n";
Moritz Pflanzer2ac50402017-07-24 15:52:54 +0100611 }
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100612
steniu013e05e4e2017-08-25 17:18:01 +0100613 int num_successful_tests = results[TestResult::Status::SUCCESS] + results[TestResult::Status::EXPECTED_FAILURE] + results[TestResult::Status::DISABLED];
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100614
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100615 return (static_cast<unsigned int>(num_successful_tests) == _test_results.size());
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100616}
617
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100618void Framework::set_test_result(TestInfo info, TestResult result)
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100619{
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100620 _test_results.emplace(std::move(info), std::move(result));
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100621}
622
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100623void Framework::print_test_results(Printer &printer) const
624{
625 printer.print_run_header();
626
627 for(const auto &test : _test_results)
628 {
629 printer.print_test_header(test.first);
630 printer.print_measurements(test.second.measurements);
631 printer.print_test_footer();
632 }
633
634 printer.print_run_footer();
635}
636
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100637Profiler Framework::get_profiler() const
638{
639 Profiler profiler;
640
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100641 const bool all_instruments = std::any_of(
642 _instruments.begin(),
643 _instruments.end(),
Giorgio Arenace58a9f2017-10-31 17:59:17 +0000644 [](InstrumentsDescription type) -> bool { return type.first == InstrumentType::ALL; });
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100645
Giorgio Arenace58a9f2017-10-31 17:59:17 +0000646 auto is_selected = [&](InstrumentsDescription instrument) -> bool
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100647 {
Giorgio Arenace58a9f2017-10-31 17:59:17 +0000648 return std::find_if(_instruments.begin(), _instruments.end(), [&](InstrumentsDescription type) -> bool {
649 const auto group = static_cast<InstrumentType>(static_cast<uint64_t>(type.first) & 0xFF00);
650 return (group == instrument.first) && (instrument.second == type.second);
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100651 })
652 != _instruments.end();
653 };
654
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100655 for(const auto &instrument : _available_instruments)
656 {
Moritz Pflanzer09e4f982017-08-30 12:47:06 +0100657 if(all_instruments || is_selected(instrument.first))
Moritz Pflanzera4f711b2017-07-05 11:02:23 +0100658 {
659 profiler.add(instrument.second());
660 }
661 }
662
663 return profiler;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100664}
665
Giorgio Arena2d099932017-10-25 15:47:08 +0100666void Framework::add_printer(Printer *printer)
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100667{
Giorgio Arena2d099932017-10-25 15:47:08 +0100668 _printers.push_back(printer);
Moritz Pflanzer80fffae2017-07-05 11:02:37 +0100669}
670
Moritz Pflanzer542002c2017-07-26 16:03:58 +0100671std::vector<TestInfo> Framework::test_infos() const
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100672{
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100673 std::vector<TestInfo> ids;
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100674
675 int id = 0;
676
677 for(const auto &factory : _test_factories)
678 {
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100679 TestInfo test_info{ id, factory->name(), factory->mode(), factory->status() };
680
Moritz Pflanzerec2de0f2017-07-27 14:43:46 +0100681 if(_test_filter.is_selected(test_info))
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100682 {
Moritz Pflanzerbf234e02017-07-24 15:04:14 +0100683 ids.emplace_back(std::move(test_info));
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100684 }
685
686 ++id;
687 }
688
689 return ids;
690}
steniu01172c58d2017-08-31 13:49:08 +0100691
692LogLevel Framework::log_level() const
693{
694 return _log_level;
695}
Georgios Pinitas12833d02019-07-25 13:31:10 +0100696
697void Framework::set_instruments_info(InstrumentsInfo instr_info)
698{
699 ARM_COMPUTE_ERROR_ON(instruments_info == nullptr);
700 *instruments_info = instr_info;
701}
Moritz Pflanzerfc95ed22017-07-05 11:07:07 +0100702} // namespace framework
703} // namespace test
704} // namespace arm_compute