misc: Delete the now unnecessary create methods.
[gem5.git] / src / mem / ruby / network / fault_model / FaultModel.cc
1 /*
2 * Copyright (c) 2011 Massachusetts Institute of Technology
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 * Official Tool Website: www.mit.edu/~kaisopos/FaultModel
31 *
32 * If you use our tool for academic research, we request that you cite:
33 * Konstantinos Aisopos, Chia-Hsin Owen Chen, and Li-Shiuan Peh. Enabling
34 * System-Level Modeling of Variation-Induced Faults in Networks-on-Chip.
35 * Proceedings of the 48th Design Automation Conference (DAC'11)
36 */
37
38 // C++ includes
39 #include <cassert>
40 #include <fstream>
41 #include <iostream>
42 #include <vector>
43
44 // GEM5 includes
45 #include "FaultModel.hh"
46 #include "base/logging.hh"
47
48 using namespace std;
49
50 #define MAX(a,b) ((a > b) ? (a) : (b))
51
52
53 FaultModel::FaultModel(const Params &p) : SimObject(p)
54 {
55 // read configurations into "configurations" vector
56 // format: <buff/vc> <vcs> <10 fault types>
57 bool more_records = true;
58 for (int i = 0; more_records; i += (fields_per_conf_record)){
59 system_conf configuration;
60 configuration.buff_per_vc =
61 p.baseline_fault_vector_database[i + conf_record_buff_per_vc];
62 configuration.vcs =
63 p.baseline_fault_vector_database[i + conf_record_vcs];
64 for (int fault_index = 0; fault_index < number_of_fault_types;
65 fault_index++){
66 configuration.fault_type[fault_index] =
67 p.baseline_fault_vector_database[i +
68 conf_record_first_fault_type + fault_index] / 100;
69 }
70 configurations.push_back(configuration);
71 if (p.baseline_fault_vector_database[i+fields_per_conf_record] < 0){
72 more_records = false;
73 }
74 }
75
76 // read temperature weights into "temperature_weights" vector
77 // format: <temperature> <weight>
78 more_records = true;
79 for (int i = 0; more_records; i += (fields_per_temperature_record)){
80 int record_temperature =
81 p.temperature_weights_database[i + temperature_record_temp];
82 int record_weight =
83 p.temperature_weights_database[i + temperature_record_weight];
84 static int first_record = true;
85 if (first_record){
86 for (int temperature = 0; temperature < record_temperature;
87 temperature++){
88 temperature_weights.push_back(0);
89 }
90 first_record = false;
91 }
92 assert(record_temperature == temperature_weights.size());
93 temperature_weights.push_back(record_weight);
94 if (p.temperature_weights_database[i +
95 fields_per_temperature_record] < 0){
96 more_records = false;
97 }
98 }
99 }
100
101 string
102 FaultModel::fault_type_to_string(int ft)
103 {
104 if (ft == data_corruption__few_bits){
105 return "data_corruption__few_bits";
106 } else if (ft == data_corruption__all_bits){
107 return "data_corruption__all_bits";
108 } else if (ft == flit_conservation__flit_duplication){
109 return "flit_conservation__flit_duplication";
110 } else if (ft == flit_conservation__flit_loss_or_split){
111 return "flit_conservation__flit_loss_or_split";
112 } else if (ft == misrouting){
113 return "misrouting";
114 } else if (ft == credit_conservation__credit_generation){
115 return "credit_conservation__credit_generation";
116 } else if (ft == credit_conservation__credit_loss){
117 return "credit_conservation__credit_loss";
118 } else if (ft == erroneous_allocation__VC){
119 return "erroneous_allocation__VC";
120 } else if (ft == erroneous_allocation__switch){
121 return "erroneous_allocation__switch";
122 } else if (ft == unfair_arbitration){
123 return "unfair_arbitration";
124 } else if (ft == number_of_fault_types){
125 return "none";
126 } else {
127 return "none";
128 }
129 }
130
131
132 int
133 FaultModel::declare_router(int number_of_inputs,
134 int number_of_outputs,
135 int number_of_vcs_per_input,
136 int number_of_buff_per_data_vc,
137 int number_of_buff_per_ctrl_vc)
138 {
139 // check inputs (are they legal?)
140 if (number_of_inputs <= 0 || number_of_outputs <= 0 ||
141 number_of_vcs_per_input <= 0 || number_of_buff_per_data_vc <= 0 ||
142 number_of_buff_per_ctrl_vc <= 0){
143 fatal("Fault Model: ERROR in argument of FaultModel_declare_router!");
144 }
145 int number_of_buffers_per_vc = MAX(number_of_buff_per_data_vc,
146 number_of_buff_per_ctrl_vc);
147 int total_vcs = number_of_inputs * number_of_vcs_per_input;
148 if (total_vcs > MAX_VCs){
149 fatal("Fault Model: ERROR! Number inputs*VCs (MAX_VCs) unsupported");
150 }
151 if (number_of_buffers_per_vc > MAX_BUFFERS_per_VC){
152 fatal("Fault Model: ERROR! buffers/VC (MAX_BUFFERS_per_VC) too high");
153 }
154
155 // link the router to a DB record
156 int record_hit = -1;
157 for (int record = 0; record < configurations.size(); record++){
158 if ((configurations[record].buff_per_vc == number_of_buffers_per_vc)&&
159 (configurations[record].vcs == total_vcs)){
160 record_hit = record;
161 }
162 }
163 if (record_hit == -1){
164 panic("Fault Model: ERROR! configuration not found in DB. BUG?");
165 }
166
167 // remember the router and return its ID
168 routers.push_back(configurations[record_hit]);
169 static int router_index = 0;
170 return router_index++;
171 }
172
173 bool
174 FaultModel::fault_vector(int routerID,
175 int temperature_input,
176 float fault_vector[])
177 {
178 bool ok = true;
179
180 // is the routerID recorded?
181 if (routerID < 0 || routerID >= ((int) routers.size())){
182 warn("Fault Model: ERROR! unknown router ID argument.");
183 fatal("Fault Model: Did you enable the fault model flag)?");
184 }
185
186 // is the temperature too high/too low?
187 int temperature = temperature_input;
188 if (temperature_input >= ((int) temperature_weights.size())){
189 ok = false;
190 warn_once("Fault Model: Temperature exceeded simulated upper bound.");
191 warn_once("Fault Model: The fault model is not accurate any more.");
192 temperature = (temperature_weights.size() - 1);
193 } else if (temperature_input < 0){
194 ok = false;
195 warn_once("Fault Model: Temperature exceeded simulated lower bound.");
196 warn_once("Fault Model: The fault model is not accurate any more.");
197 temperature = 0;
198 }
199
200 // recover the router record and return its fault vector
201 for (int i = 0; i < number_of_fault_types; i++){
202 fault_vector[i] = routers[routerID].fault_type[i] *
203 ((float)temperature_weights[temperature]);
204 }
205 return ok;
206 }
207
208 bool
209 FaultModel::fault_prob(int routerID,
210 int temperature_input,
211 float *aggregate_fault_prob)
212 {
213 *aggregate_fault_prob = 1.0;
214 bool ok = true;
215
216 // is the routerID recorded?
217 if (routerID < 0 || routerID >= ((int) routers.size())){
218 warn("Fault Model: ERROR! unknown router ID argument.");
219 fatal("Fault Model: Did you enable the fault model flag)?");
220 }
221
222 // is the temperature too high/too low?
223 int temperature = temperature_input;
224 if (temperature_input >= ((int) temperature_weights.size()) ){
225 ok = false;
226 warn_once("Fault Model: Temperature exceeded simulated upper bound.");
227 warn_once("Fault Model: The fault model is not accurate any more.");
228 temperature = (temperature_weights.size()-1);
229 } else if (temperature_input < 0){
230 ok = false;
231 warn_once("Fault Model: Temperature exceeded simulated lower bound.");
232 warn_once("Fault Model: The fault model is not accurate any more.");
233 temperature = 0;
234 }
235
236 // recover the router record and return its aggregate fault probability
237 for (int i = 0; i < number_of_fault_types; i++){
238 *aggregate_fault_prob= *aggregate_fault_prob *
239 ( 1.0 - (routers[routerID].fault_type[i] *
240 ((float)temperature_weights[temperature])) );
241 }
242 *aggregate_fault_prob = 1.0 - *aggregate_fault_prob;
243 return ok;
244 }
245
246 // this function is used only for debugging purposes
247 void
248 FaultModel::print(void)
249 {
250 cout << "--- PRINTING configurations ---\n";
251 for (int record = 0; record < configurations.size(); record++){
252 cout << "(" << record << ") ";
253 cout << "VCs=" << configurations[record].vcs << " ";
254 cout << "Buff/VC=" << configurations[record].buff_per_vc << " [";
255 for (int fault_type_num = 0;
256 fault_type_num < number_of_fault_types;
257 fault_type_num++){
258 cout << (100 * configurations[record].fault_type[fault_type_num]);
259 cout << "% ";
260 }
261 cout << "]\n";
262 }
263 cout << "--- PRINTING temperature weights ---\n";
264 for (int record = 0; record < temperature_weights.size(); record++){
265 cout << "temperature=" << record << " => ";
266 cout << "weight=" << temperature_weights[record];
267 cout << "\n";
268 }
269 }