Python のモジュールをCで書く。行列の積。
python から2次元のリストを2つ投げて、行列の積を2次元のリストでを返すモジュールをCで書いてみました。buildはiccを使った時のものです。
#include <Python.h> #include <stdio.h> #include <stdlib.h> #include <math.h> static PyObject* matrix(PyObject *matrix1,PyObject *matrix2) { long i,j,k; PyObject* out_matrix,*d1_list,*temp_l1,*temp_l2; long line1=PyList_Size(matrix1); long low1=PyList_Size(PyList_GetItem(matrix1,0)); long line2=PyList_Size(matrix2); long low2=PyList_Size(PyList_GetItem(matrix2,0)); double double1,double2; double d2_outmat[line1][low2]; out_matrix=PyList_New(line1); if(low1!=line2){ return NULL; } for(i=0;i<line1;i++){ for(j=0;j<low2;j++){ d2_outmat[i][j]=0; } } for(i=0;i<line1;i++){ for(j=0;j<low2;j++){ for(k=0;k<low1;k++){ temp_l1=PyList_GetItem(matrix1,i); temp_l2=PyList_GetItem(matrix2,k); double1=PyFloat_AsDouble(PyList_GetItem(temp_l1,k)); double2=PyFloat_AsDouble(PyList_GetItem(temp_l2,j)); d2_outmat[i][j]+=double1*double2; } } } for(i=0;i<line1;i++){ d1_list=PyList_New(low2); for(j=0;j<low2;j++){ PyList_SetItem(d1_list,j,PyInt_FromLong(d2_outmat[i][j])); } PyList_SetItem(out_matrix,i,d1_list); } return out_matrix; } static PyObject* wrap_matrix(PyObject* self,PyObject* args) { PyObject *matrix1,*matrix2; if(!PyArg_ParseTuple(args,"OO", &matrix1, &matrix2 )){ return NULL; } return matrix(matrix1,matrix2); } static PyMethodDef matrixmethods[]={ {"matrix",wrap_matrix,METH_VARARGS}, {NULL}, }; void initmatrix() { Py_InitModule("matrix",matrixmethods); }
build
#! /usr/enb/bin python from distutils.core import setup,Extension from distutils.command import build_py, build_ext from distutils.errors import DistutilsPlatformError from distutils.unixccompiler import UnixCCompiler class MyIntelCCompiler(UnixCCompiler): compiler_type = "intel" executables = dict(UnixCCompiler.executables) executables.update({ "compiler" : ["icc", "-O3", "-xhost", "-no-prec-div","-fpic"], "compiler_so" : ["icc", "-O3", "-xhost", "-no-prec-div","-fpic"], "compiler_cxx" : ["icc", "-O3", "-xhost", "-no-prec-div","-fpic"], "linker_so" : ["icc", "-shared"], "linker_exe" : ["icc"], }) class matrix_build_ext(build_ext.build_ext): def run(self): import distutils.ccompiler def wrap_new_compiler(func): def _wrap_new_compiler(*args, **kwargs): try: return func(*args, **kwargs) except DistutilsPlatformError: return MyIntelCCompiler(None, kwargs["dry_run"], kwargs["force"]) return _wrap_new_compiler distutils.ccompiler.new_compiler = wrap_new_compiler(distutils.ccompiler.new_compiler) self.compiler = "intel" build_ext.build_ext.run(self) module1=Extension("matrixmodule",["cal_matrix.c"],extra_link_args=["-fPIC"]) setup(name='matrixmodule',version='1.0', cmdclass={"build_ext":matrix_build_ext}, description='calculate matrix', ext_modules=[module1])