I just wrote cython code just as simple as that
# distutils: language = c++
from libcpp.map cimport map,pair
from ios import *
cdef map[int,int] * u = new map[int,int]()
cdef add_item(int n, int x):
cdef pair[int,int]p = pair[int,int](n,x)
u.insert(p)
def add(int n, int x):
add_item(n,x)
added build file like
def make_ext(modname, pyxfilename):
from distutils.extension import Extension
return Extension(name=modname,
sources=[pyxfilename],
language='C++')
and run simple script like
import hello
with lines
import pyximport
pyximport.install()
in my sitecustomize.py
At script execution i get ImportError: Building module hello failed: ['ImportError: /home/odomontois/.pyxbld/lib.linux-x86_64-2.7/hello.so: undefined symbol: _ZTINSt8ios_base7failureE\n']
c++filt _ZTINSt8ios_base7failureE prints typeinfo for std::ios_base::failure
Is there any possibility to find out what object file i should include and how to do this in my pyxbld file for example.
Resolved by adding
libraries=["stdc++"]
to pyxbld
Related
I have this setup.py for my Cython project:
from setuptools import setup
from Cython.Build import cythonize
setup(
name = 'phase-engine',
version = '0.1',
ext_modules = cythonize(["phase_engine.pyx"] + ['music-synthesizer-for-android/src/' + p for p in [
'fm_core.cc', 'dx7note.cc', 'env.cc', 'exp2.cc', 'fm_core.cc', 'fm_op_kernel.cc', 'freqlut.cc', 'lfo.cc', 'log2.cc', 'patch.cc', 'pitchenv.cc', 'resofilter.cc', 'ringbuffer.cc', 'sawtooth.cc', 'sin.cc', 'synth_unit.cc'
]],
include_path = ['music-synthesizer-for-android/src/'],
language = 'c++',
)
)
when I run buildozer, it gets angry about some Cython features only being available in C++ mode:
def __dealloc__(self):
del self.p_synth_unit
^
------------------------------------------------------------
phase_engine.pyx:74:8: Operation only allowed in c++
from which I understand it's ignoring my setup.py and doing its own somehow. How do I give it all these parameters?
CythonRecipe doesn't work well for Cython code that imports C/C++ code. Try CompiledComponentsPythonRecipe, or if you're having issues with #include <ios> or some other thing from the C++ STL, CppCompiledComponentsPythonRecipe:
from pythonforandroid.recipe import IncludedFilesBehaviour, CppCompiledComponentsPythonRecipe
import os
import sys
class MyRecipe(IncludedFilesBehaviour, CppCompiledComponentsPythonRecipe):
version = 'stable'
src_filename = "../../../phase-engine"
name = 'phase-engine'
depends = ['setuptools']
call_hostpython_via_targetpython = False
install_in_hostpython = True
def get_recipe_env(self, arch):
env = super().get_recipe_env(arch)
env['LDFLAGS'] += ' -lc++_shared'
return env
recipe = MyRecipe()
The dependency on setuptools is essential because of some weird stuff, otherwise you get an error no module named setuptools. The two other flags were also related to that error, the internet said they're relevant so I tried value combinations until one worked.
The LDFLAGS thing fixes an issue I had later (see buildozer + Cython + C++ library: dlopen failed: cannot locate symbol symbol-name referenced by module.so).
I am trying to do a complex exponential in Cython.
I have been able to cobble together the following code for my pyx:
from libc.math cimport sin, cos, acos, exp, sqrt, fabs, M_PI, floor, ceil
cdef extern from "complex.h":
double complex cexp(double complex z)
import numpy as np
cimport numpy as np
import cython
from cython.parallel cimport prange, parallel
def try_cexp():
cdef:
double complex rr1
double complex rr2
rr1 = 1j
rr2 = 2j
print(rr1*rr2)
#print(cexp(rr1))
Note that the print(cexp(rr1)) is commented. When the line is active, I get the following error when running setup.py:
error: command 'C:\\WinPYthon\\Winpython-64bit-3.4.3.6\\python-3.4.3.amd64\\scripts\\gcc.exe' failed with exit status 1
Note that when cexp is commented out, everything runs expected... I can run setup.py, and when I test the function it prints out the product of the two complex numbers.
Here is my setup.py file. Note that it includes code to run openmp in Cython using g++:
from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension
from Cython.Distutils import build_ext
import numpy as np
import os
os.environ["CC"] = "g++-4.7"
os.environ["CXX"] = "g++-4.7"
# These were added based on some examples I had seen of cexp in Cython. No effect.
#import pyximport
#pyximport.install(reload_support=True)
ext_modules = [
Extension('complex_test',
['complex_test.pyx'],
language="c++",
extra_compile_args=['-fopenmp'],
extra_link_args=['-fopenmp', '-lm']) # Note that '-lm' was
# added due to an example where someone mentioned g++ required
# this. Same results with and without it.
]
setup(
name='complex_test',
cmdclass={'build_ext': build_ext},
ext_modules=ext_modules,
include_dirs=[np.get_include()]
)
Ultimately my goal is to speed up a calcualtion that looks like k*exp(z), where k and z are complex. Currently I am using Numerical expressions, however that has a large memory overhead, and I believe that it's possible to optimize further than it can.
Thank you for your help.
You're using cexp instead of exp as it is in C++. Change your cdef extern to:
cdef extern from "<complex.h>" namespace "std":
double complex exp(double complex z)
float complex exp(float complex z) # overload
and your print call to:
print(exp(rr1))
and it should work as a charm.
I know the compilation messages are lengthy, but in there you can find the error that points to the culprit:
complex_test.cpp: In function ‘PyObject* __pyx_pf_12complex_test_try_cexp(PyObject*)’:
complex_test.cpp:1270:31: error: cannot convert ‘__pyx_t_double_complex {aka std::complex<double>}’ to ‘__complex__ double’ for argument ‘1’ to ‘__complex__ double cexp(__complex__ double)’
__pyx_t_3 = cexp(__pyx_v_rr1);
It's messy, but you can see the cause. *You're supplying a C++ defined type (__pyx_t_double_complex in Cython Jargon) to a C function which expects a different type (__complex__ double).
I am trying to compile some cython code files using distutils.core.setup
In order to prevent compilation from crashing but to continue as much as possible I put each file Extension in a try statement as such
from distutils.core import setup, Extension
from Cython.Build import cythonize
from Cython.Distutils import build_ext
import numpy as np
pyx = [#file 1
Extension('file1',
include_dirs=[np.get_include()],
sources ["file1.pyx"]),
#file 2
Extension('file2',
include_dirs=[np.get_include()],
language="c",
sources = ["file2.pyx"]),
#rest of files
]
# compile extensions
for E in pyx :
try:
setup( ext_modules = [E], cmdclass={'build_ext': build_ext})
except Exception as e:
print "THIS IS AN ERROR", e
All is working nicely except when there is an error, try and catch seems to be useless. The compilation will stop without going through except statement.
Any idea why and what to do?
SystemExit must be included in the except
# compile extensions
for E in pyx :
try:
setup( ext_modules = [E], cmdclass={'build_ext': build_ext})
except (Exception, SystemExit) as e:
print "THIS IS AN ERROR", e
I have been trying to get over my fear of Cython (fear because I literally know NOTHING about c, or c++)
I have a function which takes 2 arguments, a set (we'll call it testSet), and a list of sets (we'll call that targetSets). The function then iterates through targetSets, and computes the length of the intersection with testSet, adding that value to a list, which is then returned.
Now, this isn't by itself that slow, but the problem is I need to do simulations of the testSet (and a large number at that, ~ 10,000), and the targetSet is about 10,000 sets long.
So for a small number of simulations to test, the pure python implementation was taking ~50 secs.
I tried making a cython function, and it worked and it's now running at ~16 secs.
If there is anything else that I could do to the cython function that anyone could think of that would be great (python 2.7 btw)
Here is my Cython implementation in overlapFunc.pyx
def computeOverlap(set testSet, list targetSets):
cdef list obsOverlaps = []
cdef int i, N
cdef set overlap
N = len(targetSets)
for i in range(N):
overlap = testSet & targetSets[i]
if len(overlap) <= 1:
obsOverlaps.append(0)
else:
obsOverlaps.append(len(overlap))
return obsOverlaps
and the setup.py
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules = [Extension("overlapFunc",
["overlapFunc.pyx"])]
setup(
name = 'computeOverlap function',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)
and some code to build some random sets for testing and to time the function. test.py
import numpy as np
from overlapFunc import computeOverlap
import time
def simRandomSet(n):
for i in range(n):
simSet= set(np.random.randint(low=1, high=100, size=50))
yield simSet
if __name__ == '__main__':
np.random.seed(23032014)
targetSet = [set(np.random.randint(low=1, high=100, size=50)) for i in range(10000)]
simulatedTestSets = simRandomSet(200)
start = time.time()
for i in simulatedTestSets:
obsOverlaps = computeOverlap(i, targetSet)
print time.time()-start
I tried changing the def at the start of the computerOverlap function, as in:
cdef list computeOverlap(set testSet, list targetSets):
but I get the following warning message when I run the setup.py script:
'__pyx_f_11overlapFunc_computeOverlap' defined but not used [-Wunused-function]
and then when I run something that tries to use the function I get an import Error:
from overlapFunc import computeOverlap
ImportError: cannot import name computeOverlap
Thanks in advance for your help,
Cheers,
Davy
In the following line, the extension module name and the filename does not match actual filename.
ext_modules = [Extension("computeOverlapWithGeneList",
["computeOverlapWithGeneList.pyx"])]
Replace it with:
ext_modules = [Extension("overlapFunc",
["overlapFunc.pyx"])]
I'm working on osx 10.8.4 64 bit with python 2.7, cython 0.19.1 and numpy 1.6.1.
I'm trying to create an c++ extension to be used with python. The c++ code is given and I wrote a wrapper c++ class to make using the needed functions in python easier.Compiling works but importing the extension file causes the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: dlopen(./mserP.so, 2): Symbol not found: __ZN4mser12MSERDetectorC1Ejj
Referenced from: ./mserP.so
Expected in: flat namespace
in ./mserP.so
I tried a smaller example with an easy c++ class with a function that has got a numpy array as its argument. Importing and using of the extension file works great!
Here the wrapper class (maser_wrapper.cpp):
#include "mser_wrapper.h"
#include "mser.h"
#include <iostream>
namespace mser {
CallMser::CallMser(unsigned int imageSizeX,unsigned int imageSizeY)
{
//Create MSERDetector
mser::MSERDetector* detector = new mser::MSERDetector(imageSizeX, imageSizeY);
}
CallMser::~CallMser()
{
delete detector;
}
}
And here the cython file (mserP.pyx):
# distutils: language = c++
# distutils: sources= mser_wrapper.cpp
cdef extern from "mser_wrapper.h" namespace "mser":
cdef cppclass CallMser:
CallMser(unsigned int, unsigned int) except +
cdef class PyCallMser:
cdef CallMser *thisptr
def __cinit__(self, unsigned int imageSizeX, unsigned int imageSizeY):
self.thisptr = new CallMser(imageSizeX, imageSizeY)
def __dealloc__(self):
del self.thisptr
Last but not least the setup.py:
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize(
"mserP.pyx", # our Cython source
sources=["mser_wrapper.cpp"], # additional source file(s)
language="c++", # generate C++ code
))
In namespace "mser" the class "MSERDetector" exists but cannot be found. It's defined in the header file "mser.h" which is included by my wrapper class.
Has anybody an idea what the problem could be? Thanks!
You are missing the object code from mser.cpp. Tell cython to include it by adding it to the sources in setup.py and distutil sources in the cython file.