1 /**CFile****************************************************************
2 
3   FileName    [ifTest.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [FPGA mapping based on priority cuts.]
8 
9   Synopsis    []
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - November 21, 2006.]
16 
17   Revision    [$Id: ifTest.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "if.h"
22 #include "aig/gia/gia.h"
23 
24 #ifdef ABC_USE_PTHREADS
25 
26 #ifdef _WIN32
27 #include "../lib/pthread.h"
28 #else
29 #include <pthread.h>
30 #include <unistd.h>
31 #endif
32 
33 #endif
34 
35 ABC_NAMESPACE_IMPL_START
36 
37 ////////////////////////////////////////////////////////////////////////
38 ///                        DECLARATIONS                              ///
39 ////////////////////////////////////////////////////////////////////////
40 
41 #ifndef ABC_USE_PTHREADS
42 
43 // do nothing
44 
45 #else // pthreads are used
46 
47 static inline word * Gia_ParTestObj( Gia_Man_t * p, int Id )         { return (word *)p->pData + Id * p->iData; }
48 static inline void   Gia_ParTestAlloc( Gia_Man_t * p, int nWords )   { assert( !p->pData ); p->pData = (unsigned *)ABC_ALLOC(word, Gia_ManObjNum(p) * nWords); p->iData = nWords; }
49 static inline void   Gia_ParTestFree( Gia_Man_t * p )                { ABC_FREE( p->pData ); p->iData = 0; }
50 
51 ////////////////////////////////////////////////////////////////////////
52 ///                     FUNCTION DEFINITIONS                         ///
53 ////////////////////////////////////////////////////////////////////////
54 
55 /**Function*************************************************************
56 
57   Synopsis    []
58 
59   Description []
60 
61   SideEffects []
62 
63   SeeAlso     []
64 
65 ***********************************************************************/
66 void Gia_ParComputeSignature( Gia_Man_t * p, int nWords )
67 {
68     Gia_Obj_t * pObj;
69     word * pData, Sign = 0;
70     int i, k;
71     Gia_ManForEachCo( p, pObj, k )
72     {
73         pData = Gia_ParTestObj( p, Gia_ObjId(p, pObj) );
74         for ( i = 0; i < p->iData; i++ )
75             Sign ^= pData[i];
76     }
77     Abc_TtPrintHexRev( stdout, &Sign, 6 );
78 }
79 
80 /**Function*************************************************************
81 
82   Synopsis    []
83 
84   Description []
85 
86   SideEffects []
87 
88   SeeAlso     []
89 
90 ***********************************************************************/
91 void Gia_ParTestSimulateInit( Gia_Man_t * p )
92 {
93     Gia_Obj_t * pObj;
94     word * pData;
95     int i, k;
96     Gia_ManForEachCi( p, pObj, k )
97     {
98         pData = Gia_ParTestObj( p, Gia_ObjId(p, pObj) );
99         for ( i = 0; i < p->iData; i++ )
100             pData[i] = Gia_ManRandomW( 0 );
101     }
102 }
103 void Gia_ParTestSimulateObj( Gia_Man_t * p, int Id )
104 {
105     Gia_Obj_t * pObj = Gia_ManObj( p, Id );
106     word * pData, * pData0, * pData1;
107     int i;
108     if ( Gia_ObjIsAnd(pObj) )
109     {
110         pData  = Gia_ParTestObj( p, Id );
111         pData0 = Gia_ParTestObj( p, Gia_ObjFaninId0(pObj, Id) );
112         pData1 = Gia_ParTestObj( p, Gia_ObjFaninId1(pObj, Id) );
113         if ( Gia_ObjFaninC0(pObj) )
114         {
115             if ( Gia_ObjFaninC1(pObj) )
116                 for ( i = 0; i < p->iData; i++ )
117                     pData[i] = ~(pData0[i] | pData1[i]);
118             else
119                 for ( i = 0; i < p->iData; i++ )
120                     pData[i] = ~pData0[i] & pData1[i];
121         }
122         else
123         {
124             if ( Gia_ObjFaninC1(pObj) )
125                 for ( i = 0; i < p->iData; i++ )
126                     pData[i] = pData0[i] & ~pData1[i];
127             else
128                 for ( i = 0; i < p->iData; i++ )
129                     pData[i] = pData0[i] & pData1[i];
130         }
131     }
132     else if ( Gia_ObjIsCo(pObj) )
133     {
134         pData  = Gia_ParTestObj( p, Id );
135         pData0 = Gia_ParTestObj( p, Gia_ObjFaninId0(pObj, Id) );
136         if ( Gia_ObjFaninC0(pObj) )
137             for ( i = 0; i < p->iData; i++ )
138                 pData[i] = ~pData0[i];
139         else
140             for ( i = 0; i < p->iData; i++ )
141                 pData[i] = pData0[i];
142     }
143     else if ( Gia_ObjIsCi(pObj) )
144     {
145     }
146     else if ( Gia_ObjIsConst0(pObj) )
147     {
148         pData = Gia_ParTestObj( p, Id );
149         for ( i = 0; i < p->iData; i++ )
150             pData[i] = 0;
151     }
152     else assert( 0 );
153 }
154 void Gia_ParTestSimulate( Gia_Man_t * p, int nWords )
155 {
156     Gia_Obj_t * pObj;
157     int i;
158     Gia_ManRandom( 1 );
159     Gia_ParTestAlloc( p, nWords );
160     Gia_ParTestSimulateInit( p );
161     Gia_ManForEachObj( p, pObj, i )
162         Gia_ParTestSimulateObj( p, i );
163 //    Gia_ParComputeSignature( p, nWords ); printf( "   " );
164     Gia_ParTestFree( p );
165 }
166 
167 
168 /**Function*************************************************************
169 
170   Synopsis    [Assigns references.]
171 
172   Description []
173 
174   SideEffects []
175 
176   SeeAlso     []
177 
178 ***********************************************************************/
179 Vec_Int_t * Gia_ManCreateFaninCounts( Gia_Man_t * p )
180 {
181     Vec_Int_t * vCounts;
182     Gia_Obj_t * pObj; int i;
183     vCounts = Vec_IntAlloc( Gia_ManObjNum(p) );
184     Gia_ManForEachObj( p, pObj, i )
185     {
186         if ( Gia_ObjIsAnd(pObj) )
187             Vec_IntPush( vCounts, 2 );
188         else if ( Gia_ObjIsCo(pObj) )
189             Vec_IntPush( vCounts, 1 );
190         else
191             Vec_IntPush( vCounts, 0 );
192     }
193     assert( Vec_IntSize(vCounts) == Gia_ManObjNum(p) );
194     return vCounts;
195 }
196 
197 /**Function*************************************************************
198 
199   Synopsis    []
200 
201   Description []
202 
203   SideEffects []
204 
205   SeeAlso     []
206 
207 ***********************************************************************/
208 #define PAR_THR_MAX 100
209 typedef struct Par_ThData_t_
210 {
211     Gia_Man_t * p;
212     int         Id;
213     int         Status;
214 } Par_ThData_t;
215 void * Gia_ParWorkerThread( void * pArg )
216 {
217     Par_ThData_t * pThData = (Par_ThData_t *)pArg;
218     volatile int * pPlace = &pThData->Status;
219     while ( 1 )
220     {
221         while ( *pPlace == 0 );
222         assert( pThData->Status == 1 );
223         if ( pThData->Id == -1 )
224         {
225             pthread_exit( NULL );
226             assert( 0 );
227             return NULL;
228         }
229         assert( pThData->Id >= 0 );
230         Gia_ParTestSimulateObj( pThData->p, pThData->Id );
231         pThData->Status = 0;
232     }
233     assert( 0 );
234     return NULL;
235 }
236 void Gia_ParTestSimulate2( Gia_Man_t * p, int nWords, int nProcs )
237 {
238     pthread_t WorkerThread[PAR_THR_MAX];
239     Par_ThData_t ThData[PAR_THR_MAX];
240     Vec_Int_t * vStack, * vFanins;
241     int i, k, iFan, status, nCountFanins;
242     assert( nProcs <= PAR_THR_MAX );
243     Gia_ManRandom( 1 );
244     Gia_ParTestAlloc( p, nWords );
245     Gia_ParTestSimulateInit( p );
246     // start the stack
247     vStack = Vec_IntAlloc( 1000 );
248     Vec_IntForEachEntryReverse( p->vCis, iFan, i )
249         Vec_IntPush( vStack, iFan );
250     Vec_IntPush( vStack, 0 );
251     Gia_ManStaticFanoutStart( p );
252     vFanins = Gia_ManCreateFaninCounts( p );
253     nCountFanins = Vec_IntSum(vFanins);
254     // start the threads
255     for ( i = 0; i < nProcs; i++ )
256     {
257         ThData[i].p = p;
258         ThData[i].Id = -1;
259         ThData[i].Status = 0;
260         status = pthread_create( WorkerThread + i, NULL, Gia_ParWorkerThread, (void *)(ThData + i) );  assert( status == 0 );
261     }
262     while ( nCountFanins > 0 || Vec_IntSize(vStack) > 0 )
263     {
264         for ( i = 0; i < nProcs; i++ )
265         {
266             if ( ThData[i].Status )
267                 continue;
268             assert( ThData[i].Status == 0 );
269             if ( ThData[i].Id >= 0 )
270             {
271                 Gia_ObjForEachFanoutStaticId( p, ThData[i].Id, iFan, k )
272                 {
273                     assert( Vec_IntEntry(vFanins, iFan) > 0 );
274                     if ( Vec_IntAddToEntry(vFanins, iFan, -1) == 0 )
275                         Vec_IntPush( vStack, iFan );
276                     assert( nCountFanins > 0 );
277                     nCountFanins--;
278                 }
279                 ThData[i].Id = -1;
280             }
281             if ( Vec_IntSize(vStack) > 0 )
282             {
283                 ThData[i].Id = Vec_IntPop( vStack );
284                 ThData[i].Status = 1;
285             }
286         }
287     }
288     Vec_IntForEachEntry( vFanins, iFan, k )
289         if ( iFan != 0 )
290         {
291             printf( "%d -> %d    ", k, iFan );
292             Gia_ObjPrint( p, Gia_ManObj(p, k) );
293         }
294 //    assert( Vec_IntSum(vFanins) == 0 );
295     // stop the threads
296     while ( 1 )
297     {
298         for ( i = 0; i < nProcs; i++ )
299             if ( ThData[i].Status )
300                 break;
301         if ( i == nProcs )
302             break;
303     }
304     for ( i = 0; i < nProcs; i++ )
305     {
306         assert( ThData[i].Status == 0 );
307         ThData[i].Id = -1;
308         ThData[i].Status = 1;
309     }
310     Gia_ManStaticFanoutStop( p );
311     Vec_IntFree( vStack );
312     Vec_IntFree( vFanins );
313 //    Gia_ParComputeSignature( p, nWords ); printf( "   " );
314     Gia_ParTestFree( p );
315 }
316 
317 
318 /**Function*************************************************************
319 
320   Synopsis    []
321 
322   Description []
323 
324   SideEffects []
325 
326   SeeAlso     []
327 
328 ***********************************************************************/
329 void Gia_ParTest( Gia_Man_t * p, int nWords, int nProcs )
330 {
331     abctime clk;
332     printf( "Trying with %d words and %d threads.  ", nWords, nProcs );
333     printf( "Memory usage = %.2f MB\n", (8.0*nWords*Gia_ManObjNum(p))/(1<<20) );
334 
335     clk = Abc_Clock();
336     Gia_ParTestSimulate( p, nWords );
337     Abc_PrintTime( 1, "Regular time", Abc_Clock() - clk );
338 
339     clk = Abc_Clock();
340     Gia_ParTestSimulate2( p, nWords, nProcs );
341     Abc_PrintTime( 1, "Special time", Abc_Clock() - clk );
342 }
343 
344 ////////////////////////////////////////////////////////////////////////
345 ///                       END OF FILE                                ///
346 ////////////////////////////////////////////////////////////////////////
347 
348 #endif // pthreads are used
349 
350 
351 ABC_NAMESPACE_IMPL_END
352 
353