blob: a7b18ce55515481d1974c6fcbe255d141665d534 [file] [log] [blame]
Anthony Barbier979dc4f2018-03-07 09:27:48 +00001/*
2 * Copyright (c) 2018 ARM Limited.
3 *
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 "utils/Utils.h"
25//FIXME / INTERNAL_ONLY: This file should not be released!
26
27#define BENCHMARK_EXAMPLES
28#include "utils/Utils.cpp"
29
30#include "ValidateExample.h"
31#include "arm_compute/runtime/Scheduler.h"
32#include "tests/AssetsLibrary.h"
33#include "tests/Globals.h"
34#include "tests/framework/Framework.h"
35#include "tests/framework/Macros.h"
36#include "tests/framework/command_line/CommandLineParser.h"
37#include "tests/framework/command_line/CommonOptions.h"
38#include "tests/framework/instruments/Instruments.h"
39
40#ifdef ARM_COMPUTE_CL
41#include "arm_compute/runtime/CL/CLScheduler.h"
42#endif /* ARM_COMPUTE_CL */
43#ifdef ARM_COMPUTE_GC
44#include "arm_compute/runtime/GLES_COMPUTE/GCScheduler.h"
45#endif /* ARM_COMPUTE_GC */
46
47#include <libgen.h>
48
49using namespace arm_compute;
50using namespace arm_compute::test;
51
52namespace arm_compute
53{
54namespace test
55{
56std::unique_ptr<AssetsLibrary> library;
57} // namespace test
58namespace utils
59{
60static ValidateExample *g_example = nullptr;
61template <bool validate>
62class ExampleTest : public arm_compute::test::framework::TestCase
63{
64public:
65 ExampleTest() = default;
66 void do_run() override
67 {
68 g_example->do_run();
69 }
70 void do_teardown() override
71 {
72 if(validate)
73 {
74 g_example->do_validate();
75 }
76 g_example->do_teardown();
77 }
78};
79
80int run_example(int argc, char **argv, ValidateExample &example)
81{
82 framework::CommandLineParser parser;
83 framework::CommonOptions options(parser);
84 auto example_args = parser.add_option<framework::ListOption<std::string>>("example_args");
85 example_args->set_help("Arguments to pass to the example separated by commas (e.g: arg0,arg1,arg2)");
86 auto seed = parser.add_option<framework::SimpleOption<std::random_device::result_type>>("seed", std::random_device()());
87 seed->set_help("Global seed for random number generation");
88 auto validate = parser.add_option<framework::SimpleOption<int>>("validate", 1);
89 validate->set_help("Enable / disable output validation (0/1)");
90
91 framework::Framework &framework = framework::Framework::get();
92
93 parser.parse(argc, argv);
94
95 if(options.help->is_set() && options.help->value())
96 {
97 parser.print_help(argv[0]);
98 return 0;
99 }
100
101 std::vector<std::unique_ptr<framework::Printer>> printers = options.create_printers();
102 g_example = &example;
103 std::vector<char *> example_argv = {};
104 example_argv.clear();
105 example_argv.emplace_back(argv[0]);
106 for(auto &arg : example_args->value())
107 {
108 example_argv.emplace_back(const_cast<char *>(arg.c_str())); // NOLINT
109 }
110
111 // Set number of threads in Scheduler
112 Scheduler::get().set_num_threads(options.threads->value());
113 library = support::cpp14::make_unique<AssetsLibrary>("." /* Only using random values */, seed->value());
114
115 // We need to do the setup here because framework.init() will need CL / GLES to be initialised
116 try
117 {
118 example.do_setup(example_argv.size(), &example_argv[0]);
119 }
120#ifdef ARM_COMPUTE_CL
121 catch(cl::Error &err)
122 {
123 std::cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
124 std::cerr << std::endl
125 << "ERROR " << err.what() << "(" << err.err() << ")" << std::endl;
126 std::cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
127 return 1;
128 }
129#endif /* ARM_COMPUTE_CL */
130 catch(std::runtime_error &err)
131 {
132 std::cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
133 std::cerr << std::endl
134 << "ERROR " << err.what() << " " << (errno ? strerror(errno) : "") << std::endl;
135 std::cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
136 return 1;
137 }
138
139 if(options.log_level->value() > framework::LogLevel::NONE)
140 {
141 for(auto &p : printers)
142 {
143 p->print_global_header();
144 }
145 }
146
147 if(options.log_level->value() >= framework::LogLevel::CONFIG)
148 {
149 for(auto &p : printers)
150 {
151 p->print_entry("Version", build_information());
152 p->print_entry("Seed", support::cpp11::to_string(seed->value()));
153#ifdef ARM_COMPUTE_CL
154 if(opencl_is_available())
155 {
156 p->print_entry("CL_DEVICE_VERSION", CLKernelLibrary::get().get_device_version());
157 }
158 else
159 {
160 p->print_entry("CL_DEVICE_VERSION", "Unavailable");
161 }
162#endif /* ARM_COMPUTE_CL */
163 p->print_entry("Iterations", support::cpp11::to_string(options.iterations->value()));
164 p->print_entry("Threads", support::cpp11::to_string(options.threads->value()));
165 example.print_parameters(*p);
166 }
167 }
168
169 framework.init(options.instruments->value(), options.iterations->value(), framework::DatasetMode::ALL, "", "", options.log_level->value());
170 for(auto &p : printers)
171 {
172 framework.add_printer(p.get());
173 }
174
175 framework.set_throw_errors(options.throw_errors->value());
176 arm_compute::test::framework::detail::TestSuiteRegistrar suite{ "Examples" };
177 if(validate->value() != 0)
178 {
179 framework.add_test_case<ExampleTest<true>>(basename(argv[0]), framework::DatasetMode::ALL, arm_compute::test::framework::TestCaseFactory::Status::ACTIVE);
180 }
181 else
182 {
183 framework.add_test_case<ExampleTest<false>>(basename(argv[0]), framework::DatasetMode::ALL, arm_compute::test::framework::TestCaseFactory::Status::ACTIVE);
184 }
185
186 //func(argc, argv);
187 bool success = framework.run();
188 if(options.log_level->value() > framework::LogLevel::NONE)
189 {
190 for(auto &p : printers)
191 {
192 p->print_global_footer();
193 }
194 }
195
196 return (success ? 0 : 1);
197}
198
199} // namespace utils
200} // namespace arm_compute