From 6130e39b18b5f53902e4eab14f6d5cdde5219563 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Mon, 1 Nov 2010 01:35:04 -0700 Subject: initial commit of public abc --- src/python/abc.sh | 78 +++++++++++ src/python/abcpy_test.py | 54 ++++++++ src/python/build.txt | 32 +++++ src/python/module.make | 64 +++++++++ src/python/package.py | 124 ++++++++++++++++++ src/python/pyabc.i | 330 +++++++++++++++++++++++++++++++++++++++++++++++ src/python/setup.py | 64 +++++++++ 7 files changed, 746 insertions(+) create mode 100644 src/python/abc.sh create mode 100644 src/python/abcpy_test.py create mode 100644 src/python/build.txt create mode 100644 src/python/module.make create mode 100644 src/python/package.py create mode 100644 src/python/pyabc.i create mode 100644 src/python/setup.py (limited to 'src/python') diff --git a/src/python/abc.sh b/src/python/abc.sh new file mode 100644 index 00000000..688cf567 --- /dev/null +++ b/src/python/abc.sh @@ -0,0 +1,78 @@ +#!/bin/sh +# +# Setup the ABC/Py environment and run the ABC/Py executable +# (ABC/Py stands for ABC with embedded Python) +# +# ABC/Py expects the following directory structure +# +# abc_root/ +# bin/ +# abc - this script +# abc_exe - the ABC executable +# ... - Other scripts +# lib/ +# pyabc.py - support file for pyabc extension +# python_library.zip - The Python standard library. Only if not using the system Python interpreter. +# *.so - Python extensions, Only if not using the system Python interpreter. +# scripts/ +# *.py - default directory for python scripts +# + +# usage: abspath +# get the absolute path of +abspath() +{ + cwd="$(pwd)" + cd "$1" + echo "$(pwd)" + cd "${cwd}" +} + +self=$0 + +self_dir=$(dirname "${self}") +self_dir=$(abspath "${self_dir}") + +abc_root=$(dirname "${self_dir}") + +abc_exe="${abc_root}/bin/abc_exe" + +PYTHONPATH="${abc_root}/lib":"${PYTHONPATH}" +export PYTHONPATH + +if [ -d "${abc_root}/scripts" ] ; then + ABC_PYTHON_SCRIPTS="${abc_root}/scripts" + export ABC_PYTHON_SCRIPTS + + PYTHONPATH="${ABC_PYTHON_SCRIPTS}":"${PYTHONPATH}" + export PYTHONPATH +fi + +if [ -f "${abc_root}/scripts/abc.rc" ] ; then + ABC_PYTHON_ABC_RC="${abc_root}/scripts/abc.rc" + export ABC_PYTHON_ABC_RC +fi + +if [ -f "${abc_root}/lib/python_library.zip" ] ; then + PYTHONHOME="${abc_root}" + export PYTHONHOME + + PYTHONPATH="${abc_root}/lib/python_library.zip":"${PYTHONPATH}" + export PYTHONPATH +fi + +PATH="${abc_root}/bin:$PATH" +export PATH + +if [ "$1" = "--debug" ]; then + shift + abc_debugger="$1" + shift + + echo export PYTHONHOME=$PYTHONHOME + echo export PYTHONPATH=$PYTHONPATH + echo export ABC_PYTHON_SCRIPTS=$ABC_PYTHON_SCRIPTS + echo export ABC_PYTHON_ABC_RC=$ABC_PYTHON_ABC_RC +fi + +exec ${abc_debugger} "${abc_exe}" "$@" diff --git a/src/python/abcpy_test.py b/src/python/abcpy_test.py new file mode 100644 index 00000000..912cae9f --- /dev/null +++ b/src/python/abcpy_test.py @@ -0,0 +1,54 @@ +# You can use 'from pyabc import *' and then not need the pyabc. prefix everywhere +import pyabc + +# A new command is just a function that accepts a list of string arguments +# The first argument is always the name of the command +# It MUST return an integer. -1: user quits, -2: error. Return 0 for success. + +# a simple command that just prints its arguments and returns success +def pytest1_cmd(args): + print args + return 0 + +# registers the command: +# The first argument is the function +# The second argument is the category (mainly for the ABC help command) +# The third argument is the new command name +# Keet the fourth argument 0, or consult with Alan +pyabc.add_abc_command(pytest1_cmd, "Python-Test", "pytest1", 0) + +# a simple command that just prints its arguments and runs the command 'scorr -h' +def pytest2_cmd(args): + print args + pyabc.run_command('scorr -h') + return 0 + +pyabc.add_abc_command(pytest2_cmd, "Python-Test", "pytest2", 0) + +# Now a more complicated command with argument parsing +# This command gets two command line arguments -c and -v. -c cmd runs the command 'cmd -h' and -v prints the python version +# for more details see the optparse module: http://docs.python.org/library/optparse.html + +import optparse + +def pytest3_cmd(args): + usage = "usage: %prog [options]" + + parser = optparse.OptionParser(usage) + + parser.add_option("-c", "--cmd", dest="cmd", help="command to ask help for") + parser.add_option("-v", "--version", action="store_true", dest="version", help="display Python Version") + + options, args = parser.parse_args(args) + + if options.version: + print sys.version + return 0 + + if options.cmd: + pyabc.run_command("%s -h"%options.cmd) + return 0 + + return 0 + +pyabc.add_abc_command(pytest3_cmd, "Python-Test", "pytest3", 0) diff --git a/src/python/build.txt b/src/python/build.txt new file mode 100644 index 00000000..60a3a9ba --- /dev/null +++ b/src/python/build.txt @@ -0,0 +1,32 @@ +On Windows: + +python setup.py build +python setup.py bdist_wininst + +On Linux (from the main abc directory) + +To build the extensions (make sure -fPIC is added to OPTFLAG in the main ABC Makefile first) + +make ABC_PYTHON=/usr/bin/python pyabc_extension_install + +To build the ABC with embedded python + +make pyabc.tgz + + + + +Updating the latest version on mima: + +alanmi@mima:~/abc_60$ cp ./src/python/build/lib.linux-x86_64-2.6/_pyabc.so /hd/common/pyabc/builds/101030/_pyabc.so +alanmi@mima:~/abc_60$ cp ./src/python/build/lib.linux-x86_64-2.6/pyabc.py /hd/common/pyabc/builds/101030/pyabc.py + +alanmi@mima:/hd/common/pyabc$ rm current +alanmi@mima:/hd/common/pyabc$ ln -s builds/101030 current +alanmi@mima:/hd/common/pyabc$ ls -l +total 4 +lrwxrwxrwx 1 alanmi common 13 2010-10-30 14:55 current -> builds/101030 + + +Latest documentation: +http://goo.gl/jNV2 \ No newline at end of file diff --git a/src/python/module.make b/src/python/module.make new file mode 100644 index 00000000..ac56208d --- /dev/null +++ b/src/python/module.make @@ -0,0 +1,64 @@ +# To compile with the embedded python interpreter set +# the variable ABC_PYTHON to point to the python executable +# +# Examples: +# make ABC_PYTHON=/usr/bin/python +# make ABC_PYTHON=/usr/bin/python2.5 +# +# To build the Python extension build the target pyabc +# To create a package of ABC with embedded Python use the target pyabc.tgz + +ifdef ABC_PYTHON + + # get the directory containing this file + ABC_PYTHON_FILES_PREFIX := $(CURDIR)/src/python + + ABC_SWIG := swig + ABC_PYTHON_CONFIG := $(ABC_PYTHON)-config + ABC_PYTHON_CFLAGS := $(shell $(ABC_PYTHON_CONFIG) --includes) -DABC_PYTHON_EMBED=1 + ABC_PYTHON_LDFLAGS := $(shell $(ABC_PYTHON_CONFIG) --ldflags) + + CFLAGS += $(ABC_PYTHON_CFLAGS) + CXXFLAGS += $(ABC_PYTHON_CFLAGS) + LIBS += $(ABC_PYTHON_LDFLAGS) + + ABC_PYTHON_SRC := $(ABC_PYTHON_FILES_PREFIX)/pyabc_wrap.c + + SRC += $(ABC_PYTHON_SRC) + + GARBAGE += \ + $(ABC_PYTHON_SRC) \ + $(ABC_PYTHON_SRC:_wrap.c=.py) \ + $(ABC_PYTHON_SRC:_wrap.c=.pyc) \ + $(ABC_PYTHON_FILES_PREFIX)/build \ + $(ABC_PYTHON_FILES_PREFIX)/dist \ + pyabc.tgz + +%_wrap.c %.py : %.i + $(ABC_SWIG) -python -outdir $( 1: + parser.print_help() + return 1 + + if not options.abc or not options.abc_sh or not options.pyabc or not options.out: + parser.print_help() + return 1 + + return package(options.abc, options.abc_sh, options.pyabc, options.out, options.scripts, options.sys) + +if __name__=="__main__": + main(sys.argv) diff --git a/src/python/pyabc.i b/src/python/pyabc.i new file mode 100644 index 00000000..9dabc3db --- /dev/null +++ b/src/python/pyabc.i @@ -0,0 +1,330 @@ +%module pyabc + +// ------------------------------------------------------------------- +// SWIG typemap allowing us to grab a Python callable object +// ------------------------------------------------------------------- + +#ifdef SWIG + +%typemap(in) PyObject *PyFunc +{ + + if ( !PyCallable_Check($source) ) + { + PyErr_SetString(PyExc_TypeError, "Need a callable object!"); + return NULL; + } + + $target = $source; +} + +#endif /* #ifdef SWIG */ + +%{ + +#include +#include +#include + +void sigint_signal_handler(int sig) +{ + _exit(1); +} + + +int n_ands() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + + if ( pNtk && Abc_NtkIsStrash(pNtk) ) + { + return Abc_NtkNodeNum(pNtk); + } + + return -1; +} + +int n_pis() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + + if ( pNtk && Abc_NtkIsStrash(pNtk) ) + { + return Abc_NtkPiNum(pNtk); + } + + return -1; +} + + +int n_pos() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + + if ( pNtk && Abc_NtkIsStrash(pNtk) ) + { + return Abc_NtkPoNum(pNtk); + } + + return -1; +} + +int n_latches() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + + if ( pNtk && Abc_NtkIsStrash(pNtk) ) + { + return Abc_NtkLatchNum(pNtk); + } + + return -1; +} + +int run_command(char* cmd) +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + int fStatus = Cmd_CommandExecute(pAbc, cmd); + + return fStatus; +} + +bool has_comb_model() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + + return pNtk && pNtk->pModel; +} + +bool has_seq_model() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + + return pNtk && pNtk->pSeqModel; +} + +int n_bmc_frames() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + return Abc_FrameReadBmcFrames(pAbc); +} + +int prob_status() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + return Abc_FrameReadProbStatus(pAbc); +} + +bool is_valid_cex() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + + return pNtk && Abc_FrameReadCex(pAbc) && Abc_NtkIsValidCex( pNtk, Abc_FrameReadCex(pAbc) ); +} + +bool is_true_cex() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + + return pNtk && Abc_FrameReadCex(pAbc) && Abc_NtkIsTrueCex( pNtk, Abc_FrameReadCex(pAbc) ); +} + +int n_cex_pis() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + + return Abc_FrameReadCex(pAbc) ? Abc_FrameReadCexPiNum( Abc_FrameReadCex(pAbc) ) : -1; +} + +int n_cex_regs() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + + return Abc_FrameReadCex(pAbc) ? Abc_FrameReadCexRegNum( Abc_FrameReadCex(pAbc) ) : -1; +} + +int cex_po() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + + return Abc_FrameReadCex(pAbc) ? Abc_FrameReadCexPo( Abc_FrameReadCex(pAbc) ) : -1; +} + +int cex_frame() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + + return Abc_FrameReadCex(pAbc) ? Abc_FrameReadCexFrame( Abc_FrameReadCex(pAbc) ) : -1; +} + +int n_phases() +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + Abc_Ntk_t * pNtk = Abc_FrameReadNtk(pAbc); + + return pNtk ? Abc_NtkPhaseFrameNum(pNtk) : 1; +} + +static PyObject* pyabc_internal_python_command_callback = 0; + +void pyabc_internal_set_command_callback( PyObject* callback ) +{ + Py_XINCREF(callback); + Py_XDECREF(pyabc_internal_python_command_callback); + + pyabc_internal_python_command_callback = callback; +} + +static int pyabc_internal_abc_command_callback(Abc_Frame_t * pAbc, int argc, char ** argv) +{ + int i; + + PyObject* args; + PyObject* arglist; + PyObject* res; + long lres; + + if ( !pyabc_internal_python_command_callback ) + return 0; + + args = PyList_New(argc); + + for( i=0 ; i 0 + + cmd = args[0] + assert cmd in _registered_commands + + res = _registered_commands[cmd](args) + + assert type(res) == int, "User-defined Python command must return an integer." + + return res + + except Exception, e: + print "Python error: ", e + + except SystemExit, se: + pass + + return 0 + +pyabc_internal_set_command_callback( _cmd_callback ) + +def add_abc_command(fcmd, group, cmd, change): + _registered_commands[ cmd ] = fcmd + pyabc_internal_register_command( group, cmd, change) + +import sys +import optparse +import os.path + +import __main__ + +def cmd_python(cmd_args): + global __main__ + + usage = "usage: %prog [options] " + + parser = optparse.OptionParser(usage) + + parser.add_option("-c", "--cmd", dest="cmd", help="Execute Python command directly") + parser.add_option("-v", "--version", action="store_true", dest="version", help="Display Python Version") + + options, args = parser.parse_args(cmd_args) + + if options.version: + print sys.version + return 0 + + if options.cmd: + exec options.cmd in __main__.__dict__ + return 0 + + scripts_dir = os.getenv('ABC_PYTHON_SCRIPTS', ".") + scripts_dirs = scripts_dir.split(':') + + for fname in args[1:]: + if os.path.isabs(fname): + execfile(fname, __main__.__dict__) + else: + for d in scripts_dirs: + fname = os.path.join(scripts_dir, fname) + if os.path.exists(fname): + execfile(fname, __main__.__dict__) + break + + return 0 + +add_abc_command(cmd_python, "Python", "python", 0) + +%} diff --git a/src/python/setup.py b/src/python/setup.py new file mode 100644 index 00000000..abc07afa --- /dev/null +++ b/src/python/setup.py @@ -0,0 +1,64 @@ +import sys + +from distutils.core import setup, Extension +from distutils.sysconfig import get_config_vars +from distutils import util + +include_dirs = [ + '../aig/hop', + '../base/abc', + '../base/cmd', + '../base/io', + '../base/main', + '../bdd/cudd', + '../bdd/epd', + '../bdd/mtr', + '../misc/extra', + '../misc/nm', + '../misc/st', + '../misc/util', + '../misc/vec', + ] + +define_macros = [] +libraries = [] +library_dirs = [] + +if sys.platform == "win32": + + src_file = [ 'pyabc.i' ] + + define_macros.append( ('WIN32', 1) ) + define_macros.append( ('ABC_DLL', 'ABC_DLLEXPORT') ) + + libraries.append('abcr') + library_dirs.append('./../../lib') + +else: + + src_file = [ 'pyabc_wrap.c' ] + + if get_config_vars()['SIZEOF_VOID_P'] > 4: + define_macros.append( ('LIN64', 1) ) + else: + define_macros.append( ('LIN', 1) ) + + libraries.append( 'abc' ) + libraries.append( 'readline' ) + library_dirs.append('./../../') + +ext = Extension( + '_pyabc', + src_file, + define_macros=define_macros, + include_dirs = include_dirs, + library_dirs=library_dirs, + libraries=libraries + ) + +setup( + name='pyabc', + version='1.0', + ext_modules=[ext], + py_modules=['pyabc'] +) -- cgit v1.2.3