Source code for instant.inlining

"""This module contains the inline* functions, which allows easy inlining of C/C++ functions."""

# Copyright (C) 2008-2010 Kent-Andre Mardal
# Copyright (C) 2008-2010 Martin Sandve Alnes
#
# This file is part of Instant.
#
# Instant is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Instant is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with Instant. If not, see <http://www.gnu.org/licenses/>.
#
# Alternatively, Instant may be distributed under the terms of the BSD license.

from .output import instant_assert, instant_warning, instant_error
from .build import build_module, build_module_vtk, build_module_vmtk


[docs]def get_func_name(c_code): # TODO: Something more robust? Regexp? try: func = c_code[:c_code.index('(')] ret, func_name = func.split() except: instant_error("Failed to extract function name from c_code.") return func_name
[docs]def inline(c_code, **kwargs): """This is a short wrapper around the build_module function in instant. It creates a module given that the input is a valid C function. It is only possible to inline one C function each time. Usage: >>> from instant import inline >>> add_func = inline("double add(double a, double b){ return a+b; }") >>> print "The sum of 3 and 4.5 is ", add_func(3, 4.5) """ instant_assert("code" not in kwargs, "Cannot specify code twice.") kwargs["code"] = c_code func_name = get_func_name(c_code) module = build_module(**kwargs) if hasattr(module, func_name): return getattr(module, func_name) else: instant_warning("Didn't find function '%s', returning module." % func_name) return module
[docs]def inline_module(c_code, **kwargs): """This is a short wrapper around the build_module function in instant. It creates a module given that the input is a valid C function. It is only possible to inline one C function each time. Usage: >>> from instant import inline >>> add_func = inline("double add(double a, double b){ return a+b; }") >>> print "The sum of 3 and 4.5 is ", add_func(3, 4.5) """ instant_assert("code" not in kwargs, "Cannot specify code twice.") kwargs["code"] = c_code module = build_module(**kwargs) return module
[docs]def inline_with_numpy(c_code, **kwargs): '''This is a short wrapper around the build_module function in instant. It creates a module given that the input is a valid C function. It is only possible to inline one C function each time. The difference between this function and the inline function is that C-arrays can be used. The following example illustrates that. Usage: >>> import numpy >>> import time >>> from instant import inline_with_numpy >>> c_code = """ double sum (int n1, double* array1){ double tmp = 0.0; for (int i=0; i<n1; i++) { tmp += array1[i]; } return tmp; } """ >>> sum_func = inline_with_numpy(c_code, arrays = [['n1', 'array1']]) >>> a = numpy.arange(10000000); a = numpy.sin(a) >>> sum_func(a) ''' import numpy instant_assert("code" not in kwargs, "Cannot specify code twice.") kwargs["code"] = c_code kwargs["init_code"] = kwargs.get("init_code", "") + "\nimport_array();\n" kwargs["system_headers"] = kwargs.get("system_headers", []) + ["numpy/arrayobject.h"] kwargs["include_dirs"] = kwargs.get("include_dirs", []) + ["%s" %numpy.get_include()] func_name = get_func_name(c_code) module = build_module(**kwargs) if hasattr(module, func_name): return getattr(module, func_name) else: instant_warning("Didn't find function '%s', returning module." % func_name) return module
[docs]def inline_module_with_numpy(c_code, **kwargs): '''This is a short wrapper around the build_module function in instant. It creates a module given that the input is a valid C function. It is only possible to inline one C function each time. The difference between this function and the inline function is that C-arrays can be used. The following example illustrates that. Usage: >>> import numpy >>> import time >>> from instant import inline_with_numpy >>> c_code = """ double sum (int n1, double* array1){ double tmp = 0.0; for (int i=0; i<n1; i++) { tmp += array1[i]; } return tmp; } """ >>> sum_func = inline_with_numpy(c_code, arrays = [['n1', 'array1']]) >>> a = numpy.arange(10000000); a = numpy.sin(a) >>> sum_func(a) ''' import numpy instant_assert("code" not in kwargs, "Cannot specify code twice.") kwargs["code"] = c_code kwargs["init_code"] = kwargs.get("init_code", "") + "\nimport_array();\n" kwargs["system_headers"] = kwargs.get("system_headers", []) + ["numpy/arrayobject.h"] kwargs["include_dirs"] = kwargs.get("include_dirs", []) + ["%s" % numpy.get_include()] module = build_module(**kwargs) return module
[docs]def inline_vtk(c_code, cache_dir=None): module = build_module_vtk(c_code) func_name = get_func_name(c_code) if hasattr(module, func_name): return getattr(module, func_name) else: instant_warning("Didn't find function '%s', returning module." % func_name) return module
[docs]def inline_vmtk(c_code, cache_dir=None): module = build_module_vmtk(c_code) func_name = get_func_name(c_code) if hasattr(module, func_name): return getattr(module, func_name) else: instant_warning("Didn't find function '%s', returning module." % func_name) return module