VPR-7.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
PowerSpicedComponent.c
Go to the documentation of this file.
1 /************************* INCLUDES *********************************/
2 #include <cstring>
3 #include <cfloat>
4 #include <limits>
5 #include <algorithm>
6 
7 using namespace std;
8 
9 #include <assert.h>
10 
11 #include "util.h"
12 #include "PowerSpicedComponent.h"
13 
15  float inputs) :
16  parent(parent_), num_inputs(inputs), sorted(false), done_callibration(
17  false) {
18 
19  /* Add min/max bounding entries */
20  add_size(0);
22 }
23 
24 void PowerCallibInputs::add_size(float transistor_size, float power) {
25  PowerCallibSize * entry = new PowerCallibSize(transistor_size, power);
26  entries.push_back(entry);
27  sorted = false;
28 }
29 
31  return a->transistor_size < b->transistor_size;
32 }
33 
35  sort(entries.begin(), entries.end(), sorter_PowerCallibSize);
36  sorted = true;
37 }
38 
40  assert(entries.size() >= 2);
41 
42  for (vector<PowerCallibSize*>::iterator it = entries.begin() + 1;
43  it != entries.end() - 1; it++) {
44  float est_power = parent->component_usage(num_inputs,
45  (*it)->transistor_size);
46  (*it)->factor = (*it)->power / est_power;
47  }
48 
49  /* Set min-value placeholder */
50  entries[0]->factor = entries[1]->factor;
51 
52  /* Set max-value placeholder */
53  entries[entries.size() - 1]->factor = entries[entries.size() - 2]->factor;
54 
55  done_callibration = true;
56 }
57 
59  float transistor_size) {
60  PowerCallibSize * prev = entries[0];
61 
62  assert(sorted);
63  for (vector<PowerCallibSize*>::iterator it = entries.begin() + 1;
64  it != entries.end(); it++) {
65  if ((*it)->transistor_size > transistor_size) {
66  if (lower)
67  return prev;
68  else
69  return *it;
70  }
71  prev = *it;
72  }
73  return NULL;
74 }
75 
77  float (*usage_fn)(int num_inputs, float transistor_size)) {
78  component_usage = usage_fn;
79 
80  /* Always pad with a high and low entry */
81  add_entry(0);
82 // add_entry(std::numeric_limits<int>::max());
83  add_entry(1000000000);
84 
85  done_callibration = false;
86  sorted = true;
87 }
88 
90  PowerCallibInputs * entry = new PowerCallibInputs(this, num_inputs);
91  entries.push_back(entry);
92  return entry;
93 }
94 
96  vector<PowerCallibInputs*>::iterator it;
97 
98  for (it = entries.begin(); it != entries.end(); it++) {
99  if ((*it)->num_inputs == num_inputs) {
100  break;
101  }
102  }
103 
104  if (it == entries.end()) {
105  return add_entry(num_inputs);
106  } else {
107  return *it;
108  }
109 }
110 
112  int num_inputs) {
113  PowerCallibInputs * prev = entries[0];
114 
115  assert(sorted);
116  for (vector<PowerCallibInputs*>::iterator it = entries.begin() + 1;
117  it != entries.end(); it++) {
118  if ((*it)->num_inputs > num_inputs) {
119  if (lower) {
120  if (prev == entries[0])
121  return NULL;
122  else
123  return prev;
124  } else {
125  if (*it == entries[entries.size() - 1])
126  return NULL;
127  else
128  return *it;
129  }
130  }
131  prev = *it;
132  }
133  return NULL;
134 }
135 
136 void PowerSpicedComponent::add_data_point(int num_inputs, float transistor_size,
137  float power) {
138  assert(!done_callibration);
139  PowerCallibInputs * inputs_entry = get_entry(num_inputs);
140  inputs_entry->add_size(transistor_size, power);
141  sorted = false;
142 }
143 
145  float transistor_size) {
146 
147  PowerCallibInputs * inputs_lower;
148  PowerCallibInputs * inputs_upper;
149 
150  PowerCallibSize * size_lower;
151  PowerCallibSize * size_upper;
152 
153  float factor_lower = 0.;
154  float factor_upper = 0.;
155  float factor;
156 
157  float perc_upper;
158 
159  assert(done_callibration);
160 
161  inputs_lower = get_entry_bound(true, num_inputs);
162  inputs_upper = get_entry_bound(false, num_inputs);
163 
164  if (inputs_lower) {
165  /* Interpolation of factor between sizes for lower # inputs */
166  assert(inputs_lower->done_callibration);
167  size_lower = inputs_lower->get_entry_bound(true, transistor_size);
168  size_upper = inputs_lower->get_entry_bound(false, transistor_size);
169 
170  perc_upper = (transistor_size - size_lower->transistor_size)
171  / (size_upper->transistor_size - size_lower->transistor_size);
172  factor_lower = perc_upper * size_upper->factor
173  + (1 - perc_upper) * size_lower->factor;
174  }
175 
176  if (inputs_upper) {
177  /* Interpolation of factor between sizes for upper # inputs */
178  assert(inputs_upper->done_callibration);
179  size_lower = inputs_upper->get_entry_bound(true, transistor_size);
180  size_upper = inputs_upper->get_entry_bound(false, transistor_size);
181 
182  perc_upper = (transistor_size - size_lower->transistor_size)
183  / (size_upper->transistor_size - size_lower->transistor_size);
184  factor_upper = perc_upper * size_upper->factor
185  + (1 - perc_upper) * size_lower->factor;
186  }
187 
188  if (!inputs_lower) {
189  factor = factor_upper;
190  } else if (!inputs_upper) {
191  factor = factor_lower;
192  } else {
193  /* Interpolation of factor between inputs */
194  perc_upper =
195  ((float) (num_inputs - inputs_lower->num_inputs))
196  / ((float) (inputs_upper->num_inputs
197  - inputs_lower->num_inputs));
198  factor = perc_upper * factor_upper + (1 - perc_upper) * factor_lower;
199  }
200  return factor;
201 
202 }
203 
205  return a->num_inputs < b->num_inputs;
206 }
207 
209  sort(entries.begin(), entries.end(), sorter_PowerCallibInputs);
210 
211  for (vector<PowerCallibInputs*>::iterator it = entries.begin();
212  it != entries.end(); it++) {
213  (*it)->sort_me();
214  }
215  sorted = true;
216 }
217 
219  sort_me();
220 
221  for (vector<PowerCallibInputs*>::iterator it = entries.begin();
222  it != entries.end(); it++) {
223  (*it)->callibrate();
224  }
225  done_callibration = true;
226 }
227 
229  return done_callibration;
230 }
bool sorter_PowerCallibInputs(PowerCallibInputs *a, PowerCallibInputs *b)
float(* component_usage)(int num_inputs, float transistor_size)
PowerSpicedComponent * parent
void add_size(float transistor_size, float power=0.)
std::vector< PowerCallibInputs * > entries
PowerCallibInputs * add_entry(int num_inputs)
PowerSpicedComponent(float(*usage_fn)(int num_inputs, float transistor_size))
#define max(a, b)
Definition: graphics.c:171
PowerCallibSize * get_entry_bound(bool lower, float transistor_size)
PowerCallibInputs * get_entry(int num_inputs)
void add_data_point(int num_inputs, float transistor_size, float power)
std::vector< PowerCallibSize * > entries
PowerCallibInputs * get_entry_bound(bool lower, int num_inputs)
PowerCallibInputs(PowerSpicedComponent *parent, float num_inputs)
bool sorter_PowerCallibSize(PowerCallibSize *a, PowerCallibSize *b)
float scale_factor(int num_inputs, float transistor_size)