ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
sswPart.c
Go to the documentation of this file.
1
20
21#include "sswInt.h"
22#include "aig/ioa/ioa.h"
23#include "aig/gia/giaAig.h"
24#include "proof/cec/cec.h"
25
26#ifdef ABC_USE_PTHREADS
27
28#ifdef _WIN32
29#include "../lib/pthread.h"
30#else
31#include <pthread.h>
32#include <unistd.h>
33#endif
34
35#ifdef __cplusplus
36#include <atomic>
37using namespace std;
38#else
39#include <stdatomic.h>
40#include <stdbool.h>
41#endif
42
43#endif
44
45
47
51
55
68{
69 Gia_Man_t * pGia; int i;
70 Cec_ParCor_t CorPars, * pCorPars = &CorPars;
72 pCorPars->nBTLimit = pPars->nBTLimit;
73 pCorPars->fVerbose = pPars->fVerbose;
74 pCorPars->fUseCSat = 1;
75 Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
76 if ( Gia_ManPiNum(pGia) > 0 )
77 Cec_ManLSCorrespondenceClasses( pGia, pCorPars );
78}
79
91#ifndef ABC_USE_PTHREADS
92
94{
95 Ssw_SignalCorrespondenceArray1( vGias, pPars );
96}
97
98#else // pthreads are used
99
100
101#define PAR_THR_MAX 100
102typedef struct Par_ScorrThData_t_
103{
104 Cec_ParCor_t CorPars;
105 Gia_Man_t * p;
106 int * pMap;
107 int iThread;
108 int nTimeOut;
109 atomic_bool fWorking;
110} Par_ScorrThData_t;
111
112void * Ssw_GiaWorkerThread( void * pArg )
113{
114 struct timespec pause_duration;
115 pause_duration.tv_sec = 0;
116 pause_duration.tv_nsec = 10000000L; // 10 milliseconds
117
118 Par_ScorrThData_t * pThData = (Par_ScorrThData_t *)pArg;
119 while ( 1 )
120 {
121 while ( !atomic_load_explicit((atomic_bool *)&pThData->fWorking, memory_order_acquire) )
122 nanosleep(&pause_duration, NULL);
123 if ( pThData->p == NULL )
124 {
125 pthread_exit( NULL );
126 assert( 0 );
127 return NULL;
128 }
129 Cec_ManLSCorrespondenceClasses( pThData->p, &pThData->CorPars );
130 atomic_store_explicit(&pThData->fWorking, false, memory_order_release);
131 }
132 assert( 0 );
133 return NULL;
134}
135
137{
138 //abctime clkTotal = Abc_Clock();
139 Par_ScorrThData_t ThData[PAR_THR_MAX];
140 pthread_t WorkerThread[PAR_THR_MAX];
141 int i, status, nProcs = pPars->nProcs;
142 Vec_Ptr_t * vStack;
143 Cec_ParCor_t CorPars, * pCorPars = &CorPars;
144 Cec_ManCorSetDefaultParams( pCorPars );
145 if ( pPars->fVerbose )
146 printf( "Running concurrent &scorr with %d processes.\n", nProcs );
147 fflush( stdout );
148 if ( pPars->nProcs < 2 )
149 return Ssw_SignalCorrespondenceArray1( vGias, pPars );
150 // subtract manager thread
151 nProcs--;
152 assert( nProcs >= 1 && nProcs <= PAR_THR_MAX );
153 // start threads
154 for ( i = 0; i < nProcs; i++ )
155 {
156 ThData[i].CorPars = *pCorPars;
157 ThData[i].iThread = i;
158 atomic_store_explicit(&ThData[i].fWorking, false, memory_order_release);
159 status = pthread_create( WorkerThread + i, NULL, Ssw_GiaWorkerThread, (void *)(ThData + i) ); assert( status == 0 );
160 }
161
162 struct timespec pause_duration;
163 pause_duration.tv_sec = 0;
164 pause_duration.tv_nsec = 10000000L; // 10 milliseconds
165
166 // look at the threads
167 vStack = Vec_PtrDup( vGias );
168 while ( Vec_PtrSize(vStack) > 0 )
169 {
170 for ( i = 0; i < nProcs; i++ )
171 {
172 if ( atomic_load_explicit(&ThData[i].fWorking, memory_order_acquire) )
173 continue;
174 ThData[i].p = (Gia_Man_t*)Vec_PtrPop( vStack );
175 atomic_store_explicit(&ThData[i].fWorking, true, memory_order_release);
176 break;
177 }
178 }
179 Vec_PtrFree( vStack );
180 // wait till threads finish
181 for ( i = 0; i < nProcs; i++ )
182 {
183 if ( atomic_load_explicit(&ThData[i].fWorking, memory_order_acquire) )
184 i = -1; // Start from the beginning again
185 nanosleep(&pause_duration, NULL);
186 }
187
188 // stop threads
189 for ( i = 0; i < nProcs; i++ )
190 {
191 ThData[i].p = NULL;
192 atomic_store_explicit(&ThData[i].fWorking, true, memory_order_release);
193 }
194
195 // Join threads
196 for ( i = 0; i < nProcs; i++ )
197 pthread_join( WorkerThread[i], NULL );
198}
199
200#endif // pthreads are used
201
202
215{
216 int fPrintParts = 1;
217 char Buffer[100];
218 Aig_Man_t * pTemp, * pNew;
219 Vec_Ptr_t * vResult;
220 Vec_Int_t * vPart;
221 int * pMapBack;
222 int i, nCountPis, nCountRegs;
223 int nClasses, nPartSize, fVerbose;
224 abctime clk = Abc_Clock();
225 if ( pPars->fConstrs )
226 {
227 Abc_Print( 1, "Cannot use partitioned computation with constraints.\n" );
228 return NULL;
229 }
230 // save parameters
231 nPartSize = pPars->nPartSize; pPars->nPartSize = 0;
232 fVerbose = pPars->fVerbose; pPars->fVerbose = 0;
233 // generate partitions
234 if ( pAig->vClockDoms )
235 {
236 // divide large clock domains into separate partitions
237 vResult = Vec_PtrAlloc( 100 );
238 Vec_PtrForEachEntry( Vec_Int_t *, (Vec_Ptr_t *)pAig->vClockDoms, vPart, i )
239 {
240 if ( nPartSize && Vec_IntSize(vPart) > nPartSize )
241 Aig_ManPartDivide( vResult, vPart, nPartSize, pPars->nOverSize );
242 else
243 Vec_PtrPush( vResult, Vec_IntDup(vPart) );
244 }
245 }
246 else
247 vResult = Aig_ManRegPartitionSimple( pAig, nPartSize, pPars->nOverSize );
248// vResult = Aig_ManPartitionSmartRegisters( pAig, nPartSize, 0 );
249// vResult = Aig_ManRegPartitionSmart( pAig, nPartSize );
250 if ( fPrintParts )
251 {
252 // print partitions
253 Abc_Print( 1, "Simple partitioning. %d partitions are saved:\n", Vec_PtrSize(vResult) );
254 Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i )
255 {
256// extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact );
257 sprintf( Buffer, "part%03d.aig", i );
258 pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, NULL );
259 Ioa_WriteAiger( pTemp, Buffer, 0, 0 );
260 Abc_Print( 1, "part%03d.aig : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d.\n",
261 i, Vec_IntSize(vPart), Aig_ManCiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp) );
262 Aig_ManStop( pTemp );
263 }
264 }
265
266 // perform SSW with partitions
267 Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
268 Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i )
269 {
270 pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, &pMapBack );
271 Aig_ManSetRegNum( pTemp, pTemp->nRegs );
272 // create the projection of 1-hot registers
273 if ( pAig->vOnehots )
274 pTemp->vOnehots = Aig_ManRegProjectOnehots( pAig, pTemp, pAig->vOnehots, fVerbose );
275 // run SSW
276 if (nCountPis>0) {
277 pNew = Ssw_SignalCorrespondence( pTemp, pPars );
278 nClasses = Aig_TransferMappedClasses( pAig, pTemp, pMapBack );
279 if ( fVerbose )
280 Abc_Print( 1, "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d.\n",
281 i, Vec_IntSize(vPart), Aig_ManCiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp), pPars->nIters, nClasses );
282 Aig_ManStop( pNew );
283 }
284 Aig_ManStop( pTemp );
285 ABC_FREE( pMapBack );
286 }
287 // remap the AIG
288 pNew = Aig_ManDupRepr( pAig, 0 );
289 Aig_ManSeqCleanup( pNew );
290// Aig_ManPrintStats( pAig );
291// Aig_ManPrintStats( pNew );
292 Vec_VecFree( (Vec_Vec_t *)vResult );
293 pPars->nPartSize = nPartSize;
294 pPars->fVerbose = fVerbose;
295 if ( fVerbose )
296 {
297 ABC_PRT( "Total time", Abc_Clock() - clk );
298 }
299 return pNew;
300}
301
302
315{
316 int fPrintParts = 1;
317 //char Buffer[100];
318 Aig_Man_t * pTemp, * pNew;
319 Vec_Ptr_t * vAigs;
320 Vec_Ptr_t * vGias;
321 Vec_Ptr_t * vMaps;
322 Vec_Ptr_t * vResult;
323 Vec_Int_t * vPart;
324 int * pMapBack = NULL;
325 int i, nCountPis, nCountRegs;
326 int nClasses, nPartSize, fVerbose;
327 abctime clk = Abc_Clock();
328 if ( pPars->fConstrs )
329 {
330 Abc_Print( 1, "Cannot use partitioned computation with constraints.\n" );
331 return NULL;
332 }
333 // save parameters
334 nPartSize = pPars->nPartSize; pPars->nPartSize = 0;
335 fVerbose = pPars->fVerbose; pPars->fVerbose = 0;
336 // generate partitions
337 if ( pAig->vClockDoms )
338 {
339 // divide large clock domains into separate partitions
340 vResult = Vec_PtrAlloc( 100 );
341 Vec_PtrForEachEntry( Vec_Int_t *, (Vec_Ptr_t *)pAig->vClockDoms, vPart, i )
342 {
343 if ( nPartSize && Vec_IntSize(vPart) > nPartSize )
344 Aig_ManPartDivide( vResult, vPart, nPartSize, pPars->nOverSize );
345 else
346 Vec_PtrPush( vResult, Vec_IntDup(vPart) );
347 }
348 }
349 else
350 vResult = Aig_ManRegPartitionSimple( pAig, nPartSize, pPars->nOverSize );
351// vResult = Aig_ManPartitionSmartRegisters( pAig, nPartSize, 0 );
352// vResult = Aig_ManRegPartitionSmart( pAig, nPartSize );
353 // collect partitions
354 vAigs = Vec_PtrAlloc( 100 );
355 vGias = Vec_PtrAlloc( 100 );
356 vMaps = Vec_PtrAlloc( 100 );
357 if ( fPrintParts )
358 Abc_Print( 1, "Simple partitioning. %d partitions are saved:\n", Vec_PtrSize(vResult) );
359 Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i )
360 {
361 pTemp = Aig_ManRegCreatePart( pAig, vPart, &nCountPis, &nCountRegs, &pMapBack );
362 Aig_ManSetRegNum( pTemp, pTemp->nRegs );
363 Vec_PtrPush( vAigs, pTemp );
364 Vec_PtrPush( vGias, Gia_ManFromAigSimple(pTemp) );
365 Vec_PtrPush( vMaps, pMapBack );
366 //sprintf( Buffer, "part%03d.aig", i );
367 //Ioa_WriteAiger( pTemp, Buffer, 0, 0 );
368 if ( fPrintParts )
369 Abc_Print( 1, "part%03d.aig : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d.\n",
370 i, Vec_IntSize(vPart), Aig_ManCiNum(pTemp)-Vec_IntSize(vPart), nCountPis, nCountRegs, Aig_ManNodeNum(pTemp) );
371 }
372 // solve partitions
373 Ssw_SignalCorrespondenceArray( vGias, pPars );
374 // collect the results
375 Aig_ManReprStart( pAig, Aig_ManObjNumMax(pAig) );
376 Vec_PtrForEachEntry( Vec_Int_t *, vResult, vPart, i )
377 {
378 int * pMapBack = (int *)Vec_PtrEntry( vMaps, i );
379 Gia_Man_t * pGia = (Gia_Man_t *)Vec_PtrEntry( vGias, i );
380 Aig_Man_t * pTemp2 = Gia_ManToAigSimple( pGia );
381 pTemp = (Aig_Man_t *)Vec_PtrEntry( vAigs, i );
382 Gia_ManReprToAigRepr2( pTemp2, pGia );
383 // remap back
384 nClasses = Aig_TransferMappedClasses( pAig, pTemp2, pMapBack );
385 if ( fVerbose )
386 Abc_Print( 1, "%3d : Reg = %4d. PI = %4d. (True = %4d. Regs = %4d.) And = %5d. It = %3d. Cl = %5d.\n",
387 i, Vec_IntSize(vPart), Aig_ManCiNum(pTemp)-Vec_IntSize(vPart), 0, 0, Aig_ManNodeNum(pTemp), 0, nClasses );
388 Aig_ManStop( pTemp );
389 Aig_ManStop( pTemp2 );
390 Gia_ManStop( pGia );
391 ABC_FREE( pMapBack );
392 }
393 Vec_PtrFree( vAigs );
394 Vec_PtrFree( vGias );
395 Vec_PtrFree( vMaps );
396
397 // remap the AIG
398 pNew = Aig_ManDupRepr( pAig, 0 );
399 Aig_ManSeqCleanup( pNew );
400// Aig_ManPrintStats( pAig );
401// Aig_ManPrintStats( pNew );
402 Vec_VecFree( (Vec_Vec_t *)vResult );
403 pPars->nPartSize = nPartSize;
404 pPars->fVerbose = fVerbose;
405 if ( fVerbose )
406 {
407 ABC_PRT( "Total time", Abc_Clock() - clk );
408 }
409 return pNew;
410}
412{
413 Aig_Obj_t * pObjAig; int i;
414 assert( Gia_ManObjNum(pGia) == Aig_ManObjNum(pAig) );
415 Aig_ManForEachObj( pAig, pObjAig, i )
416 pObjAig->iData = Abc_Var2Lit(i, 0);
417}
419{
420 Gia_Man_t * pRes = NULL;
421 Aig_Man_t * pNew = NULL;
423 Ssw_Pars_t SswPars, * pSswPars = &SswPars;
424 assert( pPars->nProcs > 0 );
425 assert( pPars->nPartSize > 0 );
426 Ssw_ManSetDefaultParams( pSswPars );
427 pSswPars->nBTLimit = pPars->nBTLimit;
428 pSswPars->nProcs = pPars->nProcs;
429 pSswPars->nPartSize = pPars->nPartSize;
430 pSswPars->fVerbose = pPars->fVerbose;
431 pNew = Ssw_SignalCorrespondencePart2( pAig, pSswPars );
433 Gia_ManReprFromAigRepr2( pAig, p );
434 pRes = Gia_ManFromAigSimple(pNew);
435 Aig_ManStop( pNew );
436 Aig_ManStop( pAig );
437 return pRes;
438}
439
443
444
ABC_INT64_T abctime
Definition abc_global.h:332
#define ABC_PRT(a, t)
Definition abc_global.h:255
#define ABC_FREE(obj)
Definition abc_global.h:267
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
Aig_Man_t * Aig_ManDupRepr(Aig_Man_t *p, int fOrdered)
Definition aigRepr.c:267
int Aig_ManSeqCleanup(Aig_Man_t *p)
Definition aigScl.c:158
void Aig_ManSetRegNum(Aig_Man_t *p, int nRegs)
Definition aigMan.c:438
void Aig_ManReprStart(Aig_Man_t *p, int nIdMax)
DECLARATIONS ///.
Definition aigRepr.c:45
#define Aig_ManForEachObj(p, pObj, i)
Definition aig.h:403
void Aig_ManStop(Aig_Man_t *p)
Definition aigMan.c:187
struct Aig_Obj_t_ Aig_Obj_t
Definition aig.h:51
void Aig_ManPartDivide(Vec_Ptr_t *vResult, Vec_Int_t *vDomain, int nPartSize, int nOverSize)
Definition aigPartReg.c:513
Aig_Man_t * Aig_ManRegCreatePart(Aig_Man_t *pAig, Vec_Int_t *vPart, int *pnCountPis, int *pnCountRegs, int **ppMapBack)
Definition aigPartReg.c:308
Vec_Ptr_t * Aig_ManRegPartitionSimple(Aig_Man_t *pAig, int nPartSize, int nOverSize)
Definition aigPartReg.c:474
typedefABC_NAMESPACE_HEADER_START struct Aig_Man_t_ Aig_Man_t
INCLUDES ///.
Definition aig.h:50
int Aig_TransferMappedClasses(Aig_Man_t *pAig, Aig_Man_t *pPart, int *pMapBack)
Definition aigRepr.c:533
Vec_Ptr_t * Aig_ManRegProjectOnehots(Aig_Man_t *pAig, Aig_Man_t *pPart, Vec_Ptr_t *vOnehots, int fVerbose)
Definition aigPartReg.c:248
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
#define PAR_THR_MAX
DECLARATIONS ///.
Definition bmcBmcG.c:31
void Cec_ManCorSetDefaultParams(Cec_ParCor_t *p)
Definition cecCore.c:183
int Cec_ManLSCorrespondenceClasses(Gia_Man_t *pAig, Cec_ParCor_t *pPars)
Definition cecCorr.c:924
struct Cec_ParCor_t_ Cec_ParCor_t
Definition cec.h:145
Cube * p
Definition exorList.c:222
void Gia_ManReprFromAigRepr2(Aig_Man_t *pAig, Gia_Man_t *pGia)
Definition giaAig.c:559
Aig_Man_t * Gia_ManToAigSimple(Gia_Man_t *p)
Definition giaAig.c:408
void Gia_ManReprToAigRepr2(Aig_Man_t *pAig, Gia_Man_t *pGia)
Definition giaAig.c:500
Gia_Man_t * Gia_ManFromAigSimple(Aig_Man_t *p)
Definition giaAig.c:212
void Gia_ManStop(Gia_Man_t *p)
Definition giaMan.c:82
struct Gia_Man_t_ Gia_Man_t
Definition gia.h:96
void Ioa_WriteAiger(Aig_Man_t *pMan, char *pFileName, int fWriteSymbols, int fCompact)
ABC_NAMESPACE_IMPL_START void Ssw_SignalCorrespondenceArray1(Vec_Ptr_t *vGias, Ssw_Pars_t *pPars)
DECLARATIONS ///.
Definition sswPart.c:67
Gia_Man_t * Gia_SignalCorrespondencePart(Gia_Man_t *p, Cec_ParCor_t *pPars)
Definition sswPart.c:418
void Ssw_SignalCorrespondenceArray(Vec_Ptr_t *vGias, Ssw_Pars_t *pPars)
Definition sswPart.c:93
void Gia_ManRestoreNodeMapping(Aig_Man_t *pAig, Gia_Man_t *pGia)
Definition sswPart.c:411
Aig_Man_t * Ssw_SignalCorrespondencePart2(Aig_Man_t *pAig, Ssw_Pars_t *pPars)
Definition sswPart.c:314
Aig_Man_t * Ssw_SignalCorrespondencePart(Aig_Man_t *pAig, Ssw_Pars_t *pPars)
Definition sswPart.c:214
void Ssw_ManSetDefaultParams(Ssw_Pars_t *p)
DECLARATIONS ///.
Definition sswCore.c:45
typedefABC_NAMESPACE_HEADER_START struct Ssw_Pars_t_ Ssw_Pars_t
INCLUDES ///.
Definition ssw.h:40
Aig_Man_t * Ssw_SignalCorrespondence(Aig_Man_t *pAig, Ssw_Pars_t *pPars)
Definition sswCore.c:436
int iData
Definition aig.h:88
int fUseCSat
Definition cec.h:162
int nPartSize
Definition cec.h:154
int nBTLimit
Definition cec.h:152
int nProcs
Definition cec.h:153
int fVerbose
Definition cec.h:168
#define assert(ex)
Definition util_old.h:213
char * sprintf()
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
Definition vecPtr.h:42
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.
Definition vecPtr.h:55
typedefABC_NAMESPACE_HEADER_START struct Vec_Vec_t_ Vec_Vec_t
INCLUDES ///.
Definition vecVec.h:42