python - How can I import an external C function into an IPython Notebook using Cython? -
i'd import c function ipython notebook using cython. currently, i'm trying replicate example in cython documentation, compilation error.
my python code (from ipython notebook):
import cython %load_ext cython
---------------------------------- new cell
%%cython cdef extern "spam.c": void order_spam(int tons)
my c code:
// spam.c #include <stdio.h> static void order_spam(int tons) { printf("ordered %i tons of spam!\n", tons); }
running code, following traceback , error message:
compileerror traceback (most recent call last) <ipython-input-13-8bb733557977> in <module>() ----> 1 get_ipython().run_cell_magic(u'cython', u'', u'\ncdef extern "spam.c":\n void order_spam(int tons)') /users/danielacker/anaconda2/lib/python2.7/site-packages/ipython/core/interactiveshell.pyc in run_cell_magic(self, magic_name, line, cell) 2118 magic_arg_s = self.var_expand(line, stack_depth) 2119 self.builtin_trap: -> 2120 result = fn(magic_arg_s, cell) 2121 return result 2122 <decorator-gen-126> in cython(self, line, cell) /users/danielacker/anaconda2/lib/python2.7/site-packages/ipython/core/magic.pyc in <lambda>(f, *a, **k) 191 # it's overkill 1 bit of state. 192 def magic_deco(arg): --> 193 call = lambda f, *a, **k: f(*a, **k) 194 195 if callable(arg): /users/danielacker/anaconda2/lib/python2.7/site-packages/cython/build/ipythonmagic.py in cython(self, line, cell) 276 build_extension.build_temp = os.path.dirname(pyx_file) 277 build_extension.build_lib = lib_dir --> 278 build_extension.run() 279 self._code_cache[key] = module_name 280 /users/danielacker/anaconda2/lib/python2.7/distutils/command/build_ext.pyc in run(self) 337 338 # compile , link everything. --> 339 self.build_extensions() 340 341 def check_extensions_list(self, extensions): /users/danielacker/anaconda2/lib/python2.7/distutils/command/build_ext.pyc in build_extensions(self) 446 447 ext in self.extensions: --> 448 self.build_extension(ext) 449 450 def build_extension(self, ext): /users/danielacker/anaconda2/lib/python2.7/distutils/command/build_ext.pyc in build_extension(self, ext) 496 debug=self.debug, 497 extra_postargs=extra_args, --> 498 depends=ext.depends) 499 500 # xxx -- vile hack! /users/danielacker/anaconda2/lib/python2.7/distutils/ccompiler.pyc in compile(self, sources, output_dir, macros, include_dirs, debug, extra_preargs, extra_postargs, depends) 572 except keyerror: 573 continue --> 574 self._compile(obj, src, ext, cc_args, extra_postargs, pp_opts) 575 576 # return *all* object filenames, not ones built. /users/danielacker/anaconda2/lib/python2.7/distutils/unixccompiler.pyc in _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts) 120 extra_postargs) 121 except distutilsexecerror, msg: --> 122 raise compileerror, msg 123 124 def create_static_lib(self, objects, output_libname, compileerror: command 'gcc' failed exit status 1
i've tried searching google error, can't seem find relevant.
the %cython
magic command probaby doesn't seem trick.
the %cython
magic command doesn't task here. in order compile need supply *.c
source file , (as far i'm aware) isn't allowed %cython
. (the source file indicates uses text entered in cell source file.)
wrap c
functions:
before presenting probable solution, let me point out .pyx
file have created doesn't wrap c
function order_spam
automatically. can have automatically wrapped if specify cpdef
inside cdef extern
block (alternatively wrap on own outside cdef extern
block, allows more flexibility).
i'll use filename of cyspam.pyx
cython file:
cdef extern "spam.c": cpdef void order_spam(int tons)
notice how i've prefixed function declaration cpdef
, instructs cython automatically wrap function.
use setup.py
script:
in order have full control on compilation process, need create setup.py
script has required sources, include directories et cetera, specified.
here's how setup.py
script should like:
from distutils.core import setup, extension cython.build import cythonize # specify c source file in sources list ext = extension('cyspam', sources = ['cyspam.pyx', 'spam.c']) setup(name="c spam", ext_modules = cythonize([ext]))
you can either create file via simple text editor or via ipython
%%writefile
magic command. setup.py
script should of course placed in same directory cyspam.pyx
, spam.c
files.
compile files:
you can either open terminal or use %%bash
command ipython
, either way trick. issue following command:
python setup.py build_ext --inplace
--inplace
places generated .so
file in current directory.
after doing these can import file cyspam
in ipython
, call wrapped c
function:
rounding commands ipython
:
all in all, if want ipython
you'll issue following commands:
in [1]: %%writefile setup.py ....: distutils.core import setup, extension ....: cython.build import cythonize ....: ext = extension('cyspam', sources = ['cyspam.pyx', 'spam.c']) ....: setup(name="c spam", ext_modules = cythonize([ext])) in [2]: %%bash ...: python setup.py build_ext --inplace in [3]: import cyspam in [4]: cyspam.order_spam(1000) ordered 1000 ammount of spam!
as alternative create .pyxbld
file specifies needed arguments pyximport.install()
. offers same level of control counter-intuitive python users have experience using setup.py
scripts.
see related:
Comments
Post a Comment