Esempio n. 1
0
def create_module(module_name, expression_name_tuples, directory):
    """Generates a cython module that can be imported."""

    routines = []

    for name, expression, args in expression_name_tuples:
        try:
            routine = make_routine(name, [expression], args)

        except CodeGenArgumentListError as e:
            new_args = []
            for missing in e.missing_args:
                if not isinstance(missing, OutputArgument):
                    raise
                new_args.append(missing.name)

            routine = make_routine(name, expression, list(args) + new_args)

        routines.append(routine)

    if not os.path.exists(directory):
        os.makedirs(directory)

    cg = CCodeGen()

    [(cf, cs), (hf, hs)] = cg.write(routines, module_name + '_code')

    with open(directory + '/' + cf, "w") as text_file:
        text_file.write(cs)

    with open(directory + '/' + hf, "w") as text_file:
        text_file.write(hs)

    ccw = CythonCodeWrapper(cg)

    with open(directory + '/' + module_name + '.pyx', "w") as text_file:
        ccw.dump_pyx(routines, text_file, module_name + '_code')

    create_setup(module_name + '.pyx', module_name + '_code.c', directory,
                 module_name)

    open(directory + '/__init__.py', 'w').close()

    oldwork = os.getcwd()
    os.chdir(directory)
    workdir = os.getcwd()
    command = [sys.executable, "setup.py", "build_ext", "--inplace"]
    try:
        sys.path.append(workdir)
        retoutput = check_output(command, stderr=STDOUT)
    except CalledProcessError as e:
        raise CodeWrapError(
            "Error while executing command: %s. Command output is:\n%s" %
            (" ".join(command), e.output.decode()))

    finally:
        sys.path.remove(workdir)
        os.chdir(oldwork)
Esempio n. 2
0
 def __init__(self, model, with_jacobian=False, cleanup=True, _logger=None):
     super(CythonRhsBuilder, self).__init__(model, with_jacobian, cleanup,
                                            _logger)
     routine_names = ["kinetics"]
     if with_jacobian:
         routine_names += ["kinetics_jacobian_y", "kinetics_jacobian_o"]
     # We want more control over various details of code generation and
     # wrapper module creation than sympy's autowrap provides, so we'll use
     # the lower-level building blocks directly.
     routines = {name: self._build_routine(name) for name in routine_names}
     code_gen = C99CodeGen()
     extra_compile_args = [
         # The RHS evaluation is such a tiny part of overall integration
         # time, even for huge models, that compiler optimization actually
         # takes more time than it will ever yield back. Since Cython sets
         # -O2 by default we need to override it.
         "-O0",
     ]
     # Opt in to the newer numpy C API which is only supported in Cython 3+.
     import Cython
     if not Cython.__version__.startswith("0."):
         extra_compile_args.append(
             "-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION")
     code_wrapper = CythonCodeWrapper(
         code_gen,
         filepath=self.work_path,
         extra_compile_args=extra_compile_args,
     )
     # Build a module-name-safe string that identifies the model as uniquely
     # as possible to assist in debugging.
     escaped_name = re.sub(
         r"[^A-Za-z0-9]",
         "_",
         self.model_name.encode("unicode_escape").decode(),
     )
     base_name = "pysb_" + escaped_name + "_kinetics"
     code_wrapper._filename = base_name
     code_wrapper._module_basename = base_name + "_wrapper"
     self._logger.debug("Running code generation and Cython compilation")
     functions = {
         name: code_wrapper.wrap_code(routine)
         for name, routine in routines.items()
     }
     # Grab specs for the Cython-compiled modules for reloading later.
     self.module_specs = {
         name: inspect.getmodule(function).__spec__
         for name, function in functions.items()
     }
Esempio n. 3
0
def test_cython_wrapper_scalar_function():
    x, y, z = symbols('xyz')
    expr = (x + y) * z
    routine = Routine("test", expr)
    code_gen = CythonCodeWrapper(CCodeGen())
    source = get_string(code_gen.dump_pyx, [routine])
    expected = ('cdef extern from "file.h":\n'
                '   double test(double x, double y, double z)\n'
                'def test_c(double x, double y, double z):\n'
                '   return test(x, y, z)\n')
    assert source == expected
