Skip to content

Instantly share code, notes, and snippets.

@aterrel
Last active December 29, 2015 14:28
Show Gist options
  • Save aterrel/7683716 to your computer and use it in GitHub Desktop.
Save aterrel/7683716 to your computer and use it in GitHub Desktop.
Cython Test
from __future__ import division
import numpy as np
# "cimport" is used to import special compile-time information
# about the numpy module (this is stored in a file numpy.pxd which is
# currently part of the Cython distribution).
cimport numpy as np
# We now need to fix a datatype for our arrays. I've used the variable
# DTYPE for this, which is assigned to the usual NumPy runtime
# type info object.
DTYPE = np.int
# "ctypedef" assigns a corresponding compile-time type to DTYPE_t. For
# every type in the numpy module there's a corresponding compile-time
# type with a _t-suffix.
ctypedef np.int_t DTYPE_t
# "def" can type its arguments but not have a return type. The type of the
# arguments for a "def" function is checked at run-time when entering the
# function.
#
# The arrays f, g and h is typed as "np.ndarray" instances. The only effect
# this has is to a) insert checks that the function arguments really are
# NumPy arrays, and b) make some attribute access like f.shape[0] much
# more efficient. (In this example this doesn't matter though.)
def naive_convolve(np.ndarray f, np.ndarray g):
if g.shape[0] % 2 != 1 or g.shape[1] % 2 != 1:
raise ValueError("Only odd dimensions on filter supported")
assert f.dtype == DTYPE and g.dtype == DTYPE
# The "cdef" keyword is also used within functions to type variables. It
# can only be used at the top indendation level (there are non-trivial
# problems with allowing them in other places, though we'd love to see
# good and thought out proposals for it).
#
# For the indices, the "int" type is used. This corresponds to a C int,
# other C types (like "unsigned int") could have been used instead.
# Purists could use "Py_ssize_t" which is the proper Python type for
# array indices.
cdef int vmax = f.shape[0]
cdef int wmax = f.shape[1]
cdef int smax = g.shape[0]
cdef int tmax = g.shape[1]
cdef int smid = smax // 2
cdef int tmid = tmax // 2
cdef int xmax = vmax + 2*smid
cdef int ymax = wmax + 2*tmid
cdef np.ndarray h = np.zeros([xmax, ymax], dtype=DTYPE)
cdef int x, y, s, t, v, w
# It is very important to type ALL your variables. You do not get any
# warnings if not, only much slower code (they are implicitly typed as
# Python objects).
cdef int s_from, s_to, t_from, t_to
# For the value variable, we want to use the same data type as is
# stored in the array, so we use "DTYPE_t" as defined above.
# NB! An important side-effect of this is that if "value" overflows its
# datatype size, it will simply wrap around like in C, rather than raise
# an error like in Python.
cdef DTYPE_t value
for x in range(xmax):
for y in range(ymax):
s_from = max(smid - x, -smid)
s_to = min((xmax - x) - smid, smid + 1)
t_from = max(tmid - y, -tmid)
t_to = min((ymax - y) - tmid, tmid + 1)
value = 0
for s in range(s_from, s_to):
for t in range(t_from, t_to):
v = x - smid + s
w = y - tmid + t
value += g[smid - s, tmid - t] * f[v, w]
h[x, y] = value
return h
#!/bin/bash
python setup.py build_ext --inplace 2>&1 | tee -a out
python -c "import convolve; print convolve.naive_convolve" 2>&1 | tee -a out
running build_ext
cythoning convolve.pyx to convolve.c
building 'convolve' extension
creating build
creating build/temp.macosx-10.5-x86_64-2.7
gcc -fno-strict-aliasing -I/Users/aterrel/workspace/opt/apps/anaconda/1.8.0/include -arch x86_64 -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Users/aterrel/workspace/opt/apps/anaconda/1.8.0/lib/python2.7/site-packages/numpy/core/include -I/Users/aterrel/workspace/opt/apps/anaconda/1.8.0/include/python2.7 -c convolve.c -o build/temp.macosx-10.5-x86_64-2.7/convolve.o
In file included from convolve.c:314:
In file included from /Users/aterrel/workspace/opt/apps/anaconda/1.8.0/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h:15:
In file included from /Users/aterrel/workspace/opt/apps/anaconda/1.8.0/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:17:
In file included from /Users/aterrel/workspace/opt/apps/anaconda/1.8.0/lib/python2.7/site-packages/numpy/core/include/numpy/ndarraytypes.h:1728:
/Users/aterrel/workspace/opt/apps/anaconda/1.8.0/lib/python2.7/site-packages/numpy/core/include/numpy/npy_deprecated_api.h:11:2: warning: "Using deprecated NumPy API, disable it by #defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-W#warnings]
#warning "Using deprecated NumPy API, disable it by #defining NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION"
^
In file included from convolve.c:314:
In file included from /Users/aterrel/workspace/opt/apps/anaconda/1.8.0/lib/python2.7/site-packages/numpy/core/include/numpy/arrayobject.h:15:
In file included from /Users/aterrel/workspace/opt/apps/anaconda/1.8.0/lib/python2.7/site-packages/numpy/core/include/numpy/ndarrayobject.h:26:
/Users/aterrel/workspace/opt/apps/anaconda/1.8.0/lib/python2.7/site-packages/numpy/core/include/numpy/__multiarray_api.h:1594:1: warning: unused function '_import_array' [-Wunused-function]
_import_array(void)
^
In file included from convolve.c:315:
In file included from /Users/aterrel/workspace/opt/apps/anaconda/1.8.0/lib/python2.7/site-packages/numpy/core/include/numpy/ufuncobject.h:311:
/Users/aterrel/workspace/opt/apps/anaconda/1.8.0/lib/python2.7/site-packages/numpy/core/include/numpy/__ufunc_api.h:236:1: warning: unused function '_import_umath' [-Wunused-function]
_import_umath(void)
^
3 warnings generated.
gcc -bundle -undefined dynamic_lookup -L/Users/aterrel/workspace/opt/apps/anaconda/1.8.0/lib -arch x86_64 -arch x86_64 build/temp.macosx-10.5-x86_64-2.7/convolve.o -L/Users/aterrel/workspace/opt/apps/anaconda/1.8.0/lib -o /Users/aterrel/workspace/scratch/cython_convolve/convolve.so
<built-in function naive_convolve>
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = [Extension("convolve", ["convolve.pyx"],
include_dirs=[np.get_include()]),]
)
_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment