Skip to content

Instantly share code, notes, and snippets.

@zed
Created September 22, 2011 18:14
Show Gist options
  • Save zed/1235546 to your computer and use it in GitHub Desktop.
Save zed/1235546 to your computer and use it in GitHub Desktop.
Build 1d array of unknown size in Cython
/build/
*.so
*.cpp
/cachegrind.out.profilestats
/profilestats.prof
/build1darray.s
#cython: boundscheck=False, wraparound=False
"""
http://stackoverflow.com/questions/7403966/most-efficient-way-to-build-a-1-d-array-list-vector-of-unknown-length-using-cython
"""
from libc.math cimport log
from cython.parallel cimport prange
import numpy as pynp
cimport numpy as np
# copy declarations from libcpp.vector to allow nogil
cdef extern from "<vector>" namespace "std":
cdef cppclass vector[T]:
void push_back(T&) nogil except+
size_t size()
T& operator[](size_t)
def makearray(Py_ssize_t t):
cdef vector[np.float_t] v
cdef Py_ssize_t i
with nogil:
for i in range(t):
if i % 10 == 0:
v.push_back(log(i+1))
cdef np.ndarray[np.float_t] a = pynp.empty(v.size(), dtype=pynp.float)
for i in prange(a.shape[0], nogil=True):
a[i] = v[i]
return a
.PHONY: test clean
NAME = build1darray
test: $(NAME).so
python test_$(NAME).py
$(NAME).so: $(NAME).pyx
python setup.py build_ext -i
clean:
git clean -x -d -f
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
setup(ext_modules=[Extension(
"build1darray", # name of extension
["build1darray.pyx"], # our Cython source
language="c++", # causes Cython to create C++ source
extra_compile_args=['-fopenmp'],
extra_link_args=['-fopenmp'],
)],
cmdclass={'build_ext': build_ext})
import math
import numpy as np
from profilestats import profile # pip install profilestats
from build1darray import makearray
@profile
def test():
N = int(1e7)
assert np.allclose(makearray(N),
np.vectorize(lambda i, l=math.log: l(i+1))(np.arange(0, N, 10)))
if __name__=="__main__":
test()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment