blob: 58738f871d32e2daed71e56a8f720458f8913102 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
2 * Copyright (c) 2017 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#ifndef __ARM_COMPUTE_TEST_TENSOR_LIBRARY_H__
25#define __ARM_COMPUTE_TEST_TENSOR_LIBRARY_H__
26
Anthony Barbier6ff3b192017-09-04 18:44:23 +010027#include "arm_compute/core/Coordinates.h"
28#include "arm_compute/core/Error.h"
29#include "arm_compute/core/Helpers.h"
30#include "arm_compute/core/TensorInfo.h"
31#include "arm_compute/core/TensorShape.h"
32#include "arm_compute/core/Types.h"
33#include "arm_compute/core/Window.h"
Moritz Pflanzere49e2662017-07-21 15:55:28 +010034#include "tests/RawTensor.h"
35#include "tests/TensorCache.h"
36#include "tests/Utils.h"
37#include "tests/validation/half.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010038
39#include <algorithm>
40#include <cstddef>
41#include <fstream>
42#include <random>
43#include <string>
44#include <type_traits>
45
46namespace arm_compute
47{
48namespace test
49{
50/** Factory class to create and fill tensors.
51 *
52 * Allows to initialise tensors from loaded images or by specifying the shape
53 * explicitly. Furthermore, provides methods to fill tensors with the content of
54 * loaded images or with random values.
55 */
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +010056class AssetsLibrary final
Anthony Barbier6ff3b192017-09-04 18:44:23 +010057{
58public:
59 /** Initialises the library with a @p path to the image directory.
Anthony Barbier6ff3b192017-09-04 18:44:23 +010060 * Furthermore, sets the seed for the random generator to @p seed.
61 *
62 * @param[in] path Path to load images from.
63 * @param[in] seed Seed used to initialise the random number generator.
64 */
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +010065 AssetsLibrary(std::string path, std::random_device::result_type seed);
Anthony Barbier6ff3b192017-09-04 18:44:23 +010066
67 /** Seed that is used to fill tensors with random values. */
68 std::random_device::result_type seed() const;
69
Giorgio Arenafda46182017-06-16 13:57:33 +010070 /** Provides a tensor shape for the specified image.
71 *
72 * @param[in] name Image file used to look up the raw tensor.
73 */
74 TensorShape get_image_shape(const std::string &name);
75
Anthony Barbier6ff3b192017-09-04 18:44:23 +010076 /** Provides a contant raw tensor for the specified image.
77 *
78 * @param[in] name Image file used to look up the raw tensor.
79 */
80 const RawTensor &get(const std::string &name) const;
81
82 /** Provides a raw tensor for the specified image.
83 *
84 * @param[in] name Image file used to look up the raw tensor.
85 */
86 RawTensor get(const std::string &name);
87
88 /** Creates an uninitialised raw tensor with the given @p data_type and @p
89 * num_channels. The shape is derived from the specified image.
90 *
91 * @param[in] name Image file used to initialise the tensor.
92 * @param[in] data_type Data type used to initialise the tensor.
93 * @param[in] num_channels Number of channels used to initialise the tensor.
94 */
95 RawTensor get(const std::string &name, DataType data_type, int num_channels = 1) const;
96
97 /** Provides a contant raw tensor for the specified image after it has been
98 * converted to @p format.
99 *
100 * @param[in] name Image file used to look up the raw tensor.
101 * @param[in] format Format used to look up the raw tensor.
102 */
103 const RawTensor &get(const std::string &name, Format format) const;
104
105 /** Provides a raw tensor for the specified image after it has been
106 * converted to @p format.
107 *
108 * @param[in] name Image file used to look up the raw tensor.
109 * @param[in] format Format used to look up the raw tensor.
110 */
111 RawTensor get(const std::string &name, Format format);
112
113 /** Provides a contant raw tensor for the specified channel after it has
114 * been extracted form the given image.
115 *
116 * @param[in] name Image file used to look up the raw tensor.
117 * @param[in] channel Channel used to look up the raw tensor.
118 *
119 * @note The channel has to be unambiguous so that the format can be
120 * inferred automatically.
121 */
122 const RawTensor &get(const std::string &name, Channel channel) const;
123
124 /** Provides a raw tensor for the specified channel after it has been
125 * extracted form the given image.
126 *
127 * @param[in] name Image file used to look up the raw tensor.
128 * @param[in] channel Channel used to look up the raw tensor.
129 *
130 * @note The channel has to be unambiguous so that the format can be
131 * inferred automatically.
132 */
133 RawTensor get(const std::string &name, Channel channel);
134
135 /** Provides a constant raw tensor for the specified channel after it has
136 * been extracted form the given image formatted to @p format.
137 *
138 * @param[in] name Image file used to look up the raw tensor.
139 * @param[in] format Format used to look up the raw tensor.
140 * @param[in] channel Channel used to look up the raw tensor.
141 */
142 const RawTensor &get(const std::string &name, Format format, Channel channel) const;
143
144 /** Provides a raw tensor for the specified channel after it has been
145 * extracted form the given image formatted to @p format.
146 *
147 * @param[in] name Image file used to look up the raw tensor.
148 * @param[in] format Format used to look up the raw tensor.
149 * @param[in] channel Channel used to look up the raw tensor.
150 */
151 RawTensor get(const std::string &name, Format format, Channel channel);
152
153 /** Fills the specified @p tensor with random values drawn from @p
154 * distribution.
155 *
156 * @param[in, out] tensor To be filled tensor.
157 * @param[in] distribution Distribution used to fill the tensor.
158 * @param[in] seed_offset The offset will be added to the global seed before initialising the random generator.
159 *
160 * @note The @p distribution has to provide operator(Generator &) which
161 * will be used to draw samples.
162 */
163 template <typename T, typename D>
164 void fill(T &&tensor, D &&distribution, std::random_device::result_type seed_offset) const;
165
166 /** Fills the specified @p raw tensor with random values drawn from @p
167 * distribution.
168 *
169 * @param[in, out] raw To be filled raw.
170 * @param[in] distribution Distribution used to fill the tensor.
171 * @param[in] seed_offset The offset will be added to the global seed before initialising the random generator.
172 *
173 * @note The @p distribution has to provide operator(Generator &) which
174 * will be used to draw samples.
175 */
176 template <typename D>
177 void fill(RawTensor &raw, D &&distribution, std::random_device::result_type seed_offset) const;
178
179 /** Fills the specified @p tensor with the content of the specified image
180 * converted to the given format.
181 *
182 * @param[in, out] tensor To be filled tensor.
183 * @param[in] name Image file used to fill the tensor.
184 * @param[in] format Format of the image used to fill the tensor.
185 *
186 * @warning No check is performed that the specified format actually
187 * matches the format of the tensor.
188 */
189 template <typename T>
190 void fill(T &&tensor, const std::string &name, Format format) const;
191
192 /** Fills the raw tensor with the content of the specified image
193 * converted to the given format.
194 *
195 * @param[in, out] raw To be filled raw tensor.
196 * @param[in] name Image file used to fill the tensor.
197 * @param[in] format Format of the image used to fill the tensor.
198 *
199 * @warning No check is performed that the specified format actually
200 * matches the format of the tensor.
201 */
202 void fill(RawTensor &raw, const std::string &name, Format format) const;
203
204 /** Fills the specified @p tensor with the content of the specified channel
205 * extracted from the given image.
206 *
207 * @param[in, out] tensor To be filled tensor.
208 * @param[in] name Image file used to fill the tensor.
209 * @param[in] channel Channel of the image used to fill the tensor.
210 *
211 * @note The channel has to be unambiguous so that the format can be
212 * inferred automatically.
213 *
214 * @warning No check is performed that the specified format actually
215 * matches the format of the tensor.
216 */
217 template <typename T>
218 void fill(T &&tensor, const std::string &name, Channel channel) const;
219
220 /** Fills the raw tensor with the content of the specified channel
221 * extracted from the given image.
222 *
223 * @param[in, out] raw To be filled raw tensor.
224 * @param[in] name Image file used to fill the tensor.
225 * @param[in] channel Channel of the image used to fill the tensor.
226 *
227 * @note The channel has to be unambiguous so that the format can be
228 * inferred automatically.
229 *
230 * @warning No check is performed that the specified format actually
231 * matches the format of the tensor.
232 */
233 void fill(RawTensor &raw, const std::string &name, Channel channel) const;
234
235 /** Fills the specified @p tensor with the content of the specified channel
236 * extracted from the given image after it has been converted to the given
237 * format.
238 *
239 * @param[in, out] tensor To be filled tensor.
240 * @param[in] name Image file used to fill the tensor.
241 * @param[in] format Format of the image used to fill the tensor.
242 * @param[in] channel Channel of the image used to fill the tensor.
243 *
244 * @warning No check is performed that the specified format actually
245 * matches the format of the tensor.
246 */
247 template <typename T>
248 void fill(T &&tensor, const std::string &name, Format format, Channel channel) const;
249
250 /** Fills the raw tensor with the content of the specified channel
251 * extracted from the given image after it has been converted to the given
252 * format.
253 *
254 * @param[in, out] raw To be filled raw tensor.
255 * @param[in] name Image file used to fill the tensor.
256 * @param[in] format Format of the image used to fill the tensor.
257 * @param[in] channel Channel of the image used to fill the tensor.
258 *
259 * @warning No check is performed that the specified format actually
260 * matches the format of the tensor.
261 */
262 void fill(RawTensor &raw, const std::string &name, Format format, Channel channel) const;
263
264 /** Fill a tensor with uniform distribution across the range of its type
265 *
266 * @param[in, out] tensor To be filled tensor.
267 * @param[in] seed_offset The offset will be added to the global seed before initialising the random generator.
268 */
269 template <typename T>
270 void fill_tensor_uniform(T &&tensor, std::random_device::result_type seed_offset) const;
271
272 /** Fill a tensor with uniform distribution across the a specified range
273 *
274 * @param[in, out] tensor To be filled tensor.
275 * @param[in] seed_offset The offset will be added to the global seed before initialising the random generator.
276 * @param[in] low lowest value in the range (inclusive)
277 * @param[in] high highest value in the range (inclusive)
278 *
279 * @note @p low and @p high must be of the same type as the data type of @p tensor
280 */
281 template <typename T, typename D>
282 void fill_tensor_uniform(T &&tensor, std::random_device::result_type seed_offset, D low, D high) const;
283
284 /** Fills the specified @p tensor with data loaded from binary in specified path.
285 *
286 * @param[in, out] tensor To be filled tensor.
287 * @param[in] name Data file.
288 */
289 template <typename T>
290 void fill_layer_data(T &&tensor, std::string name) const;
291
292private:
293 // Function prototype to convert between image formats.
294 using Converter = void (*)(const RawTensor &src, RawTensor &dst);
295 // Function prototype to extract a channel from an image.
296 using Extractor = void (*)(const RawTensor &src, RawTensor &dst);
297 // Function prototype to load an image file.
298 using Loader = RawTensor (*)(const std::string &path);
299
300 const Converter &get_converter(Format src, Format dst) const;
301 const Converter &get_converter(DataType src, Format dst) const;
302 const Converter &get_converter(Format src, DataType dst) const;
303 const Converter &get_converter(DataType src, DataType dst) const;
304 const Extractor &get_extractor(Format format, Channel) const;
305 const Loader &get_loader(const std::string &extension) const;
306
307 /** Creates a raw tensor from the specified image.
308 *
309 * @param[in] name To be loaded image file.
310 *
311 * @note If use_single_image is true @p name is ignored and the user image
312 * is loaded instead.
313 */
314 RawTensor load_image(const std::string &name) const;
315
316 /** Provides a raw tensor for the specified image and format.
317 *
318 * @param[in] name Image file used to look up the raw tensor.
319 * @param[in] format Format used to look up the raw tensor.
320 *
321 * If the tensor has already been requested before the cached version will
322 * be returned. Otherwise the tensor will be added to the cache.
323 *
324 * @note If use_single_image is true @p name is ignored and the user image
325 * is loaded instead.
326 */
327 const RawTensor &find_or_create_raw_tensor(const std::string &name, Format format) const;
328
329 /** Provides a raw tensor for the specified image, format and channel.
330 *
331 * @param[in] name Image file used to look up the raw tensor.
332 * @param[in] format Format used to look up the raw tensor.
333 * @param[in] channel Channel used to look up the raw tensor.
334 *
335 * If the tensor has already been requested before the cached version will
336 * be returned. Otherwise the tensor will be added to the cache.
337 *
338 * @note If use_single_image is true @p name is ignored and the user image
339 * is loaded instead.
340 */
341 const RawTensor &find_or_create_raw_tensor(const std::string &name, Format format, Channel channel) const;
342
343 mutable TensorCache _cache{};
344 mutable std::mutex _format_lock{};
345 mutable std::mutex _channel_lock{};
Anthony Barbierac69aa12017-07-03 17:39:37 +0100346 const std::string _library_path;
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100347 std::random_device::result_type _seed;
348};
349
350template <typename T, typename D>
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100351void AssetsLibrary::fill(T &&tensor, D &&distribution, std::random_device::result_type seed_offset) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100352{
353 Window window;
354 for(unsigned int d = 0; d < tensor.shape().num_dimensions(); ++d)
355 {
356 window.set(d, Window::Dimension(0, tensor.shape()[d], 1));
357 }
358
359 std::mt19937 gen(_seed + seed_offset);
360
361 //FIXME: Replace with normal loop
362 execute_window_loop(window, [&](const Coordinates & id)
363 {
364 using ResultType = typename std::remove_reference<D>::type::result_type;
365 const ResultType value = distribution(gen);
366 void *const out_ptr = tensor(id);
367 store_value_with_data_type(out_ptr, value, tensor.data_type());
368 });
369}
370
371template <typename D>
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100372void AssetsLibrary::fill(RawTensor &raw, D &&distribution, std::random_device::result_type seed_offset) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100373{
374 std::mt19937 gen(_seed + seed_offset);
375
376 for(size_t offset = 0; offset < raw.size(); offset += raw.element_size())
377 {
378 using ResultType = typename std::remove_reference<D>::type::result_type;
379 const ResultType value = distribution(gen);
380 store_value_with_data_type(raw.data() + offset, value, raw.data_type());
381 }
382}
383
384template <typename T>
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100385void AssetsLibrary::fill(T &&tensor, const std::string &name, Format format) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100386{
387 const RawTensor &raw = get(name, format);
388
389 for(size_t offset = 0; offset < raw.size(); offset += raw.element_size())
390 {
391 const Coordinates id = index2coord(raw.shape(), offset / raw.element_size());
392
393 const RawTensor::BufferType *const raw_ptr = raw.data() + offset;
394 const auto out_ptr = static_cast<RawTensor::BufferType *>(tensor(id));
395 std::copy_n(raw_ptr, raw.element_size(), out_ptr);
396 }
397}
398
399template <typename T>
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100400void AssetsLibrary::fill(T &&tensor, const std::string &name, Channel channel) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100401{
402 fill(std::forward<T>(tensor), name, get_format_for_channel(channel), channel);
403}
404
405template <typename T>
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100406void AssetsLibrary::fill(T &&tensor, const std::string &name, Format format, Channel channel) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100407{
408 const RawTensor &raw = get(name, format, channel);
409
410 for(size_t offset = 0; offset < raw.size(); offset += raw.element_size())
411 {
412 const Coordinates id = index2coord(raw.shape(), offset / raw.element_size());
413
414 const RawTensor::BufferType *const raw_ptr = raw.data() + offset;
415 const auto out_ptr = static_cast<RawTensor::BufferType *>(tensor(id));
416 std::copy_n(raw_ptr, raw.element_size(), out_ptr);
417 }
418}
419
420template <typename T>
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100421void AssetsLibrary::fill_tensor_uniform(T &&tensor, std::random_device::result_type seed_offset) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100422{
423 switch(tensor.data_type())
424 {
425 case DataType::U8:
426 {
427 std::uniform_int_distribution<uint8_t> distribution_u8(std::numeric_limits<uint8_t>::lowest(), std::numeric_limits<uint8_t>::max());
428 fill(tensor, distribution_u8, seed_offset);
429 break;
430 }
431 case DataType::S8:
432 case DataType::QS8:
433 {
434 std::uniform_int_distribution<int8_t> distribution_s8(std::numeric_limits<int8_t>::lowest(), std::numeric_limits<int8_t>::max());
435 fill(tensor, distribution_s8, seed_offset);
436 break;
437 }
438 case DataType::U16:
439 {
440 std::uniform_int_distribution<uint16_t> distribution_u16(std::numeric_limits<uint16_t>::lowest(), std::numeric_limits<uint16_t>::max());
441 fill(tensor, distribution_u16, seed_offset);
442 break;
443 }
444 case DataType::S16:
Gian Marco Iodicebdb6b0b2017-06-30 12:21:00 +0100445 case DataType::QS16:
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100446 {
447 std::uniform_int_distribution<int16_t> distribution_s16(std::numeric_limits<int16_t>::lowest(), std::numeric_limits<int16_t>::max());
448 fill(tensor, distribution_s16, seed_offset);
449 break;
450 }
451 case DataType::U32:
452 {
453 std::uniform_int_distribution<uint32_t> distribution_u32(std::numeric_limits<uint32_t>::lowest(), std::numeric_limits<uint32_t>::max());
454 fill(tensor, distribution_u32, seed_offset);
455 break;
456 }
457 case DataType::S32:
458 {
459 std::uniform_int_distribution<int32_t> distribution_s32(std::numeric_limits<int32_t>::lowest(), std::numeric_limits<int32_t>::max());
460 fill(tensor, distribution_s32, seed_offset);
461 break;
462 }
463 case DataType::U64:
464 {
465 std::uniform_int_distribution<uint64_t> distribution_u64(std::numeric_limits<uint64_t>::lowest(), std::numeric_limits<uint64_t>::max());
466 fill(tensor, distribution_u64, seed_offset);
467 break;
468 }
469 case DataType::S64:
470 {
471 std::uniform_int_distribution<int64_t> distribution_s64(std::numeric_limits<int64_t>::lowest(), std::numeric_limits<int64_t>::max());
472 fill(tensor, distribution_s64, seed_offset);
473 break;
474 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100475 case DataType::F16:
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100476 case DataType::F32:
477 {
478 // It doesn't make sense to check [-inf, inf], so hard code it to a big number
479 std::uniform_real_distribution<float> distribution_f32(-1000.f, 1000.f);
480 fill(tensor, distribution_f32, seed_offset);
481 break;
482 }
483 case DataType::F64:
484 {
485 // It doesn't make sense to check [-inf, inf], so hard code it to a big number
486 std::uniform_real_distribution<double> distribution_f64(-1000.f, 1000.f);
487 fill(tensor, distribution_f64, seed_offset);
488 break;
489 }
490 case DataType::SIZET:
491 {
492 std::uniform_int_distribution<size_t> distribution_sizet(std::numeric_limits<size_t>::lowest(), std::numeric_limits<size_t>::max());
493 fill(tensor, distribution_sizet, seed_offset);
494 break;
495 }
496 default:
497 ARM_COMPUTE_ERROR("NOT SUPPORTED!");
498 }
499}
500
501template <typename T, typename D>
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100502void AssetsLibrary::fill_tensor_uniform(T &&tensor, std::random_device::result_type seed_offset, D low, D high) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100503{
504 switch(tensor.data_type())
505 {
506 case DataType::U8:
507 {
508 ARM_COMPUTE_ERROR_ON(!(std::is_same<uint8_t, D>::value));
509 std::uniform_int_distribution<uint8_t> distribution_u8(low, high);
510 fill(tensor, distribution_u8, seed_offset);
511 break;
512 }
513 case DataType::S8:
514 case DataType::QS8:
515 {
516 ARM_COMPUTE_ERROR_ON(!(std::is_same<int8_t, D>::value));
517 std::uniform_int_distribution<int8_t> distribution_s8(low, high);
518 fill(tensor, distribution_s8, seed_offset);
519 break;
520 }
521 case DataType::U16:
522 {
523 ARM_COMPUTE_ERROR_ON(!(std::is_same<uint16_t, D>::value));
524 std::uniform_int_distribution<uint16_t> distribution_u16(low, high);
525 fill(tensor, distribution_u16, seed_offset);
526 break;
527 }
528 case DataType::S16:
Georgios Pinitas21efeb42017-07-04 12:47:17 +0100529 case DataType::QS16:
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100530 {
531 ARM_COMPUTE_ERROR_ON(!(std::is_same<int16_t, D>::value));
532 std::uniform_int_distribution<int16_t> distribution_s16(low, high);
533 fill(tensor, distribution_s16, seed_offset);
534 break;
535 }
536 case DataType::U32:
537 {
538 ARM_COMPUTE_ERROR_ON(!(std::is_same<uint32_t, D>::value));
539 std::uniform_int_distribution<uint32_t> distribution_u32(low, high);
540 fill(tensor, distribution_u32, seed_offset);
541 break;
542 }
543 case DataType::S32:
544 {
545 ARM_COMPUTE_ERROR_ON(!(std::is_same<int32_t, D>::value));
546 std::uniform_int_distribution<int32_t> distribution_s32(low, high);
547 fill(tensor, distribution_s32, seed_offset);
548 break;
549 }
550 case DataType::U64:
551 {
552 ARM_COMPUTE_ERROR_ON(!(std::is_same<uint64_t, D>::value));
553 std::uniform_int_distribution<uint64_t> distribution_u64(low, high);
554 fill(tensor, distribution_u64, seed_offset);
555 break;
556 }
557 case DataType::S64:
558 {
559 ARM_COMPUTE_ERROR_ON(!(std::is_same<int64_t, D>::value));
560 std::uniform_int_distribution<int64_t> distribution_s64(low, high);
561 fill(tensor, distribution_s64, seed_offset);
562 break;
563 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100564 case DataType::F16:
565 {
Moritz Pflanzere49e2662017-07-21 15:55:28 +0100566 std::uniform_real_distribution<float> distribution_f16(low, high);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100567 fill(tensor, distribution_f16, seed_offset);
568 break;
569 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100570 case DataType::F32:
571 {
572 ARM_COMPUTE_ERROR_ON(!(std::is_same<float, D>::value));
573 std::uniform_real_distribution<float> distribution_f32(low, high);
574 fill(tensor, distribution_f32, seed_offset);
575 break;
576 }
577 case DataType::F64:
578 {
579 ARM_COMPUTE_ERROR_ON(!(std::is_same<double, D>::value));
580 std::uniform_real_distribution<double> distribution_f64(low, high);
581 fill(tensor, distribution_f64, seed_offset);
582 break;
583 }
584 case DataType::SIZET:
585 {
586 ARM_COMPUTE_ERROR_ON(!(std::is_same<size_t, D>::value));
587 std::uniform_int_distribution<size_t> distribution_sizet(low, high);
588 fill(tensor, distribution_sizet, seed_offset);
589 break;
590 }
591 default:
592 ARM_COMPUTE_ERROR("NOT SUPPORTED!");
593 }
594}
595
596template <typename T>
Moritz Pflanzerfb5aabb2017-07-18 14:39:55 +0100597void AssetsLibrary::fill_layer_data(T &&tensor, std::string name) const
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100598{
599#ifdef _WIN32
600 const std::string path_separator("\\");
Anthony Barbierac69aa12017-07-03 17:39:37 +0100601#else /* _WIN32 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100602 const std::string path_separator("/");
Anthony Barbierac69aa12017-07-03 17:39:37 +0100603#endif /* _WIN32 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100604
605 const std::string path = _library_path + path_separator + name;
606
607 // Open file
608 std::ifstream file(path, std::ios::in | std::ios::binary);
609 if(!file.good())
610 {
611 throw std::runtime_error("Could not load binary data: " + path);
612 }
613
614 Window window;
615 for(unsigned int d = 0; d < tensor.shape().num_dimensions(); ++d)
616 {
617 window.set(d, Window::Dimension(0, tensor.shape()[d], 1));
618 }
619
620 //FIXME : Replace with normal loop
621 execute_window_loop(window, [&](const Coordinates & id)
622 {
623 float val;
624 file.read(reinterpret_cast<char *>(&val), sizeof(float));
625 void *const out_ptr = tensor(id);
626 store_value_with_data_type(out_ptr, val, tensor.data_type());
627 });
628}
629} // namespace test
630} // namespace arm_compute
Anthony Barbierac69aa12017-07-03 17:39:37 +0100631#endif /* __ARM_COMPUTE_TEST_TENSOR_LIBRARY_H__ */