Blame projects/neural/layout.inc.cpp

Ivan Mahonin e865c9
#ifndef LAYOUT_INC_CPP
Ivan Mahonin e865c9
#define LAYOUT_INC_CPP
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
#include <cassert>
Ivan Mahonin e865c9
#include <cstdio>
Ivan Mahonin e865c9
Ivan Mahonin e865c9
#include <vector>
Ivan Mahonin e865c9
#include <algorithm>
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
struct Layout {
Ivan Mahonin e865c9
  typedef std::vector<Layout> List;
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  int sx, sy, sz;
Ivan Mahonin e865c9
  int x0, x1;
Ivan Mahonin e865c9
  int y0, y1;
Ivan Mahonin e865c9
  int z0, z1;
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  inline Layout(): sx(), sy(), sz(), x0(), x1(), y0(), y1(), z0(), z1() { }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  explicit inline Layout(int sx, int sy = 1, int sz = 1):
Ivan Mahonin e865c9
    sx(sx), sy(sy), sz(sz), x0(), x1(sx), y0(), y1(sy), z0(), z1(sz) { }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  inline Layout& expandX  (int e0, int e1) { return sx += e0+e1, x0 += e0, x1 += e0, *this; }
Ivan Mahonin e865c9
  inline Layout& expandY  (int e0, int e1) { return sy += e0+e1, y0 += e0, y1 += e0, *this; }
Ivan Mahonin e865c9
  inline Layout& expandZ  (int e0, int e1) { return sz += e0+e1, z0 += e0, z1 += e0, *this; }
Ivan Mahonin e865c9
  inline Layout& expandXY (int e0, int e1) { return expandX (e0, e1).expandY(e0, e1); }
Ivan Mahonin e865c9
  inline Layout& expandXYZ(int e0, int e1) { return expandXY(e0, e1).expandZ(e0, e1); }
Ivan Mahonin e865c9
  inline Layout& expandX  (int e)          { return expandX  (e, e); }
Ivan Mahonin e865c9
  inline Layout& expandY  (int e)          { return expandY  (e, e); }
Ivan Mahonin e865c9
  inline Layout& expandZ  (int e)          { return expandX  (e, e); }
Ivan Mahonin e865c9
  inline Layout& expandXY (int e)          { return expandXY (e, e); }
Ivan Mahonin e865c9
  inline Layout& expandXYZ(int e)          { return expandXYZ(e, e); }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  inline Layout& padX  (int p0, int p1) { return x0 += p0, x1 -= p0, *this; }
Ivan Mahonin e865c9
  inline Layout& padY  (int p0, int p1) { return y0 += p0, y1 -= p0, *this; }
Ivan Mahonin e865c9
  inline Layout& padZ  (int p0, int p1) { return z0 += p0, z1 -= p0, *this; }
Ivan Mahonin e865c9
  inline Layout& padXY (int p0, int p1) { return padX (p0, p1).padY(p0, p1); }
Ivan Mahonin e865c9
  inline Layout& padXYZ(int p0, int p1) { return padXY(p0, p1).padZ(p0, p1); }
Ivan Mahonin e865c9
  inline Layout& padX  (int p)          { return padX  (p, p); }
Ivan Mahonin e865c9
  inline Layout& padY  (int p)          { return padY  (p, p); }
Ivan Mahonin e865c9
  inline Layout& padZ  (int p)          { return padX  (p, p); }
Ivan Mahonin e865c9
  inline Layout& padXY (int p)          { return padXY (p, p); }
Ivan Mahonin e865c9
  inline Layout& padXYZ(int p)          { return padXYZ(p, p); }
Ivan Mahonin e865c9
Ivan Mahonin b579b3
  inline bool hasPadX() const { return x0 > 0 || x1 < sx; }
Ivan Mahonin b579b3
  inline bool hasPadY() const { return y0 > 0 || y1 < sy; }
Ivan Mahonin b579b3
  inline bool hasPadZ() const { return z0 > 0 || z1 < sz; }
Ivan Mahonin b579b3
  inline bool hasPad()  const { return hasPadX() || hasPadY() || hasPadZ(); }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  inline int getW() const { return x1 - x0; }
Ivan Mahonin e865c9
  inline int getH() const { return y1 - y0; }
Ivan Mahonin e865c9
  inline int getD() const { return z1 - z0; }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  inline int getCount() const { return sx*sy*sz; }
Ivan Mahonin e865c9
  inline int getActiveCount() const { return getW()*getH()*getD(); }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  inline operator bool() const {
Ivan Mahonin e865c9
    return x0 >= 0 && x0 < x1 && x1 <= sx
Ivan Mahonin e865c9
        && y0 >= 0 && y0 < y1 && y1 <= sy
Ivan Mahonin e865c9
        && z0 >= 0 && z0 < z1 && z1 <= sz;
Ivan Mahonin e865c9
  }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  
Ivan Mahonin e865c9
  inline bool isSameSizeWith(const Layout &b) const
Ivan Mahonin e865c9
    { return sx == b.sx && sy == b.sy && sz == b.sz; }
Ivan Mahonin e865c9
  inline bool isSameActiveSizeWith(const Layout &b) const
Ivan Mahonin e865c9
    { return getW() == b.getW() && getH() == b.getH() && getD() == b.getD(); }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  inline bool isSubLayoutOf(const Layout &b) const
Ivan Mahonin e865c9
    { return isSameSizeWith(b) && b.x0 <= x0 && x0 < x1 && x1 <= b.x1; }
Ivan Mahonin e865c9
  inline bool isParentLayoutOf(const Layout &b) const
Ivan Mahonin e865c9
    { return b.isSubLayoutOf(*this); }
Ivan Mahonin e865c9
  
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  void splitX(List &list, int count) const {
Ivan Mahonin e865c9
    if (count <= 0) return list.clear();
Ivan Mahonin e865c9
    list.resize(count);
Ivan Mahonin e865c9
    int v = x0, s = x1 - v;
Ivan Mahonin e865c9
    for(int i = 0; i < count; ++i) {
Ivan Mahonin e865c9
      Layout &l = list[i] = *this;
Ivan Mahonin e865c9
      l.x0 = v;
Ivan Mahonin e865c9
      l.x1 = (v += s/count + (i < s%count));
Ivan Mahonin e865c9
    }
Ivan Mahonin e865c9
  }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  void splitY(List &list, int count) const {
Ivan Mahonin e865c9
    if (count <= 0) return list.clear();
Ivan Mahonin e865c9
    list.resize(count);
Ivan Mahonin e865c9
    int v = y0, s = y1 - v;
Ivan Mahonin e865c9
    for(int i = 0; i < count; ++i) {
Ivan Mahonin e865c9
      Layout &l = list[i] = *this;
Ivan Mahonin e865c9
      l.y0 = v;
Ivan Mahonin e865c9
      l.y1 = (v += s/count + (i < s%count));
Ivan Mahonin e865c9
    }
Ivan Mahonin e865c9
  }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  void splitZ(List &list, int count) const {
Ivan Mahonin e865c9
    if (count <= 0) return list.clear();
Ivan Mahonin e865c9
    list.resize(count);
Ivan Mahonin e865c9
    int v = z0, s = z1 - v;
Ivan Mahonin e865c9
    for(int i = 0; i < count; ++i) {
Ivan Mahonin e865c9
      Layout &l = list[i] = *this;
Ivan Mahonin e865c9
      l.z0 = v;
Ivan Mahonin e865c9
      l.z1 = (v += s/count + (i < s%count));
Ivan Mahonin e865c9
    }
Ivan Mahonin e865c9
  }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  void split(List &list, int count) const {
Ivan Mahonin e865c9
    int h = getH(), w = getW(), d = getD();
Ivan Mahonin e865c9
    if (h >= w && h >= d) splitY(list, count); else
Ivan Mahonin e865c9
              if (w >= d) splitX(list, count); else
Ivan Mahonin e865c9
                          splitZ(list, count);
Ivan Mahonin e865c9
  }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  void print(const char *prefix = nullptr) const {
Ivan Mahonin e865c9
    if (prefix && *prefix) printf("%s: ", prefix);
Ivan Mahonin e865c9
    printf("x: %d (%d-%d), y: %d (%d-%d), z: %d (%d-%d)\n", sx, x0, x1, sy, y0, y1, sz, z0, z1);
Ivan Mahonin e865c9
  }
Ivan Mahonin e865c9
  void printYXZ(const char *prefix = nullptr) const {
Ivan Mahonin e865c9
    if (prefix && *prefix) printf("%s: ", prefix);
Ivan Mahonin e865c9
    printf("y: %d (%d-%d), x: %d (%d-%d), z: %d (%d-%d)\n", sy, y0, y1, sx, x0, x1, sz, z0, z1);
Ivan Mahonin e865c9
  }
Ivan Mahonin e865c9
};
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
#endif