blob: baccdc0d88bac21ae8572203327f80030f3626bf [file] [log] [blame]
Georgios Pinitas1d480652019-01-23 11:24:50 +00001/*
Sang-Hoon Park4f7693d2021-05-12 13:59:10 +01002 * Copyright (c) 2019-2021 Arm Limited.
Georgios Pinitas1d480652019-01-23 11:24:50 +00003 *
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#pragma once
25
26#include <algorithm>
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010027#include <array>
28#include <cassert>
Georgios Pinitas1d480652019-01-23 11:24:50 +000029#include <initializer_list>
30
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010031namespace arm_gemm
32{
33template <unsigned int D>
34class NDRange
35{
Georgios Pinitas1d480652019-01-23 11:24:50 +000036private:
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010037 std::array<unsigned int, D> m_sizes{};
38 std::array<unsigned int, D> m_totalsizes{};
Georgios Pinitas1d480652019-01-23 11:24:50 +000039
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010040 class NDRangeIterator
41 {
Georgios Pinitas1d480652019-01-23 11:24:50 +000042 private:
43 const NDRange &m_parent;
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010044 unsigned int m_pos = 0;
45 unsigned int m_end = 0;
Georgios Pinitas1d480652019-01-23 11:24:50 +000046
47 public:
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010048 NDRangeIterator(const NDRange &p, unsigned int s, unsigned int e) : m_parent(p), m_pos(s), m_end(e)
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010049 {
50 }
Georgios Pinitas1d480652019-01-23 11:24:50 +000051
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010052 bool done() const
53 {
Georgios Pinitas1d480652019-01-23 11:24:50 +000054 return (m_pos >= m_end);
55 }
56
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010057 unsigned int dim(unsigned int d) const
58 {
Georgios Pinitas1d480652019-01-23 11:24:50 +000059 unsigned int r = m_pos;
60
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010061 if (d < (D - 1))
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010062 {
Georgios Pinitas1d480652019-01-23 11:24:50 +000063 r %= m_parent.m_totalsizes[d];
64 }
65
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010066 if (d > 0)
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010067 {
68 r /= m_parent.m_totalsizes[d - 1];
Georgios Pinitas1d480652019-01-23 11:24:50 +000069 }
70
71 return r;
72 }
73
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010074 bool next_dim0()
75 {
Georgios Pinitas1d480652019-01-23 11:24:50 +000076 m_pos++;
77
78 return !done();
79 }
80
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010081 bool next_dim1()
82 {
Georgios Pinitas1d480652019-01-23 11:24:50 +000083 m_pos += m_parent.m_sizes[0] - dim(0);
84
85 return !done();
86 }
87
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010088 unsigned int dim0_max() const
89 {
Georgios Pinitas1d480652019-01-23 11:24:50 +000090 unsigned int offset = std::min(m_end - m_pos, m_parent.m_sizes[0] - dim(0));
91
92 return dim(0) + offset;
93 }
94 };
95
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +010096 void set_totalsizes()
97 {
98 unsigned int t = 1;
99
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100100 for (unsigned int i = 0; i < D; i++)
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100101 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100102 if (m_sizes[i] == 0)
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100103 {
104 m_sizes[i] = 1;
105 }
106
107 t *= m_sizes[i];
108
109 m_totalsizes[i] = t;
110 }
111 }
112
Georgios Pinitas1d480652019-01-23 11:24:50 +0000113public:
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100114 NDRange &operator=(const NDRange &rhs) = default;
115 NDRange(const NDRange &rhs) = default;
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000116
Georgios Pinitas1d480652019-01-23 11:24:50 +0000117 template <typename... T>
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100118 NDRange(T... ts) : m_sizes{ts...}
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000119 {
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100120 set_totalsizes();
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000121 }
122
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100123 NDRange(const std::array<unsigned int, D> &n) : m_sizes(n)
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000124 {
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100125 set_totalsizes();
Georgios Pinitas1d480652019-01-23 11:24:50 +0000126 }
127
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100128 NDRangeIterator iterator(unsigned int start, unsigned int end) const
129 {
Georgios Pinitas1d480652019-01-23 11:24:50 +0000130 return NDRangeIterator(*this, start, end);
131 }
132
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100133 unsigned int total_size() const
134 {
Georgios Pinitas1d480652019-01-23 11:24:50 +0000135 return m_totalsizes[D - 1];
136 }
137
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100138 unsigned int get_size(unsigned int v) const
139 {
Georgios Pinitas1d480652019-01-23 11:24:50 +0000140 return m_sizes[v];
141 }
142};
143
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000144/** NDCoordinate builds upon a range, but specifies a starting position
145 * in addition to a size which it inherits from NDRange
146 */
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100147template <unsigned int N>
148class NDCoordinate : public NDRange<N>
149{
150 using int_t = unsigned int;
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000151 using ndrange_t = NDRange<N>;
152
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100153 std::array<int_t, N> m_positions{};
154
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000155public:
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100156 NDCoordinate &operator=(const NDCoordinate &rhs) = default;
157 NDCoordinate(const NDCoordinate &rhs) = default;
158 NDCoordinate(const std::initializer_list<std::pair<int_t, int_t>> &list)
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000159 {
Georgios Pinitas0e240152020-05-11 12:29:03 +0100160 std::array<int_t, N> sizes{};
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000161
162 std::size_t i = 0;
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100163 for (auto &p : list)
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100164 {
165 m_positions[i] = p.first;
166 sizes[i++] = p.second;
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000167 }
168
169 //update the parents sizes
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100170 static_cast<ndrange_t &>(*this) = ndrange_t(sizes);
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000171 }
172
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100173 int_t get_position(int_t d) const
174 {
175 assert(d < N);
176
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000177 return m_positions[d];
178 }
179
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100180 void set_position(int_t d, int_t v)
181 {
182 assert(d < N);
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000183
184 m_positions[d] = v;
185 }
186
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100187 int_t get_position_end(int_t d) const
188 {
189 return get_position(d) + ndrange_t::get_size(d);
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000190 }
191}; //class NDCoordinate
192
Georgios Pinitas5aa1a0b2020-07-02 20:02:20 +0100193using ndrange_t = NDRange<6>;
194using ndcoord_t = NDCoordinate<6>;
Joseph Dobson6f8b17d2020-02-11 19:32:11 +0000195
Georgios Pinitas1d480652019-01-23 11:24:50 +0000196} // namespace arm_gemm