From 66c7f67b96fc5c4a14b96369349c737e4aadfb66 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 13 May 2024 21:31:28 -0700 Subject: [PATCH] New command "resub_core". --- src/aig/gia/giaSupps.c | 100 ++++++++++++- src/base/abci/abc.c | 88 +++++++++++ src/base/io/ioResub.h | 322 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 508 insertions(+), 2 deletions(-) create mode 100644 src/base/io/ioResub.h diff --git a/src/aig/gia/giaSupps.c b/src/aig/gia/giaSupps.c index 894e26b7d0..0d95997b83 100644 --- a/src/aig/gia/giaSupps.c +++ b/src/aig/gia/giaSupps.c @@ -20,6 +20,7 @@ #include "aig/gia/gia.h" #include "base/main/mainInt.h" +#include "base/io/ioResub.h" #include "misc/util/utilTruth.h" #include "misc/extra/extra.h" #include "misc/vec/vecHsh.h" @@ -185,6 +186,50 @@ Supp_Man_t * Supp_ManCreate( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * Supp_ManInit( p ); return p; } +int Supp_DeriveLines2( Supp_Man_t * p ) +{ + assert( Vec_WrdSize(p->vSims) % p->nWords == 0 ); + int n, nDivWords = Abc_Bit6WordNum( Vec_WrdSize(p->vSims) / p->nWords ); + for ( n = 0; n < 2; n++ ) + { + p->vDivs[n] = Vec_WrdStart( 64*p->nWords*nDivWords ); + p->vPats[n] = Vec_WrdStart( 64*p->nWords*nDivWords ); + Abc_TtCopy( Vec_WrdArray(p->vDivs[n]), Vec_WrdArray(p->vSims), Vec_WrdSize(p->vSims), !n ); + Extra_BitMatrixTransposeP( p->vDivs[n], p->nWords, p->vPats[n], nDivWords ); + } + return nDivWords; +} +Supp_Man_t * Supp_ManCreate2( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vSims, Vec_Int_t * vWeights, int nWords, int nIters, int nRounds ) +{ + Supp_Man_t * p = ABC_CALLOC( Supp_Man_t, 1 ); + assert( Vec_WrdSize(vSims)%nWords == 0 ); + p->nIters = nIters; + p->nRounds = nRounds; + p->nWords = nWords; + p->vIsfs = vIsfs; + p->vCands = Vec_IntStartNatural( Vec_WrdSize(vSims)/nWords ); + p->vWeights = NULL; + p->vSims = vSims; + p->vSimsC = NULL; + p->pGia = NULL; + // computed data + p->nDivWords = Supp_DeriveLines2( p ); + p->vMatrix = Vec_PtrAlloc( 100 ); + p->vMask = Vec_WrdAlloc( 100 ); + p->vRowTemp = Vec_WrdStart( 64*p->nDivWords ); + p->vCosts = Vec_IntStart( Vec_IntSize(p->vCands) ); + p->pHash = Hsh_VecManStart( 1000 ); + p->vSFuncs = Vec_WrdAlloc( 1000 ); + p->vSStarts = Vec_IntAlloc( 1000 ); + p->vSCount = Vec_IntAlloc( 1000 ); + p->vSPairs = Vec_IntAlloc( 1000 ); + p->vSolutions = Vec_WecStart( 16 ); + p->vTemp = Vec_IntAlloc( 10 ); + p->vTempSets = Vec_IntAlloc( 10 ); + p->vTempPairs = Vec_IntAlloc( 10 ); + Supp_ManInit( p ); + return p; +} void Supp_ManCleanMatrix( Supp_Man_t * p ) { Vec_Wrd_t * vTemp; int i; @@ -214,6 +259,8 @@ void Supp_ManDelete( Supp_Man_t * p ) Vec_IntFreeP( &p->vTemp ); Vec_IntFreeP( &p->vTempSets ); Vec_IntFreeP( &p->vTempPairs ); + if ( p->vSims == NULL ) + Vec_IntFreeP( &p->vCands ); ABC_FREE( p ); } int Supp_ManMemory( Supp_Man_t * p ) @@ -870,7 +917,11 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * int i, r, iSet, iBest = -1; abctime clk = Abc_Clock(); Vec_Int_t * vRes = NULL; - Supp_Man_t * p = Supp_ManCreate( vIsfs, vCands, vWeights, vSims, vSimsC, nWords, pGia, nIters, nRounds ); + Supp_Man_t * p; + if ( vCands ) + p = Supp_ManCreate( vIsfs, vCands, vWeights, vSims, vSimsC, nWords, pGia, nIters, nRounds ); + else + p = Supp_ManCreate2( vIsfs, vSims, NULL, nWords, nIters, nRounds ); if ( Supp_SetFuncNum(p, 0) == 0 ) { Supp_ManDelete( p ); @@ -881,7 +932,7 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t * return vRes; } if ( fVerbose ) - printf( "\nUsing %d divisors with %d words. Problem has %d functions and %d minterm pairs.\n", + printf( "Using %d divisors with %d words. Problem has %d functions and %d minterm pairs.\n", Vec_IntSize(p->vCands), p->nWords, Supp_SetFuncNum(p, 0), Supp_SetPairNum(p, 0) ); //iBest = Supp_FindGivenOne( p ); if ( iBest == -1 ) @@ -962,6 +1013,51 @@ void Supp_ManComputeTest( Gia_Man_t * p ) Vec_IntFree( vRes ); } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Gia_Man_t * Supp_GenerateGia( Vec_Int_t * vRes, Vec_Int_t * vDivs ) +{ + int i, nAddOn = 2, nIns = Vec_IntSize(vDivs)-2; + int iLit0, iLit1, iTopLit = Vec_IntEntryLast(vRes); + assert( Vec_IntSize(vRes) > 0 ); + assert( Vec_IntSize(vRes) % 2 == 1 ); + Gia_Man_t * pNew = Gia_ManStart( 100 ); + pNew->pName = Abc_UtilStrsav( "resub" ); + for ( i = 0; i < nIns; i++ ) + Gia_ManAppendCi(pNew); + Vec_IntForEachEntryDouble( vRes, iLit0, iLit1, i ) { + if ( iLit0 < iLit1 ) + Gia_ManAppendAnd( pNew, iLit0-nAddOn, iLit1-nAddOn ); + else if ( iLit0 > iLit1 ) + Gia_ManAppendXor( pNew, iLit0-nAddOn, iLit1-nAddOn ); + else assert( 0 ); + } + Gia_ManAppendCo(pNew, iTopLit-nAddOn); + return pNew; +} +Gia_Man_t * Supp_ManSolveOne( char * pFileName, int nIters, int nRounds, int fVerbose ) +{ + Abc_RData_t * p = Abc_ReadPla( pFileName ); assert( p->nOuts == 1 ); + Vec_Int_t * vDivs = Vec_IntAlloc( 100 ); + Vec_Int_t * vRes = Supp_ManCompute( p->vSimsOut, NULL, NULL, p->vSimsIn, NULL, p->nSimWords, NULL, &vDivs, nIters, nRounds, fVerbose ); + if ( fVerbose && vDivs ) printf( "Divisors: " ), Vec_IntPrint( vDivs ); + if ( fVerbose && vRes ) printf( "Solution: " ), Vec_IntPrint( vRes ); + Gia_Man_t * pNew = vRes ? Supp_GenerateGia( vRes, vDivs ) : NULL; + Vec_IntFreeP( &vRes ); + Vec_IntFreeP( &vDivs ); + Abc_RDataStop( p ); + return pNew; +} + //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// diff --git a/src/base/abci/abc.c b/src/base/abci/abc.c index ea6f787e9e..05e105a74d 100644 --- a/src/base/abci/abc.c +++ b/src/base/abci/abc.c @@ -149,6 +149,7 @@ static int Abc_CommandRefactor ( Abc_Frame_t * pAbc, int argc, cha static int Abc_CommandRestructure ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandResubstitute ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandResubCheck ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Abc_CommandResubCore ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandRr ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandCascade ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int Abc_CommandExtract ( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -931,6 +932,7 @@ void Abc_Init( Abc_Frame_t * pAbc ) // Cmd_CommandAdd( pAbc, "Synthesis", "restructure", Abc_CommandRestructure, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "resub", Abc_CommandResubstitute, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "resub_check", Abc_CommandResubCheck, 0 ); + Cmd_CommandAdd( pAbc, "Synthesis", "resub_core", Abc_CommandResubCore, 0 ); // Cmd_CommandAdd( pAbc, "Synthesis", "rr", Abc_CommandRr, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "cascade", Abc_CommandCascade, 1 ); Cmd_CommandAdd( pAbc, "Synthesis", "extract", Abc_CommandExtract, 1 ); @@ -8408,6 +8410,91 @@ int Abc_CommandResubCheck( Abc_Frame_t * pAbc, int argc, char ** argv ) return 1; } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Abc_CommandResubCore( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern Gia_Man_t * Supp_ManSolveOne( char * pFileName, int nIters, int nRounds, int fVerbose ); + Gia_Man_t * pTemp; + int nIters = 1; + int nRounds = 1; + int fVerbose = 0, c; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "IRvh" ) ) != EOF ) + { + switch ( c ) + { + case 'I': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-I\" should be followed by an integer.\n" ); + goto usage; + } + nIters = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nIters < 0 ) + goto usage; + break; + case 'R': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-R\" should be followed by an integer.\n" ); + goto usage; + } + nRounds = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nRounds < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc != globalUtilOptind + 1 ) + { + Abc_Print( -1, "Input file should be given on the command line.\n" ); + return 1; + } + pTemp = Supp_ManSolveOne( argv[globalUtilOptind], nIters, nRounds, fVerbose ); + if ( pTemp ) + { + Aig_Man_t * pMan = Gia_ManToAig( pTemp, 0 ); + Abc_Ntk_t * pNtk = Abc_NtkFromAigPhase( pMan ); + Abc_FrameReplaceCurrentNetwork( pAbc, pNtk ); + Aig_ManStop( pMan ); + Gia_ManStop( pTemp ); + return 0; + } + Abc_Print( 0, "The networks is not generated.\n" ); + return 0; + +usage: + Abc_Print( -2, "usage: resub_core [-IR ] [-vh] \n" ); + Abc_Print( -2, "\t solves one instance of the resub problem\n" ); + Abc_Print( -2, "\t-I num : the number of iterations [default = %d]\n", nIters ); + Abc_Print( -2, "\t-R num : the number of rounds in each iteration [default = %d]\n", nRounds ); + Abc_Print( -2, "\t-v : toggle verbose printout [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + Abc_Print( -2, "\t : resub problem file name\n"); + return 1; +} + + + /**Function************************************************************* Synopsis [] @@ -14811,6 +14898,7 @@ int Abc_CommandTest( Abc_Frame_t * pAbc, int argc, char ** argv ) } */ //Gia_ManTestProblem(); + //Abc_ReadPlaTest( "resub2.pla" ); return 0; usage: Abc_Print( -2, "usage: test [-CKDNM] [-aovwh] \n" ); diff --git a/src/base/io/ioResub.h b/src/base/io/ioResub.h new file mode 100644 index 0000000000..06c3d24baa --- /dev/null +++ b/src/base/io/ioResub.h @@ -0,0 +1,322 @@ +/**CFile**************************************************************** + + FileName [ioResub.h] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Command processing package.] + + Synopsis [External declarations.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: ioResub.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef ABC__base__io__ioResub_h +#define ABC__base__io__ioResub_h + + +ABC_NAMESPACE_HEADER_START + + +//////////////////////////////////////////////////////////////////////// +/// INCLUDES /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// PARAMETERS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// BASIC TYPES /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Abc_RData_t_ Abc_RData_t; +struct Abc_RData_t_ +{ + int nIns; // the number of inputs + int nOuts; // the number of outputs + int nPats; // the number of patterns + int nSimWords; // the number of words needed to store the patterns + Vec_Wrd_t * vSimsIn; // input simulation signatures + Vec_Wrd_t * vSimsOut; // output simulation signatures +}; + +//////////////////////////////////////////////////////////////////////// +/// MACRO DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +extern void Extra_BitMatrixTransposeP( Vec_Wrd_t * vSimsIn, int nWordsIn, Vec_Wrd_t * vSimsOut, int nWordsOut ); + +/**Function************************************************************* + + Synopsis [File interface to read/write resub data.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline Abc_RData_t * Abc_RDataStart( int nIns, int nOuts, int nPats ) +{ + Abc_RData_t * p = ABC_CALLOC( Abc_RData_t, 1 ); + p->nIns = nIns; + p->nOuts = nOuts; + p->nPats = nPats; + p->nSimWords = Abc_Bit6WordNum(nPats); + p->vSimsIn = Vec_WrdStart( p->nIns * p->nSimWords ); + p->vSimsOut = Vec_WrdStart( 2*p->nOuts * p->nSimWords ); + return p; +} +static inline void Abc_RDataStop( Abc_RData_t * p ) +{ + Vec_WrdFree( p->vSimsIn ); + Vec_WrdFree( p->vSimsOut ); + ABC_FREE( p ); +} +static inline int Abc_ReadPlaResubParams( char * pFileName, int * pnIns, int * pnOuts, int * pnPats ) +{ + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return 0; + } + char pBuffer[100]; int iLine = 0; + *pnIns = *pnOuts = *pnPats = 0; + while ( fgets( pBuffer, 100, pFile ) != NULL ) { + iLine += (pBuffer[0] == '0' || pBuffer[0] == '1' || pBuffer[0] == '-'); + if ( pBuffer[0] != '.' ) + continue; + if ( pBuffer[1] == 'i' ) + *pnIns = atoi(pBuffer+2); + else if ( pBuffer[1] == 'o' ) + *pnOuts = atoi(pBuffer+2); + else if ( pBuffer[1] == 'p' ) + *pnPats = atoi(pBuffer+2); + else if ( pBuffer[1] == 'e' ) + break; + } + if ( *pnPats == 0 ) + *pnPats = iLine; + else if ( *pnPats != iLine ) + printf( "The number of lines in the file (%d) does not match the number listed in .p (%d).\n", iLine, *pnPats ); + fclose(pFile); + return 1; +} +static inline int Abc_ReadPlaResubData( Abc_RData_t * p, char * pFileName ) +{ + FILE * pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) { + printf( "Cannot open file \"%s\" for reading.\n", pFileName ); + return 0; + } + int i, iLine = 0, nDashes = 0, MaxLineSize = p->nIns+p->nOuts+10000; + char * pTemp, * pBuffer = ABC_ALLOC( char, MaxLineSize ); + while ( fgets( pBuffer, MaxLineSize, pFile ) != NULL ) { + if ( pBuffer[0] == '0' || pBuffer[0] == '1' || pBuffer[0] == '-' ) { + for ( pTemp = pBuffer, i = 0; *pTemp; pTemp++ ) { + if ( i < p->nIns ) { // input part + nDashes += (*pTemp == '-'); + if ( *pTemp == '1' ) + Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(p->vSimsIn, i*p->nSimWords), iLine ); + } + else { // output part + if ( *pTemp == '0' ) + Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(p->vSimsOut, (2*(i-p->nIns)+0)*p->nSimWords), iLine ); + else if ( *pTemp == '1' ) + Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(p->vSimsOut, (2*(i-p->nIns)+1)*p->nSimWords), iLine ); + else if ( *pTemp == '-' ) { + Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(p->vSimsOut, (2*(i-p->nIns)+0)*p->nSimWords), iLine ); + Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(p->vSimsOut, (2*(i-p->nIns)+1)*p->nSimWords), iLine ); + } + } + i += (*pTemp == '0' || *pTemp == '1' || *pTemp == '-'); + } + assert( i == p->nIns + p->nOuts ); + iLine++; + } + } + if ( nDashes ) + printf( "Several (%d) don't-care literals in the input part are replaced by zeros \"%s\" \n", nDashes, pFileName ); + assert ( iLine == p->nPats ); + ABC_FREE(pBuffer); + fclose(pFile); + return 1; +} +static inline Abc_RData_t * Abc_ReadPla( char * pFileName ) +{ + int nIns, nOuts, nPats; + int RetValue = Abc_ReadPlaResubParams( pFileName, &nIns, &nOuts, &nPats ); + if ( !RetValue ) return NULL; + Abc_RData_t * p = Abc_RDataStart( nIns, nOuts, nPats ); + RetValue = Abc_ReadPlaResubData( p, pFileName ); + return p; +} +static inline void Abc_WritePla( Abc_RData_t * p, char * pFileName, int fRel ) +{ + FILE * pFile = fopen( pFileName, "wb" ); int i, k; + if ( pFile == NULL ) { + printf( "Cannot open file \"%s\" for writing.\n", pFileName ); + return; + } + assert( fRel || Vec_WrdSize(p->vSimsOut) == 2*p->nOuts*p->nSimWords ); + assert( !fRel || Vec_WrdSize(p->vSimsOut) == (1 << p->nOuts)*p->nSimWords ); + fprintf( pFile, ".i %d\n", p->nIns ); + fprintf( pFile, ".o %d\n", p->nOuts ); + if ( fRel == 2 ) { + int n, iLine = 0, Count = 0; word Entry; + Vec_WrdForEachEntry( p->vSimsOut, Entry, i ) + Count += Abc_TtCountOnes(Entry); + fprintf( pFile, ".p %d\n", Count ); + for ( i = 0; i < p->nPats; i++ ) + for ( n = 0; n < (1 << p->nOuts); n++ ) { + if ( !Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsOut, n*p->nSimWords), i) ) + continue; + for ( k = 0; k < p->nIns; k++ ) + fprintf( pFile, "%d", Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsIn, k*p->nSimWords), i) ); + fprintf( pFile, " "); + for ( k = 0; k < p->nOuts; k++ ) + fprintf( pFile, "%d", (n >> k) & 1 ); + fprintf( pFile, "\n"); + iLine++; + } + assert( iLine == Count ); + } + else { + fprintf( pFile, ".p %d\n", p->nPats ); + for ( i = 0; i < p->nPats; i++ ) { + for ( k = 0; k < p->nIns; k++ ) + fprintf( pFile, "%d", Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsIn, k*p->nSimWords), i) ); + fprintf( pFile, " "); + if ( !fRel ) { // multi-output function + for ( k = 0; k < p->nOuts; k++ ) { + int Val0 = Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsOut, (2*k+0)*p->nSimWords), i); + int Val1 = Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsOut, (2*k+1)*p->nSimWords), i); + char Val = (Val0 && Val1) ? '-' : Val1 ? '1' : '0'; + fprintf( pFile, "%c", Val ); + } + } + else { // relation + for ( k = 0; k < (1 << p->nOuts); k++ ) + fprintf( pFile, "%d", Abc_InfoHasBit((unsigned *)Vec_WrdEntryP(p->vSimsOut, k*p->nSimWords), i) ); + } + fprintf( pFile, "\n"); + } + } + fprintf( pFile, ".e\n" ); + fclose(pFile); +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +static inline int Abc_RDataIsRel( Abc_RData_t * p ) +{ + assert( p->nIns < 64 ); + Vec_Wrd_t * vTransIn = Vec_WrdStart( 64*p->nSimWords ); + Extra_BitMatrixTransposeP( p->vSimsIn, p->nSimWords, vTransIn, 64*p->nSimWords ); + Vec_WrdShrink( vTransIn, p->nPats ); + Vec_WrdUniqify( vTransIn ); + int Value = Vec_WrdSize(vTransIn) < p->nPats; + Vec_WrdFree( vTransIn ); + return Value; +} +static inline Abc_RData_t * Abc_RData2Rel( Abc_RData_t * p ) +{ + assert( p->nIns < 64 ); + assert( p->nOuts < 32 ); + int w; + Vec_Wrd_t * vSimsIn2 = Vec_WrdStart( 64*p->nSimWords ); + Vec_Wrd_t * vSimsOut2 = Vec_WrdStart( 64*p->nSimWords ); + for ( w = 0; w < p->nIns; w++ ) + Abc_TtCopy( Vec_WrdEntryP(vSimsIn2, w*p->nSimWords), Vec_WrdEntryP(p->vSimsIn, w*p->nSimWords), p->nSimWords, 0 ); + for ( w = 0; w < p->nOuts; w++ ) + Abc_TtCopy( Vec_WrdEntryP(vSimsOut2, w*p->nSimWords), Vec_WrdEntryP(p->vSimsOut, (2*w+1)*p->nSimWords), p->nSimWords, 0 ); + Vec_Wrd_t * vTransIn = Vec_WrdStart( 64*p->nSimWords ); + Vec_Wrd_t * vTransOut = Vec_WrdStart( 64*p->nSimWords ); + Extra_BitMatrixTransposeP( vSimsIn2, p->nSimWords, vTransIn, 1 ); + Extra_BitMatrixTransposeP( vSimsOut2, p->nSimWords, vTransOut, 1 ); + Vec_WrdShrink( vTransIn, p->nPats ); + Vec_WrdShrink( vTransOut, p->nPats ); + Vec_Wrd_t * vTransInCopy = Vec_WrdDup(vTransIn); + Vec_WrdUniqify( vTransInCopy ); + if ( Vec_WrdSize(vTransInCopy) == p->nPats ) + printf( "This resub problem is not a relation.\n" ); + // create the relation + Abc_RData_t * pNew = Abc_RDataStart( p->nIns, 1 << (p->nOuts-1), Vec_WrdSize(vTransInCopy) ); + pNew->nOuts = p->nOuts; + int i, k, n, iLine = 0; word Entry, Entry2; + Vec_WrdForEachEntry( vTransInCopy, Entry, i ) { + for ( n = 0; n < p->nIns; n++ ) + if ( (Entry >> n) & 1 ) + Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(pNew->vSimsIn, n*pNew->nSimWords), iLine ); + Vec_WrdForEachEntry( vTransIn, Entry2, k ) { + if ( Entry != Entry2 ) + continue; + Entry2 = Vec_WrdEntry( vTransOut, k ); + assert( Entry2 < (1 << p->nOuts) ); + Abc_InfoSetBit( (unsigned *)Vec_WrdEntryP(pNew->vSimsOut, Entry2*pNew->nSimWords), iLine ); + } + iLine++; + } + assert( iLine == pNew->nPats ); + Vec_WrdFree( vTransOut ); + Vec_WrdFree( vTransInCopy ); + Vec_WrdFree( vTransIn ); + Vec_WrdFree( vSimsIn2 ); + Vec_WrdFree( vSimsOut2 ); + return pNew; +} + +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +/* +void Abc_ReadPlaTest( char * pFileName ) +{ + Abc_RData_t * p = Abc_ReadPla( pFileName ); + Abc_WritePla( p, "resub_out.pla", 0 ); + Abc_RData_t * p2 = Abc_RData2Rel( p ); + Abc_WritePla( p2, "resub_out1.pla", 1 ); + Abc_WritePla( p2, "resub_out2.pla", 2 ); + Abc_RDataStop( p2 ); + Abc_RDataStop( p ); +} +*/ + +ABC_NAMESPACE_HEADER_END + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// +