259 if (p.nHidden.size() != 1 && p.nHidden.size() != p.nMLP) {
260 B2FATAL(
"Number of nHidden lists should be 1 or " << p.nMLP);
263 if (p.outputScale.size() != 1 && p.outputScale.size() != p.nMLP) {
264 B2FATAL(
"Number of outputScale lists should be 1 or " << p.nMLP);
267 unsigned short nTarget =
static_cast<unsigned short>(p.targetresult);
269 B2FATAL(
"No outputs! Turn on targetresult.");
272 for (
unsigned iScale = 0; iScale < p.outputScale.size(); ++iScale) {
273 if (p.outputScale.at(iScale).size() != 2 * nTarget) {
274 B2FATAL(
"outputScale should be exactly " << 2 * nTarget <<
" values");
282 auto check_size = [&](
const auto & v,
const char* name) {
283 const size_t s = v.size();
284 if (s != 1 && s !=
static_cast<size_t>(p.nMLP)) {
285 B2FATAL(std::string(name) +
" size (" + std::to_string(s)
286 +
") != 1 and != nMLP (" + std::to_string(p.nMLP) +
")");
291 check_size(p.i_cdc_sector,
"i_cdc_sector");
292 check_size(p.i_ecl_sector,
"i_ecl_sector");
293 check_size(p.nHidden,
"nHidden");
294 check_size(p.outputScale,
"outputScale");
297 check_size(p.total_bit_bias,
"total_bit_bias");
298 check_size(p.int_bit_bias,
"int_bit_bias");
299 check_size(p.is_signed_bias,
"is_signed_bias");
300 check_size(p.rounding_bias,
"rounding_bias");
301 check_size(p.saturation_bias,
"saturation_bias");
304 check_size(p.total_bit_accum,
"total_bit_accum");
305 check_size(p.int_bit_accum,
"int_bit_accum");
306 check_size(p.is_signed_accum,
"is_signed_accum");
307 check_size(p.rounding_accum,
"rounding_accum");
308 check_size(p.saturation_accum,
"saturation_accum");
311 check_size(p.total_bit_weight,
"total_bit_weight");
312 check_size(p.int_bit_weight,
"int_bit_weight");
313 check_size(p.is_signed_weight,
"is_signed_weight");
314 check_size(p.rounding_weight,
"rounding_weight");
315 check_size(p.saturation_weight,
"saturation_weight");
318 check_size(p.total_bit_relu,
"total_bit_relu");
319 check_size(p.int_bit_relu,
"int_bit_relu");
320 check_size(p.is_signed_relu,
"is_signed_relu");
321 check_size(p.rounding_relu,
"rounding_relu");
322 check_size(p.saturation_relu,
"saturation_relu");
325 check_size(p.total_bit,
"total_bit");
326 check_size(p.int_bit,
"int_bit");
327 check_size(p.is_signed,
"is_signed");
328 check_size(p.rounding,
"rounding");
329 check_size(p.saturation,
"saturation");
332 check_size(p.W_input,
"W_input");
333 check_size(p.I_input,
"I_input");
334 check_size(p.W_input_layer,
"W_input_layer");
335 check_size(p.I_input_layer,
"I_input_layer");
344 for (
unsigned iMLP = 0; iMLP < p.nMLP; ++iMLP) {
347 auto pick = [&](
const auto & container) ->
const auto& {
348 return (container.size() == 1) ? container.at(0) : container.at(iMLP);
351 unsigned short i_cdc =
static_cast<unsigned short>(pick(p.i_cdc_sector));
352 unsigned short i_ecl =
static_cast<unsigned short>(pick(p.i_ecl_sector));
353 unsigned short nInput =
static_cast<unsigned short>(i_cdc + i_ecl);
356 const vector<float>& nhidden = pick(p.nHidden);
357 vector<unsigned short> nNodes = { nInput };
359 for (
unsigned iHid = 0; iHid < nhidden.size(); ++iHid) {
360 if (p.multiplyHidden) {
361 nNodes.push_back(
static_cast<unsigned short>(nhidden.at(iHid) * nNodes.at(0)));
363 nNodes.push_back(
static_cast<unsigned short>(nhidden.at(iHid)));
367 nNodes.push_back(nTarget);
368 unsigned short targetVars =
static_cast<unsigned short>(p.targetresult);
370 const vector<float>& outputScale = pick(p.outputScale);
372 GRLMLP grlmlp_temp(nNodes, targetVars, outputScale);
376 grlmlp_temp.set_int_bit_bias(pick(p.int_bit_bias));
377 grlmlp_temp.set_is_signed_bias(pick(p.is_signed_bias));
378 grlmlp_temp.set_rounding_bias(pick(p.rounding_bias));
379 grlmlp_temp.set_saturation_bias(pick(p.saturation_bias));
382 grlmlp_temp.set_total_bit_accum(pick(p.total_bit_accum));
383 grlmlp_temp.set_int_bit_accum(pick(p.int_bit_accum));
384 grlmlp_temp.set_is_signed_accum(pick(p.is_signed_accum));
385 grlmlp_temp.set_rounding_accum(pick(p.rounding_accum));
386 grlmlp_temp.set_saturation_accum(pick(p.saturation_accum));
389 grlmlp_temp.set_total_bit_weight(pick(p.total_bit_weight));
390 grlmlp_temp.set_int_bit_weight(pick(p.int_bit_weight));
391 grlmlp_temp.set_is_signed_weight(pick(p.is_signed_weight));
392 grlmlp_temp.set_rounding_weight(pick(p.rounding_weight));
393 grlmlp_temp.set_saturation_weight(pick(p.saturation_weight));
396 grlmlp_temp.set_total_bit_relu(pick(p.total_bit_relu));
397 grlmlp_temp.set_int_bit_relu(pick(p.int_bit_relu));
398 grlmlp_temp.set_is_signed_relu(pick(p.is_signed_relu));
399 grlmlp_temp.set_rounding_relu(pick(p.rounding_relu));
400 grlmlp_temp.set_saturation_relu(pick(p.saturation_relu));
403 grlmlp_temp.set_total_bit(pick(p.total_bit));
404 grlmlp_temp.set_int_bit(pick(p.int_bit));
405 grlmlp_temp.set_is_signed(pick(p.is_signed));
406 grlmlp_temp.set_rounding(pick(p.rounding));
407 grlmlp_temp.set_saturation(pick(p.saturation));
410 grlmlp_temp.set_W_input(pick(p.W_input));
411 grlmlp_temp.set_I_input(pick(p.I_input));
414 grlmlp_temp.set_I_input_layer(pick(p.I_input_layer));
416 m_MLPs.push_back(std::move(grlmlp_temp));
426 vector<float> weights = expert.get_weights();
427 vector<float> bias = expert.get_bias();
428 vector<int> total_bit_bias = expert.get_total_bit_bias();
429 vector<int> int_bit_bias = expert.get_int_bit_bias();
430 vector<bool> is_signed_bias = expert.get_is_signed_bias();
431 vector<int> rounding_bias = expert.get_rounding_bias();
432 vector<int> saturation_bias = expert.get_saturation_bias();
433 vector<int> total_bit_accum = expert.get_total_bit_accum();
434 vector<int> int_bit_accum = expert.get_int_bit_accum();
435 vector<bool> is_signed_accum = expert.get_is_signed_accum();
436 vector<int> rounding_accum = expert.get_rounding_accum();
437 vector<int> saturation_accum = expert.get_saturation_accum();
438 vector<int> total_bit_weight = expert.get_total_bit_weight();
439 vector<int> int_bit_weight = expert.get_int_bit_weight();
440 vector<bool> is_signed_weight = expert.get_is_signed_weight();
441 vector<int> rounding_weight = expert.get_rounding_weight();
442 vector<int> saturation_weight = expert.get_saturation_weight();
443 vector<int> total_bit_relu = expert.get_total_bit_relu();
444 vector<int> int_bit_relu = expert.get_int_bit_relu();
445 vector<bool> is_signed_relu = expert.get_is_signed_relu();
446 vector<int> rounding_relu = expert.get_rounding_relu();
447 vector<int> saturation_relu = expert.get_saturation_relu();
448 vector<int> total_bit = expert.get_total_bit();
449 vector<int> int_bit = expert.get_int_bit();
450 vector<bool> is_signed = expert.get_is_signed();
451 vector<int> rounding = expert.get_rounding();
452 vector<int> saturation = expert.get_saturation();
453 vector<vector<int>> W_input = expert.get_W_input();
454 vector<vector<int>> I_input = expert.get_I_input();
456 vector<vector<int>> W_input_layer = expert.get_W_input_layer();
457 vector<vector<int>> I_input_layer = expert.get_I_input_layer();
460 vector<float> layerinput = input;
468 for (
size_t i = 0; i < layerinput.size(); ++i) {
470 layerinput.at(i) = sim_ap_fixed(layerinput.at(i), 13, 13,
true, 3, 2,
475 const auto& w_layer = W_input_layer.at(0);
476 const auto& i_layer = I_input_layer.at(0);
479 for (
size_t i = 0; i < layerinput.size(); ++i) {
481 layerinput.at(i) = sim_ap_fixed(layerinput.at(i), w_layer.at(i), i_layer.at(i),
true, 1, 2, 0);
485 vector<float> layeroutput = {};
486 unsigned num_layers = expert.get_number_of_layers();
488 unsigned num_total_neurons = 0;
490 for (
unsigned iw_layer = 0; iw_layer < num_layers - 1; iw_layer++) {
492 unsigned num_neurons = expert.get_number_of_nodes_layer(iw_layer + 1);
494 layeroutput.assign(num_neurons, 0.);
495 layeroutput.shrink_to_fit();
498 for (
unsigned io = 0; io < num_neurons; ++io) {
499 float bias_raw = bias.at(io + num_total_neurons);
500 float bias_fixed = sim_ap_fixed(bias_raw, total_bit_bias.at(iw_layer), int_bit_bias.at(iw_layer), is_signed_bias.at(iw_layer),
501 rounding_bias.at(iw_layer), saturation_bias.at(iw_layer), 0);
502 float bias_contrib = sim_ap_fixed(bias_fixed, total_bit_accum.at(iw_layer), int_bit_accum.at(iw_layer),
503 is_signed_accum.at(iw_layer),
504 rounding_accum.at(iw_layer), saturation_accum.at(iw_layer), 0);
505 layeroutput.at(io) = bias_contrib;
507 num_total_neurons += num_neurons;
510 unsigned num_inputs = layerinput.size();
512 for (
unsigned ii = 0; ii < num_inputs; ++ii) {
513 float input_val = layerinput.at(ii);
514 for (
unsigned io = 0; io < num_neurons; ++io) {
515 float weight_raw = weights.at(iw);
516 float weight_fixed = sim_ap_fixed(weight_raw, total_bit_weight.at(iw_layer), int_bit_weight.at(iw_layer),
517 is_signed_weight.at(iw_layer),
518 rounding_weight.at(iw_layer), saturation_weight.at(iw_layer), 0);
519 float product = input_val * weight_fixed;
520 float contrib = sim_ap_fixed(product, total_bit_accum.at(iw_layer), int_bit_accum.at(iw_layer), is_signed_accum.at(iw_layer),
521 rounding_accum.at(iw_layer), saturation_accum.at(iw_layer), 0);
522 layeroutput.at(io) = sim_ap_fixed(layeroutput.at(io) + contrib, total_bit_accum.at(iw_layer), int_bit_accum.at(iw_layer),
523 is_signed_accum.at(iw_layer), rounding_accum.at(iw_layer), saturation_accum.at(iw_layer), 0);
529 if (iw_layer < num_layers - 2) {
531 for (
unsigned io = 0; io < num_neurons; ++io) {
532 float fixed_val = sim_ap_fixed(layeroutput.at(io), total_bit.at(iw_layer), int_bit.at(iw_layer), is_signed.at(iw_layer), 0,
533 saturation.at(iw_layer), 0);
534 float relu_val = (fixed_val > 0) ? fixed_val : 0;
535 layeroutput.at(io) = sim_ap_fixed(relu_val, total_bit_relu.at(iw_layer), int_bit_relu.at(iw_layer), is_signed_relu.at(iw_layer),
536 rounding_relu.at(iw_layer), saturation_relu.at(iw_layer), 0);
540 layerinput.assign(num_neurons, 0);
541 layerinput.shrink_to_fit();
543 for (
unsigned i = 0; i < num_neurons; ++i) {
547 if (W_input.at(iw_layer).at(i) == 0) {
548 layerinput.at(i) = 0.0f;
550 const bool iq_is_signed = (iw_layer != 3);
551 layerinput.at(i) = sim_ap_fixed(layeroutput.at(i), W_input.at(iw_layer).at(i), I_input.at(iw_layer).at(i), iq_is_signed, 1, 2, 0);
557 vector<float> final_output(10, 0.0f);
558 for (
unsigned io = 0; io < 10; ++io) {
559 final_output.at(io) = sim_ap_fixed(layeroutput.at(io), 19, 10,
true, 3, 2, 0);
565 return vector<float>(10, 0.0f);