* \brief Describing the tensor shape. * * Uninitialized shape: ndim == 0; total_nr_elems() is also defined to be 0 * * Empty shape: ndim > 0 && shape[i] == 0 for 0 <= i < ndim; it is always * considered non-contiguous. */
| 84 | * considered non-contiguous. |
| 85 | */ |
| 86 | struct TensorShape { |
| 87 | static MEGDNN_CONSTEXPR size_t MAX_NDIM = MEGDNN_MAX_NDIM; |
| 88 | |
| 89 | #if MEGDNN_CC_HOST |
| 90 | size_t shape[MAX_NDIM], ndim = 0; |
| 91 | #else |
| 92 | size_t shape[MAX_NDIM], ndim; |
| 93 | #endif |
| 94 | |
| 95 | #if MEGDNN_CC_HOST |
| 96 | TensorShape() = default; |
| 97 | TensorShape(const TensorShape& rhs) = default; |
| 98 | MGE_WIN_DECLSPEC_FUC TensorShape& operator=(const TensorShape& rhs) = default; |
| 99 | MGE_WIN_DECLSPEC_FUC TensorShape(const SmallVector<size_t>& init_shape); |
| 100 | MGE_WIN_DECLSPEC_FUC TensorShape(std::initializer_list<size_t> init_shape); |
| 101 | MGE_WIN_DECLSPEC_FUC std::string to_string() const; |
| 102 | #endif |
| 103 | |
| 104 | //! total number of elements |
| 105 | MGE_WIN_DECLSPEC_FUC size_t total_nr_elems() const; |
| 106 | |
| 107 | //! check whether two shapes are equal |
| 108 | MGE_WIN_DECLSPEC_FUC bool eq_shape(const TensorShape& rhs) const; |
| 109 | |
| 110 | //! check whether the shape can be treated as a scalar |
| 111 | bool is_scalar() const { return ndim == 1 && shape[0] == 1; } |
| 112 | |
| 113 | //! check whether ndim != 0 and at least one shape is 0 |
| 114 | MGE_WIN_DECLSPEC_FUC bool is_empty() const; |
| 115 | |
| 116 | //! access single element, without boundary check |
| 117 | size_t& operator[](size_t i) { return shape[i]; } |
| 118 | size_t operator[](size_t i) const { return shape[i]; } |
| 119 | }; |
| 120 | |
| 121 | class Handle; |
| 122 | /** |