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