Esempio n. 4
0
def test_cython_wrapper_inoutarg():
    from sympy import Equality
    x, y, z = symbols('xyz')
    code_gen = CythonCodeWrapper(CCodeGen())
    routine = Routine("test", Equality(z, x + y + z))
    source = get_string(code_gen.dump_pyx, [routine])
    expected = ('cdef extern from "file.h":\n'
                '   void test(double x, double y, double &z)\n'
                'def test_c(double x, double y, double z):\n'
                '   test(x, y, z)\n'
                '   return z\n')
    assert source == expected
Esempio n. 5
0
def test_cython_wrapper_scalar_function():
    x, y, z = symbols('x,y,z')
    expr = (x + y) * z
    routine = make_routine("test", expr)
    code_gen = CythonCodeWrapper(CCodeGen())
    source = get_string(code_gen.dump_pyx, [routine])
    expected = ("cdef extern from 'file.h':\n"
                "    double test(double x, double y, double z)\n"
                "\n"
                "def test_c(double x, double y, double z):\n"
                "\n"
                "    return test(x, y, z)")
    assert source == expected
Esempio n. 6
0
def test_cython_wrapper_inoutarg():
    from sympy import Equality
    x, y, z = symbols('x,y,z')
    code_gen = CythonCodeWrapper(C99CodeGen())
    routine = make_routine("test", Equality(z, x + y + z))
    source = get_string(code_gen.dump_pyx, [routine])
    expected = ("cdef extern from 'file.h':\n"
                "    void test(double x, double y, double *z)\n"
                "\n"
                "def test_c(double x, double y, double z):\n"
                "\n"
                "    test(x, y, &z)\n"
                "    return z")
    assert source == expected
Esempio n. 7
0
def test_cython_wrapper_scalar_function():
    x, y, z = symbols('x,y,z')
    expr = (x + y) * z
    routine = make_routine("test", expr)
    with warnings.catch_warnings():
        warnings.filterwarnings('ignore', category=SymPyDeprecationWarning)
        code_gen = CythonCodeWrapper(CCodeGen())
        source = get_string(code_gen.dump_pyx, [routine])

    expected = ("cdef extern from 'file.h':\n"
                "    double test(double x, double y, double z)\n"
                "\n"
                "def test_c(double x, double y, double z):\n"
                "\n"
                "    return test(x, y, z)")
    assert source == expected
Esempio n. 8
0
def test_cython_wrapper_unique_dummyvars():
    from sympy import Dummy, Equality
    x, y, z = Dummy('x'), Dummy('y'), Dummy('z')
    x_id, y_id, z_id = [str(d.dummy_index) for d in [x, y, z]]
    expr = Equality(z, x + y)
    routine = make_routine("test", expr)
    code_gen = CythonCodeWrapper(CCodeGen())
    source = get_string(code_gen.dump_pyx, [routine])
    expected_template = (
        "cdef extern from 'file.h':\n"
        "    void test(double x_{x_id}, double y_{y_id}, double *z_{z_id})\n"
        "\n"
        "def test_c(double x_{x_id}, double y_{y_id}):\n"
        "\n"
        "    cdef double z_{z_id} = 0\n"
        "    test(x_{x_id}, y_{y_id}, &z_{z_id})\n"
        "    return z_{z_id}")
    expected = expected_template.format(x_id=x_id, y_id=y_id, z_id=z_id)
    assert source == expected
