Skip to content

Commit ca5af63

Browse files
authored
Merge f9f2735 into bd94e19
2 parents bd94e19 + f9f2735 commit ca5af63

File tree

11 files changed

+240
-109
lines changed

11 files changed

+240
-109
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ options:
3333
-cross_parts=2..inf number of crossover points for cross individuals
3434
-l-back number for mutation. how many back gates can use this gate
3535
-status show complete generations ids and best loss
36-
-profile for profile extesion print data in format {tranzistros}-{output error}-{score};
36+
-profile for profile extesion print data in format {tranzistros}-{MAE}-{WCE}-{score};
3737
-max_duration=1..inf maximal time duration of optimalization in minutes
3838
3939
-representation={aig, gates, mig} reprezenation of circuic for CGP

include/about.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* yosys-cgploss - Create circuics using Genetic (CGP)
3+
* about program header file
4+
* @author Lukas Plevac <xpleva07@vutbr.cz>
5+
*/
6+
7+
#include <string>
8+
9+
namespace about {
10+
11+
const std::string name = "cgploss";
12+
const unsigned version = 1;
13+
const std::string authors = "Lukas Plevac <xpleva07@vutbr.cz, lukas@plevac.eu>";
14+
const std::string build_time = __DATE__ " " __TIME__;
15+
const int optimalization = __OPTIMIZE_SIZE__;
16+
17+
18+
/**
19+
* @brief Print help informations using logger function
20+
* @param logger logger for print text to output
21+
*/
22+
void print_help(void (*logger)(const char *, ...));
23+
}

