【问题标题】:Cythonize a C function with array of complexCythonize 具有复杂数组的 C 函数
【发布时间】:2019-02-13 17:03:47
【问题描述】:

我正在分析分子动力学模拟数据,我想计算原子轨迹的中子散射光谱,以与我的实验进行比较。

我最初用纯 Python 编写了一些东西,但它很长,所以我想用 C 编写这部分代码并从 Python 调用 C 函数。

为此,我需要每个时间帧的原子坐标数组、要平均的倒数空间 q 向量数组以及周期性单元尺寸。 一切都放在一个复指数中,并在 q 个向量、时间原点和原子上取平均值。

问题来了,从 Python 调用 C 函数时如何使用复数数组? 我总是在 PowerShell 中使用 nmake 得到这些语法错误:

package/lib/src\compIntScatFunc.h(8): error C2143: erreur de syntaxe : absence de ')' avant '*'
package/lib/src\compIntScatFunc.h(8): error C2143: erreur de syntaxe : absence de '{' avant '*'
package/lib/src\compIntScatFunc.h(8): error C2059: erreur de syntaxe : 'type'
package/lib/src\compIntScatFunc.h(9): error C2059: erreur de syntaxe : ')'
package/lib/pycompIntScatFunc.c(1107): error C2061: erreur de syntaxe : identificateur '__pyx_t_double_complex'
package/lib/pycompIntScatFunc.c(1107): error C2059: erreur de syntaxe : ';'
package/lib/pycompIntScatFunc.c(1112): error C2061: erreur de syntaxe : identificateur '__pyx_t_double_complex_from_parts'
package/lib/pycompIntScatFunc.c(1112): error C2059: erreur de syntaxe : ';'
package/lib/pycompIntScatFunc.c(1112): error C2059: erreur de syntaxe : '<parameter-list>'
package/lib/pycompIntScatFunc.c(1119): error C2061: erreur de syntaxe : identificateur '__pyx_t_float_complex'
package/lib/pycompIntScatFunc.c(1119): error C2059: erreur de syntaxe : ';'
package/lib/pycompIntScatFunc.c(1124): error C2061: erreur de syntaxe : identificateur '__pyx_t_float_complex_from_parts'
package/lib/pycompIntScatFunc.c(1124): error C2059: erreur de syntaxe : ';'
package/lib/pycompIntScatFunc.c(1124): error C2059: erreur de syntaxe : '<parameter-list>'
package/lib/pycompIntScatFunc.c(1644): error C2065: '__pyx_t_double_complex' : identificateur non déclaré
package/lib/pycompIntScatFunc.c(1921): warning C4013: 'compIntScatFunc' non défini(e) ; extern retournant int pris par défaut
package/lib/pycompIntScatFunc.c(1921): error C2065: '__pyx_t_double_complex' : identificateur non déclaré
package/lib/pycompIntScatFunc.c(1921): error C2059: erreur de syntaxe : ')'
package/lib/pycompIntScatFunc.c(6580): error C2061: erreur de syntaxe : identificateur '__pyx_t_double_complex_from_parts'
package/lib/pycompIntScatFunc.c(6580): error C2059: erreur de syntaxe : ';'
package/lib/pycompIntScatFunc.c(6580): error C2059: erreur de syntaxe : '<parameter-list>'
package/lib/pycompIntScatFunc.c(6779): error C2061: erreur de syntaxe : identificateur '__pyx_t_float_complex_from_parts'
package/lib/pycompIntScatFunc.c(6779): error C2059: erreur de syntaxe : ';'
package/lib/pycompIntScatFunc.c(6779): error C2059: erreur de syntaxe : '<parameter-list>'

这是我的文件(.c 和 .h 文件可以用 gcc 编译):

compIntScatFunc.h

#ifndef COMPINTSCATFUNC_H
#define COMPINTSCATFUNC_H

#include <complex.h>

void compIntScatFunc(double *atomPos, int atomPos_dim0, int atomPos_dim1, int atomPos_dim2, 
                     double *qVecs, int qVecs_dim0, int qVecs_dim1, int qVecs_dim2, 
                     double complex *out, int out_dim0, int out_dim1, 
                     double *cellDims, int nbrBins, int minFrames, int maxFrames);

#endif

pycompIntScatFunc.pyx

cimport numpy as np
cimport cython

np.import_array()


cdef extern from "compIntScatFunc.h":
    void compIntScatFunc(double *atomPos, int atomPos_dim0, int atomPos_dim1, int atomPos_dim2, 
                         double *qVecs, int qVecs_dim0, int qVecs_dim1, int qVecs_dim2, 
                         double complex *out, int out_dim0, int out_dim1, 
                         double *cellDims, int nbrBins, int minFrames, int maxFrames)



@cython.boundscheck(False)
@cython.wraparound(False)
def py_compIntScatFunc( np.ndarray[double, ndim=3, mode="c"] atomPos not None,
                        np.ndarray[double, ndim=3, mode="c"] qVecs not None,
                        np.ndarray[np.complex128_t, ndim=2, mode="c"] out not None,
                        np.ndarray[double, ndim=1, mode="c"] cellDims not None,
                        nbrBins, minFrames, maxFrames ):
    compIntScatFunc(<double*> np.PyArray_DATA(atomPos), atomPos.shape[0], atomPos.shape[1], atomPos.shape[2],
                    <double*> np.PyArray_DATA(qVecs), qVecs.shape[0], qVecs.shape[1], qVecs.shape[2],
                    <double complex*> np.PyArray_DATA(out), out.shape[0], out.shape[1],
                    <double*> np.PyArray_DATA(cellDims), nbrBins, minFrames, maxFrames )

setup.py

from distutils.core import setup, Extension
from Cython.Build import cythonize
import numpy as np


with open('README.md', 'r') as f:
    description = f.read()


packagesList = [    'package',
                    'package.dataManipulation',
                    'package.dataParsers',
                    'package.dataConverters',
                    'package.helpersFunctions',
                    'package.test'  ]


pycompIntScatFunc_ext = Extension( "pycompIntScatFunc", 
                                    ["package/lib/pycompIntScatFunc.pyx", "package/lib/src/compIntScatFunc.c"],
                                    include_dirs=["package/lib/src", np.get_include()],
                                    libraries=["compIntScatFunc"],
                                    library_dirs=["pacakge/lib/"] )



setup(  name='NAMDAnalyzer',
        version='alpha',
        description=description,
        author='Kevin Pounot',
        author_email='kpounot@hotmail.fr',
        url='github.com/kpounot/NAMDAnalyzer',
        packages=packagesList,
        ext_modules=cythonize( [pycompIntScatFunc_ext] )  )

【问题讨论】:

  • 编译扩展时使用哪个编译器? MSVC?
  • 是的,确实调用了 cl 进行编译。我用 gcc 得到这个错误:“Unkown MS compiler version 1900”(我看到有一些补丁)。有没有办法让 MSVC 工作?我需要使用 Visual Studio 工具安装 python 吗?

标签: python c cython


【解决方案1】:

好的,实际上,添加以下内容:

[build]
compiler=gcc

并使用此处描述的补丁方法:ValueError: Unknown MS Compiler version 1900 解决了问题。

现在编译好了,谢谢ead。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-30
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多