Esempio n. 9
0
def test_cython_wrapper_compile_flags():
    from sympy import Equality
    x, y, z = symbols('x,y,z')
    routine = make_routine("test", Equality(z, x + y))

    code_gen = CythonCodeWrapper(CCodeGen())

    expected = """\
try:
    from setuptools import setup
    from setuptools import Extension
except ImportError:
    from distutils.core import setup
    from distutils.extension import Extension
from Cython.Build import cythonize
cy_opts = {}

ext_mods = [Extension(
    'wrapper_module_0', ['wrapper_module_0.pyx', 'wrapped_code_0.c'],
    include_dirs=[],
    library_dirs=[],
    libraries=[],
    extra_compile_args=['-std=c99'],
    extra_link_args=[]
)]
setup(ext_modules=cythonize(ext_mods, **cy_opts))
"""
    temp_dir = tempfile.mkdtemp()
    setup_file_path = os.path.join(temp_dir, 'setup.py')

    code_gen._prepare_files(routine, build_dir=temp_dir)
    with open(setup_file_path) as f:
        setup_text = f.read()
    assert setup_text == expected

    code_gen = CythonCodeWrapper(
        CCodeGen(),
        include_dirs=['/usr/local/include', '/opt/booger/include'],
        library_dirs=['/user/local/lib'],
        libraries=['thelib', 'nilib'],
        extra_compile_args=['-slow-math'],
        extra_link_args=['-lswamp', '-ltrident'],
        cythonize_options={'compiler_directives': {
            'boundscheck': False
        }})

    expected = """\
try:
    from setuptools import setup
    from setuptools import Extension
except ImportError:
    from distutils.core import setup
    from distutils.extension import Extension
from Cython.Build import cythonize
cy_opts = {'compiler_directives': {'boundscheck': False}}

ext_mods = [Extension(
    'wrapper_module_0', ['wrapper_module_0.pyx', 'wrapped_code_0.c'],
    include_dirs=['/usr/local/include', '/opt/booger/include'],
    library_dirs=['/user/local/lib'],
    libraries=['thelib', 'nilib'],
    extra_compile_args=['-slow-math', '-std=c99'],
    extra_link_args=['-lswamp', '-ltrident']
)]
setup(ext_modules=cythonize(ext_mods, **cy_opts))
"""
    code_gen._prepare_files(routine, build_dir=temp_dir)
    with open(setup_file_path) as f:
        setup_text = f.read()
    assert setup_text == expected

    expected = """\
try:
    from setuptools import setup
    from setuptools import Extension
except ImportError:
    from distutils.core import setup
    from distutils.extension import Extension
from Cython.Build import cythonize
cy_opts = {'compiler_directives': {'boundscheck': False}}
import numpy as np

ext_mods = [Extension(
    'wrapper_module_0', ['wrapper_module_0.pyx', 'wrapped_code_0.c'],
    include_dirs=['/usr/local/include', '/opt/booger/include', np.get_include()],
    library_dirs=['/user/local/lib'],
    libraries=['thelib', 'nilib'],
    extra_compile_args=['-slow-math', '-std=c99'],
    extra_link_args=['-lswamp', '-ltrident']
)]
setup(ext_modules=cythonize(ext_mods, **cy_opts))
"""

    code_gen._need_numpy = True
    code_gen._prepare_files(routine, build_dir=temp_dir)
    with open(setup_file_path) as f:
        setup_text = f.read()
    assert setup_text == expected
