Blob Blame Raw
#ifndef TEST_INC_CPP
#define TEST_INC_CPP


#include "common.inc.cpp"



class Test {
public:
  class Stage {
  public:
    const int errors;
    inline explicit Stage(const char *name): errors(Test::errors) {
      for(int i = 0; i < level; ++i) printf("- ");
      printf("%s\n", name);
      fflush(stdout);
      ++level;
    }
    inline ~Stage() {
      --level;
      if (!*this) {
        for(int i = 0; i < level; ++i) printf("- ");
        printf("FAILED\n");
      }
      fflush(stdout);
    }
    operator bool() { return Test::errors == errors; }
  };

private:
  static int level;

protected:
  static std::vector<Neuron> c_neurons;
  static std::vector<Neuron> p_neurons;
  static std::vector<Weight> weights;
  static std::vector<NeuronReal> values;

public:
  static int errors;


  static void init(int c_count, int p_count, int w_count, int v_count = 0) {
    Neuron n = {};
    Weight w = {};

    c_neurons.clear();
    p_neurons.clear();
    weights.clear();
    values.clear();
    
    c_neurons.resize(c_count, n);
    p_neurons.resize(p_count, n);
    weights.resize(w_count, w);
    values.resize(v_count, 0);
  }


  static bool verifyNeurons(const char *name, const Layout &l, const Neuron *neurons, bool ignorePadded = false) {
    Stage st(name);
    for(int y = 0; y < l.sy; ++y)
    for(int x = 0; x < l.sx; ++x)
    for(int z = 0; z < l.sz; ++z) {
      int n = neurons[ (y*l.sx + x)*l.sz + z ].a.i;
      int i = x >= l.x0 && x < l.x1
           && y >= l.y0 && y < l.y1
           && z >= l.z0 && z < l.z1;
      if (ignorePadded ? i && n != i : n != i) {
        printf(
          "wrong neuron mark %d, expected %d (%d, %d, %d)\n",
          n, i, y, x, z );
        l.printYXZ("layout");
        ++errors;
        return st;
      }
    }
    return st;
  }
  
  
  static bool verifyNeuronIndices(const char *name, const Layout &l, const Neuron *neurons, int base = 1, int stride = 1) {
    Stage st(name);
    for(int y = 0; y < l.sy; ++y)
    for(int x = 0; x < l.sx; ++x)
    for(int z = 0; z < l.sz; ++z) {
      bool active = x >= l.x0 && x < l.x1
                 && y >= l.y0 && y < l.y1
                 && z >= l.z0 && z < l.z1;
      
      int n = neurons[ (y*l.sx + x)*l.sz + z ].a.i;
      int i = (((y - l.y0)*l.getW() + x - l.x0)*l.getD() + z - l.z0)*stride + base;
      
      if (!active) i = 0;
      
      if (n != i) {
        printf(
          "wrong neuron mark %d, expected %d (%d, %d, %d)\n",
          n, i, y, x, z );
        l.printYXZ("layout");
        ++errors;
        return st;
      }
    }
    return st;
  }
  
  
  static bool verifyNeuronsAccum(const Layout &l, Neuron *neurons, int accum = 1, bool ignoreBounds = false) {
    for(int y = 0; y < l.sy; ++y)
    for(int x = 0; x < l.sx; ++x)
    for(int z = 0; z < l.sz; ++z) {
      Neuron &n = neurons[ (y*l.sx + x)*l.sz + z ];
      int i = ( x >= l.x0 && x < l.x1
             && y >= l.y0 && y < l.y1
             && z >= l.z0 && z < l.z1 )*accum;
      if (ignoreBounds) i = accum;
      if (n.v != 0 && n.v != i) {
        printf(
          "wrong neuron mark %g, expected 0 or %d (%d, %d, %d)\n",
          n.v, i, y, x, z );
        l.printYXZ("layout");
        ++errors;
        return false;
      }
      if (n.v) n.a.i = 1;
      n.v = 0;
    }
    return true;
  }
};


int Test::level = 0;
std::vector<Neuron> Test::c_neurons;
std::vector<Neuron> Test::p_neurons;
std::vector<Weight> Test::weights;
std::vector<NeuronReal> Test::values;
int Test::errors = 0;



#endif