From 17652cfda6fa1802e95d53bf5efe0f74feda7451 Mon Sep 17 00:00:00 2001 From: wjrforcyber Date: Wed, 25 Dec 2024 15:37:36 +0800 Subject: [PATCH 1/4] Feat(write_hmetis): Write out hMetis file format --- src/base/io/io.c | 69 ++++++++++++++++++++++++ src/base/io/ioAbc.h | 5 +- src/base/io/ioWriteHMetis.c | 101 ++++++++++++++++++++++++++++++++++++ src/base/io/module.make | 1 + 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 src/base/io/ioWriteHMetis.c diff --git a/src/base/io/io.c b/src/base/io/io.c index 3327a9dfd..97d30c1b8 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -79,6 +79,7 @@ static int IoCommandWriteCex ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteDot ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteEqn ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteGml ( Abc_Frame_t * pAbc, int argc, char **argv ); +static int IoCommandWriteHMetis ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteList ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWritePla ( Abc_Frame_t * pAbc, int argc, char **argv ); static int IoCommandWriteVerilog( Abc_Frame_t * pAbc, int argc, char **argv ); @@ -155,6 +156,7 @@ void Io_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "I/O", "write_edgelist",IoCommandWriteEdgelist, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_gml", IoCommandWriteGml, 0 ); // Cmd_CommandAdd( pAbc, "I/O", "write_list", IoCommandWriteList, 0 ); + Cmd_CommandAdd( pAbc, "I/O", "write_hmetis", IoCommandWriteHMetis, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_pla", IoCommandWritePla, 0 ); Cmd_CommandAdd( pAbc, "I/O", "write_verilog", IoCommandWriteVerilog, 0 ); // Cmd_CommandAdd( pAbc, "I/O", "write_verlib", IoCommandWriteVerLib, 0 ); @@ -3398,6 +3400,73 @@ usage: } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int IoCommandWriteHMetis( Abc_Frame_t * pAbc, int argc, char **argv ) +{ + char * pFileName; + int fVerbose; + int fSkipPo; + int c; + + fSkipPo = 1; + fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "svh" ) ) != EOF ) + { + switch ( c ) + { + case 's': + fSkipPo ^= 1; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( pAbc->pNtkCur == NULL ) + { + fprintf( pAbc->Out, "Empty network.\n" ); + return 0; + } + if ( argc != globalUtilOptind + 1 ) + goto usage; + // get the output file name + pFileName = argv[globalUtilOptind]; + // call the corresponding file writer + if ( !Abc_NtkIsStrash(pAbc->pNtkCur) ) + { + fprintf( stdout, "Writing this format is only possible for structurally hashed AIGs.\n" ); + return 1; + } + //Io_WriteAiger( pAbc->pNtkCur, pFileName, fWriteSymbols, fCompact, fUnique ); + Io_WriteHMetis( pAbc->pNtkCur, pFileName, fSkipPo, fVerbose ); + return 0; + +usage: + fprintf( pAbc->Err, "usage: write_hmetis \n" ); + fprintf( pAbc->Err, "\t writes the network in the hMetis format (https://karypis.github.io/glaros/files/sw/hmetis/manual.pdf)\n" ); + fprintf( pAbc->Err, "\t-s : skip PO as sink explictly [default = %s]\n", fSkipPo? "yes" : "no" ); + fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes" : "no" ); + fprintf( pAbc->Err, "\t-h : print the help massage\n" ); + fprintf( pAbc->Err, "\tfile : the name of the file to write\n" ); + return 1; +} + + /**Function************************************************************* diff --git a/src/base/io/ioAbc.h b/src/base/io/ioAbc.h index cf30196f2..0f3034882 100644 --- a/src/base/io/ioAbc.h +++ b/src/base/io/ioAbc.h @@ -57,7 +57,8 @@ typedef enum { IO_FILE_DOT, IO_FILE_EDIF, IO_FILE_EQN, - IO_FILE_GML, + IO_FILE_GML, + IO_FILE_HMETIS, IO_FILE_JSON, IO_FILE_LIST, IO_FILE_PLA, @@ -129,6 +130,8 @@ extern void Io_WriteEqn( Abc_Ntk_t * pNtk, char * pFileName ); extern void Io_WriteEdgelist( Abc_Ntk_t * pNtk, char * pFileName, int fWriteLatches, int fBb2Wb, int fSeq , int fName); /*=== abcWriteGml.c ===========================================================*/ extern void Io_WriteGml( Abc_Ntk_t * pNtk, char * pFileName ); +/*=== abcWriteHMetis.c ===========================================================*/ +extern void Io_WriteHMetis( Abc_Ntk_t * pNtk, char * pFileName, int fSkipPo, int fVerbose ); /*=== abcWriteList.c ==========================================================*/ extern void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost ); /*=== abcWritePla.c ===========================================================*/ diff --git a/src/base/io/ioWriteHMetis.c b/src/base/io/ioWriteHMetis.c new file mode 100644 index 000000000..ebe322e81 --- /dev/null +++ b/src/base/io/ioWriteHMetis.c @@ -0,0 +1,101 @@ +/**CFile**************************************************************** + + FileName [ioWriteHMetis.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Command processing package.] + + Synopsis [Procedures to write hMetis format developed by + George Karypis and Vipin Kumar from the University of +Minnesota(https://karypis.github.io/glaros/files/sw/hmetis/manual.pdf)] + + Author [Jingren Wang] + + Affiliation [] + + Date [Ver. 1.0. Started - December 16, 2006.] + + Revision [] + +***********************************************************************/ +#include "base/abc/abc.h" +#include "ioAbc.h" +#include "misc/vec/vecInt.h" +#include "misc/vec/vecPtr.h" + + +ABC_NAMESPACE_IMPL_START + +void Io_WriteHMetis( Abc_Ntk_t * pNtk, char * pFileName, int fSkipPo, int fVerbose) +{ + Abc_Obj_t * pObj; + Abc_Obj_t * pFanout; + int i, j; + Vec_Int_t * vHyperEdgeEachWrite; + int Entry; + // check that the network is valid + assert( Abc_NtkIsStrash( pNtk ) && Abc_NtkIsComb( pNtk )); + + FILE * pFHMetis = fopen( pFileName, "wb" ); + Vec_Ptr_t * vHyperEdges = Vec_PtrAlloc(1000); + if ( pFHMetis == NULL ) + { + fprintf( stdout, "Io_WriteHMetis(): Cannot open the output file \"%s\".\n", pFileName ); + ABC_FREE(pFHMetis); + return; + } + + //show pi/po/and number + if ( fVerbose ) + { + Abc_Print( 1, "Writing hMetis file \"%s\" with %d nodes (%d pi, %d po, %d and nodes).\n", pFileName, Abc_NtkObjNum(pNtk), Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk), Abc_NtkNodeNum(pNtk) ); + } + + Abc_NtkForEachObj( pNtk, pObj, i ) + { + Vec_Int_t * vHyperEdgeEach = Vec_IntAlloc(20); + //push the node itself, which is a source node + Vec_IntPush(vHyperEdgeEach, Abc_ObjId(pObj)); + //iterate through all the fanouts(sink) of the node + if( !Abc_ObjIsCo(pObj) ) + { + Abc_ObjForEachFanout(pObj, pFanout, j) + { + Vec_IntPush(vHyperEdgeEach, Abc_ObjId(pFanout)); + } + } + else{ + if ( fSkipPo ) + { + continue; + } + Vec_IntPush(vHyperEdgeEach, Abc_ObjId(Abc_ObjFanin0(pObj))); + } + Vec_PtrPush(vHyperEdges, vHyperEdgeEach); + } + + //write the number of hyperedges and the number of vertices + fprintf(pFHMetis, "%d %d\n", Vec_PtrSize(vHyperEdges), Abc_NtkObjNum(pNtk)); + //write the hyperedges + Vec_PtrForEachEntry(Vec_Int_t *, vHyperEdges, vHyperEdgeEachWrite, i) + { + Vec_IntForEachEntry(vHyperEdgeEachWrite, Entry, j) + { + if (j == Vec_IntSize(vHyperEdgeEachWrite) - 1) + { + fprintf(pFHMetis, "%d", Entry); + } + else + { + fprintf(pFHMetis, "%d ", Entry); + } + } + fprintf(pFHMetis, "\n"); + } + fprintf( pFHMetis, "\nThis file was written by ABC on %s\n", Extra_TimeStamp() ); + fprintf( pFHMetis, "For information about hMetis format, refer to %s\n", "https://karypis.github.io/glaros/files/sw/hmetis/manual.pdf" ); + Vec_PtrFreeFree(vHyperEdges); +} + +ABC_NAMESPACE_IMPL_END \ No newline at end of file diff --git a/src/base/io/module.make b/src/base/io/module.make index d80642134..19f9fa2d2 100644 --- a/src/base/io/module.make +++ b/src/base/io/module.make @@ -26,6 +26,7 @@ SRC += src/base/io/io.c \ src/base/io/ioWriteEqn.c \ src/base/io/ioWriteEdgelist.c \ src/base/io/ioWriteGml.c \ + src/base/io/ioWriteHMetis.c \ src/base/io/ioWriteList.c \ src/base/io/ioWritePla.c \ src/base/io/ioWriteVerilog.c \ From 47e4e23bc55141c66ba01cae11be03aab642ca42 Mon Sep 17 00:00:00 2001 From: wjrforcyber Date: Wed, 25 Dec 2024 15:43:50 +0800 Subject: [PATCH 2/4] Fix(write_hmetis): Comments should be start with % --- src/base/io/ioWriteHMetis.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/base/io/ioWriteHMetis.c b/src/base/io/ioWriteHMetis.c index ebe322e81..293dc7207 100644 --- a/src/base/io/ioWriteHMetis.c +++ b/src/base/io/ioWriteHMetis.c @@ -93,8 +93,9 @@ void Io_WriteHMetis( Abc_Ntk_t * pNtk, char * pFileName, int fSkipPo, int fVerbo } fprintf(pFHMetis, "\n"); } - fprintf( pFHMetis, "\nThis file was written by ABC on %s\n", Extra_TimeStamp() ); - fprintf( pFHMetis, "For information about hMetis format, refer to %s\n", "https://karypis.github.io/glaros/files/sw/hmetis/manual.pdf" ); + //comments should be started with "%" in hMetis format + fprintf( pFHMetis, "\n%%This file was written by ABC on %s\n", Extra_TimeStamp() ); + fprintf( pFHMetis, "%%For information about hMetis format, refer to %s\n", "https://karypis.github.io/glaros/files/sw/hmetis/manual.pdf" ); Vec_PtrFreeFree(vHyperEdges); } From 7a5a0ad8b3c1a6284524e032dacf23784518e10e Mon Sep 17 00:00:00 2001 From: wjrforcyber Date: Thu, 26 Dec 2024 11:27:24 +0800 Subject: [PATCH 3/4] Refactor(Compile): For MSVS build --- abclib.dsp | 4 ++++ src/base/io/ioWriteHMetis.c | 6 +----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/abclib.dsp b/abclib.dsp index 559d59d2a..88e5e87f6 100644 --- a/abclib.dsp +++ b/abclib.dsp @@ -691,6 +691,10 @@ SOURCE=.\src\base\io\ioWriteGml.c # End Source File # Begin Source File +SOURCE=.\src\base\io\ioWriteHMetis.c +# End Source File +# Begin Source File + SOURCE=.\src\base\io\ioWriteList.c # End Source File # Begin Source File diff --git a/src/base/io/ioWriteHMetis.c b/src/base/io/ioWriteHMetis.c index 293dc7207..fa4d3d76d 100644 --- a/src/base/io/ioWriteHMetis.c +++ b/src/base/io/ioWriteHMetis.c @@ -19,15 +19,11 @@ Minnesota(https://karypis.github.io/glaros/files/sw/hmetis/manual.pdf)] Revision [] ***********************************************************************/ -#include "base/abc/abc.h" #include "ioAbc.h" -#include "misc/vec/vecInt.h" -#include "misc/vec/vecPtr.h" - ABC_NAMESPACE_IMPL_START -void Io_WriteHMetis( Abc_Ntk_t * pNtk, char * pFileName, int fSkipPo, int fVerbose) +void Io_WriteHMetis( Abc_Ntk_t * pNtk, char * pFileName, int fSkipPo, int fVerbose ) { Abc_Obj_t * pObj; Abc_Obj_t * pFanout; From 0dff4dbc4b919817ef6c29b05cf2902330f687b7 Mon Sep 17 00:00:00 2001 From: wjrforcyber Date: Thu, 26 Dec 2024 13:54:55 +0800 Subject: [PATCH 4/4] Feat(write_hmetis): Add weight on hyperedges and format --- src/base/io/io.c | 11 +++-- src/base/io/ioAbc.h | 2 +- src/base/io/ioWriteHMetis.c | 99 +++++++++++++++++++++---------------- 3 files changed, 65 insertions(+), 47 deletions(-) diff --git a/src/base/io/io.c b/src/base/io/io.c index 97d30c1b8..364d82d0b 100644 --- a/src/base/io/io.c +++ b/src/base/io/io.c @@ -3416,18 +3416,23 @@ int IoCommandWriteHMetis( Abc_Frame_t * pAbc, int argc, char **argv ) char * pFileName; int fVerbose; int fSkipPo; + int fWeightEdges; int c; fSkipPo = 1; + fWeightEdges = 0; fVerbose = 0; Extra_UtilGetoptReset(); - while ( ( c = Extra_UtilGetopt( argc, argv, "svh" ) ) != EOF ) + while ( ( c = Extra_UtilGetopt( argc, argv, "swvh" ) ) != EOF ) { switch ( c ) { case 's': fSkipPo ^= 1; break; + case 'w': + fWeightEdges ^= 1; + break; case 'v': fVerbose ^= 1; break; @@ -3452,14 +3457,14 @@ int IoCommandWriteHMetis( Abc_Frame_t * pAbc, int argc, char **argv ) fprintf( stdout, "Writing this format is only possible for structurally hashed AIGs.\n" ); return 1; } - //Io_WriteAiger( pAbc->pNtkCur, pFileName, fWriteSymbols, fCompact, fUnique ); - Io_WriteHMetis( pAbc->pNtkCur, pFileName, fSkipPo, fVerbose ); + Io_WriteHMetis( pAbc->pNtkCur, pFileName, fSkipPo, fWeightEdges, fVerbose ); return 0; usage: fprintf( pAbc->Err, "usage: write_hmetis \n" ); fprintf( pAbc->Err, "\t writes the network in the hMetis format (https://karypis.github.io/glaros/files/sw/hmetis/manual.pdf)\n" ); fprintf( pAbc->Err, "\t-s : skip PO as sink explictly [default = %s]\n", fSkipPo? "yes" : "no" ); + fprintf( pAbc->Err, "\t-w : simulate weight on hyperedges [default = %s]\n", fWeightEdges? "yes" : "no" ); fprintf( pAbc->Err, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes" : "no" ); fprintf( pAbc->Err, "\t-h : print the help massage\n" ); fprintf( pAbc->Err, "\tfile : the name of the file to write\n" ); diff --git a/src/base/io/ioAbc.h b/src/base/io/ioAbc.h index 0f3034882..77c7dc292 100644 --- a/src/base/io/ioAbc.h +++ b/src/base/io/ioAbc.h @@ -131,7 +131,7 @@ extern void Io_WriteEdgelist( Abc_Ntk_t * pNtk, char * pFileName, /*=== abcWriteGml.c ===========================================================*/ extern void Io_WriteGml( Abc_Ntk_t * pNtk, char * pFileName ); /*=== abcWriteHMetis.c ===========================================================*/ -extern void Io_WriteHMetis( Abc_Ntk_t * pNtk, char * pFileName, int fSkipPo, int fVerbose ); +extern void Io_WriteHMetis( Abc_Ntk_t * pNtk, char * pFileName, int fSkipPo, int fWeightEdges, int fVerbose ); /*=== abcWriteList.c ==========================================================*/ extern void Io_WriteList( Abc_Ntk_t * pNtk, char * pFileName, int fUseHost ); /*=== abcWritePla.c ===========================================================*/ diff --git a/src/base/io/ioWriteHMetis.c b/src/base/io/ioWriteHMetis.c index fa4d3d76d..5bb28783b 100644 --- a/src/base/io/ioWriteHMetis.c +++ b/src/base/io/ioWriteHMetis.c @@ -23,76 +23,89 @@ Minnesota(https://karypis.github.io/glaros/files/sw/hmetis/manual.pdf)] ABC_NAMESPACE_IMPL_START -void Io_WriteHMetis( Abc_Ntk_t * pNtk, char * pFileName, int fSkipPo, int fVerbose ) +void Io_WriteHMetis( Abc_Ntk_t *pNtk, char *pFileName, int fSkipPo, int fWeightEdges, int fVerbose ) { - Abc_Obj_t * pObj; - Abc_Obj_t * pFanout; + Abc_Obj_t *pObj; + Abc_Obj_t *pFanout; int i, j; - Vec_Int_t * vHyperEdgeEachWrite; - int Entry; + Vec_Int_t *vHyperEdgeEachWrite; + int iEntry; + int nHyperNodesNum = 0; // check that the network is valid - assert( Abc_NtkIsStrash( pNtk ) && Abc_NtkIsComb( pNtk )); - - FILE * pFHMetis = fopen( pFileName, "wb" ); - Vec_Ptr_t * vHyperEdges = Vec_PtrAlloc(1000); + assert( Abc_NtkIsStrash( pNtk ) && Abc_NtkIsComb( pNtk ) ); + + FILE *pFHMetis = fopen( pFileName, "wb" ); + Vec_Ptr_t *vHyperEdges = Vec_PtrAlloc( 1000 ); if ( pFHMetis == NULL ) { fprintf( stdout, "Io_WriteHMetis(): Cannot open the output file \"%s\".\n", pFileName ); - ABC_FREE(pFHMetis); + ABC_FREE( pFHMetis ); return; } - - //show pi/po/and number + + // show pi/po/and number if ( fVerbose ) { - Abc_Print( 1, "Writing hMetis file \"%s\" with %d nodes (%d pi, %d po, %d and nodes).\n", pFileName, Abc_NtkObjNum(pNtk), Abc_NtkPiNum(pNtk), Abc_NtkPoNum(pNtk), Abc_NtkNodeNum(pNtk) ); + Abc_Print( 1, "Writing hMetis file \"%s\" with %d nodes (%d pi, %d po, %d and nodes).\n", pFileName, Abc_NtkObjNum( pNtk ), Abc_NtkPiNum( pNtk ), Abc_NtkPoNum( pNtk ), Abc_NtkNodeNum( pNtk ) ); } - + Abc_NtkForEachObj( pNtk, pObj, i ) { - Vec_Int_t * vHyperEdgeEach = Vec_IntAlloc(20); - //push the node itself, which is a source node - Vec_IntPush(vHyperEdgeEach, Abc_ObjId(pObj)); - //iterate through all the fanouts(sink) of the node - if( !Abc_ObjIsCo(pObj) ) + Vec_Int_t *vHyperEdgeEach = Vec_IntAlloc( 20 ); + // push the node itself, which is a source node + Vec_IntPush( vHyperEdgeEach, Abc_ObjId( pObj ) ); + // iterate through all the fanouts(sink) of the node + if ( !Abc_ObjIsCo( pObj ) ) { - Abc_ObjForEachFanout(pObj, pFanout, j) + Abc_ObjForEachFanout( pObj, pFanout, j ) { - Vec_IntPush(vHyperEdgeEach, Abc_ObjId(pFanout)); + Vec_IntPush( vHyperEdgeEach, Abc_ObjId( pFanout ) ); } - } - else{ + } else + { if ( fSkipPo ) { continue; } - Vec_IntPush(vHyperEdgeEach, Abc_ObjId(Abc_ObjFanin0(pObj))); + Vec_IntPush( vHyperEdgeEach, Abc_ObjId( Abc_ObjFanin0( pObj ) ) ); } - Vec_PtrPush(vHyperEdges, vHyperEdgeEach); + Vec_PtrPush( vHyperEdges, vHyperEdgeEach ); } - //write the number of hyperedges and the number of vertices - fprintf(pFHMetis, "%d %d\n", Vec_PtrSize(vHyperEdges), Abc_NtkObjNum(pNtk)); - //write the hyperedges - Vec_PtrForEachEntry(Vec_Int_t *, vHyperEdges, vHyperEdgeEachWrite, i) + nHyperNodesNum = fSkipPo ? Abc_NtkObjNum( pNtk ) - Abc_NtkPoNum( pNtk ) : Abc_NtkObjNum( pNtk ); + + // write the number of hyperedges and the number of vertices + if ( fWeightEdges ) { - Vec_IntForEachEntry(vHyperEdgeEachWrite, Entry, j) - { - if (j == Vec_IntSize(vHyperEdgeEachWrite) - 1) - { - fprintf(pFHMetis, "%d", Entry); - } - else - { - fprintf(pFHMetis, "%d ", Entry); - } - } - fprintf(pFHMetis, "\n"); + fprintf( pFHMetis, "%d %d 1\n", Vec_PtrSize( vHyperEdges ), nHyperNodesNum ); + } else + { + fprintf( pFHMetis, "%d %d\n", Vec_PtrSize( vHyperEdges ), nHyperNodesNum ); } - //comments should be started with "%" in hMetis format + // write the hyperedges + Vec_PtrForEachEntry( Vec_Int_t *, vHyperEdges, vHyperEdgeEachWrite, i ) + { + if ( fWeightEdges ) + { + fprintf( pFHMetis, "%d ", Vec_IntSize( vHyperEdgeEachWrite ) ); + } + + Vec_IntForEachEntry( vHyperEdgeEachWrite, iEntry, j ) + { + if ( j == Vec_IntSize( vHyperEdgeEachWrite ) - 1 ) + { + fprintf( pFHMetis, "%d", iEntry ); + } else + { + fprintf( pFHMetis, "%d ", iEntry ); + } + } + fprintf( pFHMetis, "\n" ); + } + // comments should be started with "%" in hMetis format fprintf( pFHMetis, "\n%%This file was written by ABC on %s\n", Extra_TimeStamp() ); fprintf( pFHMetis, "%%For information about hMetis format, refer to %s\n", "https://karypis.github.io/glaros/files/sw/hmetis/manual.pdf" ); - Vec_PtrFreeFree(vHyperEdges); + Vec_PtrFreeFree( vHyperEdges ); } ABC_NAMESPACE_IMPL_END \ No newline at end of file