Files
2024-07-23 13:00:49 +03:00

138 lines
6.6 KiB
Python

import mpq_quantize
import pareto_sols
import configure_ibex
import simulate_ibex
import os
import sys
import numpy as np
def create_ibex_qnn(net, name, device, X_train, y_train, X_test, y_test, X_val = None, y_val = None,
BATCH_SIZE = 32, epochs = 20, lr = 0.0001, max_acc_drop = None):
net = net.to(device)
in_shape = mpq_quantize.net_input_size(X_train)
macc_per_layer, _ = mpq_quantize.display_model_info(net, in_shape)
train_loader, val_loader, test_loader = mpq_quantize.create_dataloaders(BATCH_SIZE, X_train, y_train, X_test, y_test,
X_val, y_val)
if isinstance(epochs, (int, float)):
tr_epochs = [epochs]
else:
tr_epochs = epochs
if isinstance(lr, (int, float)):
tr_lr = [lr]
else:
tr_lr = lr
if len(tr_epochs) != len(tr_lr):
print("Error: The lengths of 'epochs' and 'lr' are not equal.")
sys.exit(1)
print('\nFULL PRECISION MODEL TRAINING ...')
for i in range(len(tr_epochs)):
print(f'Round No{i+1}')
fp_net = mpq_quantize.fp_train(net, train_loader, val_loader, device,
epochs = tr_epochs[i], lr = tr_lr[i])
fp_accuracy = mpq_quantize.fp_evaluate(net, test_loader, device)
weights_per_layer, total_macc_opt_sorted = mpq_quantize.create_weight_confs(macc_per_layer)
if(max_acc_drop is None):
quant_net, accuracy = mpq_quantize.dse(fp_net, max_acc_drop, weights_per_layer, fp_accuracy, train_loader,
test_loader, val_loader, device, tr_epochs, tr_lr)
optimal_config = pareto_sols.pareto_space(fp_accuracy, accuracy, weights_per_layer, macc_per_layer,
total_macc_opt_sorted, name)
layer_mapping = mpq_quantize.create_layer_mapping(optimal_config)
quant_net = mpq_quantize.Quant_Model(fp_net, optimal_config, layer_mapping,
mpq_quantize.calculate_minimum(train_loader) >= 0)
quant_net = mpq_quantize.train_quant_model(quant_net, train_loader, val_loader, device, epochs, lr)
mpq_quantize.quant_net_evaluation(quant_net, test_loader, device)
else:
quant_net, optimal_config = mpq_quantize.dse(fp_net, max_acc_drop, weights_per_layer, fp_accuracy, train_loader,
test_loader, val_loader, device, tr_epochs, tr_lr)
print('\nCREATING FILES FOR SIMULATION ON IBEX CORE ...')
mode_per_layer, layer_type = configure_ibex.decide_mode(fp_net,
optimal_config, mpq_quantize.calculate_minimum(train_loader) >= 0)
int_weights, int_og_bias, int_biases, shift_biases, mul_vals, shift_vals = configure_ibex.get_int_params(quant_net)
input, padded_input, padded_w, padded_b, padded_sb_v, padded_mv, padded_sv = configure_ibex.pad_inputs_weights(quant_net,
test_loader, mode_per_layer, int_weights,
int_biases, shift_biases, mul_vals, shift_vals)
combined_input, new_int_w, new_int_b, shift_b, mul_v, shift_v = configure_ibex.concat_inputs_weights(mode_per_layer,
padded_input, padded_w, padded_b,
padded_sb_v, padded_mv, padded_sv)
optimized_path = '../inference_codes/' + name + '/optimized'
original_path = '../inference_codes/' + name + '/original'
os.makedirs(optimized_path, exist_ok = True)
os.makedirs(original_path, exist_ok = True)
configure_ibex.generate_Makefile(original_path, name)
if np.unique(layer_type)[0] =='Linear':
configure_ibex.save_1d_inputs(original_path, input)
configure_ibex.save_1d_inputs(optimized_path, combined_input)
configure_ibex.save_mlp_net_params(original_path, int_weights, int_og_bias, mul_vals, shift_vals)
configure_ibex.save_mlp_net_params(optimized_path, new_int_w, new_int_b, mul_v, shift_v, shift_b)
configure_ibex.generate_og_c_code_mlp(original_path, name, int_weights, optimal_config, layer_type)
configure_ibex.generate_opt_c_code_mlp(optimized_path, name, new_int_w, optimal_config, layer_type)
else:
configure_ibex.save_2d_inputs(original_path, input)
configure_ibex.save_2d_inputs(optimized_path, combined_input)
configure_ibex.save_cnn_net_params(original_path, int_weights, int_og_bias, mul_vals, shift_vals)
configure_ibex.save_cnn_net_params(optimized_path, new_int_w, new_int_b, mul_v, shift_v, shift_b)
cnn_details = configure_ibex.get_cnn_details(fp_net)
configure_ibex.generate_og_c_code_cnn(original_path, name, input, cnn_details, int_weights)
configure_ibex.generate_opt_c_code_cnn(optimized_path, name, combined_input, cnn_details,
new_int_w, optimal_config)
print('FINISHED ...')
if(name == 'elderly_fall'):
print('\nSIMULATING MODEL ON IBEX CORE\nUSE THE OUTPUTS TO VERIFY THAT THE RESULTS ARE CORRECT !!')
ibex_model = simulate_ibex.create_fann_model(int_weights, int_og_bias, mul_vals, shift_vals)
simulate_ibex.eval_sim_model(quant_net, ibex_model, test_loader)
elif(name == 'uci_fann_net'):
print('\nSIMULATING MODEL ON IBEX CORE\nUSE THE OUTPUTS TO VERIFY THAT THE RESULTS ARE CORRECT !!')
ibex_model = simulate_ibex.create_uci_model(int_weights, int_og_bias, mul_vals, shift_vals)
simulate_ibex.eval_sim_model(quant_net, ibex_model, test_loader)
elif(name == 'lenet5_mnist'):
print('\nSIMULATING MODEL ON IBEX CORE\nUSE THE OUTPUTS TO VERIFY THAT THE RESULTS ARE CORRECT !!')
ibex_model = simulate_ibex.create_lenet_model(int_weights, int_og_bias, mul_vals, shift_vals)
simulate_ibex.eval_sim_model(quant_net, ibex_model, test_loader)
elif(name == 'cmsis_cnn'):
print('\nSIMULATING MODEL ON IBEX CORE\nUSE THE OUTPUTS TO VERIFY THAT THE RESULTS ARE CORRECT !!')
ibex_model = simulate_ibex.create_cmsis_cnn_model(int_weights, int_og_bias, mul_vals, shift_vals)
simulate_ibex.eval_sim_model(quant_net, ibex_model, test_loader)
elif(name == 'cifar10_dws_cnn'):
print('\nSIMULATING MODEL ON IBEX CORE\nUSE THE OUTPUTS TO VERIFY THAT THE RESULTS ARE CORRECT !!')
ibex_model = simulate_ibex.create_ibex_dws_model(int_weights, int_og_bias, mul_vals, shift_vals)
simulate_ibex.eval_sim_model(quant_net, ibex_model, test_loader)