252 B2DEBUG(10,
"GRLNeuro::initialize: nMLP=" << p.nMLP);
258 if (p.nHidden.size() != 1 && p.nHidden.size() != p.nMLP) {
259 B2FATAL(
"Number of nHidden lists should be 1 or " << p.nMLP);
266 auto check_size = [&](
const auto & v,
const char* name) {
267 const size_t s = v.size();
268 if (s != 1 && s !=
static_cast<size_t>(p.nMLP)) {
269 B2FATAL(std::string(name) +
" size (" + std::to_string(s)
270 +
") != 1 and != nMLP (" + std::to_string(p.nMLP) +
")");
275 check_size(p.i_cdc_sector,
"i_cdc_sector");
276 check_size(p.i_ecl_sector,
"i_ecl_sector");
277 check_size(p.nHidden,
"nHidden");
278 check_size(p.nn_thres,
"nn_thres");
281 check_size(p.total_bit_bias,
"total_bit_bias");
282 check_size(p.int_bit_bias,
"int_bit_bias");
283 check_size(p.is_signed_bias,
"is_signed_bias");
284 check_size(p.rounding_bias,
"rounding_bias");
285 check_size(p.saturation_bias,
"saturation_bias");
288 check_size(p.total_bit_accum,
"total_bit_accum");
289 check_size(p.int_bit_accum,
"int_bit_accum");
290 check_size(p.is_signed_accum,
"is_signed_accum");
291 check_size(p.rounding_accum,
"rounding_accum");
292 check_size(p.saturation_accum,
"saturation_accum");
295 check_size(p.total_bit_weight,
"total_bit_weight");
296 check_size(p.int_bit_weight,
"int_bit_weight");
297 check_size(p.is_signed_weight,
"is_signed_weight");
298 check_size(p.rounding_weight,
"rounding_weight");
299 check_size(p.saturation_weight,
"saturation_weight");
302 check_size(p.total_bit_relu,
"total_bit_relu");
303 check_size(p.int_bit_relu,
"int_bit_relu");
304 check_size(p.is_signed_relu,
"is_signed_relu");
305 check_size(p.rounding_relu,
"rounding_relu");
306 check_size(p.saturation_relu,
"saturation_relu");
309 check_size(p.total_bit,
"total_bit");
310 check_size(p.int_bit,
"int_bit");
311 check_size(p.is_signed,
"is_signed");
312 check_size(p.rounding,
"rounding");
313 check_size(p.saturation,
"saturation");
316 check_size(p.W_input,
"W_input");
317 check_size(p.I_input,
"I_input");
326 for (
unsigned iMLP = 0; iMLP < p.nMLP; ++iMLP) {
329 auto pick = [&](
const auto & container) ->
const auto& {
330 return (container.size() == 1) ? container[0] : container[iMLP];
333 unsigned short i_cdc =
static_cast<unsigned short>(pick(p.i_cdc_sector));
334 unsigned short i_ecl =
static_cast<unsigned short>(pick(p.i_ecl_sector));
335 unsigned short nInput =
static_cast<unsigned short>(i_cdc + i_ecl);
338 const vector<float>& nhidden = pick(p.nHidden);
339 vector<unsigned short> nNodes = { nInput };
341 for (
unsigned iHid = 0; iHid < nhidden.size(); ++iHid) {
342 if (p.multiplyHidden) {
343 nNodes.push_back(
static_cast<unsigned short>(nhidden[iHid] * nNodes[0]));
345 nNodes.push_back(
static_cast<unsigned short>(nhidden[iHid]));
348 nNodes.push_back(
static_cast<float>(pick(p.nOutput)));
350 GRLMLP grlmlp_temp(nNodes);
354 grlmlp_temp.set_int_bit_bias(pick(p.int_bit_bias));
355 grlmlp_temp.set_is_signed_bias(pick(p.is_signed_bias));
356 grlmlp_temp.set_rounding_bias(pick(p.rounding_bias));
357 grlmlp_temp.set_saturation_bias(pick(p.saturation_bias));
360 grlmlp_temp.set_total_bit_accum(pick(p.total_bit_accum));
361 grlmlp_temp.set_int_bit_accum(pick(p.int_bit_accum));
362 grlmlp_temp.set_is_signed_accum(pick(p.is_signed_accum));
363 grlmlp_temp.set_rounding_accum(pick(p.rounding_accum));
364 grlmlp_temp.set_saturation_accum(pick(p.saturation_accum));
367 grlmlp_temp.set_total_bit_weight(pick(p.total_bit_weight));
368 grlmlp_temp.set_int_bit_weight(pick(p.int_bit_weight));
369 grlmlp_temp.set_is_signed_weight(pick(p.is_signed_weight));
370 grlmlp_temp.set_rounding_weight(pick(p.rounding_weight));
371 grlmlp_temp.set_saturation_weight(pick(p.saturation_weight));
374 grlmlp_temp.set_total_bit_relu(pick(p.total_bit_relu));
375 grlmlp_temp.set_int_bit_relu(pick(p.int_bit_relu));
376 grlmlp_temp.set_is_signed_relu(pick(p.is_signed_relu));
377 grlmlp_temp.set_rounding_relu(pick(p.rounding_relu));
378 grlmlp_temp.set_saturation_relu(pick(p.saturation_relu));
381 grlmlp_temp.set_total_bit(pick(p.total_bit));
382 grlmlp_temp.set_int_bit(pick(p.int_bit));
383 grlmlp_temp.set_is_signed(pick(p.is_signed));
384 grlmlp_temp.set_rounding(pick(p.rounding));
385 grlmlp_temp.set_saturation(pick(p.saturation));
388 grlmlp_temp.set_W_input(pick(p.W_input));
389 grlmlp_temp.set_I_input(pick(p.I_input));
394 m_MLPs.push_back(std::move(grlmlp_temp));
397 B2DEBUG(10,
"GRLNeuro::initialize finished. created "
398 <<
m_MLPs.size() <<
" MLP(s).");
407 vector<float> weights = expert.get_weights();
408 vector<float> bias = expert.get_bias();
409 vector<int> total_bit_bias = expert.get_total_bit_bias();
410 vector<int> int_bit_bias = expert.get_int_bit_bias();
411 vector<bool> is_signed_bias = expert.get_is_signed_bias();
412 vector<int> rounding_bias = expert.get_rounding_bias();
413 vector<int> saturation_bias = expert.get_saturation_bias();
414 vector<int> total_bit_accum = expert.get_total_bit_accum();
415 vector<int> int_bit_accum = expert.get_int_bit_accum();
416 vector<bool> is_signed_accum = expert.get_is_signed_accum();
417 vector<int> rounding_accum = expert.get_rounding_accum();
418 vector<int> saturation_accum = expert.get_saturation_accum();
419 vector<int> total_bit_weight = expert.get_total_bit_weight();
420 vector<int> int_bit_weight = expert.get_int_bit_weight();
421 vector<bool> is_signed_weight = expert.get_is_signed_weight();
422 vector<int> rounding_weight = expert.get_rounding_weight();
423 vector<int> saturation_weight = expert.get_saturation_weight();
424 vector<int> total_bit_relu = expert.get_total_bit_relu();
425 vector<int> int_bit_relu = expert.get_int_bit_relu();
426 vector<bool> is_signed_relu = expert.get_is_signed_relu();
427 vector<int> rounding_relu = expert.get_rounding_relu();
428 vector<int> saturation_relu = expert.get_saturation_relu();
429 vector<int> total_bit = expert.get_total_bit();
430 vector<int> int_bit = expert.get_int_bit();
431 vector<bool> is_signed = expert.get_is_signed();
432 vector<int> rounding = expert.get_rounding();
433 vector<int> saturation = expert.get_saturation();
434 vector<vector<int>> W_input = expert.get_W_input();
435 vector<vector<int>> I_input = expert.get_I_input();
439 vector<float> layerinput = input;
442 for (
size_t i = 0; i < layerinput.size(); ++i) {
444 int W_arr[24] = { 12, 12, 11, 11, 8, 8, 7, 7, 5, 6, 6, 6, 8, 8, 6, 5, 4, 5, 7, 7, 6, 4, 5, 5 };
445 int I_arr[24] = { 12, 12, 11, 11, 10, 9, 7, 7, 7, 7, 7, 7, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
447 layerinput[i] = sim_input_layer_t(layerinput[i]);
448 layerinput[i] = sim_ap_dense_0_iq(layerinput[i], W_arr[i], I_arr[i]);
450 }
else layerinput[i] = 0;
454 vector<float> layeroutput = {};
455 unsigned num_layers = expert.get_number_of_layers();
458 vector<float> final_fixed = {};
460 unsigned num_total_neurons = 0;
462 for (
unsigned i_layer = 0; i_layer < num_layers - 1; i_layer++) {
464 unsigned num_neurons = expert.get_number_of_nodes_layer(i_layer + 1);
466 layeroutput.assign(num_neurons, 0.);
467 layeroutput.shrink_to_fit();
469 for (
unsigned io = 0; io < num_neurons; ++io) {
470 float bias_raw = bias[io + num_total_neurons];
471 float bias_fixed = sim_fixed(bias_raw, total_bit_bias[i_layer], int_bit_bias[i_layer], is_signed_bias[i_layer],
472 rounding_bias[i_layer], saturation_bias[i_layer]);
473 float bias_contrib = sim_fixed(bias_fixed, total_bit_accum[i_layer], int_bit_accum[i_layer], is_signed_accum[i_layer],
474 rounding_accum[i_layer], saturation_accum[i_layer]);
475 layeroutput[io] = bias_contrib;
478 num_total_neurons += num_neurons;
481 unsigned num_inputs = layerinput.size();
482 for (
unsigned ii = 0; ii < num_inputs; ++ii) {
483 float input_val = layerinput[ii];
484 for (
unsigned io = 0; io < num_neurons; ++io) {
485 float weight_raw = weights[iw];
486 float weight_fixed = sim_fixed(weight_raw, total_bit_weight[i_layer], int_bit_weight[i_layer], is_signed_weight[i_layer],
487 rounding_weight[i_layer], saturation_weight[i_layer]);
488 float product = input_val * weight_fixed;
489 float contrib = sim_fixed(product, total_bit_accum[i_layer], int_bit_accum[i_layer], is_signed_accum[i_layer],
490 rounding_accum[i_layer], saturation_accum[i_layer]);
491 layeroutput[io] += contrib;
496 if (i_layer < num_layers - 2) {
498 for (
unsigned io = 0; io < num_neurons; ++io) {
499 float fixed_val = sim_fixed(layeroutput[io], total_bit[i_layer], int_bit[i_layer], is_signed[i_layer], rounding[i_layer],
500 saturation[i_layer]);
501 float relu_val = (fixed_val > 0) ? fixed_val : 0;
502 layeroutput[io] = sim_fixed(relu_val, total_bit_relu[i_layer], int_bit_relu[i_layer], is_signed_relu[i_layer],
503 rounding_relu[i_layer], saturation_relu[i_layer]);
509 layerinput.assign(num_neurons, 0);
510 layerinput.shrink_to_fit();
512 for (
unsigned i = 0; i < num_neurons; ++i) {
514 layerinput[i] = sim_ap_fixed(layeroutput[i], W_input[i_layer][i], I_input[i_layer][i],
false, 1, 4, 0);
518 else if (i_layer == 1) {
524 }
else if (i_layer == 2) {
534 unsigned num_final_fixed = layeroutput.size();
535 for (
unsigned io = 0; io < num_final_fixed; ++io) {
536 final_fixed.push_back(sim_result_t(layeroutput[io]));