From 1b993389a3ac0cd1b0edc0b11e92fbdee127576f Mon Sep 17 00:00:00 2001 From: Abe Mbise Date: Tue, 19 Dec 2017 13:51:59 +0000 Subject: COMPMID-568: Implement Canny edge function for CL/NEON Change-Id: Ic5f197463f962bac4b23663bcef7ac744be6fc2a Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/114250 Tested-by: Jenkins Reviewed-by: Anthony Barbier --- tests/SimpleTensorPrinter.h | 157 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 tests/SimpleTensorPrinter.h (limited to 'tests/SimpleTensorPrinter.h') diff --git a/tests/SimpleTensorPrinter.h b/tests/SimpleTensorPrinter.h new file mode 100644 index 0000000000..905a1563a9 --- /dev/null +++ b/tests/SimpleTensorPrinter.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2017-2018 ARM Limited. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include "arm_compute/core/Error.h" + +#include "tests/RawTensor.h" +#include "tests/SimpleTensor.h" + +#include +#include + +namespace arm_compute +{ +namespace test +{ +namespace +{ +template +inline std::string prettify_tensor(const SimpleTensor &input, const IOFormatInfo &io_fmt = IOFormatInfo{ IOFormatInfo::PrintRegion::NoPadding }) +{ + ARM_COMPUTE_ERROR_ON(input.data() == nullptr); + + RawTensor tensor(std::move(SimpleTensor(input))); + + TensorInfo info(tensor.shape(), tensor.num_channels(), tensor.data_type()); + + const DataType dt = info.data_type(); + const size_t slices2D = info.tensor_shape().total_size_upper(2); + const Strides strides = info.strides_in_bytes(); + const PaddingSize padding = info.padding(); + const size_t num_channels = info.num_channels(); + + std::ostringstream os; + + // Set precision + if(is_data_type_float(dt) && (io_fmt.precision_type != IOFormatInfo::PrecisionType::Default)) + { + int precision = io_fmt.precision; + if(io_fmt.precision_type == IOFormatInfo::PrecisionType::Full) + { + precision = std::numeric_limits().max_digits10; + } + os.precision(precision); + } + + // Define region to print + size_t print_width = 0; + size_t print_height = 0; + int start_offset = 0; + switch(io_fmt.print_region) + { + case IOFormatInfo::PrintRegion::NoPadding: + print_width = info.dimension(0); + print_height = info.dimension(1); + start_offset = info.offset_first_element_in_bytes(); + break; + case IOFormatInfo::PrintRegion::ValidRegion: + print_width = info.valid_region().shape.x(); + print_height = info.valid_region().shape.y(); + start_offset = info.offset_element_in_bytes(Coordinates(info.valid_region().anchor.x(), + info.valid_region().anchor.y())); + break; + case IOFormatInfo::PrintRegion::Full: + print_width = padding.left + info.dimension(0) + padding.right; + print_height = padding.top + info.dimension(1) + padding.bottom; + start_offset = static_cast(info.offset_first_element_in_bytes()) - padding.top * strides[1] - padding.left * strides[0]; + break; + default: + break; + } + + print_width = print_width * num_channels; + + // Set pointer to start + const uint8_t *ptr = tensor.data() + start_offset; + + // Start printing + for(size_t i = 0; i < slices2D; ++i) + { + // Find max_width of elements in slice to align columns + int max_element_width = 0; + if(io_fmt.align_columns) + { + size_t offset = i * strides[2]; + for(size_t h = 0; h < print_height; ++h) + { + max_element_width = std::max(max_element_width, max_consecutive_elements_display_width(os, dt, ptr + offset, print_width)); + offset += strides[1]; + } + } + + // Print slice + { + size_t offset = i * strides[2]; + for(size_t h = 0; h < print_height; ++h) + { + print_consecutive_elements(os, dt, ptr + offset, print_width, max_element_width, io_fmt.element_delim); + offset += strides[1]; + os << io_fmt.row_delim; + } + os << io_fmt.row_delim; + } + } + + return os.str(); +} + +template +inline std::ostream &operator<<(std::ostream &os, const SimpleTensor &tensor) +{ + os << prettify_tensor(tensor, IOFormatInfo{ IOFormatInfo::PrintRegion::NoPadding }); + return os; +} + +template +inline std::string to_string(const SimpleTensor &tensor) +{ + std::stringstream ss; + ss << tensor; + return ss.str(); +} + +#if PRINT_TENSOR_LIMIT +template +void print_simpletensor(const SimpleTensor &tensor, const std::string &title, const IOFormatInfo::PrintRegion ®ion = IOFormatInfo::PrintRegion::NoPadding) +{ + if(tensor.num_elements() < PRINT_TENSOR_LIMIT) + { + std::cout << title << ":" << std::endl; + std::cout << prettify_tensor(tensor, IOFormatInfo{ region }); + } +} +#endif // PRINT_TENSOR_LIMIT +} +} // namespace test +} // namespace arm_compute -- cgit v1.2.1