diff options
Diffstat (limited to 'src/python')
-rw-r--r-- | src/python/abc.sh | 78 | ||||
-rw-r--r-- | src/python/abcpy_test.py | 54 | ||||
-rw-r--r-- | src/python/build.txt | 32 | ||||
-rw-r--r-- | src/python/module.make | 64 | ||||
-rw-r--r-- | src/python/package.py | 124 | ||||
-rw-r--r-- | src/python/pyabc.i | 330 | ||||
-rw-r--r-- | src/python/setup.py | 64 |
7 files changed, 746 insertions, 0 deletions
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 <dir> +# get the absolute path of <dir> +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 $(<D) $< + +.PHONY: pyabc_extension_build + +pyabc_extension_build : lib$(PROG).a $(ABC_PYTHON_SRC) $(ABC_PYTHON_SRC:_wrap.c=.py) + ( cd $(ABC_PYTHON_FILES_PREFIX) && rm -rf build/ ) + ( cd $(ABC_PYTHON_FILES_PREFIX) && $(ABC_PYTHON) setup.py build ) + +.PHONY: pyabc_extension_install + +pyabc_extension_install : pyabc_extension_build + ( cd $(ABC_PYTHON_FILES_PREFIX) && $(ABC_PYTHON) setup.py install --user ) + +.PHONY: pyabc_extension_bdist + +pyabc_extension_bdist : pyabc_extension_build + ( cd $(ABC_PYTHON_FILES_PREFIX) && python setup.py bdist ) + +pyabc.tgz : $(PROG) $(ABC_PYTHON_SRC:_wrap.c=.py) $(ABC_PYTHON_FILES_PREFIX)/abc.sh $(ABC_PYTHON_FILES_PREFIX)/package.py + $(ABC_PYTHON) $(ABC_PYTHON_FILES_PREFIX)/package.py \ + --abc=$(PROG) \ + --abc_sh=$(ABC_PYTHON_FILES_PREFIX)/abc.sh \ + --pyabc=$(ABC_PYTHON_SRC:_wrap.c=.py) \ + --out=$@ \ + $(ABC_PYTHON_OPTIONS) + +endif diff --git a/src/python/package.py b/src/python/package.py new file mode 100644 index 00000000..9c79a944 --- /dev/null +++ b/src/python/package.py @@ -0,0 +1,124 @@ +import os +import sys +import optparse +import zipfile +import tarfile +import tempfile +import time + +def zip_library(f, extra_files = []): + lib = "%s/lib/python%s/"%(sys.prefix,sys.version[:3]) + + zf = zipfile.ZipFile(f, "w", zipfile.ZIP_DEFLATED) + + for root, _, files in os.walk(lib): + arcroot = os.path.relpath(root, lib) + for f in files: + _, ext = os.path.splitext(f) + if ext in ['.py', '.pyo', '.pyc']: + zf.write(os.path.join(root,f), os.path.join(arcroot, f)) + + for s, r in extra_files: + zf.write( s, r ) + + zf.close() + +def add_dir(tf, dir, mtime): + ti = tarfile.TarInfo(dir) + ti.mode = 0777 + ti.mtime = mtime + ti.type = tarfile.DIRTYPE + + tf.addfile(ti) + +def add_fileobj(tf, f, arcname, mode, mtime): + ti = tarfile.TarInfo(arcname) + ti.mode = mode + ti.mtime = mtime + + f.seek(0, os.SEEK_END) + ti.size = f.tell() + + f.seek(0, os.SEEK_SET) + tf.addfile(ti, f) + +def add_file(tf, fname, arcname, mode, mtime): + f = open(fname, "rb") + add_fileobj(tf, f, arcname, mode, mtime) + f.close() + +def package(abc_exe, abc_sh, pyabc, ofname, scripts_dir, use_sys): + mtime = time.time() + + tf = tarfile.open(ofname, "w:gz") + + add_dir(tf, "pyabc", mtime) + + add_dir(tf, "pyabc/bin", mtime) + + add_file(tf, abc_exe, "pyabc/bin/abc_exe", 0777, mtime) + add_file(tf, abc_sh, "pyabc/bin/abc", 0777, mtime) + + if scripts_dir: + for fn in os.listdir(scripts_dir): + fullname = os.path.join(scripts_dir, fn) + if os.path.isfile(fullname): + fnroot, fnext = os.path.splitext(fn) + if fnext==".sh": + add_file( tf, fullname, os.path.join("pyabc/bin", fnroot), 0777, mtime) + else: + add_file( tf, fullname, os.path.join("pyabc/scripts", fn), 0666, mtime) + + add_dir(tf, "pyabc/lib", mtime) + add_file( tf, pyabc, "pyabc/lib/pyabc.py", 0666, mtime) + + if not use_sys: + # ZIP standard library + zf = tempfile.NamedTemporaryFile("w+b") + #zip_library(zf, [(pyabc, "pyabc.py")]) + zip_library(zf, []) + zf.flush() + + add_fileobj(tf, zf, "pyabc/lib/python_library.zip", 0666, mtime) + + zf.close() + + # add all extensions + + lib_dynload = os.path.join(sys.exec_prefix,"lib", "python%s"%sys.version[:3], "lib-dynload") + + for fn in os.listdir(lib_dynload): + fullname = os.path.join(lib_dynload, fn) + if os.path.isfile(fullname): + add_file( tf, fullname, os.path.join("pyabc/lib", fn), 0666, mtime) + + tf.close() + + +def main(args): + + usage = "usage: %prog [options]" + + parser = optparse.OptionParser(usage) + + parser.add_option("-a", "--abc", dest="abc", help="location of the ABC exeutable") + parser.add_option("-s", "--abc_sh", dest="abc_sh", help="location of the ABC setup script") + parser.add_option("-p", "--pyabc", dest="pyabc", help="location of pyabc.py") + parser.add_option("-o", "--out", dest="out", help="location of output tar gzipped file") + parser.add_option("-x", "--scripts", dest="scripts", default="scripts", help="location of scripts") + parser.add_option("-S", "--system", action="store_false", dest="sys", default=True, help="use default python installation") + + options, args = parser.parse_args(args) + + if len(args) > 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<Python> + +%typemap(in) PyObject *PyFunc +{ + + if ( !PyCallable_Check($source) ) + { + PyErr_SetString(PyExc_TypeError, "Need a callable object!"); + return NULL; + } + + $target = $source; +} + +#endif /* #ifdef SWIG<Python> */ + +%{ + +#include <main.h> +#include <stdlib.h> +#include <signal.h> + +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<argc ; i++ ) + PyList_SetItem(args, i, PyString_FromString(argv[i]) ); + + arglist = Py_BuildValue("(O)", args); + Py_INCREF(arglist); + + res = PyEval_CallObject( pyabc_internal_python_command_callback, arglist ); + Py_DECREF(arglist); + + lres = PyInt_AsLong(res); + Py_DECREF(res); + + return lres; +} + +void pyabc_internal_register_command( char * sGroup, char * sName, int fChanges ) +{ + Abc_Frame_t* pAbc = Abc_FrameGetGlobalFrame(); + + Cmd_CommandAdd( pAbc, sGroup, sName, (void*)pyabc_internal_abc_command_callback, fChanges); +} + +%} + +%init +%{ + Abc_Start(); + signal(SIGINT, sigint_signal_handler); +%} + +int n_ands(); +int n_pis(); +int n_pos(); +int n_latches(); + +int run_command(char* cmd); + +bool has_comb_model(); +bool has_seq_model(); + +int n_bmc_frames(); +int prob_status(); + +bool is_valid_cex(); +bool is_true_cex(); +int n_cex_pis(); +int n_cex_regs(); +int cex_po(); +int cex_frame(); + +int n_phases(); + +void pyabc_internal_set_command_callback( PyObject* callback ); +void pyabc_internal_register_command( char * sGroup, char * sName, int fChanges ); + +%pythoncode +%{ + +_registered_commands = {} + +def _cmd_callback(args): + try: + assert len(args) > 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] <Python files>" + + 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'] +) |