autotuner.cpp 2.59 KB
Newer Older
Luka Stanisic's avatar
Luka Stanisic committed
1 2 3 4 5 6 7 8 9 10 11 12
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   < BioEM software for Bayesian inference of Electron Microscopy images>
   Copyright (C) 2017 Pilar Cossio, Markus Rampp, Luka Stanisic and Gerhard
   Hummer.
   Max Planck Institute of Biophysics, Frankfurt, Germany.
   Max Planck Computing and Data Facility, Garching, Germany.

   Released under the GNU Public License, v3.
   See license statement for terms of distribution.

   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

Luka Stanisic's avatar
Luka Stanisic committed
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#include "autotuner.h"

void Autotuner::Reset()
{
  stopTuning = false;
  workload = 100;

  best_time = 0.;
  best_workload = 0;

  a = 1;
  b = 50;
  c = 100;
  x = 50;
  limit = 1;
  fb = 0.;
  fx = 0.;

Luka Stanisic's avatar
Luka Stanisic committed
31 32
  if (algo == 3)
    workload = 50;
Luka Stanisic's avatar
Luka Stanisic committed
33 34 35 36
}

bool Autotuner::Needed(int iteration)
{
Luka Stanisic's avatar
Luka Stanisic committed
37 38
  if (stopTuning)
    return false;
Luka Stanisic's avatar
Luka Stanisic committed
39 40

  switch (algo)
Luka Stanisic's avatar
Luka Stanisic committed
41
  {
Luka Stanisic's avatar
Luka Stanisic committed
42 43 44
    case 1:
    case 3:
      return iteration % (stable + 1) == stable;
Luka Stanisic's avatar
Luka Stanisic committed
45 46
    case 2:
      return (iteration == (int) stable / 2) || (iteration == stable);
Luka Stanisic's avatar
Luka Stanisic committed
47
    default: /* Should never happen */;
Luka Stanisic's avatar
Luka Stanisic committed
48
  }
Luka Stanisic's avatar
Luka Stanisic committed
49 50 51 52 53 54
  return false;
}

bool Autotuner::Finished()
{
  switch (algo)
Luka Stanisic's avatar
Luka Stanisic committed
55
  {
Luka Stanisic's avatar
Luka Stanisic committed
56 57
    case 1:
      if (workload < 30)
Luka Stanisic's avatar
Luka Stanisic committed
58 59 60 61
      {
        workload = best_workload;
        return stopTuning = true;
      }
Luka Stanisic's avatar
Luka Stanisic committed
62 63
      break;
    case 2:
Luka Stanisic's avatar
Luka Stanisic committed
64 65
      if (best_workload != 0)
        return stopTuning = true;
Luka Stanisic's avatar
Luka Stanisic committed
66 67
      break;
    case 3:
Luka Stanisic's avatar
Luka Stanisic committed
68 69
      if ((c - b == limit) && (b - a == limit))
        return stopTuning = true;
Luka Stanisic's avatar
Luka Stanisic committed
70 71
      break;
    default: /* Should never happen */;
Luka Stanisic's avatar
Luka Stanisic committed
72
  }
Luka Stanisic's avatar
Luka Stanisic committed
73 74 75 76 77 78
  return false;
}

void Autotuner::Tune(double compTime)
{
  switch (algo)
Luka Stanisic's avatar
Luka Stanisic committed
79 80 81 82 83 84 85 86 87 88
  {
    case 1:
      AlgoSimple(compTime);
      break;
    case 2:
      AlgoRatio(compTime);
      break;
    case 3:
      AlgoBisection(compTime);
      break;
Luka Stanisic's avatar
Luka Stanisic committed
89
    default: /* Should never happen */;
Luka Stanisic's avatar
Luka Stanisic committed
90
  }
Luka Stanisic's avatar
Luka Stanisic committed
91 92 93 94 95
}

void Autotuner::AlgoSimple(double compTime)
{
  if (best_time == 0. || compTime < best_time)
Luka Stanisic's avatar
Luka Stanisic committed
96 97 98 99
  {
    best_time = compTime;
    best_workload = workload;
  }
Luka Stanisic's avatar
Luka Stanisic committed
100 101 102 103 104 105 106

  workload -= 5;
}

void Autotuner::AlgoRatio(double compTime)
{
  if (best_time == 0.)
Luka Stanisic's avatar
Luka Stanisic committed
107 108 109 110
  {
    best_time = compTime;
    workload = 1;
  }
Luka Stanisic's avatar
Luka Stanisic committed
111
  else
Luka Stanisic's avatar
Luka Stanisic committed
112 113 114 115
  {
    best_workload = (int) 100 * (compTime / (best_time + compTime));
    workload = best_workload;
  }
Luka Stanisic's avatar
Luka Stanisic committed
116 117 118 119 120
}

void Autotuner::AlgoBisection(double compTime)
{
  if (fb == 0.)
Luka Stanisic's avatar
Luka Stanisic committed
121 122 123 124 125 126
  {
    fb = compTime;
    x = 75;
    workload = x;
    return;
  }
Luka Stanisic's avatar
Luka Stanisic committed
127 128 129 130

  fx = compTime;

  if (fx < fb)
Luka Stanisic's avatar
Luka Stanisic committed
131 132 133 134 135 136 137 138
  {
    if (x < b)
      c = b;
    else
      a = b;
    b = x;
    fb = fx;
  }
Luka Stanisic's avatar
Luka Stanisic committed
139
  else
Luka Stanisic's avatar
Luka Stanisic committed
140 141 142 143 144 145 146 147
  {
    if (x < b)
      a = x;
    else
      c = x;
  }

  x = (c - b > b - a) ? (int) (b + (c - b) / 2) : (int) (a + (b - a + 1) / 2);
Luka Stanisic's avatar
Luka Stanisic committed
148 149
  workload = x;
}