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