gem5 v24.0.0.0
Loading...
Searching...
No Matches
matrix.hh
Go to the documentation of this file.
1/*
2 * Copyright (c) 2022 Arm Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
107#ifndef __ARCH_ARM_MATRIX_HH__
108#define __ARCH_ARM_MATRIX_HH__
109
110#include <array>
111#include <cassert>
112#include <cstring>
113#include <iostream>
114#include <type_traits>
115
116#include "base/cprintf.hh"
117#include "base/logging.hh"
118#include "base/types.hh"
120
121namespace gem5
122{
123
124constexpr unsigned MaxMatRegRowLenInBytes = 256;
125constexpr unsigned MaxMatRegRows = 256;
126
127// Forward declarations
128template <size_t X, size_t Y>
129class MatStore;
130template <typename ElemType, typename Container>
131class Tile;
132
133template <size_t X, size_t Y>
134struct ParseParam<MatStore<X, Y>>;
135
150template <typename ElemType, typename Container, bool FromTile>
152{
153 template <size_t, size_t> friend class MatStore;
154 template <typename, typename> friend class Tile;
155
156 private:
157 Container * container;
158 size_t index;
159 size_t xElems;
160 size_t yElems;
161 size_t startElts;
163
164 private:
165 HorizontalSlice(Container& cnt, size_t _startBytes, size_t _strideBytes,
166 size_t idx)
167 : container(&cnt), index(idx),
168 xElems(container->xSize() / sizeof(ElemType)),
169 yElems(container->ySize() / (FromTile ? sizeof(ElemType): 1)),
170 startElts(_startBytes / sizeof(ElemType)),
171 strideElts(_strideBytes / sizeof(ElemType))
172 {
173 gem5_assert(xElems > 0, "The number of xElems cannot be 0");
174 gem5_assert(yElems > 0, "The number of yElems cannot be 0");
175
176 // Make sure that we have a whole multiple of an element size
177 assert (_startBytes % sizeof(ElemType) == 0);
178 assert (_strideBytes % sizeof(ElemType) == 0);
179
180 if constexpr (!FromTile) {
181 // If we are not operating on a tile, the stride must be the
182 // same as the row length, X.
183 assert(_strideBytes == container->xSize());
184 } else {
185 // If we are operating on a tile, then the stride must be
186 // sizeof(ElemSize) greater than X.
187 assert(_strideBytes / container->xSize() == sizeof(ElemType));
188 }
189 };
190
191 public:
192 ElemType&
193 operator[](size_t elem_idx)
194 {
195 assert(elem_idx < xElems);
196 size_t linear_index = startElts + index * strideElts + elem_idx;
197 return container->template rawPtr<ElemType>()[linear_index];
198 };
199
200 void
202 {
203 for (int i = 0; i < xElems; ++i) {
204 (*this)[i] = (ElemType)0;
205 }
206 };
207};
208
223template <typename ElemType, typename Container, bool FromTile>
225{
226 template <size_t, size_t> friend class MatStore;
227 template <typename, typename> friend class Tile;
228
229 private:
230 Container * container;
231 size_t index;
232 size_t xElems;
233 size_t yElems;
234 size_t startElts;
236
237 private:
238 VerticalSlice(Container& cnt, size_t _startBytes, size_t _strideBytes, size_t idx)
239 : container(&cnt), index(idx),
240 xElems(container->xSize() / sizeof(ElemType)),
241 yElems(container->ySize() / (FromTile ? sizeof(ElemType): 1)),
242 startElts(_startBytes / sizeof(ElemType)),
243 strideElts(_strideBytes / sizeof(ElemType))
244 {
245 gem5_assert(xElems > 0, "The number of xElems cannot be 0");
246 gem5_assert(yElems > 0, "The number of yElems cannot be 0");
247
248 // Make sure that we have a whole multiple of an element size
249 assert (_startBytes % sizeof(ElemType) == 0);
250 assert (_strideBytes % sizeof(ElemType) == 0);
251
252 if constexpr (!FromTile) {
253 // If we are not operating on a tile, the stride must be the
254 // same as the row length, X.
255 assert(_strideBytes == container->xSize());
256 } else {
257 // If we are operating on a tile, then the stride must be
258 // sizeof(ElemSize) greater than X.
259 assert(_strideBytes / container->xSize() == sizeof(ElemType));
260 }
261 };
262
263 public:
264 ElemType&
265 operator[](size_t elem_idx)
266 {
267 assert(elem_idx < yElems);
268 size_t linear_index = startElts + elem_idx * strideElts + index;
269 return container->template rawPtr<ElemType>()[linear_index];
270 };
271
272 void
274 {
275 for (int i = 0; i < yElems; ++i) {
276 (*this)[i] = (ElemType)0;
277 }
278 };
279};
280
294template <typename ElemType, typename Container>
295class Tile
296{
297 template <size_t, size_t> friend class MatStore;
298
299 // We "calculate" the number of possible tiles based on the element size
300 static constexpr size_t NUM_TILES = sizeof(ElemType);
301
302 private:
303 Container * container;
304 size_t index;
307
308 private:
309 Tile(Container& cnt, size_t idx)
310 : container(&cnt), index(idx)
311 {
312 assert(index < NUM_TILES);
313 startBytes = container->xSize() * index;
314 strideBytes = NUM_TILES * container->xSize();
315 };
316
317 public:
318 auto
319 operator[](size_t idx)
320 {
321 assert(idx < (container->ySize() / NUM_TILES));
322 return asHSlice(idx);
323 };
324
325 Container*
327 {
328 return container;
329 };
330
331 auto
332 asHSlice(size_t row_idx)
333 {
334 assert(row_idx < container->ySize() / NUM_TILES);
338 row_idx);
339 };
340
341 auto
342 asVSlice(size_t col_idx)
343 {
344 assert(col_idx < container->xSize());
346 strideBytes, col_idx);
347 };
348
349 void
351 {
352 for (int i = 0; i < container->ySize() / NUM_TILES; ++i) {
353 // We zero the tile by rows. We need to do it this way due
354 // to the interleaving.
355 auto row = this->asHSlice(i);
356 row.zero();
357 }
358 };
359};
360
361// Base container class for a matrix. Allows for non-square matricies.
379template <size_t X, size_t Y>
381{
382 static_assert(X > 0, "X size cannot be 0");
383 static_assert(Y > 0, "Y size cannot be 0");
384
385 static constexpr size_t LINEAR_SIZE = X * Y;
386
387 template <typename, typename, bool> friend class HorizontalSlice;
388 template <typename, typename, bool> friend class VerticalSlice;
389
390 public:
391 static constexpr inline size_t xSize() { return X; };
392 static constexpr inline size_t ySize() { return Y; };
393 static constexpr inline size_t linearSize() { return LINEAR_SIZE; };
394
395 using Container = std::array<uint8_t, LINEAR_SIZE>;
397 private:
398 // We need to be able to handle 128-bit types; align accordingly
399 alignas(16) Container container;
400
401 public:
404
405 MatStore(const MatStore&) = default;
406
407 void
409 {
410 memset(container.data(), 0 , LINEAR_SIZE);
411 }
412
416 MyClass&
417 operator=(const MyClass& that)
418 {
419 if (&that == this)
420 return *this;
421 memcpy(container.data(), that.container.data(), LINEAR_SIZE);
422 return *this;
423 }
429 template<size_t X2, size_t Y2>
430 inline bool
431 operator==(const MatStore<X2, Y2>& that) const
432 {
433 return X == X2 && Y == Y2 &&
434 !memcmp(container.data(), that.container.data(), LINEAR_SIZE);
435 }
436
440 template<size_t X2, size_t Y2>
441 bool
442 operator!=(const MatStore<X2, Y2>& that) const
443 {
444 return !operator==(that);
445 }
446
447 private:
449 template <typename ElemType>
450 const ElemType* rawPtr() const
451 {
452 return reinterpret_cast<const ElemType*>(container.data());
453 }
454
455 template <typename ElemType>
456 ElemType* rawPtr() { return reinterpret_cast<ElemType*>(container.data()); }
457
458 public:
459 template <typename ElemType>
460 auto
461 asTile(size_t index)
462 {
463 return Tile<ElemType, MyClass>(*this, index);
464 }
465
466 template <typename ElemType>
467 auto
468 asHSlice(size_t row_idx)
469 {
470 return HorizontalSlice<ElemType, MyClass, false>(*this, 0, X, row_idx);
471 }
472
473 template <typename ElemType>
474 auto
475 asVSlice(size_t col_idx)
476 {
477 return VerticalSlice<ElemType, MyClass, false>(*this, 0, X, col_idx);
478 }
479
480 friend std::ostream&
481 operator<<(std::ostream& os, const MatStore<X, Y>& v)
482 {
483 // When printing for human consumption, break into 4 byte chunks.
484 ccprintf(os, "[");
485 size_t count = 0;
486 for (auto& b: v.container) {
487 if (count && (count % 4) == 0)
488 os << "_";
489 ccprintf(os, "%02x", b);
490 count++;
491 }
492 ccprintf(os, "]");
493 return os;
494 }
495
502
503};
504
509template <size_t X, size_t Y>
510struct ParseParam<MatStore<X, Y>>
511{
512 static bool
513 parse(const std::string &str, MatStore<X, Y> &value)
514 {
515 fatal_if(str.size() > 2 * X * Y,
516 "Matrix register value overflow at unserialize");
517 fatal_if(str.size() < 2 * X * Y,
518 "Matrix register value underflow at unserialize");
519
520 for (int i = 0; i < X * Y; i++) {
521 uint8_t b = 0;
522 if (2 * i < str.size())
523 b = stoul(str.substr(i * 2, 2), nullptr, 16);
524 value.template rawPtr<uint8_t>()[i] = b;
525 }
526 return true;
527 }
528};
529
530template <size_t X, size_t Y>
531struct ShowParam<MatStore<X, Y>>
532{
533 static void
534 show(std::ostream &os, const MatStore<X, Y> &value)
535 {
536 for (auto& b: value.container)
537 ccprintf(os, "%02x", b);
538 }
539};
548{
550 bool operator == (const DummyMatRegContainer &d) const { return true; }
551 bool operator != (const DummyMatRegContainer &d) const { return true; }
552};
553template <>
555{
556 static bool
557 parse(const std::string &s, DummyMatRegContainer &value)
558 {
559 return false;
560 }
561};
562static_assert(sizeof(DummyMatRegContainer) == sizeof(RegVal));
563static inline std::ostream &
564operator<<(std::ostream &os, const DummyMatRegContainer &d)
565{
566 return os;
567}
570} // namespace gem5
571
572#endif // __ARCH_ARM_MATRIX_HH__
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,...
Provides a view of a horizontal slice of either a MatStore or a Tile.
Definition matrix.hh:152
Container * container
Definition matrix.hh:157
HorizontalSlice(Container &cnt, size_t _startBytes, size_t _strideBytes, size_t idx)
Definition matrix.hh:165
ElemType & operator[](size_t elem_idx)
Definition matrix.hh:193
Backing store for matrices.
Definition matrix.hh:381
bool operator!=(const MatStore< X2, Y2 > &that) const
Inequality operator.
Definition matrix.hh:442
friend std::ostream & operator<<(std::ostream &os, const MatStore< X, Y > &v)
Definition matrix.hh:481
auto asTile(size_t index)
Definition matrix.hh:461
MatStore(const MatStore &)=default
static constexpr size_t LINEAR_SIZE
Definition matrix.hh:385
MatStore()
Constructor.
Definition matrix.hh:403
auto asVSlice(size_t col_idx)
Definition matrix.hh:475
static constexpr size_t linearSize()
Definition matrix.hh:393
MyClass & operator=(const MyClass &that)
Assignment operators.
Definition matrix.hh:417
friend class HorizontalSlice
Definition matrix.hh:387
void zero()
Definition matrix.hh:408
const ElemType * rawPtr() const
Get pointer to the raw data.
Definition matrix.hh:450
auto asHSlice(size_t row_idx)
Definition matrix.hh:468
friend class VerticalSlice
Definition matrix.hh:388
std::array< uint8_t, LINEAR_SIZE > Container
Definition matrix.hh:395
Container container
Definition matrix.hh:399
static constexpr size_t xSize()
Definition matrix.hh:391
MatStore< X, Y > MyClass
Definition matrix.hh:396
ElemType * rawPtr()
Definition matrix.hh:456
bool operator==(const MatStore< X2, Y2 > &that) const
Equality operator.
Definition matrix.hh:431
static constexpr size_t ySize()
Definition matrix.hh:392
Provides a view of a matrix that is row-interleaved onto a MatStore.
Definition matrix.hh:296
auto operator[](size_t idx)
Definition matrix.hh:319
Container * getContainer()
Definition matrix.hh:326
auto asVSlice(size_t col_idx)
Definition matrix.hh:342
size_t startBytes
Definition matrix.hh:305
Tile(Container &cnt, size_t idx)
Definition matrix.hh:309
size_t strideBytes
Definition matrix.hh:306
static constexpr size_t NUM_TILES
Definition matrix.hh:300
void zero()
Definition matrix.hh:350
auto asHSlice(size_t row_idx)
Definition matrix.hh:332
size_t index
Definition matrix.hh:304
Container * container
Definition matrix.hh:303
Provides a view of a vertical slice of either a MatStore or a Tile.
Definition matrix.hh:225
Container * container
Definition matrix.hh:230
VerticalSlice(Container &cnt, size_t _startBytes, size_t _strideBytes, size_t idx)
Definition matrix.hh:238
ElemType & operator[](size_t elem_idx)
Definition matrix.hh:265
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
#define gem5_assert(cond,...)
The assert macro will function like a normal assert, but will use panic instead of straight abort().
Definition logging.hh:317
Bitfield< 28 > v
Definition misc_types.hh:54
Bitfield< 4 > s
Bitfield< 7 > b
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 9 > d
Definition misc_types.hh:64
Bitfield< 30, 0 > index
Bitfield< 15, 0 > X
Definition int.hh:58
Bitfield< 17 > os
Definition misc.hh:838
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
constexpr unsigned MaxMatRegRowLenInBytes
Definition matrix.hh:124
uint64_t RegVal
Definition types.hh:173
constexpr unsigned MaxMatRegRows
Definition matrix.hh:125
static std::ostream & operator<<(std::ostream &os, const DummyMatRegContainer &d)
Definition matrix.hh:564
void ccprintf(cp::Print &print)
Definition cprintf.hh:130
Dummy type aliases and constants for architectures that do not implement matrix registers.
Definition matrix.hh:548
bool operator!=(const DummyMatRegContainer &d) const
Definition matrix.hh:551
bool operator==(const DummyMatRegContainer &d) const
Definition matrix.hh:550
static bool parse(const std::string &s, DummyMatRegContainer &value)
Definition matrix.hh:557
static bool parse(const std::string &str, MatStore< X, Y > &value)
Definition matrix.hh:513
static void show(std::ostream &os, const MatStore< X, Y > &value)
Definition matrix.hh:534

Generated on Tue Jun 18 2024 16:23:56 for gem5 by doxygen 1.11.0