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.h | 355 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 arm_compute/core/Window.h (limited to 'arm_compute/core/Window.h') diff --git a/arm_compute/core/Window.h b/arm_compute/core/Window.h new file mode 100644 index 0000000000..6e7ef22531 --- /dev/null +++ b/arm_compute/core/Window.h @@ -0,0 +1,355 @@ +/* + * 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. + */ +#ifndef __ARM_COMPUTE_WINDOW_H__ +#define __ARM_COMPUTE_WINDOW_H__ + +#include +#include +#include + +#include "arm_compute/core/Coordinates.h" +#include "arm_compute/core/Error.h" +#include "arm_compute/core/ITensorInfo.h" +#include "arm_compute/core/Utils.h" + +namespace arm_compute +{ +/** Describe a multidimensional execution window. */ +class Window +{ +public: + /** Alias for dimension 0 also known as X dimension */ + static constexpr size_t DimX = 0; + /** Alias for dimension 1 also known as Y dimension */ + static constexpr size_t DimY = 1; + /** Alias for dimension 2 also known as Z dimension */ + static constexpr size_t DimZ = 2; + + /** Default constructor: create a window containing a single element. */ + constexpr Window() + : _dims(), _thread_id(0), _num_threads(1) + { + } + /** Copy constructor + * + * @param[in] src Copy the values from src to a new object + */ + Window(const Window &src); + + /** Describe one of the image's dimensions with a start, end and step. + * + * Iteration through the elements of the dimension is done like this: + * for(int v = start(); v < end(); v += step()) + * { + * ... + * } + */ + class Dimension + { + public: + /** Constructor, by default creates a dimension of 1. + * + * @param[in] start Start of the dimension + * @param[in] end End of the dimension + * @param[in] step Step between two elements of the dimension when iterating. + * + */ + constexpr Dimension(int start = 0, int end = 1, int step = 1) + : _start(start), _end(end), _step(step) + { + } + /** Default assignment operator to allow dimensions to be copied */ + Dimension &operator=(const Dimension &d) = default; + /** Return the start of the dimension */ + constexpr int start() const + { + return _start; + } + /** Return the end of the dimension */ + constexpr int end() const + { + return _end; + } + /** Return the step of the dimension */ + constexpr int step() const + { + return _step; + } + /** Set the dimension's step + * + * @param[in] step The new step + */ + void set_step(int step) + { + _step = step; + } + + private: + int _start; /**< Start of the dimension */ + int _end; /**< End of the dimension */ + int _step; + }; + + /** Read only access to a given dimension of the window + * + * @note Precondition: dimension < Coordinates::num_max_dimensions + * + * @param[in] dimension The dimension to access + * + * @return The requested dimension + */ + constexpr const Dimension &operator[](size_t dimension) const; + + /** Alias to access the first dimension of the window + * + * @return First dimension of the window + */ + constexpr const Dimension &x() const + { + return _dims.at(Window::DimX); + } + + /** Alias to access the second dimension of the window + * + * @return Second dimension of the window + */ + constexpr const Dimension &y() const + { + return _dims.at(Window::DimY); + } + + /** Alias to access the third dimension of the window + * + * @return Third dimension of the window + */ + constexpr const Dimension &z() const + { + return _dims.at(Window::DimZ); + } + + /** Set the values of a given dimension + * + * @param[in] dimension The dimension to set + * @param[in] dim The values to set the dimension to + */ + void set(size_t dimension, const Dimension &dim); + + /** Use the tensor's dimensions to fill the window dimensions. + * + * @param[in] info Tensor information to copy the dimensions from. + * @param[in] first_dimension Only copy dimensions which are greater or equal to this value. + */ + void use_tensor_dimensions(const ITensorInfo *info, size_t first_dimension = Window::DimX); + + /** Shift the values of a given dimension by the given shift_value + * + * @param[in] dimension The dimension to shift + * @param[in] shift_value Value to shift the start and end values of. + */ + void shift(size_t dimension, int shift_value); + + /** Adjust the start or end of a given dimension by the given value + * + * @param[in] dimension The dimension to adjust + * @param[in] adjust_value The adjusted value. + * @param[in] is_at_start The flag to indicate whether adjust the start or end of the dimension. + */ + void adjust(size_t dimension, int adjust_value, bool is_at_start); + + /** Scale the values of a given dimension by the given scale_value + * + * @note The end of the window is rounded up to be a multiple of step after the scaling. + * + * @param[in] dimension The dimension to scale + * @param[in] scale_value Value to scale the start, end and step values of. + */ + void scale(size_t dimension, float scale_value); + + /** Set the step of a given dimension. + * + * @param[in] dimension Dimension to update + * @param[in] step The new dimension's step value + */ + void set_dimension_step(size_t dimension, int step); + + /** Will validate all the window's dimensions' values when asserts are enabled + * + * No-op when asserts are disabled + */ + void validate() const; + + /** Return the number of iterations needed to iterate through a given dimension + * + * @param[in] dimension The requested dimension + * + * @return The number of iterations + */ + constexpr size_t num_iterations(size_t dimension) const; + + /** Split a window into a set of sub windows along a given dimension + * + * For example to split a window into 3 sub-windows along the Y axis, you would have to do:
+ * Window sub0 = window.split_window( 1, 0, 3);
+ * Window sub1 = window.split_window( 1, 1, 3);
+ * Window sub2 = window.split_window( 1, 2, 3);
+ * + * @param[in] dimension Dimension along which the split will be performed + * @param[in] id Id of the sub-window to return. Must be in the range (0, total-1) + * @param[in] total Total number of sub-windows the window will be split into. + * + * @return The subwindow "id" out of "total" + */ + Window split_window(size_t dimension, size_t id, size_t total) const; + /** First 1D slice of the window + * + * @return The first slice of the window. + */ + Window first_slice_window_1D() const + { + return first_slice_window<1>(); + }; + /** First 2D slice of the window + * + * @return The first slice of the window. + */ + Window first_slice_window_2D() const + { + return first_slice_window<2>(); + }; + /** First 3D slice of the window + * + * @return The first slice of the window. + */ + Window first_slice_window_3D() const + { + return first_slice_window<3>(); + }; + /** Slide the passed 1D window slice. + * + * If slice contains the last slice then it will remain unchanged and false will be returned. + * + * @param[in,out] slice Current slice, to be updated to the next slice. + * + * @return true if slice contains a new slice, false if slice already contained the last slice + */ + bool slide_window_slice_1D(Window &slice) const + { + return slide_window_slice<1>(slice); + } + /** Slide the passed 2D window slice. + * + * If slice contains the last slice then it will remain unchanged and false will be returned. + * + * @param[in,out] slice Current slice, to be updated to the next slice. + * + * @return true if slice contains a new slice, false if slice already contained the last slice + */ + bool slide_window_slice_2D(Window &slice) const + { + return slide_window_slice<2>(slice); + } + /** Slide the passed 3D window slice. + * + * If slice contains the last slice then it will remain unchanged and false will be returned. + * + * @param[in,out] slice Current slice, to be updated to the next slice. + * + * @return true if slice contains a new slice, false if slice already contained the last slice + */ + bool slide_window_slice_3D(Window &slice) const + { + return slide_window_slice<3>(slice); + } + /** Slide the passed 4D window slice. + * + * If slice contains the last slice then it will remain unchanged and false will be returned. + * + * @param[in,out] slice Current slice, to be updated to the next slice. + * + * @return true if slice contains a new slice, false if slice already contained the last slice + */ + bool slide_window_slice_4D(Window &slice) const + { + return slide_window_slice<4>(slice); + } + /** Sets the ID of the thread that the window is associated with. + * + * @param id ID of the thread that the window is associated with. + */ + void set_thread_id(unsigned int id) + { + _thread_id = id; + } + /** Sets the number of threads dispatched that the window is associated with. + * + * @param num_threads The number of threads dispatched that the window is associated with. + */ + void set_num_threads(unsigned int num_threads) + { + _num_threads = num_threads; + } + /** Get the ID of the thread that the window is associated with. + * + * @return ID of the thread that the window is associated with. + */ + constexpr unsigned int thread_id() const + { + return _thread_id; + } + /** Get the number of threads dispatched that the window is associated with. + * + * @return The number of threads dispatched that the window is associated with. + */ + constexpr unsigned int num_threads() const + { + return _num_threads; + } + +private: + /** First slice of the window + * + * @return The first slice of the window. + */ + template + Window first_slice_window() const; + + /** Slide the passed window slice. + * + * If slice contains the last slice then it will remain unchanged and false will be returned. + * + * @param[in,out] slice Current slice, to be updated to the next slice. + * + * @return true if slice contains a new slice, false if slice already contained the last slice + */ + template + bool slide_window_slice(Window &slice) const; + +private: + std::array _dims; + unsigned int _thread_id; + unsigned int _num_threads; +}; +} +#include "Window.inl" +#endif /*__ARM_COMPUTE_WINDOW_H__ */ -- cgit v1.2.1