/**CFile**************************************************************** FileName [reoProfile.c] PackageName [REO: A specialized DD reordering engine.] Synopsis [Procudures that compute variables profiles (nodes, width, APL).] Author [Alan Mishchenko] Affiliation [UC Berkeley] Date [Ver. 1.0. Started - October 15, 2002.] Revision [$Id: reoProfile.c,v 1.0 2002/15/10 03:00:00 alanmi Exp $] ***********************************************************************/ #include "reo.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function******************************************************************** Synopsis [Start the profile for the BDD nodes.] Description [TopRef is the first level, on this the given node counts towards the width of the BDDs. (In other words, it is the level of the referencing node plus 1.)] SideEffects [] SeeAlso [] ******************************************************************************/ void reoProfileNodesStart( reo_man * p ) { int Total, i; Total = 0; for ( i = 0; i <= p->nSupp; i++ ) { p->pPlanes[i].statsCost = p->pPlanes[i].statsNodes; Total += p->pPlanes[i].statsNodes; } assert( Total == p->nNodesCur ); p->nNodesBeg = p->nNodesCur; } /**Function************************************************************* Synopsis [Start the profile for the APL.] Description [Computes the total path length. The path length is normalized by dividing it by 2^|supp(f)|. To get the "real" APL, multiply by 2^|supp(f)|. This procedure assumes that Weight field of all nodes has been set to 0.0 before the call, except for the weight of the topmost node, which is set to 1.0 (1.0 is the probability of traversing the topmost node). This procedure assigns the edge weights. Because of the equal probability of selecting 0 and 1 assignment at a node, the edge weights are the same for the node. Instead of storing them, we store the weight of the node, which is the probability of traversing the node (pUnit->Weight) during the top down evalation of the BDD. ] SideEffects [] SeeAlso [] ***********************************************************************/ void reoProfileAplStart( reo_man * p ) { reo_unit * pER, * pTR; reo_unit * pUnit; double Res, Half; int i; // clean the weights of all nodes for ( i = 0; i < p->nSupp; i++ ) for ( pUnit = p->pPlanes[i].pHead; pUnit; pUnit = pUnit->Next ) pUnit->Weight = 0.0; // to assign the node weights (the probability of visiting each node) // we visit the node after visiting its predecessors // set the probability of visits to the top nodes for ( i = 0; i < p->nTops; i++ ) Unit_Regular(p->pTops[i])->Weight += 1.0; // to compute the path length (the sum of products of edge weight by edge length) // we visit the nodes in any order (the above order will do) Res = 0.0; for ( i = 0; i < p->nSupp; i++ ) { p->pPlanes[i].statsCost = 0.0; for ( pUnit = p->pPlanes[i].pHead; pUnit; pUnit = pUnit->Next ) { pER = Unit_Regular(pUnit->pE); pTR = Unit_Regular(pUnit->pT); Half = 0.5 * pUnit->Weight; pER->Weight += Half; pTR->Weight += Half; // add to the path length p->pPlanes[i].statsCost += pUnit->Weight; } Res += p->pPlanes[i].statsCost; } p->pPlanes[p->nSupp].statsCost = 0.0; p->nAplBeg = p->nAplCur = Res; } /**Function******************************************************************** Synopsis [Start the profile for the BDD width. Complexity of the algorithm is O(N + n).] Description [TopRef is the first level, on which the given node counts towards the width of the BDDs. (In other words, it is the level of the referencing node plus 1.)] SideEffects [] SeeAlso [] ******************************************************************************/ void reoProfileWidthStart( reo_man * p ) { reo_unit * pUnit; int * pWidthStart; int * pWidthStop; int v; // allocate and clean the storage for starting and stopping levels pWidthStart = ABC_ALLOC( int, p->nSupp + 1 ); pWidthStop = ABC_ALLOC( int, p->nSupp + 1 ); memset( pWidthStart, 0, sizeof(int) * (p->nSupp + 1) ); memset( pWidthStop, 0, sizeof(int) * (p->nSupp + 1) ); // go through the non-constant nodes and set the topmost level of their cofactors for ( v = 0; v <= p->nSupp; v++ ) for ( pUnit = p->pPlanes[v].pHead; pUnit; pUnit = pUnit->Next ) { pUnit->TopRef = REO_TOPREF_UNDEF; pUnit->Sign = 0; } // add the topmost level of the width profile for ( v = 0; v < p->nTops; v++ ) { pUnit = Unit_Regular(p->pTops[v]); if ( pUnit->TopRef == REO_TOPREF_UNDEF ) { // set the starting level pUnit->TopRef = 0; pWidthStart[pUnit->TopRef]++; // set the stopping level if ( pUnit->lev != REO_CONST_LEVEL ) pWidthStop[pUnit->lev+1]++; } } for ( v = 0; v < p->nSupp; v++ ) for ( pUnit = p->pPlanes[v].pHead; pUnit; pUnit = pUnit->Next ) { if ( pUnit->pE->TopRef == REO_TOPREF_UNDEF ) { // set the starting level pUnit->pE->TopRef = pUnit->lev + 1; pWidthStart[pUnit->pE->TopRef]++; // set the stopping level if ( pUnit->pE->lev != REO_CONST_LEVEL ) pWidthStop[pUnit->pE->lev+1]++; } if ( pUnit->pT->TopRef == REO_TOPREF_UNDEF ) { // set the starting level pUnit->pT->TopRef = pUnit->lev + 1; pWidthStart[pUnit->pT->TopRef]++; // set the stopping level if ( pUnit->pT->lev != REO_CONST_LEVEL ) pWidthStop[pUnit->pT->lev+1]++; } } // verify the top reference for ( v = 0; v < p->nSupp; v++ ) reoProfileWidthVerifyLevel( p->pPlanes + v, v ); // derive the profile p->nWidthCur = 0; for ( v = 0; v <= p->nSupp; v++ ) { if ( v == 0 ) p->pPlanes[v].statsWidth = pWidthStart[v] - pWidthStop[v]; else p->pPlanes[v].statsWidth = p->pPlanes[v-1].statsWidth + pWidthStart[v] - pWidthStop[v]; p->pPlanes[v].statsCost = p->pPlanes[v].statsWidth; p->nWidthCur += p->pPlanes[v].statsWidth; printf( "Level %2d: Width = %5d.\n", v, p->pPlanes[v].statsWidth ); } p->nWidthBeg = p->nWidthCur; ABC_FREE( pWidthStart ); ABC_FREE( pWidthStop ); } /**Function******************************************************************** Synopsis [Start the profile for the BDD width. Complexity of the algorithm is O(N * n).] Description [TopRef is the first level, on which the given node counts towards the width of the BDDs. (In other words, it is the level of the referencing node plus 1.)] SideEffects [] SeeAlso [] ******************************************************************************/ void reoProfileWidthStart2( reo_man * p ) { reo_unit * pUnit; int i, v; // clean the profile for ( i = 0; i <= p->nSupp; i++ ) p->pPlanes[i].statsWidth = 0; // clean the node structures for ( v = 0; v <= p->nSupp; v++ ) for ( pUnit = p->pPlanes[v].pHead; pUnit; pUnit = pUnit->Next ) { pUnit->TopRef = REO_TOPREF_UNDEF; pUnit->Sign = 0; } // set the topref to the topmost nodes for ( i = 0; i < p->nTops; i++ ) Unit_Regular(p->pTops[i])->TopRef = 0; // go through the non-constant nodes and set the topmost level of their cofactors for ( i = 0; i < p->nSupp; i++ ) for ( pUnit = p->pPlanes[i].pHead; pUnit; pUnit = pUnit->Next ) { if ( pUnit->pE->TopRef > i+1 ) pUnit->pE->TopRef = i+1; if ( pUnit->pT->TopRef > i+1 ) pUnit->pT->TopRef = i+1; } // verify the top reference for ( i = 0; i < p->nSupp; i++ ) reoProfileWidthVerifyLevel( p->pPlanes + i, i ); // compute the profile for the internal nodes for ( i = 0; i < p->nSupp; i++ ) for ( pUnit = p->pPlanes[i].pHead; pUnit; pUnit = pUnit->Next ) for ( v = pUnit->TopRef; v <= pUnit->lev; v++ ) p->pPlanes[v].statsWidth++; // compute the profile for the constant nodes for ( pUnit = p->pPlanes[p->nSupp].pHead; pUnit; pUnit = pUnit->Next ) for ( v = pUnit->TopRef; v <= p->nSupp; v++ ) p->pPlanes[v].statsWidth++; // get the width cost p->nWidthCur = 0; for ( i = 0; i <= p->nSupp; i++ ) { p->pPlanes[i].statsCost = p->pPlanes[i].statsWidth; p->nWidthCur += p->pPlanes[i].statsWidth; } p->nWidthBeg = p->nWidthCur; } /**Function******************************************************************** Synopsis [] Description [] SideEffects [] SeeAlso [] ******************************************************************************/ void reoProfileNodesPrint( reo_man * p ) { printf( "NODES: Total = %6d. Average = %6.2f.\n", p->nNodesCur, p->nNodesCur / (float)p->nSupp ); } /**Function******************************************************************** Synopsis [] Description [] SideEffects [] SeeAlso [] ******************************************************************************/ void reoProfileAplPrint( reo_man * p ) { printf( "APL: Total = %8.2f. Average =%6.2f.\n", p->nAplCur, p->nAplCur / (float)p->nSupp ); } /**Function******************************************************************** Synopsis [] Description [] SideEffects [] SeeAlso [] ******************************************************************************/ void reoProfileWidthPrint( reo_man * p ) { int WidthMax; int TotalWidth; int i; WidthMax = 0; TotalWidth = 0; for ( i = 0; i <= p->nSupp; i++ ) { printf( "Level = %2d. Width = %3d.\n", i, p->pPlanes[i].statsWidth ); if ( WidthMax < p->pPlanes[i].statsWidth ) WidthMax = p->pPlanes[i].statsWidth; TotalWidth += p->pPlanes[i].statsWidth; } assert( p->nWidthCur == TotalWidth ); printf( "WIDTH: " ); printf( "Maximum = %5d. ", WidthMax ); printf( "Total = %7d. ", p->nWidthCur ); printf( "Average = %6.2f.\n", TotalWidth / (float)p->nSupp ); } /**Function******************************************************************** Synopsis [] Description [] SideEffects [] SeeAlso [] ******************************************************************************/ void reoProfileWidthVerifyLevel( reo_plane * pPlane, int Level ) { reo_unit * pUnit; for ( pUnit = pPlane->pHead; pUnit; pUnit = pUnit->Next ) { assert( pUnit->TopRef <= Level ); assert( pUnit->pE->TopRef <= Level + 1 ); assert( pUnit->pT->TopRef <= Level + 1 ); } } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END