30 #ifndef NNVM_LAYOUT_H_ 31 #define NNVM_LAYOUT_H_ 57 inline Layout(
const std::string& layout) {
80 this->parse(src.name_);
89 Layout(std::move(src)).swap(*
this);
106 return name_ == s.name_;
113 return !(*
this == s);
129 return Layout(this->name_ + other.name_);
138 return dim >=
'A' && dim <=
'Z';
147 return dim >=
'a' && dim <=
'z';
157 return dim -
'a' +
'A';
169 return dim -
'A' +
'a';
188 std::swap(name_, other.name_);
189 std::swap(superdim_pos_, other.superdim_pos_);
190 std::swap(subdim_pos_, other.subdim_pos_);
191 std::swap(subdim_size_, other.subdim_size_);
192 std::swap(layout_simplified_, other.layout_simplified_);
205 for (
size_t i = 0; i < kUniqueDim; ++i) {
206 if ((superdim_pos_[i] >= 0 && dst.superdim_pos_[i] < 0) ||
207 (superdim_pos_[i] < 0 && dst.superdim_pos_[i] >= 0)) {
224 if (pos + len >
ndim()) len =
ndim() - pos;
226 std::ostringstream new_layout;
227 for (
size_t i = pos; i < pos + len; ++i) {
229 auto block_size = this->
subsizeof(layout_simplified_[i]);
230 CHECK_GT(block_size, 0);
231 new_layout << block_size;
233 new_layout << layout_simplified_[i];
235 return Layout(new_layout.str());
241 std::ostringstream new_layout;
242 for (int64_t i = this->
ndim() - 1; i >= 0; --i) {
244 auto block_size = this->
subsizeof(layout_simplified_[i]);
245 CHECK_GT(block_size, 0);
246 new_layout << block_size;
248 new_layout << layout_simplified_[i];
250 return Layout(new_layout.str());
261 CHECK(target_pos <= this->
ndim()) <<
"Invalid split position " 262 << target_pos <<
" for layout " << name_;
263 CHECK(
is_superdim(dim)) <<
"Cannot split a sub-dimension " << dim;
264 CHECK(this->
contains(dim)) <<
"Axis " << dim <<
" does not exist in " << name_;
266 <<
" has already been split in " 268 CHECK(size > 0) <<
"Invalid split size " << size;
269 std::ostringstream new_layout;
270 for (
size_t i = 0; i <= this->
ndim(); ++i) {
271 if (i == target_pos) {
274 if (i == this->
ndim())
break;
275 new_layout << this->
at(i);
277 Layout x(new_layout.str());
281 using iterator = std::vector<LayoutDim>::const_iterator;
286 return layout_simplified_.begin();
290 return layout_simplified_.end();
294 return layout_simplified_.rbegin();
298 return layout_simplified_.rend();
303 return layout_simplified_.size();
313 inline std::string
at(
size_t i)
const {
314 CHECK_LT(i, this->
ndim()) <<
"position " << i
315 <<
" exceeds ndim=" << this->
ndim();
316 std::ostringstream repr;
318 auto factor =
subsizeof(layout_simplified_[i]);
322 repr << layout_simplified_[i];
334 if (!this->
defined())
return -1;
335 else if (
is_superdim(dim))
return superdim_pos_[dim -
'A'];
336 else if (
is_subdim(dim))
return subdim_pos_[dim -
'a'];
352 return subdim_size_[idx];
362 return superdim_pos_[dim-
'A'] >= 0;
364 return subdim_pos_[dim-
'a'] >= 0;
370 return layout_simplified_[i];
375 return name_ !=
"__undef__";
379 inline const std::string&
name()
const {
388 writer->
Write(name_);
413 static const uint32_t kUniqueDim = 26;
416 int32_t superdim_pos_[kUniqueDim];
417 int32_t subdim_pos_[kUniqueDim];
418 int64_t subdim_size_[kUniqueDim];
419 std::vector<LayoutDim> layout_simplified_;
421 void parse(
const std::string& layout) {
423 std::fill_n(superdim_pos_, kUniqueDim, -1);
424 std::fill_n(subdim_pos_, kUniqueDim, -1);
425 std::fill_n(subdim_size_, kUniqueDim, -1);
426 layout_simplified_.clear();
428 if (layout ==
"__undef__")
return;
432 for (
size_t i = 0; i < layout.size(); ++i) {
436 CHECK_EQ(factor, 0) <<
"Invalid layout " << layout
437 <<
": invalid factor size " << factor
438 <<
" before dimension " << c;
439 CHECK_EQ(superdim_pos_[pos], -1) <<
"Invalid layout " << layout
440 <<
": duplicate dimension " << c;
441 superdim_pos_[pos] = curr++;
442 layout_simplified_.push_back(c);
445 CHECK_GT(factor, 0) <<
"Invalid layout " << layout <<
": invalid factor size " 446 << factor <<
" for dimension " << c;
447 CHECK_EQ(subdim_pos_[pos], -1) <<
"Invalid layout " << layout
448 <<
": duplicate dimension " << c;
449 CHECK_EQ(subdim_size_[pos], -1) <<
"Invalid layout " << layout
450 <<
": duplicate dimension " << c;
451 subdim_pos_[pos] = curr++;
452 subdim_size_[pos] = factor;
453 layout_simplified_.push_back(c);
455 }
else if (c >=
'0' && c <=
'9') {
456 CHECK(factor >= 0) <<
"Invalid layout " << layout <<
": _ is adjacent to a number.";
457 factor = factor * 10 + c -
'0';
459 LOG(FATAL) <<
"Invalid layout " << layout;
462 CHECK(!layout_simplified_.empty()) <<
"Invalid layout " << layout;
463 for (
LayoutDim dim : layout_simplified_) {
464 CHECK(
is_superdim(dim) || superdim_pos_[dim-
'a'] >= 0)
465 <<
"Invalid layout " << layout <<
": missing axis " 466 <<
static_cast<char>(dim -
'a' +
'A');
473 #endif // NNVM_LAYOUT_H_ void swap(Layout &other)
Swap current object with other.
Definition: layout.h:187
Layout reverse() const
Definition: layout.h:239
Layout(Layout &&src)
move constructor from Layout
Definition: layout.h:71
Layout(const std::string &layout)
construct from a string.
Definition: layout.h:57
Layout()
default constructor
Definition: layout.h:47
bool operator==(const Layout &s) const
Definition: layout.h:105
static LayoutDim to_subdim(LayoutDim dim)
Convert a given dimension to sub-dimension.
Definition: layout.h:167
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:260
iterator begin() const
Definition: layout.h:285
void Load(dmlc::JSONReader *reader)
Load layout from JSON.
Definition: layout.h:395
static bool is_superdim(LayoutDim dim)
Check whether a given dimension is a super-dimension.
Definition: layout.h:137
void Save(dmlc::JSONWriter *writer) const
Write layout in JSON format.
Definition: layout.h:387
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:333
Layout operator+(const Layout &other) const
Append the current layout by another.
Definition: layout.h:121
Layout(const Layout &s)
copy constructor from another layout
Definition: layout.h:64
static const Layout & Undef()
Return an undefined layout.
Definition: layout.h:178
std::vector< LayoutDim >::const_iterator iterator
Definition: layout.h:281
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:297
std::vector< LayoutDim >::const_reverse_iterator reverse_iterator
Definition: layout.h:282
friend std::ostream & operator<<(std::ostream &os, const Layout &l)
allow output string of layout to ostream
Definition: layout.h:407
void Write(const ValueType &value)
Write value to json.
Layout & operator=(Layout &&src)
assignment from rvalue of another layout.
Definition: layout.h:88
LayoutDim operator[](size_t i) const
Definition: layout.h:369
Layout & operator=(const std::string &src)
assignment from string.
Definition: layout.h:97
bool defined() const
Definition: layout.h:374
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:313
Layout & operator=(const Layout &src)
assignment from another layout.
Definition: layout.h:79
void Read(ValueType *out_value)
Read next ValueType.
iterator end() const
Definition: layout.h:289
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:222
static bool is_subdim(LayoutDim dim)
Check whether a given dimension is a sub-dimension.
Definition: layout.h:146
size_t ndim() const
Definition: layout.h:302
bool contains(LayoutDim dim) const
Whether the layout contains a dimension.
Definition: layout.h:360
char LayoutDim
Definition: layout.h:44
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:203
bool operator!=(const Layout &s) const
Definition: layout.h:112
reverse_iterator rbegin() const
Definition: layout.h:293
int64_t subsizeof(LayoutDim dim) const
Definition: layout.h:346
static LayoutDim to_superdim(LayoutDim dim)
Convert a given dimension to super-dimension.
Definition: layout.h:155
Provide lightweight util to do parameter setup and checking.
const std::string & name() const
Definition: layout.h:379
Lightweight json to write any STL compositions.
Definition: json.h:189