Esempio n. 10
0
def test_cython_wrapper_compile_flags():
    from sympy import Equality
    x, y, z = symbols('x,y,z')
    routine = make_routine("test", Equality(z, x + y))

    code_gen = CythonCodeWrapper(CCodeGen())

    expected = """\
try:
    from setuptools import setup
    from setuptools import Extension
except ImportError:
    from distutils.core import setup
    from distutils.extension import Extension
from Cython.Build import cythonize
cy_opts = {}

ext_mods = [Extension(
    'wrapper_module_%(num)s', ['wrapper_module_%(num)s.pyx', 'wrapped_code_%(num)s.c'],
    include_dirs=[],
    library_dirs=[],
    libraries=[],
    extra_compile_args=['-std=c99'],
    extra_link_args=[]
)]
setup(ext_modules=cythonize(ext_mods, **cy_opts))
""" % {'num': CodeWrapper._module_counter}

    temp_dir = tempfile.mkdtemp()
    setup_file_path = os.path.join(temp_dir, 'setup.py')

    code_gen._prepare_files(routine, build_dir=temp_dir)
    with open(setup_file_path) as f:
        setup_text = f.read()
    assert setup_text == expected

    code_gen = CythonCodeWrapper(CCodeGen(),
                                 include_dirs=['/usr/local/include', '/opt/booger/include'],
                                 library_dirs=['/user/local/lib'],
                                 libraries=['thelib', 'nilib'],
                                 extra_compile_args=['-slow-math'],
                                 extra_link_args=['-lswamp', '-ltrident'],
                                 cythonize_options={'compiler_directives': {'boundscheck': False}}
                                 )
    expected = """\
try:
    from setuptools import setup
    from setuptools import Extension
except ImportError:
    from distutils.core import setup
    from distutils.extension import Extension
from Cython.Build import cythonize
cy_opts = {'compiler_directives': {'boundscheck': False}}

ext_mods = [Extension(
    'wrapper_module_%(num)s', ['wrapper_module_%(num)s.pyx', 'wrapped_code_%(num)s.c'],
    include_dirs=['/usr/local/include', '/opt/booger/include'],
    library_dirs=['/user/local/lib'],
    libraries=['thelib', 'nilib'],
    extra_compile_args=['-slow-math', '-std=c99'],
    extra_link_args=['-lswamp', '-ltrident']
)]
setup(ext_modules=cythonize(ext_mods, **cy_opts))
""" % {'num': CodeWrapper._module_counter}

    code_gen._prepare_files(routine, build_dir=temp_dir)
    with open(setup_file_path) as f:
        setup_text = f.read()
    assert setup_text == expected

    expected = """\
try:
    from setuptools import setup
    from setuptools import Extension
except ImportError:
    from distutils.core import setup
    from distutils.extension import Extension
from Cython.Build import cythonize
cy_opts = {'compiler_directives': {'boundscheck': False}}
import numpy as np

ext_mods = [Extension(
    'wrapper_module_%(num)s', ['wrapper_module_%(num)s.pyx', 'wrapped_code_%(num)s.c'],
    include_dirs=['/usr/local/include', '/opt/booger/include', np.get_include()],
    library_dirs=['/user/local/lib'],
    libraries=['thelib', 'nilib'],
    extra_compile_args=['-slow-math', '-std=c99'],
    extra_link_args=['-lswamp', '-ltrident']
)]
setup(ext_modules=cythonize(ext_mods, **cy_opts))
""" % {'num': CodeWrapper._module_counter}

    code_gen._need_numpy = True
    code_gen._prepare_files(routine, build_dir=temp_dir)
    with open(setup_file_path) as f:
        setup_text = f.read()
    assert setup_text == expected
Esempio n. 11
0
# Use codegen and autowrap to write c code and wrappers
from sympy.utilities.autowrap import CythonCodeWrapper
from sympy.utilities.codegen import CCodeGen
from sympy.utilities.codegen import Routine

routines = []
for ds, args in [(derivs, symbols('st dms sf1 f sf2')), (derivs_sfc, symbols('st dms sfc f sf2')),
                 (derivs_sfs, symbols('st dms sfc f sfs')),
                 (derivs_sfc_calib, symbols('st stm dms sfco sfcs f sf2o sf2s')),
                 (derivs_sfs_calib, symbols('st stm dms sfco sfcs f sfso sfss'))]:
    for name, expr in ds.iteritems():
        routines.append(Routine(name, expr, argument_sequence = args))

cgen = CCodeGen(project = 'P2VV')
with open(os.path.join(install_dir, "dilution_impl.c"), "w") as c_file:
    cgen.dump_c(routines, c_file, 'dilution')

with open(os.path.join(install_dir, "dilution.h"), "w") as h_file:
    cgen.dump_h(routines, h_file, 'dilution')

wrapper = CythonCodeWrapper(cgen)
with open(os.path.join(install_dir, "dilution.pyx"), "w") as wrapper_file:
    wrapper.dump_pyx(routines, wrapper_file, 'dilution')

# Call cython to create the python wrapper c file.
import subprocess
pwd = os.path.realpath('.')
wd = os.chdir(install_dir)
subprocess.call(['cython', 'dilution.pyx'])
os.chdir(pwd)