Skip to content

Commit

Permalink
Merge pull request #9 from Lukas0025/HelpAndInfo
Browse files Browse the repository at this point in the history
Help and info
  • Loading branch information
Lukas0025 authored Jun 16, 2022
2 parents bd94e19 + f9f2735 commit 128c19a
Show file tree
Hide file tree
Showing 11 changed files with 240 additions and 109 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ options:
-cross_parts=2..inf number of crossover points for cross individuals
-l-back number for mutation. how many back gates can use this gate
-status show complete generations ids and best loss
-profile for profile extesion print data in format {tranzistros}-{output error}-{score};
-profile for profile extesion print data in format {tranzistros}-{MAE}-{WCE}-{score};
-max_duration=1..inf maximal time duration of optimalization in minutes
-representation={aig, gates, mig} reprezenation of circuic for CGP
Expand Down
23 changes: 23 additions & 0 deletions include/about.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* yosys-cgploss - Create circuics using Genetic (CGP)
* about program header file
* @author Lukas Plevac <xpleva07@vutbr.cz>
*/

#include <string>

namespace about {

const std::string name = "cgploss";
const unsigned version = 1;
const std::string authors = "Lukas Plevac <xpleva07@vutbr.cz, lukas@plevac.eu>";
const std::string build_time = __DATE__ " " __TIME__;
const int optimalization = __OPTIMIZE_SIZE__;


/**
* @brief Print help informations using logger function
* @param logger logger for print text to output
*/
void print_help(void (*logger)(const char *, ...));
}
8 changes: 4 additions & 4 deletions include/convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ mapper_t design2genome(Design* design, representation::representation *repres) {
for (auto mod : design->selected_modules()) {

if (mod->processes.size() > 0) {
log("[WARNING] Skipping module %s because it contains processes.\n", log_id(mod));
warning_message("Skipping module %s because it contains processes.\n", log_id(mod));
continue;
}

Expand All @@ -247,7 +247,7 @@ mapper_t design2genome(Design* design, representation::representation *repres) {
continue;
}

log("[INFO] load: deleting output wire %u - %s from chromosome\n", output.first, output.second.wire->name.c_str());
info_message("load: deleting output wire %u - %s from chromosome\n", output.first, output.second.wire->name.c_str());
to_del.push_back(output.first);
}

Expand All @@ -260,7 +260,7 @@ mapper_t design2genome(Design* design, representation::representation *repres) {
for (auto &it : mod->wires_) {
RTLIL::Wire *wire = it.second;
if (!wire->port_output && !wire->port_input) { //is inner
log("[INFO] load: deleting inner wire %s\n", wire->name.c_str());
info_message("load: deleting inner wire %s\n", wire->name.c_str());
mod->wires_.erase(wire->name);
}

Expand All @@ -271,7 +271,7 @@ mapper_t design2genome(Design* design, representation::representation *repres) {

repres->chromosome->order(mapper.in, mapper.out);

log("[INFO] load: loaded chromosome with %u gens, %lu inputs and %lu outputs\n", repres->chromosome->size(), mapper.in.size(), mapper.out.size());
info_message("load: loaded chromosome with %u gens, %lu inputs and %lu outputs\n", repres->chromosome->size(), mapper.in.size(), mapper.out.size());


return mapper;
Expand Down
8 changes: 5 additions & 3 deletions include/generation.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ namespace evolution {
typedef struct {
representation::representation* repres;
float score;
float mae;
float wce;
} individual_t;

/**
Expand Down Expand Up @@ -105,11 +107,11 @@ namespace evolution {

/**
* @brief Score individual with simulation
* @param individual reprezenation of individual
* @param index index of individual in generation
* @param config_parse config praser with port weights
* @return float score
* @post set .mae .wce and .score in individual
*/
float score_individual(representation::representation *individual, config::parse *config_parse);
void score_individual(unsigned index, config::parse *config_parse);

/**
* @brief replicate individual (copy individual to generation)
Expand Down
2 changes: 2 additions & 0 deletions include/genome.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
#define DUMMY_GENE_TYPE 0 // if of dummy gene
#define MAX_INPUTS 3 // maximal size of inputs array in gene
#define IO_ID_T_UNUSED 0xFFFFFFFF // id of unused input
#define TO_REAL_INPUT(IN) (IN - 2) //convert input index in geneme to real index
#define TO_GENOME_INPUT(IN) (IN + 2) //convert real input index to genome input index

namespace genome {
typedef uint32_t io_id_t;
Expand Down
5 changes: 4 additions & 1 deletion include/simulation.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#define VARIANTS_BITS_G {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
#define VARIANTS_BITS_H {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
#define VARIANTS_BITS_ALL0 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
#define VARIANTS_BITS_ALL1 {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}


//macro for set variant to vector by variant index
#define SET_VARIANTS_BITS(VEC, X) { \
Expand Down Expand Up @@ -61,9 +63,10 @@ namespace simulation {
/**
* @brief Get number of one bits in vector
* @param vec vestor for operatiom
* @param limit number of bits to count (example: first 8bits)
* @return unsigned count of bits
*/
unsigned bits_count(io_t vec);
unsigned bits_count(io_t vec, unsigned limit);

/**
* @brief Return maximal error per one variant
Expand Down
45 changes: 45 additions & 0 deletions src/about.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* yosys-cgploss - Create circuics using Genetic (CGP)
* about program implementation file
* @author Lukas Plevac <xpleva07@vutbr.cz>
*/

#include "about.h"

namespace about {
void print_help(void (*logger)(const char *, ...)) {
logger("%s V%d\n", about::name.c_str(), about::version);
logger("Yosys extension for aproximate circuits using genetic algoritms.\n\n");
logger("Build %s with O%d\n", about::build_time.c_str(), about::optimalization);
logger("Authors: %s\n\n", about::authors.c_str());
logger("Using: %s [options]\n", about::name.c_str());
logger("Options:\n");
logger("-wire-test test load and save part, do not use CGP only load and save [DEBUG]\n");
logger("-save_individuals=file create debug file with all individuals [DEBUG]\n");
logger("-ports_weights=file ports weights file\n");
logger("-selection_size=size size of selected individuals on end of generation\n");
logger("-generation_size=size number of individuals in generation\n");
logger("-max_one_error=0..inf maximal accepted error of circuic (one combination - WCE)\n");
logger("-max_abs_error=num maximal accepted abs error of circuic (all combinations - MAE)\n");
logger("-generations=count count of generations\n");
logger("-mutations_count=count number of mutation for center of normal distribution\n");
logger("-mutations_count_sigma=num sigma for normal distribution\n");
logger("-parents=1..2 number of parents for kid\n");
logger("-power_accuracy_ratio=0..1 float number for loss (1 - power_accuracy_ratio) * abs_error + power_accuracy_ratio * power_loss\n");
logger("-cross_parts=2..inf number of crossover points for cross individuals\n");
logger("-l-back=num number for mutation. how many back gates can use this gate \n");
logger("-status show complete generations ids and best loss\n");
logger("-profile for profile extesion print data in format {tranzistros}-{MAE}-{WCE}-{score};\n");
logger("-max_duration=1..inf maximal time duration of optimalization in minutes\n");
logger("-representation={aig, gates, mig} reprezenation of circuic for CGP\n\n");
logger("Example ports weights file:\n");
logger("# example comment\n");
logger("# Generic weights\n");
logger("\\sum: msb-first\n");
logger("\\spi_data: lsb-first\n\n");
logger("# Custom multi-bits port LSB [3], ..., MSB [0]\n");
logger("\\sum2: 1, 2, 4, 8\n\n");
logger("# Custom one-bits port\n");
logger("\\sum3 : 100\n\n");
}
}
75 changes: 47 additions & 28 deletions src/generation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,66 +77,85 @@ namespace evolution {
return (a.score < b.score);
}

float generation::score_individual(representation::representation *individual, config::parse *config_parse) {
void generation::score_individual(unsigned index, config::parse *config_parse) {

std::vector<simulation::io_t> xor_outputs(individual->chromosome->wire_out.size());
std::vector<simulation::io_t> test_circuic(individual->chromosome->size());
std::vector<simulation::io_t> reference_circuic(this->reference->chromosome->size());
std::vector<unsigned> variant_counter(individual->chromosome->last_input + 2);
this->individuals[index].mae = 0;
this->individuals[index].wce = 0;
unsigned variants_count = 1 << TO_REAL_INPUT(this->individuals[index].repres->chromosome->last_input + 1);

for (unsigned i = 0; i <= individual->chromosome->last_input; i++) {
SET_VARIANTS_BITS(test_circuic[i].vec, i);
SET_VARIANTS_BITS(reference_circuic[i].vec, i);
std::vector<simulation::io_t> xor_outputs(this->individuals[index].repres->chromosome->wire_out.size());
std::vector<simulation::io_t> test_circuic(this->individuals[index].repres->chromosome->size());
std::vector<simulation::io_t> reference_circuic(this->reference->chromosome->size());
std::vector<unsigned> variant_counter(this->individuals[index].repres->chromosome->last_input + 2);

// set const inputs
SET_VECTOR_TO(test_circuic[0].vec, VARIANTS_BITS_ALL0);
SET_VECTOR_TO(test_circuic[1].vec, VARIANTS_BITS_ALL1);
SET_VECTOR_TO(reference_circuic[0].vec, VARIANTS_BITS_ALL0);
SET_VECTOR_TO(reference_circuic[1].vec, VARIANTS_BITS_ALL1);

// set varaible inputs
for (unsigned i = TO_GENOME_INPUT(0); i <= this->individuals[index].repres->chromosome->last_input; i++) {
SET_VARIANTS_BITS(test_circuic[i].vec, TO_REAL_INPUT(i));
SET_VARIANTS_BITS(reference_circuic[i].vec, TO_REAL_INPUT(i));
}

unsigned total_error = 0;
bool done = false;

if (ONE_SIM_VARIANTS > individual->chromosome->last_input) {
if (ONE_SIM_VARIANTS > TO_REAL_INPUT(this->individuals[index].repres->chromosome->last_input + 1)) {
done = true;
}

do {
individual->simulate(test_circuic);
this->individuals[index].repres->simulate(test_circuic);
this->reference->simulate(reference_circuic);

//Calc error using xor
unsigned i = 0;
for (auto output: individual->chromosome->wire_out) {
for (auto output: this->individuals[index].repres->chromosome->wire_out) {
xor_outputs[i].vec = test_circuic[output.first].vec ^ reference_circuic[this->reference_inverse_wire_out[output.second]].vec;
total_error += simulation::bits_count(xor_outputs[i]) * config_parse->port_weight(output.second);
total_error += simulation::bits_count(xor_outputs[i], variants_count) * config_parse->port_weight(output.second);
i++;
}

if (simulation::one_max_loss(xor_outputs, individual->chromosome->wire_out, config_parse) > this->max_one_loss) {
return INFINITY;
//WCE
auto current_wce = simulation::one_max_loss(xor_outputs, this->individuals[index].repres->chromosome->wire_out, config_parse);
if (this->individuals[index].wce < current_wce) {
this->individuals[index].wce = current_wce;

if (current_wce > this->max_one_loss) {
this->individuals[index].score = INFINITY;
return;
}
}

for (unsigned i = ONE_SIM_VARIANTS; i <= individual->chromosome->last_input; i++) {
//Update inputs for next simulation
for (unsigned i = ONE_SIM_VARIANTS; i <= TO_REAL_INPUT(this->individuals[index].repres->chromosome->last_input); i++) {
variant_counter[i] = (variant_counter[i] + 1) % (1 << (i - ONE_SIM_VARIANTS));

if (variant_counter[i] == 0) {
test_circuic[i].vec = ~test_circuic[i].vec;
reference_circuic[i].vec = ~reference_circuic[i].vec;
test_circuic[TO_GENOME_INPUT(i)].vec = ~test_circuic[TO_GENOME_INPUT(i)].vec;
reference_circuic[TO_GENOME_INPUT(i)].vec = ~reference_circuic[TO_GENOME_INPUT(i)].vec;

if (i == individual->chromosome->last_input) {
if (variant_counter[individual->chromosome->last_input + 1]) {
if (TO_GENOME_INPUT(i) == this->individuals[index].repres->chromosome->last_input) {
if (variant_counter[TO_REAL_INPUT(this->individuals[index].repres->chromosome->last_input + 1)]) {
done = true;
}

variant_counter[individual->chromosome->last_input + 1]++;
variant_counter[TO_REAL_INPUT(this->individuals[index].repres->chromosome->last_input + 1)]++;
}
}
}
} while (!done);

unsigned variants_count = 1 << (individual->chromosome->last_input + 1);
float abs_error = (float) total_error / variants_count;
this->individuals[index].mae = (float) total_error / variants_count;

if (abs_error > this->max_abs_loss) {
return INFINITY;
if (this->individuals[index].mae > this->max_abs_loss) {
this->individuals[index].score = INFINITY;
} else {
this->individuals[index].score = (1 - this->power_accuracy_ratio) * this->individuals[index].mae + this->power_accuracy_ratio * this->individuals[index].repres->power_loss();
}

return (1 - this->power_accuracy_ratio) * abs_error + this->power_accuracy_ratio * individual->power_loss();
}

void generation::selection(unsigned count, config::parse *config_parse) {
Expand All @@ -148,7 +167,7 @@ namespace evolution {
continue;
}

this->individuals[i].score = this->score_individual(this->individuals[i].repres, config_parse);
this->score_individual(i, config_parse);
}

std::sort(this->individuals.begin(), this->individuals.end(), generation::sort_individual_score_asc);
Expand All @@ -161,7 +180,7 @@ namespace evolution {
}

unsigned generation::add_individual(representation::representation *individual) {
this->individuals.push_back({individual, 0});
this->individuals.push_back({individual, 0, 0, 0});

return this->individuals.size() - 1;
}
Expand Down
Loading

0 comments on commit 128c19a

Please sign in to comment.