gem5  [DEVELOP-FOR-23.0]
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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"
119 #include "sim/serialize_handlers.hh"
120 
121 namespace gem5
122 {
123 
124 constexpr unsigned MaxMatRegRowLenInBytes = 256;
125 constexpr unsigned MaxMatRegRows = 256;
126 
127 // Forward declarations
128 template <size_t X, size_t Y>
129 class MatStore;
130 template <typename ElemType, typename Container>
131 class Tile;
132 
133 template <size_t X, size_t Y>
134 struct ParseParam<MatStore<X, Y>>;
135 
150 template <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;
162  size_t strideElts;
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 
223 template <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;
235  size_t strideElts;
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 
294 template <typename ElemType, typename Container>
295 class 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;
305  size_t startBytes;
306  size_t strideBytes;
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);
336  startBytes,
337  strideBytes,
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.
379 template <size_t X, size_t Y>
380 class MatStore
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:
403  MatStore() {};
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 
509 template <size_t X, size_t 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 
530 template <size_t X, size_t 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 };
553 template <>
555 {
556  static bool
557  parse(const std::string &s, DummyMatRegContainer &value)
558  {
559  return false;
560  }
561 };
562 static_assert(sizeof(DummyMatRegContainer) == sizeof(RegVal));
563 static inline std::ostream &
564 operator<<(std::ostream &os, const DummyMatRegContainer &d)
565 {
566  return os;
567 }
570 } // namespace gem5
571 
572 #endif // __ARCH_ARM_MATRIX_HH__
gem5::Tile
Provides a view of a matrix that is row-interleaved onto a MatStore.
Definition: matrix.hh:131
gem5::VegaISA::s
Bitfield< 1 > s
Definition: pagetable.hh:64
gem5::HorizontalSlice::index
size_t index
Definition: matrix.hh:158
gem5::Tile::operator[]
auto operator[](size_t idx)
Definition: matrix.hh:319
gem5::MatStore::LINEAR_SIZE
static constexpr size_t LINEAR_SIZE
Definition: matrix.hh:385
gem5::RegVal
uint64_t RegVal
Definition: types.hh:173
gem5::Tile::getContainer
Container * getContainer()
Definition: matrix.hh:326
gem5::MatStore::asHSlice
auto asHSlice(size_t row_idx)
Definition: matrix.hh:468
gem5::ShowParam< MatStore< X, Y > >::show
static void show(std::ostream &os, const MatStore< X, Y > &value)
Definition: matrix.hh:534
gem5::MatStore
Backing store for matrices.
Definition: matrix.hh:129
gem5::DummyMatRegContainer
Dummy type aliases and constants for architectures that do not implement matrix registers.
Definition: matrix.hh:547
gem5::MipsISA::index
Bitfield< 30, 0 > index
Definition: pra_constants.hh:47
gem5::Tile::startBytes
size_t startBytes
Definition: matrix.hh:305
gem5::MatStore::asTile
auto asTile(size_t index)
Definition: matrix.hh:461
gem5::ParseParam< DummyMatRegContainer >::parse
static bool parse(const std::string &s, DummyMatRegContainer &value)
Definition: matrix.hh:557
gem5::VerticalSlice::VerticalSlice
VerticalSlice(Container &cnt, size_t _startBytes, size_t _strideBytes, size_t idx)
Definition: matrix.hh:238
gem5::operator<<
static std::ostream & operator<<(std::ostream &os, const DummyMatRegContainer &d)
Definition: matrix.hh:564
gem5::ArmISA::int_reg::X2
constexpr RegId X2
Definition: int.hh:242
gem5::MatStore::zero
void zero()
Definition: matrix.hh:408
gem5::HorizontalSlice::operator[]
ElemType & operator[](size_t elem_idx)
Definition: matrix.hh:193
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:67
gem5::HorizontalSlice::container
Container * container
Definition: matrix.hh:157
gem5::ccprintf
void ccprintf(cp::Print &print)
Definition: cprintf.hh:130
gem5::ShowParam
Definition: serialize_handlers.hh:125
gem5::MatStore::MyClass
MatStore< X, Y > MyClass
Definition: matrix.hh:396
gem5::MaxMatRegRowLenInBytes
constexpr unsigned MaxMatRegRowLenInBytes
Definition: matrix.hh:124
gem5::HorizontalSlice::xElems
size_t xElems
Definition: matrix.hh:159
gem5::Tile::index
size_t index
Definition: matrix.hh:304
gem5::VerticalSlice::index
size_t index
Definition: matrix.hh:231
gem5::DummyMatRegContainer::operator==
bool operator==(const DummyMatRegContainer &d) const
Definition: matrix.hh:550
gem5::MatStore::rawPtr
const ElemType * rawPtr() const
Get pointer to the raw data.
Definition: matrix.hh:450
gem5::MatStore::MatStore
MatStore()
Constructor.
Definition: matrix.hh:403
gem5::ArmISA::b
Bitfield< 7 > b
Definition: misc_types.hh:438
gem5::VerticalSlice::startElts
size_t startElts
Definition: matrix.hh:234
gem5::VerticalSlice::container
Container * container
Definition: matrix.hh:230
gem5::MatStore::asVSlice
auto asVSlice(size_t col_idx)
Definition: matrix.hh:475
gem5::HorizontalSlice::startElts
size_t startElts
Definition: matrix.hh:161
gem5::X86ISA::count
count
Definition: misc.hh:710
gem5::ArmISA::d
Bitfield< 9 > d
Definition: misc_types.hh:64
gem5::VerticalSlice::strideElts
size_t strideElts
Definition: matrix.hh:235
gem5::ParseParam< MatStore< X, Y > >::parse
static bool parse(const std::string &str, MatStore< X, Y > &value)
Definition: matrix.hh:513
gem5::MatStore::linearSize
static constexpr size_t linearSize()
Definition: matrix.hh:393
gem5::MatStore::ySize
static constexpr size_t ySize()
Definition: matrix.hh:392
gem5::HorizontalSlice
Provides a view of a horizontal slice of either a MatStore or a Tile.
Definition: matrix.hh:151
cprintf.hh
gem5::MatStore::xSize
static constexpr size_t xSize()
Definition: matrix.hh:391
gem5::Tile::asHSlice
auto asHSlice(size_t row_idx)
Definition: matrix.hh:332
gem5::VerticalSlice::zero
void zero()
Definition: matrix.hh:273
gem5::MatStore::operator!=
bool operator!=(const MatStore< X2, Y2 > &that) const
Inequality operator.
Definition: matrix.hh:442
gem5::Tile::Tile
Tile(Container &cnt, size_t idx)
Definition: matrix.hh:309
gem5::VerticalSlice::yElems
size_t yElems
Definition: matrix.hh:233
gem5::Tile::asVSlice
auto asVSlice(size_t col_idx)
Definition: matrix.hh:342
gem5::VerticalSlice::xElems
size_t xElems
Definition: matrix.hh:232
gem5::DummyMatRegContainer::filler
RegVal filler
Definition: matrix.hh:549
gem5::MatStore::operator<<
friend std::ostream & operator<<(std::ostream &os, const MatStore< X, Y > &v)
Definition: matrix.hh:481
gem5::DummyMatRegContainer::operator!=
bool operator!=(const DummyMatRegContainer &d) const
Definition: matrix.hh:551
gem5::HorizontalSlice::zero
void zero()
Definition: matrix.hh:201
gem5::VegaISA::v
Bitfield< 0 > v
Definition: pagetable.hh:65
gem5::HorizontalSlice::HorizontalSlice
HorizontalSlice(Container &cnt, size_t _startBytes, size_t _strideBytes, size_t idx)
Definition: matrix.hh:165
gem5::VerticalSlice
Provides a view of a vertical slice of either a MatStore or a Tile.
Definition: matrix.hh:224
gem5::MatStore::operator=
MyClass & operator=(const MyClass &that)
Assignment operators.
Definition: matrix.hh:417
gem5::MatStore::container
Container container
Definition: matrix.hh:399
gem5::Tile::strideBytes
size_t strideBytes
Definition: matrix.hh:306
serialize_handlers.hh
gem5::MatStore::rawPtr
ElemType * rawPtr()
Definition: matrix.hh:456
types.hh
gem5::Tile::zero
void zero()
Definition: matrix.hh:350
gem5::X86ISA::os
Bitfield< 17 > os
Definition: misc.hh:810
logging.hh
gem5::MatStore< size, size >::Container
std::array< uint8_t, LINEAR_SIZE > Container
Definition: matrix.hh:395
gem5::HorizontalSlice::strideElts
size_t strideElts
Definition: matrix.hh:162
gem5::VerticalSlice::operator[]
ElemType & operator[](size_t elem_idx)
Definition: matrix.hh:265
gem5_assert
#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
gem5::SparcISA::int_reg::Y
constexpr RegId Y
Definition: int.hh:131
gem5::ParseParam
Definition: serialize_handlers.hh:78
fatal_if
#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
gem5::HorizontalSlice::yElems
size_t yElems
Definition: matrix.hh:160
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::Tile::container
Container * container
Definition: matrix.hh:303
gem5::Tile::NUM_TILES
static constexpr size_t NUM_TILES
Definition: matrix.hh:300
gem5::MatStore::operator==
bool operator==(const MatStore< X2, Y2 > &that) const
Equality operator.
Definition: matrix.hh:431
gem5::X86ISA::X
Bitfield< 15, 0 > X
Definition: int.hh:58
gem5::MaxMatRegRows
constexpr unsigned MaxMatRegRows
Definition: matrix.hh:125

Generated on Sun Jul 30 2023 01:56:49 for gem5 by doxygen 1.8.17