mirror of https://github.com/YosysHQ/abc.git
New command for bound-set evaluation.
This commit is contained in:
parent
aeef2c6692
commit
0218e3e4cb
|
|
@ -5755,6 +5755,10 @@ SOURCE=.\src\aig\gia\giaBound.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaBsFind.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\src\aig\gia\giaCCof.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
|||
|
|
@ -0,0 +1,580 @@
|
|||
/**CFile****************************************************************
|
||||
|
||||
FileName [giaBsFind.c]
|
||||
|
||||
SystemName [ABC: Logic synthesis and verification system.]
|
||||
|
||||
PackageName [Scalable AIG package.]
|
||||
|
||||
Synopsis []
|
||||
|
||||
Author [Alan Mishchenko]
|
||||
|
||||
Affiliation [UC Berkeley]
|
||||
|
||||
Date [Ver. 1.0. Started - June 20, 2005.]
|
||||
|
||||
Revision [$Id: giaBsFind.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
#include "gia.h"
|
||||
#include "misc/util/utilTruth.h"
|
||||
|
||||
ABC_NAMESPACE_IMPL_START
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// DECLARATIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// FUNCTION DEFINITIONS ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Cost function: sum of squared differences between all pairs
|
||||
int cost_sum_squares(int* subset, int K, void * pData) {
|
||||
double cost = 0;
|
||||
for (int i = 0; i < K - 1; i++) {
|
||||
for (int j = i + 1; j < K; j++) {
|
||||
int diff = subset[i] - subset[j];
|
||||
cost += diff * diff;
|
||||
}
|
||||
}
|
||||
// Normalize to be between 2 and 100
|
||||
return (int)(2.0 + (cost / (K * K)) * 0.98);
|
||||
}
|
||||
|
||||
// Compare function for qsort - for sorting individual subsets
|
||||
int compare_ints(const void* a, const void* b) {
|
||||
return *(int*)a - *(int*)b;
|
||||
}
|
||||
|
||||
// Compare function for qsort - for sorting subsets by cost
|
||||
// Subset format: [K, element1, element2, ..., elementK, cost]
|
||||
int compare_subsets_by_cost(const void* a, const void* b) {
|
||||
const int* subset_a = (const int*)a;
|
||||
const int* subset_b = (const int*)b;
|
||||
int K_a = subset_a[0];
|
||||
int K_b = subset_b[0];
|
||||
assert( K_a == K_b );
|
||||
// Cost is at position K+1 (after K and K elements)
|
||||
return subset_a[K_a + 1] - subset_b[K_b + 1];
|
||||
}
|
||||
|
||||
// Generate a random subset of K numbers from 0 to N-1
|
||||
// Format: [K, element1, element2, ..., elementK, cost]
|
||||
void generate_random_subset(int* subset, int K, int N) {
|
||||
subset[0] = K; // Store K in first position
|
||||
int count = 0;
|
||||
|
||||
// First, generate K unique random numbers
|
||||
while (count < K) {
|
||||
int num = rand() % N;
|
||||
|
||||
// Check if number already exists in subset
|
||||
int exists = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (subset[i + 1] == num) {
|
||||
exists = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists) {
|
||||
subset[count + 1] = num;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
// Then, sort the subset using bubble sort
|
||||
for (int i = 1; i < K; i++) {
|
||||
for (int j = 1; j < K - i + 1; j++) {
|
||||
if (subset[j] > subset[j + 1]) {
|
||||
int temp = subset[j];
|
||||
subset[j] = subset[j + 1];
|
||||
subset[j + 1] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create offspring from two parent subsets
|
||||
// Uses pre-allocated arrays to avoid repeated memory allocation
|
||||
void create_offspring(int* parent1, int* parent2, int* offspring, int K, int N,
|
||||
int* in_offspring, int* in_parent1, int* in_parent2, int* candidates) {
|
||||
int count = 0;
|
||||
offspring[0] = K; // Store K in first position
|
||||
|
||||
// Mark which numbers are in each parent (skip first element which is K)
|
||||
for (int i = 1; i <= K; i++) {
|
||||
in_parent1[parent1[i]] = 1;
|
||||
in_parent2[parent2[i]] = 1;
|
||||
}
|
||||
|
||||
// First, add numbers that appear in both parents
|
||||
for (int i = 0; i < N && count < K; i++) {
|
||||
if (in_parent1[i] && in_parent2[i]) {
|
||||
offspring[count + 1] = i;
|
||||
count++;
|
||||
in_offspring[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Create array of numbers that appear in exactly one parent
|
||||
int num_candidates = 0;
|
||||
|
||||
for (int i = 0; i < N; i++) {
|
||||
if ((in_parent1[i] || in_parent2[i]) && !in_offspring[i]) {
|
||||
candidates[num_candidates++] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Randomly add from candidates until we have K numbers
|
||||
while (count < K && num_candidates > 0) {
|
||||
int idx = rand() % num_candidates;
|
||||
offspring[count + 1] = candidates[idx];
|
||||
count++;
|
||||
in_offspring[candidates[idx]] = 1;
|
||||
|
||||
// Remove selected candidate
|
||||
candidates[idx] = candidates[--num_candidates];
|
||||
}
|
||||
|
||||
// Sort the offspring elements (not including the first K value)
|
||||
qsort(&offspring[1], K, sizeof(int), compare_ints);
|
||||
|
||||
// Clean up the intean arrays for next use - only clean used entries
|
||||
for (int i = 1; i <= K; i++) {
|
||||
in_parent1[parent1[i]] = 0;
|
||||
in_parent2[parent2[i]] = 0;
|
||||
}
|
||||
for (int i = 1; i <= K; i++) {
|
||||
in_offspring[offspring[i]] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Count unique subsets in a sorted array of subsets
|
||||
// Returns the number of unique subsets and prints the percentage
|
||||
int count_unique_subsets(int* sorted_subsets, int num_subsets, int subset_size, const char* label) {
|
||||
if (num_subsets == 0) return 0;
|
||||
|
||||
int unique_count = 1; // First subset is always unique
|
||||
int K = sorted_subsets[0]; // Get K from first subset
|
||||
|
||||
// Compare each subset with the previous one
|
||||
for (int i = 1; i < num_subsets; i++) {
|
||||
int* current = &sorted_subsets[i * subset_size];
|
||||
int* previous = &sorted_subsets[(i - 1) * subset_size];
|
||||
|
||||
// Compare all K elements (skip position 0 which has K, and K+1 which has cost)
|
||||
int is_different = 0;
|
||||
for (int j = 1; j <= K; j++) {
|
||||
if (current[j] != previous[j]) {
|
||||
is_different = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_different) {
|
||||
unique_count++;
|
||||
}
|
||||
}
|
||||
|
||||
double percentage = (unique_count * 100.0) / num_subsets;
|
||||
printf("%s: %d unique subsets out of %d (%.1f%%)\n",
|
||||
label, unique_count, num_subsets, percentage);
|
||||
|
||||
return unique_count;
|
||||
}
|
||||
|
||||
// Main genetic algorithm
|
||||
int genetic_subset_selection(int N, int K, int B, int L,
|
||||
int verbose,
|
||||
int (*cost_function)(int*, int, void *),
|
||||
int** best_subsets_history,
|
||||
int* iterations_used,
|
||||
void * pUserData) {
|
||||
int print_unique = 0;
|
||||
int M = B * (B - 1) / 2;
|
||||
int subset_size = K + 2; // K value + K elements + cost
|
||||
|
||||
// Allocate arrays
|
||||
int* current_generation = (int*)malloc(M * subset_size * sizeof(int));
|
||||
int* next_generation = (int*)malloc(M * subset_size * sizeof(int));
|
||||
int* all_best_subsets = (int*)calloc(B * L * subset_size, sizeof(int));
|
||||
|
||||
// Pre-allocate reusable arrays for create_offspring
|
||||
int* in_offspring = (int*)calloc(N, sizeof(int));
|
||||
int* in_parent1 = (int*)calloc(N, sizeof(int));
|
||||
int* in_parent2 = (int*)calloc(N, sizeof(int));
|
||||
int* candidates = (int*)malloc(K * 2 * sizeof(int));
|
||||
|
||||
// Generate initial population
|
||||
for (int i = 0; i < M; i++) {
|
||||
int* subset = ¤t_generation[i * subset_size];
|
||||
generate_random_subset(subset, K, N);
|
||||
// Cost function uses elements starting at position 1
|
||||
subset[K + 1] = cost_function(&subset[1], K, pUserData);
|
||||
}
|
||||
|
||||
// Sort to get best B subsets
|
||||
qsort(current_generation, M, subset_size * sizeof(int), compare_subsets_by_cost);
|
||||
if ( print_unique ) count_unique_subsets(current_generation, M, subset_size, "Initial population");
|
||||
|
||||
int best_cost = current_generation[K + 1];
|
||||
int generation = 0;
|
||||
int total_best_count = 0;
|
||||
|
||||
// Main evolutionary loop
|
||||
while (generation < L) {
|
||||
// Store best B subsets from current generation
|
||||
for (int i = 0; i < B && total_best_count < B * L; i++) {
|
||||
memcpy(&all_best_subsets[total_best_count * subset_size],
|
||||
¤t_generation[i * subset_size],
|
||||
subset_size * sizeof(int));
|
||||
total_best_count++;
|
||||
}
|
||||
|
||||
if ( verbose ) {
|
||||
printf( "Iter %d\n", generation );
|
||||
for (int i = 0; i < B; i++ ) {
|
||||
printf( "Subset %2d : {", i );
|
||||
for (int k = 0; k < K; k++ )
|
||||
printf( " %2d", (¤t_generation[i * subset_size])[k+1] );
|
||||
printf( " } " );
|
||||
printf( "Cost %2d\n", (¤t_generation[i * subset_size])[K+1] );
|
||||
}
|
||||
}
|
||||
|
||||
// Create next generation from pairs of best B subsets
|
||||
int offspring_idx = 0;
|
||||
for (int i = 0; i < B; i++) {
|
||||
for (int j = i + 1; j < B; j++) {
|
||||
int* parent1 = ¤t_generation[i * subset_size];
|
||||
int* parent2 = ¤t_generation[j * subset_size];
|
||||
int* offspring = &next_generation[offspring_idx * subset_size];
|
||||
|
||||
create_offspring(parent1, parent2, offspring, K, N,
|
||||
in_offspring, in_parent1, in_parent2, candidates);
|
||||
offspring[K + 1] = cost_function(&offspring[1], K, pUserData);
|
||||
offspring_idx++;
|
||||
}
|
||||
}
|
||||
|
||||
// Sort next generation
|
||||
qsort(next_generation, M, subset_size * sizeof(int), compare_subsets_by_cost);
|
||||
if ( print_unique ) count_unique_subsets(next_generation, M, subset_size, "Next generation");
|
||||
|
||||
generation++;
|
||||
|
||||
// Check for improvement
|
||||
int new_best_cost = next_generation[K + 1];
|
||||
if (new_best_cost >= best_cost) {
|
||||
break; // No improvement
|
||||
}
|
||||
|
||||
best_cost = new_best_cost;
|
||||
|
||||
// Swap generations
|
||||
int* temp = current_generation;
|
||||
current_generation = next_generation;
|
||||
next_generation = temp;
|
||||
}
|
||||
|
||||
// Sort all best subsets collected using qsort
|
||||
qsort(all_best_subsets, total_best_count, subset_size * sizeof(int), compare_subsets_by_cost);
|
||||
if ( print_unique ) count_unique_subsets(all_best_subsets, total_best_count, subset_size, "All best subsets");
|
||||
|
||||
if ( verbose ) {
|
||||
printf( "Final best\n" );
|
||||
for (int i = 0; i < B; i++ ) {
|
||||
printf( "Subset %2d : {", i );
|
||||
for (int k = 0; k < K; k++ )
|
||||
printf( " %2d", (&all_best_subsets[i * subset_size])[k+1] );
|
||||
printf( " } " );
|
||||
printf( "Cost %2d\n", (&all_best_subsets[i * subset_size])[K+1] );
|
||||
}
|
||||
}
|
||||
|
||||
// Free pre-allocated arrays
|
||||
free(in_offspring);
|
||||
free(in_parent1);
|
||||
free(in_parent2);
|
||||
free(candidates);
|
||||
|
||||
// Return results
|
||||
if (best_subsets_history != NULL) {
|
||||
*best_subsets_history = all_best_subsets;
|
||||
} else {
|
||||
free(all_best_subsets);
|
||||
}
|
||||
|
||||
if (iterations_used != NULL) {
|
||||
*iterations_used = generation + 1;
|
||||
}
|
||||
|
||||
free(current_generation);
|
||||
free(next_generation);
|
||||
|
||||
return best_cost;
|
||||
}
|
||||
|
||||
// Test bench
|
||||
/*
|
||||
int bs_find_test() {
|
||||
srand(time(NULL));
|
||||
|
||||
// Test parameters
|
||||
int N = 30; // Total numbers (0 to 29)
|
||||
int K = 6; // Subset size
|
||||
int B = 10; // Number of best subsets to keep
|
||||
int L = 50; // Maximum iterations
|
||||
|
||||
printf("Genetic Algorithm for Subset Selection\n");
|
||||
printf("======================================\n");
|
||||
printf("Parameters:\n");
|
||||
printf(" N (total numbers): %d\n", N);
|
||||
printf(" K (subset size): %d\n", K);
|
||||
printf(" B (best subsets): %d\n", B);
|
||||
printf(" L (max iterations): %d\n", L);
|
||||
printf("\n");
|
||||
|
||||
// Run the algorithm
|
||||
int* best_subsets_history = NULL;
|
||||
int iterations_used = 0;
|
||||
int best_cost = genetic_subset_selection(N, K, B, L, 0,
|
||||
cost_sum_squares,
|
||||
&best_subsets_history,
|
||||
&iterations_used);
|
||||
|
||||
printf("Best cost found: %d\n", best_cost);
|
||||
printf("Iterations until convergence: %d\n\n", iterations_used);
|
||||
|
||||
// Display top 5 best subsets
|
||||
printf("Top 5 best subsets:\n");
|
||||
int subset_size = K + 2;
|
||||
for (int i = 0; i < 5 && i < B * L; i++) {
|
||||
int* subset = &best_subsets_history[i * subset_size];
|
||||
if (subset[K + 1] == 0) break; // Check if cost is 0 (uninitialized)
|
||||
|
||||
printf("Subset %d: {", i + 1);
|
||||
for (int j = 1; j <= K; j++) {
|
||||
printf("%d", subset[j]);
|
||||
if (j < K) printf(", ");
|
||||
}
|
||||
printf("} - Cost: %d\n", subset[K + 1]);
|
||||
}
|
||||
|
||||
// Test with different parameters
|
||||
printf("\n\nTesting with different parameters:\n");
|
||||
printf("==================================\n");
|
||||
|
||||
// Test 1: Smaller problem
|
||||
N = 20; K = 4; B = 6; L = 30;
|
||||
free(best_subsets_history);
|
||||
best_subsets_history = NULL;
|
||||
iterations_used = 0;
|
||||
|
||||
best_cost = genetic_subset_selection(N, K, B, L, 0,
|
||||
cost_sum_squares,
|
||||
&best_subsets_history,
|
||||
&iterations_used);
|
||||
|
||||
printf("\nTest 1 - N=%d, K=%d, B=%d, L=%d\n", N, K, B, L);
|
||||
printf("Best cost: %d\n", best_cost);
|
||||
printf("Iterations until convergence: %d\n", iterations_used);
|
||||
printf("Best subset: {");
|
||||
for (int j = 1; j <= K; j++) {
|
||||
printf("%d", best_subsets_history[j]);
|
||||
if (j < K) printf(", ");
|
||||
}
|
||||
printf("}\n");
|
||||
|
||||
// Test 2: Larger problem
|
||||
N = 50; K = 8; B = 15; L = 100;
|
||||
free(best_subsets_history);
|
||||
best_subsets_history = NULL;
|
||||
iterations_used = 0;
|
||||
|
||||
best_cost = genetic_subset_selection(N, K, B, L, 0,
|
||||
cost_sum_squares,
|
||||
&best_subsets_history,
|
||||
&iterations_used);
|
||||
|
||||
printf("\nTest 2 - N=%d, K=%d, B=%d, L=%d\n", N, K, B, L);
|
||||
printf("Best cost: %d\n", best_cost);
|
||||
printf("Iterations until convergence: %d\n", iterations_used);
|
||||
printf("Best subset: {");
|
||||
for (int j = 1; j <= K; j++) {
|
||||
printf("%d", best_subsets_history[j]);
|
||||
if (j < K) printf(", ");
|
||||
}
|
||||
printf("}\n");
|
||||
|
||||
// Test 3: Test convergence speed with different B values
|
||||
printf("\n\nConvergence Speed Analysis:\n");
|
||||
printf("===========================\n");
|
||||
N = 40; K = 7; L = 100;
|
||||
|
||||
for (int B_test = 5; B_test <= 20; B_test += 5) {
|
||||
free(best_subsets_history);
|
||||
best_subsets_history = NULL;
|
||||
iterations_used = 0;
|
||||
|
||||
best_cost = genetic_subset_selection(N, K, B_test, L, 0,
|
||||
cost_sum_squares,
|
||||
&best_subsets_history,
|
||||
&iterations_used);
|
||||
|
||||
printf("B=%2d: Best cost=%3d, Iterations=%3d\n",
|
||||
B_test, best_cost, iterations_used);
|
||||
}
|
||||
|
||||
free(best_subsets_history);
|
||||
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
Vec_Wrd_t * Gia_ManBsFindStart( Gia_Man_t * pGia, int nWords )
|
||||
{
|
||||
Vec_Wrd_t * vSims = Vec_WrdStartRandom( (Gia_ManCiNum(pGia) + 1) * nWords );
|
||||
Vec_WrdFillExtra( vSims, Gia_ManObjNum(pGia) * nWords, 0 );
|
||||
Abc_TtClear( Vec_WrdArray(vSims), nWords );
|
||||
return vSims;
|
||||
}
|
||||
void Gia_ManBsFindNext( Gia_Man_t * pGia, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsOuts, int iMint )
|
||||
{
|
||||
Gia_Obj_t * pObj; int i;
|
||||
word * pSims[2], * pSim;
|
||||
Gia_ManForEachAnd( pGia, pObj, i ) {
|
||||
pSim = Vec_WrdEntryP( vSims, i * nWords );
|
||||
pSims[0] = Vec_WrdEntryP( vSims, Gia_ObjFaninId0(pObj, i) * nWords );
|
||||
pSims[1] = Vec_WrdEntryP( vSims, Gia_ObjFaninId1(pObj, i) * nWords );
|
||||
Abc_TtAndCompl( pSim, pSims[0], Gia_ObjFaninC0(pObj), pSims[1], Gia_ObjFaninC1(pObj), nWords );
|
||||
}
|
||||
Gia_ManForEachCo( pGia, pObj, i ) {
|
||||
pSim = Vec_WrdEntryP( vSimsOuts, (iMint * Gia_ManCoNum(pGia) + i) * nWords );
|
||||
pSims[0] = Vec_WrdEntryP( vSims, Gia_ObjFaninId0p(pGia, pObj) * nWords );
|
||||
Abc_TtCopy( pSim, pSims[0], nWords, Gia_ObjFaninC0(pObj) );
|
||||
}
|
||||
}
|
||||
int Gia_ManBsFindMyu( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsOuts, Vec_Int_t * vVarNums, Vec_Wrd_t * vTemp )
|
||||
{
|
||||
int nMints = 1 << Vec_IntSize(vVarNums);
|
||||
int nWordsAll = Gia_ManCoNum(p) * nWords;
|
||||
int nMyu = 0, pMyu[256], i, k, Var;
|
||||
assert( nMints <= 256 );
|
||||
assert( Vec_WrdSize(vTemp) == nWords * Vec_IntSize(vVarNums) );
|
||||
assert( Vec_WrdSize(vSimsOuts) == nMints * nWordsAll );
|
||||
Vec_IntForEachEntry( vVarNums, Var, i )
|
||||
Abc_TtCopy( Vec_WrdEntryP(vTemp, i * nWords), Vec_WrdEntryP(vSims, Gia_ManCiIdToId(p, Var) * nWords), nWords, 0 );
|
||||
for ( int m = 0; m < nMints; m++ ) {
|
||||
Vec_IntForEachEntry( vVarNums, Var, i )
|
||||
Abc_TtConst( Vec_WrdEntryP(vSims, Gia_ManCiIdToId(p, Var) * nWords), nWords, (m >> i) & 1 );
|
||||
Gia_ManBsFindNext( p, nWords, vSims, vSimsOuts, m );
|
||||
}
|
||||
Vec_IntForEachEntry( vVarNums, Var, i )
|
||||
Abc_TtCopy( Vec_WrdEntryP(vSims, Gia_ManCiIdToId(p, Var) * nWords), Vec_WrdEntryP(vTemp, i * nWords), nWords, 0 );
|
||||
for ( i = 0; i < nMints; i++ ) {
|
||||
word * pSim = Vec_WrdEntryP(vSimsOuts, nWordsAll * i);
|
||||
for ( k = 0; k < nMyu; k++ )
|
||||
if ( Abc_TtEqual(pSim, Vec_WrdEntryP(vSimsOuts, nWordsAll * pMyu[k]), nWordsAll) )
|
||||
break;
|
||||
if ( k == nMyu )
|
||||
pMyu[nMyu++] = i;
|
||||
}
|
||||
return nMyu;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct BsFind_UserData_t_ {
|
||||
Gia_Man_t * pGia;
|
||||
int nWords;
|
||||
Vec_Wrd_t * vSims;
|
||||
Vec_Wrd_t * vSimsOuts;
|
||||
Vec_Int_t * vVarNums;
|
||||
Vec_Wrd_t * vTemp;
|
||||
} BsFind_UserData_t;
|
||||
|
||||
BsFind_UserData_t * Gia_ManBsFindMyuFunctionStart( Gia_Man_t * pGia, int nWords, int nLutSize )
|
||||
{
|
||||
BsFind_UserData_t * p = ABC_CALLOC( BsFind_UserData_t, 1 );
|
||||
p->pGia = pGia;
|
||||
p->nWords = nWords;
|
||||
p->vSims = Gia_ManBsFindStart( pGia, nWords );
|
||||
p->vSimsOuts = Vec_WrdStart( (1 << nLutSize) * Gia_ManCoNum(pGia) * nWords );
|
||||
p->vVarNums = Vec_IntAlloc( nLutSize );
|
||||
p->vTemp = Vec_WrdStart( nLutSize * nWords );
|
||||
return p;
|
||||
}
|
||||
int Gia_ManBsFindMyuFunction( int * subset, int K, void * pUserData )
|
||||
{
|
||||
BsFind_UserData_t * p = (BsFind_UserData_t *)pUserData;
|
||||
Vec_IntClear( p->vVarNums );
|
||||
for ( int i = 0; i < K; i++ )
|
||||
Vec_IntPush( p->vVarNums, subset[i] );
|
||||
return Gia_ManBsFindMyu( p->pGia, p->nWords, p->vSims, p->vSimsOuts, p->vVarNums, p->vTemp );
|
||||
}
|
||||
void Gia_ManBsFindMyuFunctionStop( BsFind_UserData_t * p )
|
||||
{
|
||||
Vec_WrdFree( p->vSims );
|
||||
Vec_WrdFree( p->vSimsOuts );
|
||||
Vec_WrdFree( p->vTemp );
|
||||
Vec_IntFree( p->vVarNums );
|
||||
ABC_FREE( p );
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Gia_ManBsFindBest( Gia_Man_t * pGia, int nWords, int nLutSize, int nBest, int nIterMax, int fVerbose )
|
||||
{
|
||||
abctime clk = Abc_Clock();
|
||||
Abc_Random(1);
|
||||
BsFind_UserData_t * p = Gia_ManBsFindMyuFunctionStart( pGia, nWords, nLutSize );
|
||||
int nIters = 0, Res = genetic_subset_selection( Gia_ManCiNum(pGia), nLutSize, nBest, nIterMax, fVerbose, Gia_ManBsFindMyuFunction, NULL, &nIters, (void *)p );
|
||||
printf( "The best Myu %d was found after considering %d bound-sets in %d iterations. ", Res, nIters*nBest*(nBest-1)/2, nIters );
|
||||
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
|
||||
Gia_ManBsFindMyuFunctionStop( p );
|
||||
return Res;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
/// END OF FILE ///
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
ABC_NAMESPACE_IMPL_END
|
||||
|
||||
|
|
@ -6041,7 +6041,7 @@ Vec_Wec_t * Gia_ManCollectIntTfos( Gia_Man_t * p, Vec_Int_t * vVarNums )
|
|||
Gia_Man_t * Gia_ManDupCofs( Gia_Man_t * p, Vec_Int_t * vVarNums )
|
||||
{
|
||||
int i, iLit, nMints = 1 << Vec_IntSize(vVarNums);
|
||||
Vec_Int_t * vOutLits = Vec_IntAlloc( nMints * Gia_ManCoNum(p) );
|
||||
Vec_Int_t * vOutLits = Vec_IntStartFull( nMints * Gia_ManCoNum(p) );
|
||||
Vec_Wec_t * vTfos = Gia_ManCollectIntTfos( p, vVarNums );
|
||||
Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj;
|
||||
assert( Gia_ManRegNum(p) == 0 );
|
||||
|
|
@ -6057,7 +6057,7 @@ Gia_Man_t * Gia_ManDupCofs( Gia_Man_t * p, Vec_Int_t * vVarNums )
|
|||
Gia_ManForEachAnd( p, pObj, i )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Vec_IntPush( vOutLits, Gia_ObjFanin0Copy(pObj) );
|
||||
Vec_IntWriteEntry( vOutLits, i, Gia_ObjFanin0Copy(pObj) );
|
||||
int m, g, x, b = 0;
|
||||
for ( m = 1; m < nMints; m++ )
|
||||
{
|
||||
|
|
@ -6067,7 +6067,7 @@ Gia_Man_t * Gia_ManDupCofs( Gia_Man_t * p, Vec_Int_t * vVarNums )
|
|||
Gia_ManForEachObjVec( vNode, p, pObj, i )
|
||||
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
|
||||
Gia_ManForEachCo( p, pObj, i )
|
||||
Vec_IntPush( vOutLits, Gia_ObjFanin0Copy(pObj) );
|
||||
Vec_IntWriteEntry( vOutLits, g * Gia_ManCoNum(p) + i, Gia_ObjFanin0Copy(pObj) );
|
||||
}
|
||||
assert( Vec_IntFindMin(vOutLits) >= 0 );
|
||||
Vec_IntForEachEntry( vOutLits, iLit, i )
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ SRC += src/aig/gia/giaAig.c \
|
|||
src/aig/gia/giaBalLut.c \
|
||||
src/aig/gia/giaBalMap.c \
|
||||
src/aig/gia/giaBidec.c \
|
||||
src/aig/gia/giaBsFind.c \
|
||||
src/aig/gia/giaCCof.c \
|
||||
src/aig/gia/giaCex.c \
|
||||
src/aig/gia/giaClp.c \
|
||||
|
|
|
|||
|
|
@ -641,6 +641,7 @@ static int Abc_CommandAbc9FunAbs ( Abc_Frame_t * pAbc, int argc, cha
|
|||
static int Abc_CommandAbc9DsdInfo ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9FunTrace ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9MulFind ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9BsFind ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
static int Abc_CommandAbc9AndCare ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
||||
static int Abc_CommandAbc9Test ( Abc_Frame_t * pAbc, int argc, char ** argv );
|
||||
|
|
@ -1465,7 +1466,8 @@ void Abc_Init( Abc_Frame_t * pAbc )
|
|||
Cmd_CommandAdd( pAbc, "ABC9", "&dsdinfo", Abc_CommandAbc9DsdInfo, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&funtrace", Abc_CommandAbc9FunTrace, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&mulfind", Abc_CommandAbc9MulFind, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&andcare", Abc_CommandAbc9AndCare, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&bsfind", Abc_CommandAbc9BsFind, 0 );
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&andcare", Abc_CommandAbc9AndCare, 0 );
|
||||
|
||||
Cmd_CommandAdd( pAbc, "ABC9", "&test", Abc_CommandAbc9Test, 0 );
|
||||
|
||||
|
|
@ -57248,6 +57250,99 @@ usage:
|
|||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
||||
Description []
|
||||
|
||||
SideEffects []
|
||||
|
||||
SeeAlso []
|
||||
|
||||
***********************************************************************/
|
||||
int Abc_CommandAbc9BsFind( Abc_Frame_t * pAbc, int argc, char ** argv )
|
||||
{
|
||||
extern int Gia_ManBsFindBest( Gia_Man_t * pGia, int nWords, int nLutSize, int nBest, int nIterMax, int fVerbose );
|
||||
int c, nWords = 256, nLutSize = 6, nBest = 20, nIterMax = 10, fVerbose = 0;
|
||||
Extra_UtilGetoptReset();
|
||||
while ( ( c = Extra_UtilGetopt( argc, argv, "WKBIvh" ) ) != EOF )
|
||||
{
|
||||
switch ( c )
|
||||
{
|
||||
case 'W':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-W\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nWords = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nWords < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'K':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-K\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nLutSize = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nLutSize < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'B':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-B\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nBest = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nBest < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'I':
|
||||
if ( globalUtilOptind >= argc )
|
||||
{
|
||||
Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" );
|
||||
goto usage;
|
||||
}
|
||||
nIterMax = atoi(argv[globalUtilOptind]);
|
||||
globalUtilOptind++;
|
||||
if ( nIterMax < 0 )
|
||||
goto usage;
|
||||
break;
|
||||
case 'v':
|
||||
fVerbose ^= 1;
|
||||
break;
|
||||
case 'h':
|
||||
goto usage;
|
||||
default:
|
||||
goto usage;
|
||||
}
|
||||
}
|
||||
if ( pAbc->pGia == NULL )
|
||||
{
|
||||
Abc_Print( -1, "Abc_CommandAbc9MulFind(): There is no AIG.\n" );
|
||||
return 0;
|
||||
}
|
||||
Gia_ManBsFindBest( pAbc->pGia, nWords, nLutSize, nBest, nIterMax, fVerbose );
|
||||
return 0;
|
||||
|
||||
usage:
|
||||
Abc_Print( -2, "usage: &bsfind [-WKBI num] [-vh]\n" );
|
||||
Abc_Print( -2, "\t found a good boundset for the multi-output function\n" );
|
||||
Abc_Print( -2, "\t-W num : the number of simulation words to use [default = %d]\n", nWords );
|
||||
Abc_Print( -2, "\t-K num : the number of bound-set variables (LUT size) [default = %d]\n", nLutSize );
|
||||
Abc_Print( -2, "\t-B num : the number of best bound-sets to consider [default = %d]\n", nBest );
|
||||
Abc_Print( -2, "\t-I num : the number of refinement iterations to perform [default = %d]\n", nIterMax );
|
||||
Abc_Print( -2, "\t-v : toggles printing verbose information [default = %s]\n", fVerbose ? "yes": "no" );
|
||||
Abc_Print( -2, "\t-h : print the command usage\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**Function*************************************************************
|
||||
|
||||
Synopsis []
|
||||
|
|
|
|||
Loading…
Reference in New Issue