mirror of https://github.com/YosysHQ/abc.git
416 lines
13 KiB
C
416 lines
13 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [ioJson.c]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Command processing package.]
|
|
|
|
Synopsis [Procedures to read JSON.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: ioJson.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "ioAbc.h"
|
|
#include "misc/vec/vecWec.h"
|
|
#include "misc/util/utilNam.h"
|
|
#include "misc/extra/extra.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
static inline int Json_EntryIsName( int Fan ) { return Abc_LitIsCompl(Fan); }
|
|
static inline char * Json_EntryName( Abc_Nam_t * pStrs, int Fan ) { assert(Json_EntryIsName(Fan)); return Abc_NamStr( pStrs, Abc_Lit2Var(Fan) ); }
|
|
static inline Vec_Int_t * Json_EntryNode( Vec_Wec_t * vObjs, int Fan ) { assert(!Json_EntryIsName(Fan)); return Vec_WecEntry( vObjs, Abc_Lit2Var(Fan) ); }
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Writes JSON into a file.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
char * Nnc_LayerType2Str( char * pStr )
|
|
{
|
|
if ( !strcmp(pStr, "InputLayer") )
|
|
return "input ";
|
|
if ( !strcmp(pStr, "Conv2D") )
|
|
return "convo ";
|
|
if ( !strcmp(pStr, "BatchNormalization") )
|
|
return "batch ";
|
|
if ( !strcmp(pStr, "Activation") )
|
|
return "relu ";
|
|
if ( !strcmp(pStr, "Add") )
|
|
return "eltwise";
|
|
if ( !strcmp(pStr, "MaxPooling2D") )
|
|
return "pool ";
|
|
if ( !strcmp(pStr, "GlobalAveragePooling2D") )
|
|
return "pool ";
|
|
if ( !strcmp(pStr, "Dense") )
|
|
return "fullcon";
|
|
if ( !strcmp(pStr, "ZeroPadding2D") )
|
|
return "pad";
|
|
// if ( !strcmp(pStr, "InputLayer") )
|
|
// return "softmax";
|
|
return NULL;
|
|
}
|
|
|
|
void Json_Extract_rec( FILE * pFile, Abc_Nam_t * pStr, Vec_Wec_t * vObjs, Vec_Int_t * vArray, int fWrite, int * pCount )
|
|
{
|
|
int i, Entry1, Entry2;
|
|
if ( Vec_IntEntry(vArray, 0) ) // array
|
|
{
|
|
if ( Vec_IntSize(vArray) == 1 )
|
|
return;
|
|
if ( Vec_IntSize(vArray) == 2 && Json_EntryIsName(Vec_IntEntry(vArray,1)) )
|
|
{
|
|
if ( fWrite )
|
|
fprintf( pFile, "%s", Json_EntryName(pStr, Vec_IntEntry(vArray,1)) );
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
Vec_IntForEachEntryStart( vArray, Entry1, i, 1 )
|
|
{
|
|
if ( Json_EntryIsName(Entry1) )
|
|
{
|
|
int Digit = Json_EntryName(pStr, Entry1)[0];
|
|
if ( fWrite && Digit != '0' )
|
|
fprintf( pFile, "%s%s", Json_EntryName(pStr, Entry1), Digit >= '0' && Digit <= '9' ? "" : " " );
|
|
}
|
|
else
|
|
Json_Extract_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry1), fWrite, pCount );
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
else // list of pairs
|
|
{
|
|
int fHaveConfig = 0;
|
|
assert( Vec_IntSize(vArray) % 2 != 0 );
|
|
Vec_IntForEachEntryDoubleStart( vArray, Entry1, Entry2, i, 1 )
|
|
{
|
|
char * pName1 = Json_EntryIsName(Entry1) ? Json_EntryName(pStr, Entry1) : NULL;
|
|
char * pName2 = Json_EntryIsName(Entry2) ? Json_EntryName(pStr, Entry2) : NULL;
|
|
char * pName3 = pName2 ? Nnc_LayerType2Str(pName2) : NULL;
|
|
if ( pName1 == NULL )
|
|
continue;
|
|
if ( !strcmp(pName1, "class_name") )
|
|
{
|
|
if ( pName3 )
|
|
fprintf( pFile, "\n%3d : %-8s ", (*pCount)++, pName3 );
|
|
}
|
|
else if ( !strcmp(pName1, "name") )
|
|
{
|
|
if ( fHaveConfig )
|
|
fprintf( pFile, " N=%s ", pName2 ? pName2 : "???" );
|
|
}
|
|
else if ( !strcmp(pName1, "kernel_size") )
|
|
{
|
|
fprintf( pFile, " K=" );
|
|
Json_Extract_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry2), 1, pCount );
|
|
}
|
|
else if ( !strcmp(pName1, "strides") )
|
|
{
|
|
fprintf( pFile, " S=" );
|
|
Json_Extract_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry2), 1, pCount );
|
|
}
|
|
else if ( !strcmp(pName1, "filters") )
|
|
fprintf( pFile, " C=%s", pName2 );
|
|
else if ( !strcmp(pName1, "inbound_nodes") )
|
|
Json_Extract_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry2), 1, pCount );
|
|
else if ( !strcmp(pName1, "layers") )
|
|
Json_Extract_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry2), 1, pCount );
|
|
else if ( !strcmp(pName1, "config") )
|
|
{
|
|
fHaveConfig = 1;
|
|
Json_Extract_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry2), 0, pCount );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void Json_Extract( char * pFileName, Abc_Nam_t * pStr, Vec_Wec_t * vObjs )
|
|
{
|
|
int Count = 0;
|
|
FILE * pFile = fopen( pFileName, "wb" );
|
|
if ( pFile == NULL )
|
|
{
|
|
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
|
|
return;
|
|
}
|
|
fprintf( pFile, "# Data extracted from JSON file:\n" );
|
|
Json_Extract_rec( pFile, pStr, vObjs, Vec_WecEntry(vObjs, 0), 0, &Count );
|
|
fprintf( pFile, "\n" );
|
|
fclose( pFile );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Parsing.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline int Json_CharIsSpace( char c )
|
|
{
|
|
return (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == ':');
|
|
}
|
|
static inline char * Json_SkipSpaces( char * pCur )
|
|
{
|
|
while ( Json_CharIsSpace(*pCur) )
|
|
pCur++;
|
|
return pCur;
|
|
}
|
|
static inline char * Json_SkipNonSpaces( char * pCur )
|
|
{
|
|
while ( !Json_CharIsSpace(*pCur) )
|
|
pCur++;
|
|
return pCur;
|
|
}
|
|
static inline int Json_TokenCompare( char * pCur, char * pNext, char ** ppCur2, char ** ppNext2 )
|
|
{
|
|
// int i;
|
|
if ( *pCur == '\"' )
|
|
pCur++;
|
|
if ( *(pNext-1) == ',' )
|
|
pNext--;
|
|
if ( *(pNext-1) == '\"' )
|
|
pNext--;
|
|
*ppCur2 = pCur;
|
|
*ppNext2 = pNext;
|
|
// for ( i = 1; i < JSON_NUM_LINES; i++ )
|
|
// if ( !strncmp( s_Types[i].pName, pCur, pNext - pCur ) )
|
|
// return i;
|
|
return 0;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Writes JSON into a file.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Json_Write_rec( FILE * pFile, Abc_Nam_t * pStr, Vec_Wec_t * vObjs, Vec_Int_t * vArray, int Level, int fAddComma, int fSpaces )
|
|
{
|
|
int i, Entry1, Entry2, fComma;
|
|
if ( Vec_IntEntry(vArray, 0) ) // array
|
|
{
|
|
if ( Vec_IntSize(vArray) == 1 )
|
|
fprintf( pFile, "[]" );
|
|
else if ( Vec_IntSize(vArray) == 2 && Json_EntryIsName(Vec_IntEntry(vArray,1)) )
|
|
fprintf( pFile, "[ \"%s\" ]", Json_EntryName(pStr, Vec_IntEntry(vArray,1)) );
|
|
else
|
|
{
|
|
if ( fSpaces )
|
|
fprintf( pFile, "%*s", 3*(Level-1), "" );
|
|
fprintf( pFile, "[\n" );
|
|
Vec_IntForEachEntryStart( vArray, Entry1, i, 1 )
|
|
{
|
|
fComma = (i < Vec_IntSize(vArray) - 1);
|
|
if ( Json_EntryIsName(Entry1) )
|
|
fprintf( pFile, "%*s\"%s\"%s\n", 3*Level, "", Json_EntryName(pStr, Entry1), fComma ? ",":"" );
|
|
else
|
|
Json_Write_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry1), Level+1, fComma, 1 );
|
|
}
|
|
fprintf( pFile, "%*s]", 3*(Level-1), "" );
|
|
}
|
|
fprintf( pFile, "%s\n", fAddComma ? ",":"" );
|
|
}
|
|
else // list of pairs
|
|
{
|
|
if ( fSpaces )
|
|
fprintf( pFile, "%*s", 3*(Level-1), "" );
|
|
fprintf( pFile, "{\n" );
|
|
assert( Vec_IntSize(vArray) % 2 != 0 );
|
|
Vec_IntForEachEntryDoubleStart( vArray, Entry1, Entry2, i, 1 )
|
|
{
|
|
fComma = (i < Vec_IntSize(vArray) - 3);
|
|
if ( Json_EntryIsName(Entry1) )
|
|
fprintf( pFile, "%*s\"%s\"", 3*Level, "", Json_EntryName(pStr, Entry1) );
|
|
else
|
|
Json_Write_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry1), Level+1, 0, 1 );
|
|
fprintf( pFile, " : " );
|
|
if ( Json_EntryIsName(Entry2) )
|
|
fprintf( pFile, "\"%s\"%s\n", Json_EntryName(pStr, Entry2), fComma ? ",":"" );
|
|
else
|
|
Json_Write_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry2), Level+1, fComma, 0 );
|
|
}
|
|
fprintf( pFile, "%*s}%s\n", 3*(Level-1), "", fAddComma ? ",":"" );
|
|
}
|
|
}
|
|
void Json_Write( char * pFileName, Abc_Nam_t * pStr, Vec_Wec_t * vObjs )
|
|
{
|
|
FILE * pFile = fopen( pFileName, "wb" );
|
|
if ( pFile == NULL )
|
|
{
|
|
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
|
|
return;
|
|
}
|
|
Json_Write_rec( pFile, pStr, vObjs, Vec_WecEntry(vObjs, 0), 1, 0, 1 );
|
|
fclose( pFile );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Reads JSON from a file.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
char * Json_ReadPreprocess( char * pIn, int nFileSize )
|
|
{
|
|
char * pOut = ABC_ALLOC( char, 3*nFileSize ); int i, k = 0;
|
|
for ( i = 0; i < nFileSize; i++ )
|
|
if ( pIn[i] == '{' || pIn[i] == '}' || pIn[i] == '[' || pIn[i] == ']' )
|
|
{
|
|
pOut[k++] = ' ';
|
|
pOut[k++] = pIn[i];
|
|
pOut[k++] = ' ';
|
|
}
|
|
else
|
|
pOut[k++] = pIn[i];
|
|
pOut[k++] = '\0';
|
|
return pOut;
|
|
}
|
|
Vec_Wec_t * Json_Read( char * pFileName, Abc_Nam_t ** ppStrs )
|
|
{
|
|
Abc_Nam_t * pStrs;
|
|
Vec_Wec_t * vObjs;
|
|
Vec_Int_t * vStack, * vTemp;
|
|
char * pContents, * pCur, * pNext, * pCur2, * pNext2;
|
|
int nFileSize, RetValue, iToken;
|
|
FILE * pFile;
|
|
|
|
// read the file into the buffer
|
|
pFile = fopen( pFileName, "rb" );
|
|
if ( pFile == NULL )
|
|
{
|
|
printf( "Cannot open file \"%s\" for reading.\n", pFileName );
|
|
return NULL;
|
|
}
|
|
nFileSize = Extra_FileSize( pFileName );
|
|
pContents = pCur = ABC_ALLOC( char, nFileSize+1 );
|
|
RetValue = fread( pContents, nFileSize, 1, pFile );
|
|
pContents[nFileSize] = 0;
|
|
fclose( pFile );
|
|
|
|
pContents = Json_ReadPreprocess( pCur = pContents, nFileSize );
|
|
nFileSize = strlen(pContents);
|
|
ABC_FREE( pCur );
|
|
pCur = pContents;
|
|
|
|
// start data-structures
|
|
vObjs = Vec_WecAlloc( 1000 );
|
|
vStack = Vec_IntAlloc( 100 );
|
|
pStrs = Abc_NamStart( 1000, 24 );
|
|
//Json_AddTypes( pStrs );
|
|
|
|
// read lines
|
|
assert( Vec_WecSize(vObjs) == 0 );
|
|
assert( Vec_IntSize(vStack) == 0 );
|
|
while ( pCur < pContents + nFileSize )
|
|
{
|
|
pCur = Json_SkipSpaces( pCur );
|
|
if ( *pCur == '\0' )
|
|
break;
|
|
pNext = Json_SkipNonSpaces( pCur );
|
|
if ( *pCur == '{' || *pCur == '[' )
|
|
{
|
|
// add fanin to node on the previous level
|
|
if ( Vec_IntSize(vStack) > 0 )
|
|
Vec_IntPush( Vec_WecEntry(vObjs, Vec_IntEntryLast(vStack)), Abc_Var2Lit(Vec_WecSize(vObjs), 0) );
|
|
// add node to the stack
|
|
Vec_IntPush( vStack, Vec_WecSize(vObjs) );
|
|
vTemp = Vec_WecPushLevel( vObjs );
|
|
Vec_IntGrow( vTemp, 4 );
|
|
// remember it as an array
|
|
Vec_IntPush( vTemp, (int)(*pCur == '[') );
|
|
pCur++;
|
|
continue;
|
|
}
|
|
if ( *pCur == '}' || *pCur == ']' )
|
|
{
|
|
Vec_IntPop( vStack );
|
|
pCur++;
|
|
continue;
|
|
}
|
|
if ( *pCur == ',' || *pCur == ':' )
|
|
{
|
|
pCur++;
|
|
continue;
|
|
}
|
|
iToken = Json_TokenCompare( pCur, pNext, &pCur2, &pNext2 );
|
|
if ( iToken == 0 )
|
|
iToken = Abc_NamStrFindOrAddLim( pStrs, pCur2, pNext2, NULL );
|
|
Vec_IntPush( Vec_WecEntry(vObjs, Vec_IntEntryLast(vStack)), Abc_Var2Lit(iToken, 1) );
|
|
pCur = pNext;
|
|
}
|
|
Vec_IntFree( vStack );
|
|
ABC_FREE( pContents );
|
|
*ppStrs = pStrs;
|
|
return vObjs;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Json_ReadTest( char * pFileName )
|
|
{
|
|
Abc_Nam_t * pStrs;
|
|
Vec_Wec_t * vObjs;
|
|
vObjs = Json_Read( pFileName, &pStrs );
|
|
if ( vObjs == NULL )
|
|
return;
|
|
Json_Write( "test.json", pStrs, vObjs );
|
|
Abc_NamDeref( pStrs );
|
|
Vec_WecFree( vObjs );
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
ABC_NAMESPACE_IMPL_END
|
|
|