#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