Blob Blame Raw

#include "segment.inc.cpp"
#include "segment.test.inc.cpp"
#include "segment.cx4.inc.cpp"


class BenchmarkSegment {
public:
  static std::vector<NeuronReal> values;
  static std::vector<Weight> weights;
  
  static void runSegment(const char *name, Segment &s, int threads, int repeats, bool backpass) {
    class H: public ThreadControl {
    public:
      Segment &s;
      int repeats;
      NeuronReal ratio;
      std::vector<Quality> qualities;
      
      H(Segment &s, int repeats, NeuronReal ratio): s(s), repeats(repeats), ratio(ratio) { }
      
      void threadFunc(Barrier &barrier) override {
        Segment &s = this->s;
        Layout l = s.layout;
        NeuronReal r = ratio;
        int sx = l.getW() - s.sx + 1;
        int sy = l.getH() - s.sy + 1;
        int sz = l.getD() - s.sz + 1;
        
        Quality q;
        for(int i = 0; i < repeats; ++i) {
          int x = l.x0 + barrier.commonRand()%sx;
          int y = l.y0 + barrier.commonRand()%sy;
          int z = l.z0 + barrier.commonRand()%sz;
          q += s.pass(barrier, x, y, z, r);
          barrier.wait();
        }
        qualities[barrier.tid] = q;
      }
    } h(s, repeats, backpass ? 1 : 0);
    
    int cnt = s.layout.getCount();
    values.resize(cnt);
    weights.resize(s.weightsCount);
    s.f_values = values.data();
    s.weights = weights.data();

    for(int i = 0; i < cnt; ++i)
      s.f_values[i] = rand()/(NeuronReal)RAND_MAX;
    for(int i = 0; i < s.weightsCount; ++i)
      s.weights[i].w = rand()/(WeightReal)RAND_MAX;
    h.qualities.resize(threads);
    
    volatile long long t0 = timeUs();
    h.runThreads(threads);
    volatile long long t1 = timeUs();

    AccumReal sum = 0;
    for(int i = 0; i < threads; ++i) sum += h.qualities[i].train + h.qualities[i].human;
    for(int i = 0; i < s.weightsCount; ++i) sum += s.weights[i].w;
    
    printf("%s %d: %f, %lld\n", name, (int)backpass, (t1 - t0)*1e-6, (long long)sum);
  }


  static void runSegment(const char *name, Segment &s, int threads, int repeats) {
    runSegment(name, s, threads, repeats, false);
    runSegment(name, s, threads, repeats, true);
  }

  
  static void runSegment(const char *name, Segment &s, int threads) {
    int repeats = (int)( (1ll*1000*1000*1000 + s.effectiveLinks/2)/s.effectiveLinks );
    if (!SegmentTest::testSegment(name, s)) return;
    runSegment(name, s, threads, repeats, false);
    runSegment(name, s, threads, repeats, true);
  }
  
  
  static void run(int threads) {
    { SegmentCx4 s(3, 24); s.layout = Layout(514, 514,  3).expandXY(2);
      runSegment("cx4-3x24", s, threads); }
  }
};


std::vector<NeuronReal> BenchmarkSegment::values;
std::vector<Weight> BenchmarkSegment::weights;