From 6ff3b19ee6120edf015fad8caab2991faa3070af Mon Sep 17 00:00:00 2001 From: Anthony Barbier Date: Mon, 4 Sep 2017 18:44:23 +0100 Subject: COMPMID-344 Updated doxygen Change-Id: I32f7b84daa560e460b77216add529c8fa8b327ae --- arm_compute/core/Window.inl | 182 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 arm_compute/core/Window.inl (limited to 'arm_compute/core/Window.inl') diff --git a/arm_compute/core/Window.inl b/arm_compute/core/Window.inl new file mode 100644 index 0000000000..75428a145b --- /dev/null +++ b/arm_compute/core/Window.inl @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2016, 2017 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. + */ +namespace arm_compute +{ +inline Window::Window(const Window &src) + : _dims(), _thread_id(src._thread_id), _num_threads(src._num_threads) +{ + for(size_t i = 0; i < Coordinates::num_max_dimensions; ++i) + { + set(i, src[i]); + } +} + +inline constexpr const Window::Dimension &Window::operator[](const size_t dimension) const +{ + // Precondition: dimension < Coordinates::num_max_dimensions + return _dims.at(dimension); +} +inline void Window::set(const size_t dimension, const Window::Dimension &dim) +{ + ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions); + _dims[dimension] = dim; +} + +inline void Window::shift(const size_t dimension, const int shift_value) +{ + ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions); + Window::Dimension &d = _dims[dimension]; + d = Window::Dimension(d.start() + shift_value, d.end() + shift_value, d.step()); +} + +inline void Window::adjust(size_t dimension, int adjust_value, bool is_at_start) +{ + ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions); + Window::Dimension &d = _dims[dimension]; + + if(is_at_start) + { + d = Window::Dimension(d.start() + adjust_value, d.end(), d.step()); + } + else + { + d = Window::Dimension(d.start(), d.end() + adjust_value, d.step()); + } +} + +inline void Window::scale(const size_t dimension, float scale_value) +{ + ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions); + Window::Dimension &d = _dims[dimension]; + const int scaled_step = d.step() * scale_value; + const int scaled_end = ceil_to_multiple(d.end() * scale_value, scaled_step); + d = Window::Dimension(d.start() * scale_value, scaled_end, scaled_step); +} + +inline void Window::set_dimension_step(const size_t dimension, const int step) +{ + ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions); + _dims[dimension].set_step(step); +} + +inline void Window::validate() const +{ + for(size_t i = 0; i < Coordinates::num_max_dimensions; ++i) + { + ARM_COMPUTE_ERROR_ON(_dims[i].step() == 0); + ARM_COMPUTE_ERROR_ON(_dims[i].end() <= _dims[i].start()); + ARM_COMPUTE_ERROR_ON((_dims[i].end() - _dims[i].start()) % _dims[i].step()); + } +} + +inline constexpr size_t Window::num_iterations(size_t dimension) const +{ + // Precondition: dimension < Coordinates::num_max_dimensions + // Precondition: (end - start) % step == 0 + return (_dims.at(dimension).end() - _dims.at(dimension).start()) / _dims.at(dimension).step(); +} + +inline Window Window::split_window(const size_t dimension, const size_t id, const size_t total) const +{ + ARM_COMPUTE_ERROR_ON(id >= total); + ARM_COMPUTE_ERROR_ON(dimension >= Coordinates::num_max_dimensions); + + Window out; + + for(size_t d = 0; d < Coordinates::num_max_dimensions; ++d) + { + if(d == dimension) + { + int start = _dims[d].start(); + int end = _dims[d].end(); + int per_sub_window = (num_iterations(d) / total) * _dims[d].step(); + + start += id * per_sub_window; + + if(id != total - 1) + { + end = start + per_sub_window; + } + + out.set(d, Dimension(start, end, _dims[d].step())); + } + else + { + out.set(d, _dims[d]); + } + } + + return out; +} + +template +inline bool Window::slide_window_slice(Window &slice) const +{ + for(unsigned int n = window_dimension; n < Coordinates::num_max_dimensions; ++n) + { + // Did we reach the end of this dimension? + const int v = slice._dims[n].start() + 1; + + if(v < _dims[n].end()) + { + // No: increment + slice._dims[n] = Dimension(v, v + 1, 1); + + // Reset lower dimensions: + for(unsigned int lower = window_dimension; lower < n; ++lower) + { + slice._dims[lower] = Dimension(_dims[lower].start(), _dims[lower].start() + 1, 1); + } + return true; + } + } + + // It was the last slice + return false; // Iteration over +} + +template +inline Window Window::first_slice_window() const +{ + Window slice; + + std::copy_n(_dims.begin(), window_dimension, slice._dims.begin()); + + //Initialise higher dimensions to be the first slice. + for(unsigned int n = window_dimension; n < Coordinates::num_max_dimensions; ++n) + { + slice._dims[n] = Dimension(_dims[n].start(), _dims[n].start() + 1, 1); + } + + return slice; +} + +inline void Window::use_tensor_dimensions(const ITensorInfo *info, const size_t first_dimension) +{ + for(unsigned int n = first_dimension; n < info->num_dimensions(); ++n) + { + set(n, Window::Dimension(0, std::max(info->dimension(n), static_cast(1)))); + } +} +} -- cgit v1.2.1