1 /**CFile****************************************************************
2 
3   FileName    [ioJson.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [Command processing package.]
8 
9   Synopsis    [Procedures to read JSON.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - June 20, 2005.]
16 
17   Revision    [$Id: ioJson.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "ioAbc.h"
22 #include "misc/vec/vecWec.h"
23 #include "misc/util/utilNam.h"
24 #include "misc/extra/extra.h"
25 
26 ABC_NAMESPACE_IMPL_START
27 
28 
29 ////////////////////////////////////////////////////////////////////////
30 ///                        DECLARATIONS                              ///
31 ////////////////////////////////////////////////////////////////////////
32 
Json_EntryIsName(int Fan)33 static inline int         Json_EntryIsName( int Fan )                     { return Abc_LitIsCompl(Fan);                                                       }
Json_EntryName(Abc_Nam_t * pStrs,int Fan)34 static inline char *      Json_EntryName( Abc_Nam_t * pStrs, int Fan )    { assert(Json_EntryIsName(Fan));  return Abc_NamStr( pStrs, Abc_Lit2Var(Fan) );     }
Json_EntryNode(Vec_Wec_t * vObjs,int Fan)35 static inline Vec_Int_t * Json_EntryNode( Vec_Wec_t * vObjs, int Fan )    { assert(!Json_EntryIsName(Fan)); return Vec_WecEntry( vObjs, Abc_Lit2Var(Fan) );   }
36 
37 ////////////////////////////////////////////////////////////////////////
38 ///                     FUNCTION DEFINITIONS                         ///
39 ////////////////////////////////////////////////////////////////////////
40 
41 /**Function*************************************************************
42 
43   Synopsis    [Writes JSON into a file.]
44 
45   Description []
46 
47   SideEffects []
48 
49   SeeAlso     []
50 
51 ***********************************************************************/
Nnc_LayerType2Str(char * pStr)52 char * Nnc_LayerType2Str( char * pStr )
53 {
54     if ( !strcmp(pStr, "InputLayer") )
55         return "input  ";
56     if ( !strcmp(pStr, "Conv2D") )
57         return "convo  ";
58     if ( !strcmp(pStr, "BatchNormalization") )
59         return "batch  ";
60     if ( !strcmp(pStr, "Activation") )
61         return "relu   ";
62     if ( !strcmp(pStr, "Add") )
63         return "eltwise";
64     if ( !strcmp(pStr, "MaxPooling2D") )
65         return "pool   ";
66     if ( !strcmp(pStr, "GlobalAveragePooling2D") )
67         return "pool   ";
68     if ( !strcmp(pStr, "Dense") )
69         return "fullcon";
70     if ( !strcmp(pStr, "ZeroPadding2D") )
71         return "pad";
72 //    if ( !strcmp(pStr, "InputLayer") )
73 //        return "softmax";
74     return NULL;
75 }
76 
Json_Extract_rec(FILE * pFile,Abc_Nam_t * pStr,Vec_Wec_t * vObjs,Vec_Int_t * vArray,int fWrite,int * pCount)77 void Json_Extract_rec( FILE * pFile, Abc_Nam_t * pStr, Vec_Wec_t * vObjs, Vec_Int_t * vArray, int fWrite, int * pCount )
78 {
79     int i, Entry1, Entry2;
80     if ( Vec_IntEntry(vArray, 0) ) // array
81     {
82         if ( Vec_IntSize(vArray) == 1 )
83             return;
84         if ( Vec_IntSize(vArray) == 2 && Json_EntryIsName(Vec_IntEntry(vArray,1)) )
85         {
86             if ( fWrite )
87                 fprintf( pFile, "%s", Json_EntryName(pStr, Vec_IntEntry(vArray,1)) );
88             return;
89         }
90         else
91         {
92             Vec_IntForEachEntryStart( vArray, Entry1, i, 1 )
93             {
94                 if ( Json_EntryIsName(Entry1) )
95                 {
96                     int Digit = Json_EntryName(pStr, Entry1)[0];
97                     if ( fWrite && Digit != '0' )
98                         fprintf( pFile, "%s%s", Json_EntryName(pStr, Entry1), Digit >= '0' && Digit <= '9' ? "" : " " );
99                 }
100                 else
101                     Json_Extract_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry1), fWrite, pCount );
102             }
103             return;
104         }
105     }
106     else // list of pairs
107     {
108         int fHaveConfig = 0;
109         assert( Vec_IntSize(vArray) % 2 != 0 );
110         Vec_IntForEachEntryDoubleStart( vArray, Entry1, Entry2, i, 1 )
111         {
112             char * pName1 = Json_EntryIsName(Entry1) ? Json_EntryName(pStr, Entry1) : NULL;
113             char * pName2 = Json_EntryIsName(Entry2) ? Json_EntryName(pStr, Entry2) : NULL;
114             char * pName3 = pName2 ? Nnc_LayerType2Str(pName2) : NULL;
115             if ( pName1 == NULL )
116                 continue;
117             if ( !strcmp(pName1, "class_name") )
118             {
119                 if ( pName3 )
120                     fprintf( pFile, "\n%3d : %-8s ", (*pCount)++, pName3 );
121             }
122             else if ( !strcmp(pName1, "name") )
123             {
124                 if ( fHaveConfig )
125                     fprintf( pFile, " N=%s  ", pName2 ? pName2 : "???" );
126             }
127             else if ( !strcmp(pName1, "kernel_size") )
128             {
129                 fprintf( pFile, " K=" );
130                 Json_Extract_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry2), 1, pCount );
131             }
132             else if ( !strcmp(pName1, "strides") )
133             {
134                 fprintf( pFile, " S=" );
135                 Json_Extract_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry2), 1, pCount );
136             }
137             else if ( !strcmp(pName1, "filters") )
138                 fprintf( pFile, " C=%s", pName2 );
139             else if ( !strcmp(pName1, "inbound_nodes") )
140                 Json_Extract_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry2), 1, pCount );
141             else if ( !strcmp(pName1, "layers") )
142                 Json_Extract_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry2), 1, pCount );
143             else if ( !strcmp(pName1, "config") )
144             {
145                 fHaveConfig = 1;
146                 Json_Extract_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry2), 0, pCount );
147             }
148         }
149     }
150 }
Json_Extract(char * pFileName,Abc_Nam_t * pStr,Vec_Wec_t * vObjs)151 void Json_Extract( char * pFileName, Abc_Nam_t * pStr, Vec_Wec_t * vObjs )
152 {
153     int Count = 0;
154     FILE * pFile = fopen( pFileName, "wb" );
155     if ( pFile == NULL )
156     {
157         printf( "Cannot open file \"%s\" for writing.\n", pFileName );
158         return;
159     }
160     fprintf( pFile, "# Data extracted from JSON file:\n" );
161     Json_Extract_rec( pFile, pStr, vObjs, Vec_WecEntry(vObjs, 0), 0, &Count );
162     fprintf( pFile, "\n" );
163     fclose( pFile );
164 }
165 
166 /**Function*************************************************************
167 
168   Synopsis    [Parsing.]
169 
170   Description []
171 
172   SideEffects []
173 
174   SeeAlso     []
175 
176 ***********************************************************************/
Json_CharIsSpace(char c)177 static inline int Json_CharIsSpace( char c )
178 {
179     return (c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == ':');
180 }
Json_SkipSpaces(char * pCur)181 static inline char * Json_SkipSpaces( char * pCur )
182 {
183     while ( Json_CharIsSpace(*pCur) )
184         pCur++;
185     return pCur;
186 }
Json_SkipNonSpaces(char * pCur)187 static inline char * Json_SkipNonSpaces( char * pCur )
188 {
189     while ( !Json_CharIsSpace(*pCur) )
190         pCur++;
191     return pCur;
192 }
Json_TokenCompare(char * pCur,char * pNext,char ** ppCur2,char ** ppNext2)193 static inline int Json_TokenCompare( char * pCur, char * pNext, char ** ppCur2, char ** ppNext2 )
194 {
195 //    int i;
196     if ( *pCur == '\"' )
197         pCur++;
198     if ( *(pNext-1) == ',' )
199         pNext--;
200     if ( *(pNext-1) == '\"' )
201         pNext--;
202     *ppCur2 = pCur;
203     *ppNext2 = pNext;
204 //    for ( i = 1; i < JSON_NUM_LINES; i++ )
205 //        if ( !strncmp( s_Types[i].pName, pCur, pNext - pCur ) )
206 //            return i;
207     return 0;
208 }
209 
210 /**Function*************************************************************
211 
212   Synopsis    [Writes JSON into a file.]
213 
214   Description []
215 
216   SideEffects []
217 
218   SeeAlso     []
219 
220 ***********************************************************************/
Json_Write_rec(FILE * pFile,Abc_Nam_t * pStr,Vec_Wec_t * vObjs,Vec_Int_t * vArray,int Level,int fAddComma,int fSpaces)221 void Json_Write_rec( FILE * pFile, Abc_Nam_t * pStr, Vec_Wec_t * vObjs, Vec_Int_t * vArray, int Level, int fAddComma, int fSpaces )
222 {
223     int i, Entry1, Entry2, fComma;
224     if ( Vec_IntEntry(vArray, 0) ) // array
225     {
226         if ( Vec_IntSize(vArray) == 1 )
227             fprintf( pFile, "[]" );
228         else if ( Vec_IntSize(vArray) == 2 && Json_EntryIsName(Vec_IntEntry(vArray,1)) )
229             fprintf( pFile, "[ \"%s\" ]", Json_EntryName(pStr, Vec_IntEntry(vArray,1)) );
230         else
231         {
232             if ( fSpaces )
233                 fprintf( pFile, "%*s", 3*(Level-1), "" );
234             fprintf( pFile, "[\n" );
235             Vec_IntForEachEntryStart( vArray, Entry1, i, 1 )
236             {
237                 fComma = (i < Vec_IntSize(vArray) - 1);
238                 if ( Json_EntryIsName(Entry1) )
239                     fprintf( pFile, "%*s\"%s\"%s\n", 3*Level, "", Json_EntryName(pStr, Entry1), fComma ? ",":"" );
240                 else
241                     Json_Write_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry1), Level+1, fComma, 1 );
242             }
243             fprintf( pFile, "%*s]", 3*(Level-1), "" );
244         }
245         fprintf( pFile, "%s\n", fAddComma ? ",":"" );
246     }
247     else // list of pairs
248     {
249         if ( fSpaces )
250             fprintf( pFile, "%*s", 3*(Level-1), "" );
251         fprintf( pFile, "{\n" );
252         assert( Vec_IntSize(vArray) % 2 != 0 );
253         Vec_IntForEachEntryDoubleStart( vArray, Entry1, Entry2, i, 1 )
254         {
255             fComma = (i < Vec_IntSize(vArray) - 3);
256             if ( Json_EntryIsName(Entry1) )
257                 fprintf( pFile, "%*s\"%s\"", 3*Level, "", Json_EntryName(pStr, Entry1) );
258             else
259                 Json_Write_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry1), Level+1, 0, 1 );
260             fprintf( pFile, " : " );
261             if ( Json_EntryIsName(Entry2) )
262                 fprintf( pFile, "\"%s\"%s\n", Json_EntryName(pStr, Entry2), fComma ? ",":"" );
263             else
264                 Json_Write_rec( pFile, pStr, vObjs, Json_EntryNode(vObjs, Entry2), Level+1, fComma, 0 );
265         }
266         fprintf( pFile, "%*s}%s\n", 3*(Level-1), "", fAddComma ? ",":"" );
267     }
268 }
Json_Write(char * pFileName,Abc_Nam_t * pStr,Vec_Wec_t * vObjs)269 void Json_Write( char * pFileName, Abc_Nam_t * pStr, Vec_Wec_t * vObjs )
270 {
271     FILE * pFile = fopen( pFileName, "wb" );
272     if ( pFile == NULL )
273     {
274         printf( "Cannot open file \"%s\" for writing.\n", pFileName );
275         return;
276     }
277     Json_Write_rec( pFile, pStr, vObjs, Vec_WecEntry(vObjs, 0), 1, 0, 1 );
278     fclose( pFile );
279 }
280 
281 /**Function*************************************************************
282 
283   Synopsis    [Reads JSON from a file.]
284 
285   Description []
286 
287   SideEffects []
288 
289   SeeAlso     []
290 
291 ***********************************************************************/
Json_ReadPreprocess(char * pIn,int nFileSize)292 char * Json_ReadPreprocess( char * pIn, int nFileSize )
293 {
294     char * pOut = ABC_ALLOC( char, 3*nFileSize ); int i, k = 0;
295     for ( i = 0; i < nFileSize; i++ )
296         if ( pIn[i] == '{' || pIn[i] == '}' || pIn[i] == '[' || pIn[i] == ']' )
297         {
298             pOut[k++] = ' ';
299             pOut[k++] = pIn[i];
300             pOut[k++] = ' ';
301         }
302         else
303             pOut[k++] = pIn[i];
304     pOut[k++] = '\0';
305     return pOut;
306 }
Json_Read(char * pFileName,Abc_Nam_t ** ppStrs)307 Vec_Wec_t * Json_Read( char * pFileName, Abc_Nam_t ** ppStrs )
308 {
309     Abc_Nam_t * pStrs;
310     Vec_Wec_t * vObjs;
311     Vec_Int_t * vStack, * vTemp;
312     char * pContents, * pCur, * pNext, * pCur2, * pNext2;
313     int nFileSize, RetValue, iToken;
314     FILE * pFile;
315 
316     // read the file into the buffer
317     pFile = fopen( pFileName, "rb" );
318     if ( pFile == NULL )
319     {
320         printf( "Cannot open file \"%s\" for reading.\n", pFileName );
321         return NULL;
322     }
323     nFileSize = Extra_FileSize( pFileName );
324     pContents = pCur = ABC_ALLOC( char, nFileSize+1 );
325     RetValue = fread( pContents, nFileSize, 1, pFile );
326     pContents[nFileSize] = 0;
327     fclose( pFile );
328 
329     pContents = Json_ReadPreprocess( pCur = pContents, nFileSize );
330     nFileSize = strlen(pContents);
331     ABC_FREE( pCur );
332     pCur = pContents;
333 
334     // start data-structures
335     vObjs  = Vec_WecAlloc( 1000 );
336     vStack = Vec_IntAlloc( 100 );
337     pStrs  = Abc_NamStart( 1000, 24 );
338     //Json_AddTypes( pStrs );
339 
340     // read lines
341     assert( Vec_WecSize(vObjs) == 0 );
342     assert( Vec_IntSize(vStack) == 0 );
343     while ( pCur < pContents + nFileSize )
344     {
345         pCur  = Json_SkipSpaces( pCur );
346         if ( *pCur == '\0' )
347             break;
348         pNext = Json_SkipNonSpaces( pCur );
349         if ( *pCur == '{' || *pCur == '[' )
350         {
351             // add fanin to node on the previous level
352             if ( Vec_IntSize(vStack) > 0 )
353                 Vec_IntPush( Vec_WecEntry(vObjs, Vec_IntEntryLast(vStack)), Abc_Var2Lit(Vec_WecSize(vObjs), 0) );
354             // add node to the stack
355             Vec_IntPush( vStack, Vec_WecSize(vObjs) );
356             vTemp = Vec_WecPushLevel( vObjs );
357             Vec_IntGrow( vTemp, 4 );
358             // remember it as an array
359             Vec_IntPush( vTemp, (int)(*pCur == '[') );
360             pCur++;
361             continue;
362         }
363         if ( *pCur == '}' || *pCur == ']' )
364         {
365             Vec_IntPop( vStack );
366             pCur++;
367             continue;
368         }
369         if ( *pCur == ',' || *pCur == ':' )
370         {
371             pCur++;
372             continue;
373         }
374         iToken = Json_TokenCompare( pCur, pNext, &pCur2, &pNext2 );
375         if ( iToken == 0 )
376             iToken = Abc_NamStrFindOrAddLim( pStrs, pCur2, pNext2, NULL );
377         Vec_IntPush( Vec_WecEntry(vObjs, Vec_IntEntryLast(vStack)), Abc_Var2Lit(iToken, 1) );
378         pCur = pNext;
379     }
380     Vec_IntFree( vStack );
381     ABC_FREE( pContents );
382     *ppStrs = pStrs;
383     return vObjs;
384 }
385 
386 /**Function*************************************************************
387 
388   Synopsis    []
389 
390   Description []
391 
392   SideEffects []
393 
394   SeeAlso     []
395 
396 ***********************************************************************/
Json_ReadTest(char * pFileName)397 void Json_ReadTest( char * pFileName )
398 {
399     Abc_Nam_t * pStrs;
400     Vec_Wec_t * vObjs;
401     vObjs = Json_Read( pFileName, &pStrs );
402     if ( vObjs == NULL )
403         return;
404     Json_Write( "test.json", pStrs, vObjs );
405     Abc_NamDeref( pStrs );
406     Vec_WecFree( vObjs );
407 }
408 
409 ////////////////////////////////////////////////////////////////////////
410 ///                       END OF FILE                                ///
411 ////////////////////////////////////////////////////////////////////////
412 
413 
414 ABC_NAMESPACE_IMPL_END
415 
416