Commit 6c1c45b9 by Alan Mishchenko

Added command 'starter' to call ABC concurrently.

parent aa705a9a
......@@ -515,6 +515,10 @@ SOURCE=.\src\base\cmd\cmdPlugin.c
# End Source File
# Begin Source File
SOURCE=.\src\base\cmd\cmdStarter.c
# End Source File
# Begin Source File
SOURCE=.\src\base\cmd\cmdUtils.c
# End Source File
# End Group
......
......@@ -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 <file> concurrently on <num> 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.]
......
......@@ -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;
......
/**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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#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 <pthread.h>
#include <unistd.h>
#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 <num> 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
......@@ -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 )
......
......@@ -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
......@@ -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
{
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment