这是一个从逻辑上将numpy数组传递给外部C函数的小巧但完整的示例
fc( int N, double* a, double* b, double* z ) # z = a + b
使用Cython。(这肯定是众所周知的人。欢迎评论。最后更改:2011年2月23日,对于Cython 0.14。)
首先阅读或略读 Cython构建
并与NumPy一起使用Cython。
2个步骤:
python f-setup.py build_ext --inplace
接通f.pyx
和fc.cpp
- >f.so
中,动态库python test-f.py
import f
负载f.so
;f.fpy( ... )
调用Cfc( ... )
。
python f-setup.py应用
distutils到运行用Cython,编译和链接:
cython f.pyx -> f.cpp
编译
f.cpp和
fc.cpp
链接
f.o fc.o- >
f.so,一个充满活力的lib了Python
import f将加载。
对于学生,我建议:绘制这些步骤的图表,浏览下面的文件,然后下载并运行它们。
(
distutils是一个庞大,复杂的软件包,用于制作要分发的Python软件包并安装它们。在这里,我们仅使用其中的一小部分进行编译并链接到
f.so。这一步骤与Cython无关,但可能会造成混淆;
.pyx中的简单错误可能会导致g ++编译和链接的页面出现模糊的错误消息。另请参阅
distutils的doc 和/或
distutils上的SO问题。)
如
make,
setup.py将重新运行
cython f.pyx,
g++ -c ... f.cpp如果
f.pyx比
f.cpp。
要清理,
rm -r build/。
的替代物
setup.py将是单独运行的步骤,在脚本或生成文件:
cython --cplus f.pyx -> f.cpp # see cython -h
g++ -c ... f.cpp -> f.o
g++ -c ... fc.cpp -> fc.o
cc-lib f.o fc.o -> dynamic library f.so。
修改
cc-lib-mac以下针对您的平台和安装的包装器:它不漂亮,但是很小。
有关Cython包装C的真实示例,请查看几乎所有SciKit中的.pyx文件 。
另请参阅:
适用于NumPy用户的Cython
和SO问题/已标记/ cython。
要解压缩以下文件,将其剪切为一个大文件,例如
cython-numpy-c-demo,然后在Unix中(在一个干净的新目录中)运行
sh cython-numpy-c-demo。
#--------------------------------------------------------------------------------cat >f.pyx <<!# f.pyx: numpy arrays -> extern from "fc.h"# 3 steps:# cython f.pyx -> f.c# link: python f-setup.py build_ext --inplace -> f.so, a dynamic library# py test-f.py: import f gets f.so, f.fpy below calls fc()import numpy as npcimport numpy as npcdef extern from "fc.h": int fc( int N, double* a, double* b, double* z ) # z = a + bdef fpy( N, np.ndarray[np.double_t,ndim=1] A, np.ndarray[np.double_t,ndim=1] B, np.ndarray[np.double_t,ndim=1] Z ): """ wrap np arrays to fc( a.data ... ) """ assert N <= len(A) == len(B) == len(Z) fcret = fc( N, <double*> A.data, <double*> B.data, <double*> Z.data ) # fcret = fc( N, A.data, B.data, Z.data ) grr char* return fcret!#--------------------------------------------------------------------------------cat >fc.h <<!// fc.h: numpy arrays from cython , double*int fc( int N, const double a[], const double b[], double z[] );!#--------------------------------------------------------------------------------cat >fc.cpp <<!// fc.cpp: z = a + b, numpy arrays from cython#include "fc.h"#include <stdio.h>int fc( int N, const double a[], const double b[], double z[] ){ printf( "fc: N=%d a[0]=%f b[0]=%f n", N, a[0], b[0] ); for( int j = 0; j < N; j ++ ){ z[j] = a[j] + b[j]; } return N;}!#--------------------------------------------------------------------------------cat >f-setup.py <<!# python f-setup.py build_ext --inplace# cython f.pyx -> f.cpp# g++ -c f.cpp -> f.o# g++ -c fc.cpp -> fc.o# link f.o fc.o -> f.so# distutils uses the Makefile distutils.sysconfig.get_makefile_filename()# for compiling and linking: a sea of options.# http://docs.python.org/distutils/introduction.html# http://docs.python.org/distutils/apiref.html 20 pages ...# https://stackoverflow.com/questions/tagged/distutils+pythonimport numpyfrom distutils.core import setupfrom distutils.extension import Extensionfrom Cython.Distutils import build_ext# from Cython.Build import cythonizeext_modules = [Extension( name="f", sources=["f.pyx", "fc.cpp"], # extra_objects=["fc.o"], # if you compile fc.cpp separately include_dirs = [numpy.get_include()], # .../site-packages/numpy/core/include language="c++", # libraries= # extra_compile_args = "...".split(), # extra_link_args = "...".split() )]setup( name = 'f', cmdclass = {'build_ext': build_ext}, ext_modules = ext_modules, # ext_modules = cythonize(ext_modules) ? not in 0.14.1 # version= # description= # author= # author_email= )# test: import f!#--------------------------------------------------------------------------------cat >test-f.py <<!#!/usr/bin/env python# test-f.pyimport numpy as npimport f # loads f.so from cc-lib: f.pyx -> f.c + fc.o -> f.soN = 3a = np.arange( N, dtype=np.float64 )b = np.arange( N, dtype=np.float64 )z = np.ones( N, dtype=np.float64 ) * np.NaNfret = f.fpy( N, a, b, z )print "fpy -> fc z:", z!#--------------------------------------------------------------------------------cat >cc-lib-mac <<!#!/bin/shme=${0##*/}case in"" ) set -- f.cpp fc.cpp ;; # default: g++ these-h* | --h* ) echo "$me [g++ flags] xx.c yy.cpp zz.o ... compiles .c .cpp .o files to a dynamic lib xx.so" exit 1esac# Logically this is simple, compile and link,# but platform-dependent, layers upon layers, gloom, doombase=${1%.c*}base=${base%.o}set -xg++ -dynamic -arch ppc -bundle -undefined dynamic_lookup -fno-strict-aliasing -fPIC -fno-common -DNDEBUG `# -g` -fwrapv -isysroot /Developer/SDKs/MacOSX10.4u.sdk -I/Library/frameworks/Python.framework/Versions/2.6/include/python2.6 -I${Pysite?}/numpy/core/include -O2 -Wall "$@" -o $base.so# undefs: nm -gpv $base.so | egrep '^ *U _+[^P]'!# 23 Feb 2011 13:38
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)