HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tensor_shape.h
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // Licensed under the MIT License.
3 
4 #pragma once
5 #include <iosfwd>
6 #include <vector>
7 #include <algorithm>
8 #include <string>
9 #include <cstring>
10 #include "core/common/gsl.h"
11 #include "onnxruntime_config.h"
12 
13 #ifndef DISABLE_ABSEIL
14 // Need to include abseil inlined_vector.h header directly here
15 // as hash tables cause CUDA 10.2 compilers to fail. inlined_vector.h is fine.
16 #ifdef _MSC_VER
17 #pragma warning(push)
18 // C4127: conditional expression is constant
19 #pragma warning(disable : 4127)
20 // C4324: structure was padded due to alignment specifier
21 // Usage of alignas causes some internal padding in places.
22 #pragma warning(disable : 4324)
23 #endif
24 
25 #include <absl/container/inlined_vector.h>
26 
27 #ifdef _MSC_VER
28 #pragma warning(pop)
29 #endif
30 #endif // DISABLE_ABSEIL
31 
32 #include "core/common/span_utils.h"
33 
34 namespace onnxruntime {
35 #ifdef __GNUC__
36 #pragma GCC diagnostic push
37 #ifdef HAS_NULL_DEREFERENCE
38 #pragma GCC diagnostic ignored "-Wnull-dereference"
39 #endif
40 #endif
41 
43 
44 #ifndef DISABLE_ABSEIL
45 // Use this type to build a shape and then create TensorShape.
46 using TensorShapeVector = absl::InlinedVector<int64_t, kTensorShapeSmallBufferElementsSize>;
47 #else
48 class TensorShapeVector : public std::vector<int64_t> {
49  using Base = std::vector<int64_t>;
50 
51  public:
52  using Base::Base;
53 };
54 
55 #endif // DISABLE_ABSEIL
56 
57 inline TensorShapeVector ToShapeVector(const gsl::span<const int64_t>& span) {
59  out.reserve(span.size());
60  out.assign(span.begin(), span.end());
61  return out;
62 }
63 
64 inline gsl::span<const int64_t> ToConstSpan(const TensorShapeVector& vec) {
65  return gsl::make_span(vec);
66 }
67 
68 class TensorShape {
69  // We use negative numbers for unknown symbolic dimension. Each negative
70  // number represents a unique symbolic dimension.
71  public:
72  TensorShape() = default;
73 
74  TensorShape(const TensorShape& other) : TensorShape(other.GetDims()) {}
75  TensorShape& operator=(const TensorShape& other);
76  TensorShape& operator=(const gsl::span<const int64_t>& dims) {
77  *this = TensorShape(dims);
78  return *this;
79  }
80 
81  TensorShape(TensorShape&& other) noexcept { operator=(std::move(other)); }
82  TensorShape& operator=(TensorShape&& other) noexcept;
83 
84  TensorShape(gsl::span<const int64_t> dims);
86  TensorShape(std::initializer_list<int64_t> dims) : TensorShape(gsl::make_span(dims.begin(), dims.end())) {}
87  TensorShape(const int64_t* dimension_sizes, size_t dimension_count) : TensorShape(gsl::span<const int64_t>(dimension_sizes, dimension_count)) {}
88  TensorShape(const std::vector<int64_t>& dims, size_t start, size_t end) : TensorShape(gsl::span<const int64_t>(&dims[start], end - start)) {}
89 
90  // Create a TensorShape that points to an existing buffer internally. As no copy is made, 'data' must remain valid for the life of the TensorShape
91  static const TensorShape FromExistingBuffer(const std::vector<int64_t>& data) {
92  return TensorShape(External{}, gsl::span<int64_t>(const_cast<int64_t*>(data.data()), data.size()));
93  }
94 
95  /**
96  Return the dimension specified by <idx>.
97  */
98  int64_t operator[](size_t idx) const { return values_[idx]; }
99  int64_t& operator[](size_t idx) { return values_[idx]; }
100 
101  bool operator==(const TensorShape& other) const noexcept { return SpanEq(GetDims(), other.GetDims()); }
102  bool operator!=(const TensorShape& other) const noexcept { return !(*this == other); }
103 
104  size_t NumDimensions() const noexcept {
105  return values_.size();
106  }
107 
108  /**
109  Copy dims into an array with given size
110  */
111  void CopyDims(int64_t* dims, size_t num_dims) const {
112  memcpy(dims, values_.data(), sizeof(int64_t) * std::min(num_dims, NumDimensions()));
113  }
114 
115  /**
116  Copy dims from a specific start dim into an array with given size
117  `start_dim` is expected to be in the inclusive range [0, NumDimensions() - 1]
118  and this function does no checks to ensure that
119  */
120  void CopyDims(int64_t* dims, size_t start_dim, size_t num_dims) const {
121  memcpy(dims, values_.data() + start_dim, sizeof(int64_t) * std::min(num_dims, NumDimensions() - start_dim));
122  }
123 
124  /**
125  Return underlying vector representation.
126  */
127  gsl::span<const int64_t> GetDims() const { return values_; }
128 
130  return ToShapeVector(values_);
131  }
132 
133  /**
134  * Return the total number of elements. Returns 1 for an empty (rank 0) TensorShape.
135  *
136  * May return -1
137  */
138  int64_t Size() const;
139 
140  /**
141  Return the total number of elements up to the specified dimension.
142  If the dimension interval is empty (dimension == 0), return 1.
143  @param dimension Return size up to this dimension. Value must be between 0 and this->NumDimensions(), inclusive.
144  */
145  int64_t SizeToDimension(size_t dimension) const;
146 
147  /**
148  Return the total number of elements from the specified dimension to the end of the tensor shape.
149  If the dimension interval is empty (dimension == this->NumDimensions()), return 1.
150  @param dimension Return size from this dimension to the end. Value must be between 0 and this->NumDimensions(),
151  inclusive.
152  */
153  int64_t SizeFromDimension(size_t dimension) const;
154 
155  /**
156  Return a new TensorShape of the dimensions from dimstart to dimend.
157  */
158  TensorShape Slice(size_t dimstart, size_t dimend) const;
159 
160  /**
161  Return a new TensorShape of the dimensions from dimstart to end.
162  */
163  TensorShape Slice(size_t dimstart) const { return Slice(dimstart, values_.size()); }
164 
165  /**
166  output dimensions nicely formatted
167  */
168  std::string ToString() const;
169 
170  /**
171  Calculate size between start and end.
172  Assumes start and end are between 0 and this->NumDimensions(), inclusive, and that
173  start < end.
174  */
175  int64_t SizeHelper(size_t start, size_t end) const;
176 
177  /**
178  empty shape or 1D shape (1) is regarded as scalar tensor
179  */
180  bool IsScalar() const {
181  size_t len = values_.size();
182  return len == 0 || (len == 1 && values_[0] == 1);
183  }
184 
185  private:
186  struct External {};
187  TensorShape(External, gsl::span<int64_t> buffer) : values_{buffer} {}
188 
189  void Allocate(size_t size);
190 
191  gsl::span<int64_t> values_;
192  int64_t small_buffer_[kTensorShapeSmallBufferElementsSize]{0};
193  std::unique_ptr<int64_t[]> allocated_buffer_;
194 
195  friend struct ProviderHostImpl; // So that the shared provider interface can access Allocate
196 };
197 #ifdef __GNUC__
198 #pragma GCC diagnostic pop
199 #endif
200 // operator<< to nicely output to a stream
201 std::ostream& operator<<(std::ostream& out, const TensorShape& shape);
202 
203 } // namespace onnxruntime
constexpr size_t kTensorShapeSmallBufferElementsSize
Definition: tensor_shape.h:42
static const TensorShape FromExistingBuffer(const std::vector< int64_t > &data)
Definition: tensor_shape.h:91
int64_t & operator[](size_t idx)
Definition: tensor_shape.h:99
int64_t Size() const
constexpr span< ElementType, Extent > make_span(span< ElementType, Extent > s) noexcept
Definition: UT_Span.h:559
int64_t SizeHelper(size_t start, size_t end) const
GLuint start
Definition: glcorearb.h:475
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
Definition: span.h:73
TensorShape Slice(size_t dimstart, size_t dimend) const
friend struct ProviderHostImpl
Definition: tensor_shape.h:195
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
gsl::span< const int64_t > ToConstSpan(const TensorShapeVector &vec)
Definition: tensor_shape.h:64
TensorShape(const int64_t *dimension_sizes, size_t dimension_count)
Definition: tensor_shape.h:87
bool operator!=(const TensorShape &other) const noexcept
Definition: tensor_shape.h:102
int64_t SizeFromDimension(size_t dimension) const
int64_t operator[](size_t idx) const
Definition: tensor_shape.h:98
size_t NumDimensions() const noexcept
Definition: tensor_shape.h:104
std::string ToString() const
Definition: core.h:760
TensorShape(TensorShape &&other) noexcept
Definition: tensor_shape.h:81
TensorShape & operator=(const TensorShape &other)
TensorShape & operator=(const gsl::span< const int64_t > &dims)
Definition: tensor_shape.h:76
GLuint GLuint end
Definition: glcorearb.h:475
TensorShapeVector AsShapeVector() const
Definition: tensor_shape.h:129
absl::InlinedVector< int64_t, kTensorShapeSmallBufferElementsSize > TensorShapeVector
Definition: tensor_shape.h:46
int64_t SizeToDimension(size_t dimension) const
TensorShape(const TensorShape &other)
Definition: tensor_shape.h:74
bool operator==(const TensorShape &other) const noexcept
Definition: tensor_shape.h:101
void CopyDims(int64_t *dims, size_t num_dims) const
Definition: tensor_shape.h:111
TensorShape Slice(size_t dimstart) const
Definition: tensor_shape.h:163
GLsizeiptr size
Definition: glcorearb.h:664
TensorShapeVector ToShapeVector(const gsl::span< const int64_t > &span)
Definition: tensor_shape.h:57
gsl::span< const int64_t > GetDims() const
Definition: tensor_shape.h:127
bool SpanEq(gsl::span< T1, Extent1 > a, gsl::span< T2, Extent2 > b)
Definition: span_utils.h:82
TensorShape(std::initializer_list< int64_t > dims)
Definition: tensor_shape.h:86
#define const
Definition: zconf.h:214
std::ostream & operator<<(std::ostream &out, AllocKind alloc_kind)
TensorShape(const std::vector< int64_t > &dims, size_t start, size_t end)
Definition: tensor_shape.h:88
void CopyDims(int64_t *dims, size_t start_dim, size_t num_dims) const
Definition: tensor_shape.h:120
Definition: format.h:895
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.
Definition: node.h:483