include/convert.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ mapper_t design2genome(Design* design, representation::representation *repres) {
225225
for (auto mod : design->selected_modules()) {
226226

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

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

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

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

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

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

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

276276

277277
return mapper;

include/generation.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ namespace evolution {
2222
typedef struct {
2323
representation::representation* repres;
2424
float score;
25+
float mae;
26+
float wce;
2527
} individual_t;
2628

2729
/**
@@ -105,11 +107,11 @@ namespace evolution {
105107

106108
/**
107109
* @brief Score individual with simulation
108-
* @param individual reprezenation of individual
110+
* @param index index of individual in generation
109111
* @param config_parse config praser with port weights
110-
* @return float score
112+
* @post set .mae .wce and .score in individual
111113
*/
112-
float score_individual(representation::representation *individual, config::parse *config_parse);
114+
void score_individual(unsigned index, config::parse *config_parse);
113115

114116
/**
115117
* @brief replicate individual (copy individual to generation)

include/genome.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#define DUMMY_GENE_TYPE 0 // if of dummy gene
2020
#define MAX_INPUTS 3 // maximal size of inputs array in gene
2121
#define IO_ID_T_UNUSED 0xFFFFFFFF // id of unused input
22+
#define TO_REAL_INPUT(IN) (IN - 2) //convert input index in geneme to real index
23+
#define TO_GENOME_INPUT(IN) (IN + 2) //convert real input index to genome input index
2224

2325
namespace genome {
2426
typedef uint32_t io_id_t;

include/simulation.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#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}
2323
#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}
2424
#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}
25+
#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}
26+
2527

2628
//macro for set variant to vector by variant index
2729
#define SET_VARIANTS_BITS(VEC, X) { \
@@ -61,9 +63,10 @@ namespace simulation {
6163
/**
6264
* @brief Get number of one bits in vector
6365
* @param vec vestor for operatiom
66+
* @param limit number of bits to count (example: first 8bits)
6467
* @return unsigned count of bits
6568
*/
66-
unsigned bits_count(io_t vec);
69+
unsigned bits_count(io_t vec, unsigned limit);
6770

6871
/**
6972
* @brief Return maximal error per one variant

src/about.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/**
2+
* yosys-cgploss - Create circuics using Genetic (CGP)
3+
* about program implementation file
4+
* @author Lukas Plevac <xpleva07@vutbr.cz>
5+
*/
6+
7+
#include "about.h"
8+
9+
namespace about {
10+
void print_help(void (*logger)(const char *, ...)) {
11+
logger("%s V%d\n", about::name.c_str(), about::version);
12+
logger("Yosys extension for aproximate circuits using genetic algoritms.\n\n");
13+
logger("Build %s with O%d\n", about::build_time.c_str(), about::optimalization);
14+
logger("Authors: %s\n\n", about::authors.c_str());
15+
logger("Using: %s [options]\n", about::name.c_str());
16+
logger("Options:\n");
17+
logger("-wire-test test load and save part, do not use CGP only load and save [DEBUG]\n");
18+
logger("-save_individuals=file create debug file with all individuals [DEBUG]\n");
19+
logger("-ports_weights=file ports weights file\n");
20+
logger("-selection_size=size size of selected individuals on end of generation\n");
21+
logger("-generation_size=size number of individuals in generation\n");
22+
logger("-max_one_error=0..inf maximal accepted error of circuic (one combination - WCE)\n");
23+
logger("-max_abs_error=num maximal accepted abs error of circuic (all combinations - MAE)\n");
24+
logger("-generations=count count of generations\n");
25+
logger("-mutations_count=count number of mutation for center of normal distribution\n");
26+
logger("-mutations_count_sigma=num sigma for normal distribution\n");
27+
logger("-parents=1..2 number of parents for kid\n");
28+
logger("-power_accuracy_ratio=0..1 float number for loss (1 - power_accuracy_ratio) * abs_error + power_accuracy_ratio * power_loss\n");
29+
logger("-cross_parts=2..inf number of crossover points for cross individuals\n");
30+
logger("-l-back=num number for mutation. how many back gates can use this gate \n");
31+
logger("-status show complete generations ids and best loss\n");
32+
logger("-profile for profile extesion print data in format {tranzistros}-{MAE}-{WCE}-{score};\n");
33+
logger("-max_duration=1..inf maximal time duration of optimalization in minutes\n");
34+
logger("-representation={aig, gates, mig} reprezenation of circuic for CGP\n\n");
35+
logger("Example ports weights file:\n");
36+
logger("# example comment\n");
37+
logger("# Generic weights\n");
38+
logger("\\sum: msb-first\n");
39+
logger("\\spi_data: lsb-first\n\n");
40+
logger("# Custom multi-bits port LSB [3], ..., MSB [0]\n");
41+
logger("\\sum2: 1, 2, 4, 8\n\n");
42+
logger("# Custom one-bits port\n");
43+
logger("\\sum3 : 100\n\n");
44+
}
45+
}

src/generation.cpp

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -77,66 +77,85 @@ namespace evolution {
7777
return (a.score < b.score);
7878
}
7979

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

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

87-
for (unsigned i = 0; i <= individual->chromosome->last_input; i++) {
88-
SET_VARIANTS_BITS(test_circuic[i].vec, i);
89-
SET_VARIANTS_BITS(reference_circuic[i].vec, i);
86+
std::vector<simulation::io_t> xor_outputs(this->individuals[index].repres->chromosome->wire_out.size());
87+
std::vector<simulation::io_t> test_circuic(this->individuals[index].repres->chromosome->size());
88+
std::vector<simulation::io_t> reference_circuic(this->reference->chromosome->size());
89+
std::vector<unsigned> variant_counter(this->individuals[index].repres->chromosome->last_input + 2);
90+
91+
// set const inputs
92+
SET_VECTOR_TO(test_circuic[0].vec, VARIANTS_BITS_ALL0);
93+
SET_VECTOR_TO(test_circuic[1].vec, VARIANTS_BITS_ALL1);
94+
SET_VECTOR_TO(reference_circuic[0].vec, VARIANTS_BITS_ALL0);
95+
SET_VECTOR_TO(reference_circuic[1].vec, VARIANTS_BITS_ALL1);
96+
97+
// set varaible inputs
98+
for (unsigned i = TO_GENOME_INPUT(0); i <= this->individuals[index].repres->chromosome->last_input; i++) {
99+
SET_VARIANTS_BITS(test_circuic[i].vec, TO_REAL_INPUT(i));
100+
SET_VARIANTS_BITS(reference_circuic[i].vec, TO_REAL_INPUT(i));
90101
}
91102

92103
unsigned total_error = 0;
93104
bool done = false;
94105

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

99110
do {
100-
individual->simulate(test_circuic);
111+
this->individuals[index].repres->simulate(test_circuic);
101112
this->reference->simulate(reference_circuic);
102113

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

110-
if (simulation::one_max_loss(xor_outputs, individual->chromosome->wire_out, config_parse) > this->max_one_loss) {
111-
return INFINITY;
122+
//WCE
123+
auto current_wce = simulation::one_max_loss(xor_outputs, this->individuals[index].repres->chromosome->wire_out, config_parse);
124+
if (this->individuals[index].wce < current_wce) {
125+
this->individuals[index].wce = current_wce;
126+
127+
if (current_wce > this->max_one_loss) {
128+
this->individuals[index].score = INFINITY;
129+
return;
130+
}
112131
}
113132

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

117137
if (variant_counter[i] == 0) {
118-
test_circuic[i].vec = ~test_circuic[i].vec;
119-
reference_circuic[i].vec = ~reference_circuic[i].vec;
138+
test_circuic[TO_GENOME_INPUT(i)].vec = ~test_circuic[TO_GENOME_INPUT(i)].vec;
139+
reference_circuic[TO_GENOME_INPUT(i)].vec = ~reference_circuic[TO_GENOME_INPUT(i)].vec;
120140

121-
if (i == individual->chromosome->last_input) {
122-
if (variant_counter[individual->chromosome->last_input + 1]) {
141+
if (TO_GENOME_INPUT(i) == this->individuals[index].repres->chromosome->last_input) {
142+
if (variant_counter[TO_REAL_INPUT(this->individuals[index].repres->chromosome->last_input + 1)]) {
123143
done = true;
124144
}
125145

126-
variant_counter[individual->chromosome->last_input + 1]++;
146+
variant_counter[TO_REAL_INPUT(this->individuals[index].repres->chromosome->last_input + 1)]++;
127147
}
128148
}
129149
}
130150
} while (!done);
131151

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

135-
if (abs_error > this->max_abs_loss) {
136-
return INFINITY;
154+
if (this->individuals[index].mae > this->max_abs_loss) {
155+
this->individuals[index].score = INFINITY;
156+
} else {
157+
this->individuals[index].score = (1 - this->power_accuracy_ratio) * this->individuals[index].mae + this->power_accuracy_ratio * this->individuals[index].repres->power_loss();
137158
}
138-
139-
return (1 - this->power_accuracy_ratio) * abs_error + this->power_accuracy_ratio * individual->power_loss();
140159
}
141160

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

151-
this->individuals[i].score = this->score_individual(this->individuals[i].repres, config_parse);
170+
this->score_individual(i, config_parse);
152171
}
153172

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

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

166185
return this->individuals.size() - 1;
167186
}

0 commit comments

Comments
 (0)