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:

how can set cython compiler flags when using pyximport?


Comments

Popular posts from this blog

scala - 'wrong top statement declaration' when using slick in IntelliJ -

c# - DevExpress.Wpf.Grid.InfiniteGridSizeException was unhandled -

PySide and Qt Properties: Connecting signals from Python to QML -