31 #ifndef NNVM_LAYOUT_H_ 32 #define NNVM_LAYOUT_H_ 58 inline Layout(
const std::string& layout) {
81 this->parse(src.name_);
90 Layout(std::move(src)).swap(*
this);
107 return name_ == s.name_;
114 return !(*
this == s);
130 return Layout(this->name_ + other.name_);
139 return dim >=
'A' && dim <=
'Z';
148 return dim >=
'a' && dim <=
'z';
158 return dim -
'a' +
'A';
170 return dim -
'A' +
'a';
189 std::swap(name_, other.name_);
190 std::swap(superdim_pos_, other.superdim_pos_);
191 std::swap(subdim_pos_, other.subdim_pos_);
192 std::swap(subdim_size_, other.subdim_size_);
193 std::swap(layout_simplified_, other.layout_simplified_);
206 for (
size_t i = 0; i < kUniqueDim; ++i) {
207 if ((superdim_pos_[i] >= 0 && dst.superdim_pos_[i] < 0) ||
208 (superdim_pos_[i] < 0 && dst.superdim_pos_[i] >= 0)) {
225 if (pos + len >
ndim()) len =
ndim() - pos;
227 std::ostringstream new_layout;
228 for (
size_t i = pos; i < pos + len; ++i) {
230 auto block_size = this->
subsizeof(layout_simplified_[i]);
231 CHECK_GT(block_size, 0);
232 new_layout << block_size;
234 new_layout << layout_simplified_[i];
236 return Layout(new_layout.str());
242 std::ostringstream new_layout;
243 for (int64_t i = this->
ndim() - 1; i >= 0; --i) {
245 auto block_size = this->
subsizeof(layout_simplified_[i]);
246 CHECK_GT(block_size, 0);
247 new_layout << block_size;
249 new_layout << layout_simplified_[i];
251 return Layout(new_layout.str());
262 CHECK(target_pos <= this->
ndim()) <<
"Invalid split position " 263 << target_pos <<
" for layout " << name_;
264 CHECK(
is_superdim(dim)) <<
"Cannot split a sub-dimension " << dim;
265 CHECK(this->
contains(dim)) <<
"Axis " << dim <<
" does not exist in " << name_;
267 <<
" has already been split in " 269 CHECK(size > 0) <<
"Invalid split size " << size;
270 std::ostringstream new_layout;
271 for (
size_t i = 0; i <= this->
ndim(); ++i) {
272 if (i == target_pos) {
275 if (i == this->
ndim())
break;
276 new_layout << this->
at(i);
278 Layout x(new_layout.str());
282 using iterator = std::vector<LayoutDim>::const_iterator;
287 return layout_simplified_.begin();
291 return layout_simplified_.end();
295 return layout_simplified_.rbegin();
299 return layout_simplified_.rend();
304 return layout_simplified_.size();
314 inline std::string
at(
size_t i)
const {
315 CHECK_LT(i, this->
ndim()) <<
"position " << i
316 <<
" exceeds ndim=" << this->
ndim();
317 std::ostringstream repr;
319 auto factor =
subsizeof(layout_simplified_[i]);
323 repr << layout_simplified_[i];
335 if (!this->
defined())
return -1;
336 else if (
is_superdim(dim))
return superdim_pos_[dim -
'A'];
337 else if (
is_subdim(dim))
return subdim_pos_[dim -
'a'];
353 return subdim_size_[idx];
363 return superdim_pos_[dim-
'A'] >= 0;
365 return subdim_pos_[dim-
'a'] >= 0;
371 return layout_simplified_[i];
376 return name_ !=
"__undef__";
380 inline const std::string&
name()
const {
389 writer->
Write(name_);
414 static const uint32_t kUniqueDim = 26;
417 int32_t superdim_pos_[kUniqueDim];
418 int32_t subdim_pos_[kUniqueDim];
419 int64_t subdim_size_[kUniqueDim];
420 std::vector<LayoutDim> layout_simplified_;
422 void parse(
const std::string& layout) {
424 std::fill_n(superdim_pos_, kUniqueDim, -1);
425 std::fill_n(subdim_pos_, kUniqueDim, -1);
426 std::fill_n(subdim_size_, kUniqueDim, -1);
427 layout_simplified_.clear();
429 if (layout ==
"__undef__")
return;
433 for (
size_t i = 0; i < layout.size(); ++i) {
437 CHECK_EQ(factor, 0) <<
"Invalid layout " << layout
438 <<
": invalid factor size " << factor
439 <<
" before dimension " << c;
440 CHECK_EQ(superdim_pos_[pos], -1) <<
"Invalid layout " << layout
441 <<
": duplicate dimension " << c;
442 superdim_pos_[pos] = curr++;
443 layout_simplified_.push_back(c);
446 CHECK_GT(factor, 0) <<
"Invalid layout " << layout <<
": invalid factor size " 447 << factor <<
" for dimension " << c;
448 CHECK_EQ(subdim_pos_[pos], -1) <<
"Invalid layout " << layout
449 <<
": duplicate dimension " << c;
450 CHECK_EQ(subdim_size_[pos], -1) <<
"Invalid layout " << layout
451 <<
": duplicate dimension " << c;
452 subdim_pos_[pos] = curr++;
453 subdim_size_[pos] = factor;
454 layout_simplified_.push_back(c);
456 }
else if (c >=
'0' && c <=
'9') {
457 CHECK(factor >= 0) <<
"Invalid layout " << layout <<
": _ is adjacent to a number.";
458 factor = factor * 10 + c -
'0';
460 LOG(FATAL) <<
"Invalid layout " << layout;
463 CHECK(!layout_simplified_.empty()) <<
"Invalid layout " << layout;
464 for (
LayoutDim dim : layout_simplified_) {
465 CHECK(
is_superdim(dim) || superdim_pos_[dim-
'a'] >= 0)
466 <<
"Invalid layout " << layout <<
": missing axis " 467 <<
static_cast<char>(dim -
'a' +
'A');
474 #endif // NNVM_LAYOUT_H_ void swap(Layout &other)
Swap current object with other.
Definition: layout.h:188
Layout reverse() const
Definition: layout.h:240
Layout(Layout &&src)
move constructor from Layout
Definition: layout.h:72
Layout(const std::string &layout)
construct from a string.
Definition: layout.h:58
Layout()
default constructor
Definition: layout.h:48
bool operator==(const Layout &s) const
Definition: layout.h:106
static LayoutDim to_subdim(LayoutDim dim)
Convert a given dimension to sub-dimension.
Definition: layout.h:168
Layout split(LayoutDim dim, size_t target_pos, uint32_t size) const
Split dim by size and put the sub-dimension to position target_pos.
Definition: layout.h:261
iterator begin() const
Definition: layout.h:286
void Load(dmlc::JSONReader *reader)
Load layout from JSON.
Definition: layout.h:396
static bool is_superdim(LayoutDim dim)
Check whether a given dimension is a super-dimension.
Definition: layout.h:138
void Save(dmlc::JSONWriter *writer) const
Write layout in JSON format.
Definition: layout.h:388
int32_t indexof(LayoutDim dim) const
return the index of the input dimension. If it is not found in the layout or the layout is undefined...
Definition: layout.h:334
Layout operator+(const Layout &other) const
Append the current layout by another.
Definition: layout.h:122
Layout(const Layout &s)
copy constructor from another layout
Definition: layout.h:65
static const Layout & Undef()
Return an undefined layout.
Definition: layout.h:179
std::vector< LayoutDim >::const_iterator iterator
Definition: layout.h:282
Lightweight JSON Reader to read any STL compositions and structs. The user need to know the schema of...
Definition: json.h:44
reverse_iterator rend() const
Definition: layout.h:298
std::vector< LayoutDim >::const_reverse_iterator reverse_iterator
Definition: layout.h:283
friend std::ostream & operator<<(std::ostream &os, const Layout &l)
allow output string of layout to ostream
Definition: layout.h:408
void Write(const ValueType &value)
Write value to json.
Layout & operator=(Layout &&src)
assignment from rvalue of another layout.
Definition: layout.h:89
LayoutDim operator[](size_t i) const
Definition: layout.h:370
Layout & operator=(const std::string &src)
assignment from string.
Definition: layout.h:98
bool defined() const
Definition: layout.h:375
std::string at(size_t i) const
The description of the i-th dimension. If it is a sub-dimension, the size will be returned as well...
Definition: layout.h:314
Layout & operator=(const Layout &src)
assignment from another layout.
Definition: layout.h:80
void Read(ValueType *out_value)
Read next ValueType.
iterator end() const
Definition: layout.h:290
Layout sublayout(size_t pos, size_t len) const
Returns a sublayout which is the portion of the object that starts at dimension pos and spans len dim...
Definition: layout.h:223
static bool is_subdim(LayoutDim dim)
Check whether a given dimension is a sub-dimension.
Definition: layout.h:147
size_t ndim() const
Definition: layout.h:303
bool contains(LayoutDim dim) const
Whether the layout contains a dimension.
Definition: layout.h:361
char LayoutDim
Definition: layout.h:45
bool convertible(const Layout &dst) const
Two layouts are convertible only if they have same set of super-dimensions. e.g., NCHW...
Definition: layout.h:204
bool operator!=(const Layout &s) const
Definition: layout.h:113
reverse_iterator rbegin() const
Definition: layout.h:294
int64_t subsizeof(LayoutDim dim) const
Definition: layout.h:347
static LayoutDim to_superdim(LayoutDim dim)
Convert a given dimension to super-dimension.
Definition: layout.h:156
Provide lightweight util to do parameter setup and checking.
const std::string & name() const
Definition: layout.h:380
Lightweight json to write any STL compositions.
Definition: json.h:189