mxnet
tuple.h
Go to the documentation of this file.
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
24 #ifndef MXNET_TUPLE_H_
25 #define MXNET_TUPLE_H_
26 
27 #include <vector>
28 #include <type_traits>
29 #include <algorithm>
30 #include <utility>
31 #include <iostream>
32 #include <string>
33 #include "nnvm/op_attr_types.h"
34 #include "nnvm/graph_attr_types.h"
35 #include "nnvm/graph.h"
36 #include "nnvm/pass.h"
37 #include "runtime/object.h"
38 #include "runtime/ffi_helper.h"
39 #include "node/container.h"
40 #include "ir/expr.h"
41 
42 namespace mxnet {
43 
57 template<typename ValueType>
58 class Tuple {
59  public:
61  Tuple() = default;
63  inline ~Tuple() {
64  delete [] data_heap_;
65  }
71  inline Tuple(const int ndim, const dim_t value) { // NOLINT(*)
72  this->SetDim(ndim);
73  if (ndim > 0) {
74  std::fill_n(begin(), ndim, value);
75  }
76  }
81  inline Tuple(const Tuple<ValueType>& s) {
82  if (s.ndim() == -1) {
83  this->SetDim(-1);
84  } else {
85  this->assign(s.begin(), s.end());
86  }
87  }
92  inline Tuple(std::initializer_list<ValueType> init) {
93  this->assign(init.begin(), init.end());
94  }
99  inline Tuple(std::vector<ValueType> init) { // NOLINT(runtime/explicit)
100  this->assign(init.begin(), init.end());
101  }
107  inline Tuple(Tuple<ValueType>&& src) { // NOLINT(runtime/explicit)
108  this->swap(src);
109  }
116  template<typename RandomAccessIterator>
117  inline Tuple(RandomAccessIterator begin,
118  RandomAccessIterator end) {
119  this->assign(begin, end);
120  }
121 
122  inline explicit Tuple(const runtime::ObjectRef& src) {
123  using namespace runtime;
124  ADT adt = Downcast<ADT, ObjectRef>(src);
125  this->SetDim(adt.size());
126  for (int i = 0; i < ndim_; ++i) {
127  this->begin()[i] = Downcast<Integer, ObjectRef>(adt[i])->value;
128  }
129  }
130 
137  template<typename RandomAccessIterator>
138  inline void assign(RandomAccessIterator begin,
139  RandomAccessIterator end) {
140  this->SetDim(end - begin);
141  CHECK_GE(ndim(), 0);
142  std::copy(begin, end, this->begin());
143  }
148  inline void swap(Tuple<ValueType>& other) { // NOLINT(*)
149  std::swap(ndim_, other.ndim_);
150  std::swap(num_heap_allocated_, other.num_heap_allocated_);
151  std::swap(data_stack_, other.data_stack_);
152  std::swap(data_heap_, other.data_heap_);
153  }
160  if (src.ndim() == -1) {
161  this->SetDim(-1);
162  } else {
163  this->assign(src.begin(), src.end());
164  }
165  return *this;
166  }
173  Tuple<ValueType>(std::move(src)).swap(*this);
174  return *this;
175  }
181  inline Tuple<ValueType> &operator=(std::initializer_list<ValueType> init) {
182  this->assign(init.begin(), init.end());
183  return *this;
184  }
189  inline bool operator==(const Tuple<ValueType> &s) const {
190  if (ndim_ != s.ndim_) return false;
191  if (ndim() == -1) return true;
192  return std::equal(begin(), end(), s.begin());
193  }
198  inline bool operator!=(const Tuple<ValueType> &s) const {
199  return !(*this == s);
200  }
202  inline const ValueType *begin() const {
203  return ndim_ <= kStackCache ? data_stack_ : data_heap_;
204  }
206  inline ValueType *begin() {
207  return ndim_ <= kStackCache ? data_stack_ : data_heap_;
208  }
210  inline const ValueType* end() const {
211  return ndim_ <= kStackCache ? (data_stack_ + ndim_): (data_heap_ + ndim_);
212  }
214  inline ValueType* end() {
215  return ndim_ <= kStackCache ? (data_stack_ + ndim_): (data_heap_ + ndim_);
216  }
218  inline int ndim() const {
219  return ndim_;
220  }
226  inline ValueType& operator[](int i) {
227  // it fixes the false alarm of assuming signed overflow does not occur
228  // when assuming that (X - c) > X is always false [-Werror=strict-overflow]
229  #pragma GCC diagnostic push
230  #pragma GCC diagnostic ignored "-Wstrict-overflow"
231  CHECK(i >= 0 && i < ndim()) << "index = " << i << " must be in range [0, " << ndim() << ")";
232  #pragma GCC diagnostic pop
233  return begin()[i];
234  }
240  inline const ValueType& operator[](int i) const {
241  // it fixes the false alarm of assuming signed overflow does not occur
242  // when assuming that (X - c) > X is always false [-Werror=strict-overflow]
243  #pragma GCC diagnostic push
244  #pragma GCC diagnostic ignored "-Wstrict-overflow"
245  CHECK(i >= 0 && i < ndim()) << "index = " << i << " must be in range [0, " << ndim() << ")";
246  #pragma GCC diagnostic pop
247  return begin()[i];
248  }
253  inline void Save(dmlc::JSONWriter* writer) const {
254  std::vector<ValueType> tmp(begin(), end());
255  writer->Write(tmp);
256  }
261  inline void Load(dmlc::JSONReader* reader) {
262  std::vector<ValueType> tmp;
263  reader->Read(&tmp);
264  this->assign(tmp.begin(), tmp.end());
265  }
272  friend std::ostream &operator<<(std::ostream &os, const Tuple<ValueType> &t) {
273  if (t.ndim() == -1) {
274  // If t is an unknown shape, return string "None".
275  // This is consistent with returning unknown shape in Python and generating
276  // C++ operator APIs by OpWrapperGenerator.py (defaultString) in cpp-package.
277  os << "None";
278  return os;
279  }
280  os << '[';
281  const ValueType* begin = t.begin();
282  const ValueType* end = t.end();
283  for (const ValueType* it = begin; it != end; ++it) {
284  if (it != begin) os << ',';
285  os << *it;
286  }
287  os << ']';
288  return os;
289  }
296  friend std::istream &operator>>(std::istream &is, Tuple<ValueType> &t) {
297  // get (
298  while (true) {
299  char ch = is.peek();
300  if (isdigit(ch) || ch == '-') {
301  ValueType idx;
302  if (is >> idx) {
303  t.assign(&idx, &idx + 1);
304  }
305  return is;
306  }
307  is.get();
308  if (ch == '(' || ch == '[') break;
309  if (!isspace(ch)) {
310  if (ch == 'N') {
311  std::string tmp_val;
312  is >> tmp_val;
313  if (tmp_val == "one") { // is stores "None"
314  t.SetDim(-1);
315  return is;
316  }
317  }
318  is.setstate(std::ios::failbit);
319  return is;
320  }
321  }
322  // Handle empty tuple. A tensor whose shape is an empty tuple
323  // represents a scalar with ndim = 0.
324  while (isspace(is.peek())) {
325  is.get();
326  }
327  if (is.peek() == ')' || is.peek() == ']') {
328  is.get();
329  t.SetDim(0);
330  return is;
331  }
332  // Handle non-empty tuple
333  ValueType idx;
334  std::vector<ValueType> tmp;
335  while (is >> idx) {
336  tmp.push_back(idx);
337  char ch;
338  do {
339  ch = is.get();
340  } while (isspace(ch));
341  if (std::is_integral<ValueType>::value && ch == 'L') {
342  ch = is.get();
343  }
344  if (ch == ',') {
345  while (true) {
346  ch = is.peek();
347  if (isspace(ch)) {
348  is.get(); continue;
349  }
350  if (ch == ')' || ch == ']') {
351  is.get(); break;
352  }
353  break;
354  }
355  if (ch == ')' || ch == ']') break;
356  } else if (ch == ')' || ch == ']') {
357  break;
358  } else {
359  is.setstate(std::ios::failbit);
360  return is;
361  }
362  }
363  t.assign(tmp.begin(), tmp.end());
364  return is;
365  }
372  template<typename DType = ValueType, typename TStream>
373  inline void Save(TStream *strm) const;
381  template<typename DType = ValueType, typename TStream>
382  inline bool Load(TStream *strm);
383 
384  protected:
385  // stack cache size
386  static const int kStackCache = 4;
388  int ndim_{0};
394  ValueType* data_heap_{nullptr};
395  // internal function to change the dimension
396  inline void SetDim(int ndim) {
397  CHECK_GE(ndim, -1) << "ndim cannot be less than -1, received " << ndim;
398  if (ndim > kStackCache &&
399  ndim > num_heap_allocated_) {
400  delete [] data_heap_;
401  data_heap_ = new ValueType[ndim];
403  } else if (ndim <= 0 && data_heap_ != nullptr) {
404  delete [] data_heap_;
405  data_heap_ = nullptr;
407  }
408  ndim_ = ndim;
409  }
410 };
411 
412 
414 inline bool ndim_is_known(const int ndim) {
415  CHECK_GE(ndim, -1) << "shape ndim must be >= -1, while received " << ndim;
416  return ndim != -1;
417 }
418 
420 inline bool dim_size_is_known(const dim_t dim_size) {
421  CHECK_GE(dim_size, -1) << "shape dim size must be >= -1, while received " << dim_size;
422  return dim_size != -1;
423 }
424 
438 class TShape : public Tuple<dim_t> {
439  public:
441  TShape() {
442  this->SetDim(-1);
443  }
449  inline TShape(const int ndim, const dim_t value) { // NOLINT(*)
450  this->SetDim(ndim);
451  if (ndim > 0) {
452  std::fill_n(begin(), ndim, value);
453  }
454  }
459  inline TShape(const Tuple<dim_t>& s) { // NOLINT(*)
460  if (s.ndim() == -1) {
461  this->SetDim(-1);
462  } else {
463  this->assign(s.begin(), s.end());
464  }
465  }
470  inline TShape(std::initializer_list<dim_t> init) {
471  this->assign(init.begin(), init.end());
472  }
477  inline TShape(Tuple<dim_t>&& s) { // NOLINT(*)
478  this->swap(s);
479  }
488  template<typename RandomAccessIterator,
489  typename std::enable_if<
490  std::is_same<typename std::iterator_traits<RandomAccessIterator>::iterator_category,
491  std::random_access_iterator_tag>::value, int>::type = 0>
492  inline TShape(RandomAccessIterator begin,
493  RandomAccessIterator end) {
494  this->assign(begin, end);
495  }
496 
497  inline explicit TShape(const ObjectRef& src): Tuple(src) {}
503  inline TShape& operator=(const Tuple<dim_t>& src) {
504  if (src.ndim() == -1) {
505  this->SetDim(-1);
506  } else {
507  this->assign(src.begin(), src.end());
508  }
509  return *this;
510  }
516  inline TShape& operator=(Tuple<dim_t>&& src) { // NOLINT(*)
517  TShape(std::move(src)).swap(*this); // NOLINT(*)
518  return *this;
519  }
521  inline size_t Size() const {
522  CHECK(ndim_is_known(this->ndim())) << "Shape is unknown.";
523  dim_t size = 1;
524  const dim_t* start = begin(), *fin = end();
525  for (const dim_t* it = start; it != fin; ++it) {
526  CHECK(dim_size_is_known(*it)) << "Shape dim size cannot be a negative value " << *it;
527  size *= *it;
528  }
529  return size;
530  }
536  inline size_t ProdShape(int dimstart, int dimend) const {
537  CHECK(ndim_is_known(this->ndim())) << "Shape is unknown.";
538  CHECK_GE(dimstart, 0) << "dimstart must be >= 0, while received " << dimstart;
539  CHECK_LE(dimend, this->ndim()) << "dimend must be <= " << this->ndim()
540  << ", while received " << dimend;
541  dim_t num = 1;
542  const dim_t *d = this->data();
543  for (int i = dimstart; i < dimend; ++i) {
544  CHECK(dim_size_is_known(d[i])) << "Shape dim size must be known, while received " << d[i];
545  num *= d[i];
546  }
547  return num;
548  }
550  inline const dim_t *data() const {
551  return begin();
552  }
554  inline dim_t *data() {
555  return begin();
556  }
557 #ifdef MSHADOW_XINLINE
558  template<int dim>
559  inline TShape(const mshadow::Shape<dim> &s) {// NOLINT(*)
560  this->assign(s.shape_, s.shape_ + dim);
561  }
562 
563  template<int dim>
564  inline TShape(mshadow::Shape<dim> &&s) {// NOLINT(*)
565  this->assign(s.shape_, s.shape_ + dim);
566  }
573  template<int dim>
574  inline TShape &operator=(const mshadow::Shape<dim> &shape) {
575  this->assign(shape.shape_, shape.shape_ + dim);
576  return *this;
577  }
583  template<int dim>
584  inline mshadow::Shape<dim> get() const {
585  CHECK_EQ(dim, ndim())
586  << "dimension do not match target dimension " << dim << " vs " << ndim();
587  const dim_t *d = this->data();
589  for (int i = 0; i < dim; ++i) {
590  s[i] = d[i];
591  }
592  return s;
593  }
598  inline mshadow::Shape<2> FlatTo2D(void) const {
600  CHECK(ndim_is_known(ndim())) << "shape must have a valid ndim";
601  if (ndim() == 0) return mshadow::Shape2(1, 1);
602  const dim_t *d = this->data();
603  s.shape_[1] = d[ndim() - 1];
604  dim_t ymax = 1;
605  for (int i = 1; i < ndim(); ++i) {
606  ymax *= d[i - 1];
607  }
608  s.shape_[0] = ymax;
609  return s;
610  }
617  inline mshadow::Shape<3> FlatTo3D(int axis_begin, int axis_end) const {
618  CHECK(axis_end >= axis_begin);
620  CHECK(ndim_is_known(ndim())) << "shape must have a valid ndim";
621  if (ndim() == 0) return mshadow::Shape3(1, 1, 1);
622  const dim_t *d = this->data();
623  s.shape_[0] = 1;
624  s.shape_[1] = 1;
625  s.shape_[2] = 1;
626 
627  for (int i = 0; i < axis_begin; ++i) {
628  s.shape_[0] *= d[i];
629  }
630  for (int i = axis_begin; i <= axis_end; ++i) {
631  s.shape_[1] *= d[i];
632  }
633  for (int i = axis_end + 1; i < ndim(); ++i) {
634  s.shape_[2] *= d[i];
635  }
636  return s;
637  }
643  inline mshadow::Shape<3> FlatTo3D(int axis) const {
644  return FlatTo3D(axis, axis);
645  }
646  inline bool operator==(const TShape &s) const {
647  if (ndim() != s.ndim()) return false;
648  return std::equal(begin(), end(), s.begin());
649  }
650  inline bool operator!=(const TShape &s) const {
651  return !(*this == s);
652  }
658  template<int dim>
659  inline bool operator==(const mshadow::Shape<dim> &s) const {
660  if (ndim_ != dim) return false;
661  const dim_t *d = dim <= kStackCache ? data_stack_ : data_heap_;
662  for (size_t i = 0; i < dim; ++i) {
663  if (d[i] != s.shape_[i]) return false;
664  }
665  return true;
666  }
672  template<int dim>
673  inline bool operator!=(const mshadow::Shape<dim> &s) const {
674  return !(*this == s);
675  }
676 #endif
677 };
678 
680 inline bool ndim_is_known(const TShape& x) {
681  return ndim_is_known(x.ndim());
682 }
683 
685 inline bool dim_size_is_known(const TShape& x, const int idx) {
686  CHECK(idx >= 0 && idx < x.ndim())
687  << "idx = " << idx << " exceeds shape dimension range [0, " << x.ndim() << ")";
688  return dim_size_is_known(x[idx]);
689 }
690 
693 inline bool shape_is_known(const TShape& x) {
694  if (!ndim_is_known(x)) return false;
695  for (int i = 0; i < x.ndim(); ++i) {
696  if (!dim_size_is_known(x, i)) return false;
697  }
698  return true;
699 }
700 
701 inline bool shape_is_known(const std::vector<TShape>& shapes) {
702  for (const TShape& shape : shapes) {
703  if (!shape_is_known(shape)) return false;
704  }
705  return true;
706 }
707 
709 template<typename SrcIter, typename DstIter>
710 inline DstIter ShapeTypeCast(const SrcIter begin,
711  const SrcIter end,
712  DstIter dst_begin) {
713  typedef typename std::iterator_traits<SrcIter>::value_type SrcDType;
714  typedef typename std::iterator_traits<DstIter>::value_type DstDType;
715  auto cast = [](const SrcDType& dim) { return static_cast<DstDType>(dim); };
716  return std::transform(begin, end, dst_begin, cast);
717 }
718 
720 template<typename SrcIter>
721 inline TShape ShapeTypeCast(const SrcIter begin, const SrcIter end) {
722  size_t ndim = std::distance(begin, end);
723  TShape res(ndim, -1);
724  ShapeTypeCast(begin, end, res.begin());
725  return res;
726 }
727 
729 template<typename ValueType>
730 template<typename DType, typename TStream>
731 inline void Tuple<ValueType>::Save(TStream *strm) const {
732  strm->Write(&ndim_, sizeof(ndim_));
733  if (typeid(DType) == typeid(ValueType)) {
734  strm->Write(begin(), sizeof(ValueType) * ndim_);
735  } else {
736  std::vector<DType> buffer(ndim_);
737  ShapeTypeCast(begin(), end(), buffer.data());
738  strm->Write(buffer.data(), sizeof(DType) * ndim_);
739  }
740 }
741 
743 template<typename ValueType>
744 template<typename DType, typename TStream>
745 inline bool Tuple<ValueType>::Load(TStream *strm) {
746  if (strm->Read(&ndim_, sizeof(ndim_)) != sizeof(ndim_)) return false;
747  this->SetDim(ndim_);
748  size_t nread = sizeof(DType) * ndim_;
749  if (typeid(DType) == typeid(ValueType)) {
750  if (strm->Read(begin(), nread) != nread) return false;
751  } else {
752  std::vector<DType> buffer(ndim_);
753  if (strm->Read(buffer.data(), nread) != nread) return false;
754  ShapeTypeCast(buffer.begin(), buffer.end(), begin());
755  }
756  return true;
757 }
758 
759 } // namespace mxnet
760 
761 namespace std {
763 template<typename T>
764 struct hash<mxnet::Tuple<T> > {
766  size_t operator()(const mxnet::Tuple<T>& val) const {
767  std::hash<int> hash_int;
768  size_t res = hash_int(val.ndim());
769  for (int i = 0; i < val.ndim(); ++i) {
770  res = dmlc::HashCombine(res, val[i]);
771  }
772  return res;
773  }
774 };
775 
777 template<>
778 struct hash<mxnet::TShape> {
780  size_t operator()(const mxnet::TShape& val) const {
781  std::hash<int> hash_int;
782  size_t res = hash_int(val.ndim());
783  for (int i = 0; i < val.ndim(); ++i) {
784  res = dmlc::HashCombine(res, val[i]);
785  }
786  return res;
787  }
788 };
789 } // namespace std
790 
791 namespace dmlc {
793 DMLC_DECLARE_TYPE_NAME(optional<mxnet::TShape>, "Shape or None");
794 DMLC_DECLARE_TYPE_NAME(optional<mxnet::Tuple<int>>, "Shape or None");
795 // avoid low version of MSVC
796 #if !(defined(_MSC_VER) && _MSC_VER < 1900)
797 template<typename T>
799  static inline std::string value() {
800  return "tuple of <" + type_name<T>() + ">";
801  }
802 };
803 #endif
804 } // namespace dmlc
805 
806 namespace mxnet {
820 using ShapeVector = std::vector<mxnet::TShape>;
821 
833 
834 } // namespace mxnet
835 
836 #endif // MXNET_TUPLE_H_
#define DMLC_DECLARE_TYPE_NAME(Type, Name)
macro to quickly declare traits information
Definition: type_traits.h:133
TShape(const ObjectRef &src)
Definition: tuple.h:497
helper class to construct a string that represents type name
Definition: type_traits.h:86
Tuple< ValueType > & operator=(const Tuple< ValueType > &src)
assignment from another tuple.
Definition: tuple.h:159
bool operator==(const Tuple< ValueType > &s) const
Definition: tuple.h:189
size_t operator()(const mxnet::TShape &val) const
hash a TShape into unsigned int
Definition: tuple.h:780
Tuple< ValueType > & operator=(Tuple< ValueType > &&src)
assignment from rvalue of another tuple.
Definition: tuple.h:172
dim_t * data()
Definition: tuple.h:554
TShape(const Tuple< dim_t > &s)
copy constructor of TShape
Definition: tuple.h:459
ValueType data_stack_[kStackCache]
in stack space used to store shape when it is small
Definition: tuple.h:392
namespace of mxnet
Definition: api_registry.h:33
TShape & operator=(Tuple< dim_t > &&src)
move assignment function from tshape
Definition: tuple.h:516
Tuple(std::initializer_list< ValueType > init)
constructor from initializer list
Definition: tuple.h:92
size_t operator()(const mxnet::Tuple< T > &val) const
hash a Tuple into unsigned int
Definition: tuple.h:766
TShape()
default constructor
Definition: tuple.h:441
int64_t dim_t
data type to store dim size
Definition: tuple.h:38
Definition: optional.h:241
DstIter ShapeTypeCast(const SrcIter begin, const SrcIter end, DstIter dst_begin)
helper function to cast type of container elements
Definition: tuple.h:710
Tuple(Tuple< ValueType > &&src)
move constructor from Tuple
Definition: tuple.h:107
void Load(dmlc::JSONReader *reader)
Load Tuple from JSON.
Definition: tuple.h:261
const dim_t * data() const
Definition: tuple.h:550
void assign(RandomAccessIterator begin, RandomAccessIterator end)
Assign content to tuple from iterator.
Definition: tuple.h:138
Base class of all object reference.
Definition: object.h:499
ValueType * end()
Definition: tuple.h:214
TShape(RandomAccessIterator begin, RandomAccessIterator end)
construct the Tuple from content of iterator. This function is enforced with template arguments of ra...
Definition: tuple.h:492
Data structures that can appear in graph attributes.
ValueType & operator[](int i)
get corresponding index
Definition: tuple.h:226
const ValueType & operator[](int i) const
get corresponding index
Definition: tuple.h:240
Tuple(const runtime::ObjectRef &src)
Definition: tuple.h:122
size_t HashCombine(size_t key, const T &value)
hash an object and combines the key with previous keys
Definition: common.h:37
std::vector< mxnet::TShape > ShapeVector
The result holder of shape of each NodeEntry in the graph.
Definition: tuple.h:820
size_t Size() const
Definition: tuple.h:521
Tuple(const Tuple< ValueType > &s)
copy constructor from another tuple
Definition: tuple.h:81
Lightweight JSON Reader to read any STL compositions and structs. The user need to know the schema of...
Definition: json.h:44
bool isspace(char c)
Inline implementation of isspace(). Tests whether the given character is a whitespace letter...
Definition: strtonum.h:26
~Tuple()
destructor
Definition: tuple.h:63
Tuple(std::vector< ValueType > init)
constructor from vector
Definition: tuple.h:99
namespace for dmlc
Definition: array_view.h:12
Tuple(RandomAccessIterator begin, RandomAccessIterator end)
construct the Tuple from content of iterator
Definition: tuple.h:117
void Write(const ValueType &value)
Write value to json.
bool dim_size_is_known(const dim_t dim_size)
Definition: tuple.h:420
Tuple()=default
default constructor
int num_heap_allocated_
number of cells allocated in data_heap_
Definition: tuple.h:390
static std::string value()
Definition: tuple.h:799
static const int kStackCache
Definition: tuple.h:386
const ValueType * end() const
Definition: tuple.h:210
void SetDim(int ndim)
Definition: tuple.h:396
std::function< bool(const NodeAttrs &attrs, std::vector< AttrType > *in_attrs, std::vector< AttrType > *out_attrs)> FInferNodeEntryAttr
Inference function of certain type.
Definition: op_attr_types.h:94
void swap(Tuple< ValueType > &other)
Swap current object with other.
Definition: tuple.h:148
index_t shape_[kDimension]
storing the dimension information
Definition: tensor.h:76
Pass that can be applied to a graph.
TShape(Tuple< dim_t > &&s)
move constructor.
Definition: tuple.h:477
void Read(ValueType *out_value)
Read next ValueType.
MSHADOW_XINLINE Shape< 2 > Shape2(index_t s0, index_t s1)
construct a two dimension shape, stride will equal s0
Definition: tensor.h:217
A dynamic sized array data structure that is optimized for storing small number of elements with same...
Definition: tuple.h:58
TShape(std::initializer_list< dim_t > init)
constructor from initializer list
Definition: tuple.h:470
Configuation of nnvm as well as basic data structure.
const ValueType * begin() const
Definition: tuple.h:202
A managed object in MXNet runtime.
int ndim_
number of dimension of the tuple
Definition: tuple.h:388
A Shape class that is used to represent shape of each tensor.
Definition: tuple.h:438
nnvm::FInferNodeEntryAttr< mxnet::TShape > FInferShape
Shape inference function. Update the shapes given the input shape information. TShape.ndim() == -1 means the shape is still unknown.
Definition: tuple.h:832
TShape & operator=(const Tuple< dim_t > &src)
assignment function from tshape
Definition: tuple.h:503
TShape(const int ndim, const dim_t value)
Definition: tuple.h:449
size_t ProdShape(int dimstart, int dimend) const
Definition: tuple.h:536
int ndim() const
Definition: tuple.h:218
Base expr nodes in MXNet.
Tuple< ValueType > & operator=(std::initializer_list< ValueType > init)
assignment from initializer list
Definition: tuple.h:181
bool operator!=(const Tuple< ValueType > &s) const
Definition: tuple.h:198
bool shape_is_known(const TShape &x)
Definition: tuple.h:693
bool ndim_is_known(const int ndim)
Definition: tuple.h:414
MSHADOW_XINLINE Shape< 3 > Shape3(index_t s0, index_t s1, index_t s2)
construct a three dimension shape, stride will equal s0
Definition: tensor.h:228
ValueType * data_heap_
space to store shape when dimension is big
Definition: tuple.h:394
ValueType * begin()
Definition: tuple.h:206
friend std::istream & operator>>(std::istream &is, Tuple< ValueType > &t)
read tuple from the istream
Definition: tuple.h:296
int64_t dim_t
data type to store dim size
Definition: c_api.h:62
Tuple(const int ndim, const dim_t value)
Definition: tuple.h:71
bool isdigit(char c)
Inline implementation of isdigit(). Tests whether the given character is a decimal digit...
Definition: strtonum.h:46
Data structures that can appear in operator attributes.
Lightweight json to write any STL compositions.
Definition: json.h:189
void Save(dmlc::JSONWriter *writer) const
Save Tuple to JSON.
Definition: tuple.h:253