blob: 057d309b2ef4433588cf630f0400cae0c8474749 [file] [log] [blame]
Anthony Barbier871448e2017-03-24 14:54:29 +00001/*
Anthony Barbier06ea0482018-02-22 15:45:35 +00002 * Copyright (c) 2017-2018 ARM Limited.
Anthony Barbier871448e2017-03-24 14:54:29 +00003 *
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.h"
25
26#include <cctype>
Anthony Barbiera4376382017-04-12 15:12:46 +010027#include <cerrno>
Anthony Barbier871448e2017-03-24 14:54:29 +000028#include <iomanip>
29#include <string>
Anthony Barbier46d59272017-05-04 09:15:15 +010030
Anthony Barbierdbdab852017-06-23 15:42:00 +010031namespace arm_compute
32{
33namespace utils
34{
Anthony Barbier871448e2017-03-24 14:54:29 +000035namespace
36{
37/* Advance the iterator to the first character which is not a comment
38 *
39 * @param[in,out] fs Stream to drop comments from
40 */
41void discard_comments(std::ifstream &fs)
42{
43 while(fs.peek() == '#')
44 {
45 fs.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
46 }
47}
48
49/* Advance the string iterator to the next character which is neither a space or a comment
50 *
51 * @param[in,out] fs Stream to drop comments from
52 */
53void discard_comments_and_spaces(std::ifstream &fs)
54{
55 while(true)
56 {
57 discard_comments(fs);
58
59 if(isspace(fs.peek()) == 0)
60 {
61 break;
62 }
63
64 fs.ignore(1);
65 }
66}
67} // namespace
68
Anthony Barbierf45d5a92018-01-24 16:23:15 +000069#ifndef BENCHMARK_EXAMPLES
Jenkinsb3a371b2018-05-23 11:36:53 +010070int run_example(int argc, char **argv, std::unique_ptr<Example> example)
Anthony Barbier871448e2017-03-24 14:54:29 +000071{
72 std::cout << "\n"
73 << argv[0] << "\n\n";
74
75 try
76 {
Jenkins52ba29e2018-08-29 15:32:11 +000077 bool status = example->do_setup(argc, argv);
78 if(!status)
79 {
80 return 1;
81 }
Jenkinsb3a371b2018-05-23 11:36:53 +010082 example->do_run();
83 example->do_teardown();
Anthony Barbier871448e2017-03-24 14:54:29 +000084
85 std::cout << "\nTest passed\n";
86 return 0;
87 }
88#ifdef ARM_COMPUTE_CL
89 catch(cl::Error &err)
90 {
91 std::cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
92 std::cerr << std::endl
93 << "ERROR " << err.what() << "(" << err.err() << ")" << std::endl;
94 std::cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
95 }
96#endif /* ARM_COMPUTE_CL */
97 catch(std::runtime_error &err)
98 {
99 std::cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
100 std::cerr << std::endl
101 << "ERROR " << err.what() << " " << (errno ? strerror(errno) : "") << std::endl;
102 std::cerr << "!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl;
103 }
104
105 std::cout << "\nTest FAILED\n";
106
107 return -1;
108}
Anthony Barbierf45d5a92018-01-24 16:23:15 +0000109#endif /* BENCHMARK_EXAMPLES */
Anthony Barbier871448e2017-03-24 14:54:29 +0000110
Anthony Barbierdbdab852017-06-23 15:42:00 +0100111void draw_detection_rectangle(ITensor *tensor, const DetectionWindow &rect, uint8_t r, uint8_t g, uint8_t b)
Anthony Barbier871448e2017-03-24 14:54:29 +0000112{
113 ARM_COMPUTE_ERROR_ON_FORMAT_NOT_IN(tensor, Format::RGB888);
114
115 uint8_t *top = tensor->info()->offset_element_in_bytes(Coordinates(rect.x, rect.y)) + tensor->buffer();
116 uint8_t *bottom = tensor->info()->offset_element_in_bytes(Coordinates(rect.x, rect.y + rect.height)) + tensor->buffer();
117 uint8_t *left = top;
118 uint8_t *right = tensor->info()->offset_element_in_bytes(Coordinates(rect.x + rect.width, rect.y)) + tensor->buffer();
119 size_t stride = tensor->info()->strides_in_bytes()[Window::DimY];
120
121 for(size_t x = 0; x < rect.width; ++x)
122 {
123 top[0] = r;
124 top[1] = g;
125 top[2] = b;
126 bottom[0] = r;
127 bottom[1] = g;
128 bottom[2] = b;
129
130 top += 3;
131 bottom += 3;
132 }
133
134 for(size_t y = 0; y < rect.height; ++y)
135 {
136 left[0] = r;
137 left[1] = g;
138 left[2] = b;
139 right[0] = r;
140 right[1] = g;
141 right[2] = b;
142
143 left += stride;
144 right += stride;
145 }
146}
147
Jenkins52ba29e2018-08-29 15:32:11 +0000148ImageType get_image_type_from_file(const std::string &filename)
149{
150 ImageType type = ImageType::UNKNOWN;
151
152 try
153 {
154 // Open file
155 std::ifstream fs;
156 fs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
157 fs.open(filename, std::ios::in | std::ios::binary);
158
159 // Identify type from magic number
160 std::array<unsigned char, 2> magic_number{ { 0 } };
161 fs >> magic_number[0] >> magic_number[1];
162
163 // PPM check
164 if(static_cast<char>(magic_number[0]) == 'P' && static_cast<char>(magic_number[1]) == '6')
165 {
166 type = ImageType::PPM;
167 }
168 else if(magic_number[0] == 0xFF && magic_number[1] == 0xD8)
169 {
170 type = ImageType::JPEG;
171 }
172
173 fs.close();
174 }
175 catch(std::runtime_error &e)
176 {
177 ARM_COMPUTE_ERROR("Accessing %s: %s", filename.c_str(), e.what());
178 }
179
180 return type;
181}
182
Anthony Barbierdbdab852017-06-23 15:42:00 +0100183std::tuple<unsigned int, unsigned int, int> parse_ppm_header(std::ifstream &fs)
Anthony Barbier871448e2017-03-24 14:54:29 +0000184{
185 // Check the PPM magic number is valid
186 std::array<char, 2> magic_number{ { 0 } };
187 fs >> magic_number[0] >> magic_number[1];
188 ARM_COMPUTE_ERROR_ON_MSG(magic_number[0] != 'P' || magic_number[1] != '6', "Invalid file type");
189 ARM_COMPUTE_UNUSED(magic_number);
190
191 discard_comments_and_spaces(fs);
192
193 unsigned int width = 0;
194 fs >> width;
195
196 discard_comments_and_spaces(fs);
197
198 unsigned int height = 0;
199 fs >> height;
200
201 discard_comments_and_spaces(fs);
202
203 int max_val = 0;
204 fs >> max_val;
205
206 discard_comments(fs);
207
208 ARM_COMPUTE_ERROR_ON_MSG(isspace(fs.peek()) == 0, "Invalid PPM header");
209 fs.ignore(1);
210
211 return std::make_tuple(width, height, max_val);
Yuxin Wub3640812017-03-31 14:54:34 -0700212}
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000213
214std::tuple<std::vector<unsigned long>, bool, std::string> parse_npy_header(std::ifstream &fs) //NOLINT
215{
216 std::vector<unsigned long> shape; // NOLINT
217
218 // Read header
219 std::string header = npy::read_header(fs);
220
221 // Parse header
222 bool fortran_order = false;
223 std::string typestr;
224 npy::parse_header(header, typestr, fortran_order, shape);
225
Jenkins52ba29e2018-08-29 15:32:11 +0000226 std::reverse(shape.begin(), shape.end());
Anthony Barbier8140e1e2017-12-14 23:48:46 +0000227
228 return std::make_tuple(shape, fortran_order, typestr);
229}
Anthony Barbier06ea0482018-02-22 15:45:35 +0000230
231/** This function returns the amount of memory free reading from /proc/meminfo
232 *
233 * @return The free memory in kB
234 */
235uint64_t get_mem_free_from_meminfo()
236{
237 std::string line_attribute;
238 std::ifstream file_meminfo("/proc/meminfo");
239
240 if(file_meminfo.is_open())
241 {
242 while(!(file_meminfo >> line_attribute).fail())
243 {
244 //Test if is the line containing MemFree
245 if(line_attribute == "MemFree:")
246 {
247 uint64_t mem_available;
248 if(!(file_meminfo >> mem_available).fail())
249 {
250 return mem_available;
251 }
252 else
253 {
254 return 0;
255 }
256 }
257 // if it's not MemFree ignore rest of the line
258 file_meminfo.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
259 }
260 }
261 // Nothing found or an error during opening the file
262 return 0;
263}
Anthony Barbierdbdab852017-06-23 15:42:00 +0100264} // namespace utils
265} // namespace arm_compute