Blame projects/neural/layer.simple.test.inc.cpp

Ivan Mahonin e865c9
#ifndef LAYER_SIMPLE_TEST_INC_CPP
Ivan Mahonin e865c9
#define LAYER_SIMPLE_TEST_INC_CPP
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
#include "layer.test.inc.cpp"
Ivan Mahonin e865c9
#include "layer.simple.inc.cpp"
Ivan Mahonin 15c502
#include "layer.sub.inc.cpp"
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin b579b3
class SimpleTest: public LayerTest {
Ivan Mahonin e865c9
public:
Ivan Mahonin e865c9
  static void init(const Layout &cl, const Layout &pl = Layout())
Ivan Mahonin e865c9
    { Test::init(cl.getCount(), pl.getCount(), cl.getActiveCount()*pl.getActiveCount()); }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  static bool verifyWeights(const char *name, const Layout &cl, const Layout &pl) {
Ivan Mahonin e865c9
    Stage st(name);
Ivan Mahonin e865c9
    for(int cy = cl.y0; cy < cl.y1; ++cy)
Ivan Mahonin e865c9
    for(int cx = cl.x0; cx < cl.x1; ++cx)
Ivan Mahonin e865c9
    for(int cz = cl.z0; cz < cl.z1; ++cz) {
Ivan Mahonin e865c9
      int ci = (cy*cl.sx + cx)*cl.sz + cz;
Ivan Mahonin e865c9
Ivan Mahonin e865c9
      for(int py = pl.y0; py < pl.y1; ++py)
Ivan Mahonin e865c9
      for(int px = pl.x0; px < pl.x1; ++px)
Ivan Mahonin e865c9
      for(int pz = pl.z0; pz < pl.z1; ++pz) {
Ivan Mahonin e865c9
        int pi = (py*pl.sx + px)*pl.sz + pz;
Ivan Mahonin e865c9
Ivan Mahonin e865c9
        int wi = ((cy - cl.y0)*cl.getW() + cx - cl.x0)*cl.getD() + cz - cl.z0;
Ivan Mahonin e865c9
        wi = ((wi*pl.getH() + py - pl.y0)*pl.getW() + px - pl.x0)*pl.getD() + pz - pl.z0;
Ivan Mahonin e865c9
Ivan Mahonin e865c9
        int s = (int)p_neurons.size();
Ivan Mahonin e865c9
        int w = weights[wi].i;
Ivan Mahonin e865c9
        int i = ci*s + pi + 1;
Ivan Mahonin e865c9
Ivan Mahonin e865c9
        if (w != i) {
Ivan Mahonin e865c9
          int ww = w;
Ivan Mahonin e865c9
          int wpz = ww%pl.sz; ww /= pl.sz;
Ivan Mahonin e865c9
          int wpx = ww%pl.sx; ww /= pl.sx;
Ivan Mahonin e865c9
          int wpy = ww%pl.sy; ww /= pl.sy;
Ivan Mahonin e865c9
          int wcz = ww%cl.sz; ww /= cl.sz;
Ivan Mahonin e865c9
          int wcx = ww%cl.sx; ww /= cl.sx;
Ivan Mahonin e865c9
          int wcy = ww;
Ivan Mahonin e865c9
Ivan Mahonin e865c9
          printf(
Ivan Mahonin e865c9
            "wrong index: %d = ((%d*%d + %d)*%d + %d)*%d + (%d*%d + %d)*%d + %d + 1,\n"
Ivan Mahonin e865c9
            "expected:    %d = ((%d*%d + %d)*%d + %d)*%d + (%d*%d + %d)*%d + %d + 1\n"
Ivan Mahonin e865c9
            "wi = %d\n",
Ivan Mahonin e865c9
            w,
Ivan Mahonin e865c9
            wcy, cl.sx, wcx, cl.sz, wcz, s,
Ivan Mahonin e865c9
            wpy, pl.sx, wpx, pl.sz, wpz,
Ivan Mahonin e865c9
            i,
Ivan Mahonin e865c9
            cy, cl.sx, cx, cl.sz, cz, s,
Ivan Mahonin e865c9
            py, pl.sx, px, pl.sz, pz,
Ivan Mahonin e865c9
            wi );
Ivan Mahonin e865c9
          pl.printYXZ("prev layout");
Ivan Mahonin e865c9
          cl.printYXZ("curr layout");
Ivan Mahonin e865c9
          ++errors;
Ivan Mahonin e865c9
          return st;
Ivan Mahonin e865c9
        }
Ivan Mahonin e865c9
      }
Ivan Mahonin e865c9
    }
Ivan Mahonin e865c9
    return st;
Ivan Mahonin e865c9
  }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  static bool testIterators(const char *name, const Layout &cl, const Layout &pl, const Layout &ocl, const Layout &opl, int threads) {
Ivan Mahonin e865c9
    Stage st(name);
Ivan Mahonin e865c9
Ivan Mahonin e865c9
    assert(cl && pl && ocl && opl && threads > 0);
Ivan Mahonin e865c9
    Layout::List oclist, oplist;
Ivan Mahonin e865c9
    ocl.split(oclist, threads);
Ivan Mahonin e865c9
    opl.split(oplist, threads);
Ivan Mahonin e865c9
Ivan Mahonin e865c9
    struct I: public Iter {
Ivan Mahonin e865c9
      typedef int DataType;
Ivan Mahonin e865c9
      typedef int DataAccumType;
Ivan Mahonin e865c9
      static inline void init(Neuron &n, Iter::AccumType &a) { ++n.a.i; a.i = (AccumInt)(&n - c_neurons.data()); }
Ivan Mahonin e865c9
      static inline void iter(Neuron &n, Weight &w, Iter::AccumType &a) {
Ivan Mahonin e865c9
        if (w.i)
Ivan Mahonin e865c9
          ++errors;
Ivan Mahonin e865c9
        w.i = (WeightInt)(&n - p_neurons.data() + a.i*p_neurons.size() + 1);
Ivan Mahonin e865c9
      }
Ivan Mahonin e865c9
      static inline void iter3(Neuron &n) { ++n.a.i; }
Ivan Mahonin e865c9
      static inline void iter4(Neuron &n, DataType d, DataAccumType &a) { n.a.i = d; ++a; }
Ivan Mahonin e865c9
    };
Ivan Mahonin e865c9
Ivan Mahonin e865c9
    struct IB: public Iter {
Ivan Mahonin e865c9
      static inline void init(Neuron &n, Iter::AccumType &a) { ++n.a.i; a.i = (AccumInt)(&n - p_neurons.data()); }
Ivan Mahonin e865c9
      static inline void iter(Neuron &n, Weight &w, Iter::AccumType &a) {
Ivan Mahonin e865c9
        if (w.i)
Ivan Mahonin e865c9
          ++errors;
Ivan Mahonin e865c9
        w.i = (WeightInt)((&n - c_neurons.data())*p_neurons.size() + a.i + 1);
Ivan Mahonin e865c9
      }
Ivan Mahonin e865c9
    };
Ivan Mahonin e865c9
Ivan Mahonin e865c9
    {
Ivan Mahonin e865c9
      Stage st("iterateNeurons");
Ivan Mahonin e865c9
      init(cl);
Ivan Mahonin e865c9
      for(int i = 0; i < threads; ++i)
Ivan Mahonin e865c9
        iterateNeurons(oclist[i], c_neurons.data());
Ivan Mahonin e865c9
      verifyNeurons("check-neurons", cl, c_neurons.data());
Ivan Mahonin e865c9
    }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
    {
Ivan Mahonin e865c9
      Stage st("iterateNeurons2");
Ivan Mahonin e865c9
      init(cl);
Ivan Mahonin e865c9
      for(int i = 0; i < threads; ++i) {
Ivan Mahonin e865c9
        int a = 5, aa = a + oclist[i].getActiveCount();
Ivan Mahonin e865c9
        iterateNeurons2(oclist[i], ocl, c_neurons.data(), 5, 3, &a);
Ivan Mahonin e865c9
        if (a != aa) {
Ivan Mahonin e865c9
          printf("wrong accum value %d, expected %d, tid: %d/%d\n", a, aa, i, threads);
Ivan Mahonin e865c9
          oclist[i].printYXZ("sub  layout");
Ivan Mahonin e865c9
          oclist[i].printYXZ("orig layout");
Ivan Mahonin e865c9
        }
Ivan Mahonin e865c9
      }
Ivan Mahonin e865c9
      verifyNeuronIndices("check-neuron-indices", cl, c_neurons.data(), 5, 3);
Ivan Mahonin e865c9
    }
Ivan Mahonin e865c9
    
Ivan Mahonin e865c9
    {
Ivan Mahonin e865c9
      Stage st("iterateSimple");
Ivan Mahonin e865c9
      init(cl, pl);
Ivan Mahonin e865c9
      for(int i = 0; i < threads; ++i)
Ivan Mahonin e865c9
        iterateSimple(oclist[i], opl, ocl, c_neurons.data(), p_neurons.data(), weights.data());
Ivan Mahonin e865c9
      verifyNeurons("check-neurons", cl, c_neurons.data());
Ivan Mahonin e865c9
      verifyWeights("check-weights", cl, pl);
Ivan Mahonin e865c9
    }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
    {
Ivan Mahonin e865c9
      Stage st("iterateSimpleInv");
Ivan Mahonin e865c9
      init(cl, pl);
Ivan Mahonin e865c9
      for(int i = 0; i < threads; ++i)
Ivan Mahonin e865c9
        iterateSimpleInv<IB>(oplist[i], ocl, opl, p_neurons.data(), c_neurons.data(), weights.data());
Ivan Mahonin e865c9
      verifyNeurons("check-neurons", pl, p_neurons.data());
Ivan Mahonin e865c9
      verifyWeights("check-weights", cl, pl);
Ivan Mahonin e865c9
    }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
    return st;
Ivan Mahonin e865c9
  }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  static bool testIterators(const char *name, const Layout &cl, const Layout &pl) {
Ivan Mahonin e865c9
    Stage st(name);
Ivan Mahonin e865c9
    
Ivan Mahonin e865c9
    {
Ivan Mahonin e865c9
      Stage st("plain");
Ivan Mahonin e865c9
      testIterators( "single-thread", cl, pl, cl, pl,   1 );
Ivan Mahonin e865c9
      testIterators( "2-threads",     cl, pl, cl, pl,   2 );
Ivan Mahonin e865c9
      testIterators( "7-threads",     cl, pl, cl, pl,   7 );
Ivan Mahonin e865c9
      testIterators( "8-threads",     cl, pl, cl, pl,   8 );
Ivan Mahonin e865c9
      testIterators( "512-threads",   cl, pl, cl, pl, 512 );
Ivan Mahonin e865c9
    }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
    {
Ivan Mahonin e865c9
      Stage st("optimized");
Ivan Mahonin e865c9
      Layout ocl = optimizeLayoutSimple(cl);
Ivan Mahonin e865c9
      Layout opl = optimizeLayoutSimple(pl);
Ivan Mahonin e865c9
      testIterators( "single-thread", cl, pl, ocl, opl,   1 );
Ivan Mahonin e865c9
      testIterators( "2-threads",     cl, pl, ocl, opl,   2 );
Ivan Mahonin e865c9
      testIterators( "7-threads",     cl, pl, ocl, opl,   7 );
Ivan Mahonin e865c9
      testIterators( "8-threads",     cl, pl, ocl, opl,   8 );
Ivan Mahonin e865c9
      testIterators( "512-threads",   cl, pl, ocl, opl, 512 );
Ivan Mahonin e865c9
    }
Ivan Mahonin e865c9
    
Ivan Mahonin e865c9
    return st;
Ivan Mahonin e865c9
  }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  
Ivan Mahonin e865c9
  static bool test(const char *name, const Layout &cl, const Layout &pl) {
Ivan Mahonin e865c9
    Stage st(name);
Ivan Mahonin e865c9
    
Ivan Mahonin e865c9
    testIterators(name, cl, pl);
Ivan Mahonin e865c9
    
Ivan Mahonin e865c9
    {
Ivan Mahonin e865c9
      Layer l(nullptr, pl);
Ivan Mahonin e865c9
      new LayerSimple<funcSigmoidExp>(l, cl);
Ivan Mahonin b579b3
      testLayer("LayerSimple", l);
Ivan Mahonin e865c9
    }
Ivan Mahonin e865c9
    
Ivan Mahonin 15c502
    {
Ivan Mahonin 15c502
      Layout ppl(cl.getW()*2, cl.getH()*2, cl.getD());
Ivan Mahonin 15c502
      ppl.expandX( pl.x0, pl.sx - pl.x1 );
Ivan Mahonin 15c502
      ppl.expandY( pl.y0, pl.sy - pl.y1 );
Ivan Mahonin 15c502
      ppl.expandZ( pl.z0, pl.sz - pl.z1 );
Ivan Mahonin 15c502
      
Ivan Mahonin 15c502
      Layer l(nullptr, ppl);
Ivan Mahonin 15c502
      new LayerSub<funcSigmoidExp>(l, cl);
Ivan Mahonin b579b3
      testLayer("LayerSub", l);
Ivan Mahonin 15c502
    }
Ivan Mahonin 15c502
    
Ivan Mahonin e865c9
    return st;
Ivan Mahonin e865c9
  }
Ivan Mahonin e865c9
Ivan Mahonin e865c9
  
Ivan Mahonin e865c9
  static bool test(const char *name = "simple") {
Ivan Mahonin e865c9
    Stage st(name);
Ivan Mahonin e865c9
    test("square-16x8", Layout(8, 8, 4), Layout(16, 16, 3));
Ivan Mahonin e865c9
    test("random-rect", Layout( 7, 4, 3).expandX(1, 2).expandY(3, 1).expandZ(5, 8),
Ivan Mahonin e865c9
                        Layout(13, 9, 4).expandX(2, 0).expandY(5, 3).expandZ(3, 1) );
Ivan Mahonin e865c9
    return st;
Ivan Mahonin e865c9
  }
Ivan Mahonin e865c9
};
Ivan Mahonin e865c9
Ivan Mahonin e865c9
Ivan Mahonin e865c9
#endif