From 6c1c45b90f689a548c2c35b5d5913cee76e7cbca Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Tue, 2 Oct 2012 21:41:24 -0700 Subject: Added command 'starter' to call ABC concurrently. --- src/base/cmd/cmd.c | 77 +++++++++++++++- src/base/cmd/cmdHist.c | 6 +- src/base/cmd/cmdStarter.c | 220 ++++++++++++++++++++++++++++++++++++++++++++++ src/base/cmd/cmdUtils.c | 5 +- src/base/cmd/module.make | 1 + src/base/main/main.c | 4 +- src/base/main/mainInt.h | 1 + 7 files changed, 306 insertions(+), 8 deletions(-) create mode 100644 src/base/cmd/cmdStarter.c (limited to 'src') diff --git a/src/base/cmd/cmd.c b/src/base/cmd/cmd.c index bb6ba3dd..50d3fdb8 100644 --- a/src/base/cmd/cmd.c +++ b/src/base/cmd/cmd.c @@ -57,6 +57,7 @@ static int CmdCommandVersion ( Abc_Frame_t * pAbc, int argc, char ** argv static int CmdCommandSis ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int CmdCommandMvsis ( Abc_Frame_t * pAbc, int argc, char ** argv ); static int CmdCommandCapo ( Abc_Frame_t * pAbc, int argc, char ** argv ); +static int Cmd_CommandStarter ( Abc_Frame_t * pAbc, int argc, char ** argv ); extern int Cmd_CommandAbcLoadPlugIn( Abc_Frame_t * pAbc, int argc, char ** argv ); @@ -103,6 +104,7 @@ void Cmd_Init( Abc_Frame_t * pAbc ) Cmd_CommandAdd( pAbc, "Various", "sis", CmdCommandSis, 1 ); Cmd_CommandAdd( pAbc, "Various", "mvsis", CmdCommandMvsis, 1 ); Cmd_CommandAdd( pAbc, "Various", "capo", CmdCommandCapo, 0 ); + Cmd_CommandAdd( pAbc, "Various", "starter", Cmd_CommandStarter, 0 ); Cmd_CommandAdd( pAbc, "Various", "load_plugin", Cmd_CommandAbcLoadPlugIn, 0 ); } @@ -334,7 +336,7 @@ int CmdCommandHistory( Abc_Frame_t * pAbc, int argc, char **argv ) { char * pName; int i, c; - int nPrints = 10; + int nPrints = 25; int iRepeat = -1; Extra_UtilGetoptReset(); while ( ( c = Extra_UtilGetopt( argc, argv, "Nh" ) ) != EOF ) @@ -2011,6 +2013,79 @@ usage: return 1; // error exit } +/**Function************************************************************* + + Synopsis [] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +int Cmd_CommandStarter( Abc_Frame_t * pAbc, int argc, char ** argv ) +{ + extern void Cmd_RunStarter( char * pFileName, int nCores ); + FILE * pFile; + char * pFileName; + int c, nCores = 3; + int fVerbose = 0; + Extra_UtilGetoptReset(); + while ( ( c = Extra_UtilGetopt( argc, argv, "Nvh" ) ) != EOF ) + { + switch ( c ) + { + case 'N': + if ( globalUtilOptind >= argc ) + { + Abc_Print( -1, "Command line switch \"-N\" should be followed by an integer.\n" ); + goto usage; + } + nCores = atoi(argv[globalUtilOptind]); + globalUtilOptind++; + if ( nCores < 0 ) + goto usage; + break; + case 'v': + fVerbose ^= 1; + break; + case 'h': + goto usage; + default: + goto usage; + } + } + if ( argc != globalUtilOptind + 1 ) + { + Abc_Print( -2, "The file name should be given on the command line.\n" ); + return 1; + } + // get the input file name + pFileName = argv[globalUtilOptind]; + if ( (pFile = Io_FileOpen( pFileName, "open_path", "rb", 0 )) == NULL ) +// if ( (pFile = fopen( pFileName, "rb" )) == NULL ) + { + Abc_Print( -2, "Cannot open input file \"%s\". ", pFileName ); + if (( pFileName = Extra_FileGetSimilarName( pFileName, ".c", ".s", ".scr", ".script", NULL ) )) + Abc_Print( -2, "Did you mean \"%s\"?", pFileName ); + Abc_Print( -2, "\n" ); + return 1; + } + fclose( pFile ); + // run commands + Cmd_RunStarter( pFileName, nCores ); + return 0; + +usage: + Abc_Print( -2, "usage: starter [-N num] [-vh]\n" ); + Abc_Print( -2, "\t executes command listed in concurrently on CPUs\n" ); + Abc_Print( -2, "\t-N num : the number of concurrent jobs counting the controler [default = %d]\n", nCores ); + Abc_Print( -2, "\t-v : toggle printing verbose information [default = %s]\n", fVerbose? "yes": "no" ); + Abc_Print( -2, "\t-h : print the command usage\n"); + return 1; +} + /**Function******************************************************************** Synopsis [Print the version string.] diff --git a/src/base/cmd/cmdHist.c b/src/base/cmd/cmdHist.c index ed1d2efa..a9e2d18d 100644 --- a/src/base/cmd/cmdHist.c +++ b/src/base/cmd/cmdHist.c @@ -49,9 +49,11 @@ void Cmd_HistoryAddCommand( Abc_Frame_t * p, const char * command ) { int nLastLooked = 10; // do not add history if the same entry appears among the last entries int nLastSaved = 500; // when saving a file, save no more than this number of last entries - char Buffer[ABC_MAX_STR]; - int Len = strlen(command); + int Len; + if ( p->fBatchMode ) + return; + Len = strlen(command); strcpy( Buffer, command ); if ( Buffer[Len-1] == '\n' ) Buffer[Len-1] = 0; diff --git a/src/base/cmd/cmdStarter.c b/src/base/cmd/cmdStarter.c new file mode 100644 index 00000000..17c52723 --- /dev/null +++ b/src/base/cmd/cmdStarter.c @@ -0,0 +1,220 @@ +/**CFile**************************************************************** + + FileName [cmdStarter.c] + + SystemName [ABC: Logic synthesis and verification system.] + + PackageName [Command processing package.] + + Synopsis [Command to start many instances of ABC in parallel.] + + Author [Alan Mishchenko] + + Affiliation [UC Berkeley] + + Date [Ver. 1.0. Started - June 20, 2005.] + + Revision [$Id: cmdStarter.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include +#include +#include +#include +#include "misc/util/abc_global.h" + +// comment out this line to disable pthreads +#define ABC_USE_PTHREADS + +#ifdef ABC_USE_PTHREADS + +#ifdef WIN32 +#include "../lib/pthread.h" +#else +#include +#include +#endif + +#endif + +ABC_NAMESPACE_IMPL_START + +//////////////////////////////////////////////////////////////////////// +/// DECLARATIONS /// +//////////////////////////////////////////////////////////////////////// + +#ifndef ABC_USE_PTHREADS + +void Cmd_RunStarter( char * pFileName, int nCores ) {} + +#else // pthreads are used + +// the number of concurrently running threads +static volatile int nThreadsRunning = 0; + +// mutex to control access to the number of threads +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +//////////////////////////////////////////////////////////////////////// +/// FUNCTION DEFINITIONS /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + + Synopsis [This procedures executes one call to system().] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void * Abc_RunThread( void * pCommand ) +{ + int status; + // perform the call + if ( system( (char *)pCommand ) ) + { + fprintf( stderr, "The following command has returned non-zero exit status:\n" ); + fprintf( stderr, "\"%s\"\n\n", (char *)pCommand ); + fflush( stdout ); + } + free( pCommand ); + + // decrement the number of threads runining + status = pthread_mutex_lock(&mutex); assert(status == 0); + nThreadsRunning--; + status = pthread_mutex_unlock(&mutex); assert(status == 0); + + // quit this thread + //printf("...Finishing %s\n", (char *)Command); + pthread_exit( NULL ); + assert(0); + return NULL; +} + +/**Function************************************************************* + + Synopsis [Takes file with commands to be executed and the number of CPUs.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Cmd_RunStarter( char * pFileName, int nCores ) +{ + FILE * pFile, * pOutput = stdout; + pthread_t * pThreadIds; + char * BufferCopy, * Buffer; + int nLines, LineMax, Line; + int i, c, status, Counter; + clock_t clk = clock(); + + // check the number of cores + if ( nCores < 2 ) + { + fprintf( pOutput, "The number of cores (%d) should be more than 1.\n", nCores ); + return; + } + + // open the file and make sure it is available + pFile = fopen( pFileName, "rb" ); + if ( pFile == NULL ) + { + fprintf( pOutput, "Input file \"%s\" cannot be opened.\n", pFileName ); + return; + } + + // count the number of lines and the longest line + nLines = LineMax = Line = 0; + while ( (c = fgetc(pFile)) != EOF ) + { + Line++; + if ( c != '\n' ) + continue; + nLines++; + LineMax = Abc_MaxInt( LineMax, Line ); + Line = 0; + } + LineMax += 10; + nLines += 10; + + // allocate storage + Buffer = ABC_ALLOC( char, LineMax ); + pThreadIds = ABC_ALLOC( pthread_t, nLines ); + + // read commands and execute at most of them at a time + rewind( pFile ); + for ( i = 0; fgets( Buffer, LineMax, pFile ) != NULL; i++ ) + { + // get the command from the file + if ( Buffer[0] == '\n' || Buffer[0] == '\r' || Buffer[0] == '\t' || + Buffer[0] == ' ' || Buffer[0] == '#') + { + continue; + } + + if ( Buffer[strlen(Buffer)-1] == '\n' ) + Buffer[strlen(Buffer)-1] = 0; + if ( Buffer[strlen(Buffer)-1] == '\r' ) + Buffer[strlen(Buffer)-1] = 0; + + // wait till there is an empty thread + while ( 1 ) + { + status = pthread_mutex_lock(&mutex); assert(status == 0); + Counter = nThreadsRunning; + status = pthread_mutex_unlock(&mutex); assert(status == 0); + if ( Counter < nCores - 1 ) + break; +// Sleep( 100 ); + } + + // increament the number of threads running + status = pthread_mutex_lock(&mutex); assert(status == 0); + nThreadsRunning++; + status = pthread_mutex_unlock(&mutex); assert(status == 0); + + printf( "Calling: %s\n", (char *)Buffer ); + fflush( stdout ); + + // create thread to execute this command + BufferCopy = Abc_UtilStrsav( Buffer ); + status = pthread_create( &pThreadIds[i], NULL, Abc_RunThread, (void *)BufferCopy ); assert(status == 0); + assert( i < nLines ); + } + ABC_FREE( pThreadIds ); + ABC_FREE( Buffer ); + fclose( pFile ); + + // wait for all the threads to finish + while ( 1 ) + { + status = pthread_mutex_lock(&mutex); assert(status == 0); + Counter = nThreadsRunning; + status = pthread_mutex_unlock(&mutex); assert(status == 0); + if ( Counter == 0 ) + break; + } + + // cleanup + status = pthread_mutex_destroy(&mutex); assert(status == 0); +// assert(mutex == NULL); + printf( "Finished processing commands in file \"%s\". ", pFileName ); + Abc_PrintTime( 1, "Total wall time", clock() - clk ); +} + +#endif + +//////////////////////////////////////////////////////////////////////// +/// END OF FILE /// +//////////////////////////////////////////////////////////////////////// + + +ABC_NAMESPACE_IMPL_END + diff --git a/src/base/cmd/cmdUtils.c b/src/base/cmd/cmdUtils.c index e65e2cb7..7f2e9b08 100644 --- a/src/base/cmd/cmdUtils.c +++ b/src/base/cmd/cmdUtils.c @@ -452,14 +452,15 @@ FILE * CmdFileOpen( Abc_Frame_t * pAbc, char *sFileName, char *sMode, char **pFi if ((pFile = fopen(sRealName, sMode)) == NULL) { if (! silent) { - perror(sRealName); +// perror(sRealName); + Abc_Print( 1, "Cannot open file \"%s\".\n", sRealName ); } } else { // print the path/name of the resource file 'abc.rc' that is being loaded if ( !silent && strlen(sRealName) >= 6 && strcmp( sRealName + strlen(sRealName) - 6, "abc.rc" ) == 0 ) - printf( "Loading resource file \"%s\".\n", sRealName ); + Abc_Print( 1, "Loading resource file \"%s\".\n", sRealName ); } } if ( pFileNameReal ) diff --git a/src/base/cmd/module.make b/src/base/cmd/module.make index 0277c760..b09ffa81 100644 --- a/src/base/cmd/module.make +++ b/src/base/cmd/module.make @@ -5,4 +5,5 @@ SRC += src/base/cmd/cmd.c \ src/base/cmd/cmdHist.c \ src/base/cmd/cmdLoad.c \ src/base/cmd/cmdPlugin.c \ + src/base/cmd/cmdStarter.c \ src/base/cmd/cmdUtils.c diff --git a/src/base/main/main.c b/src/base/main/main.c index 41836681..1ef79b73 100644 --- a/src/base/main/main.c +++ b/src/base/main/main.c @@ -98,12 +98,10 @@ int Abc_RealMain( int argc, char * argv[] ) _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); #endif -// Npn_Experiment(); -// Npn_Generate(); - // get global frame (singleton pattern) // will be initialized on first call pAbc = Abc_FrameGetGlobalFrame(); + pAbc->sBinary = argv[0]; #ifdef ABC_PYTHON_EMBED { diff --git a/src/base/main/mainInt.h b/src/base/main/mainInt.h index 5992d191..4db982f0 100644 --- a/src/base/main/mainInt.h +++ b/src/base/main/mainInt.h @@ -58,6 +58,7 @@ struct Abc_Frame_t_ { // general info char * sVersion; // the name of the current version + char * sBinary; // the name of the binary running // commands, aliases, etc st__table * tCommands; // the command table st__table * tAliases; // the alias table -- cgit v1.2.3