f2py给“重新定义'foo'......之前的定义在这里”

时间:2012-06-22 00:46:07

标签: python fortran f2py

这是我的第一个问题,所以对我很好。

我正在使用来自numpy 1.6.1的f2py。我有一个fortran模块,包含几个子程序,编译(和工作)就好了。但是,其中一个使用erf(x)函数,它是一个GNU扩展。这对我的目的来说不够准确,所以我试图使用外部erf实现。

我正在尝试使用fortran 77中的Numerical Recipes中的一个 - 我已将所有相关功能复制到一个名为'erf.f'的文件中,与我的模块位于同一文件夹中。我在模块文件的顶部使用include 'erf.f'。我将erf函数的实际名称更改为'derf',因此它不会与gfortran erf扩展名冲突。

但是,当我尝试通过f2py进行编译时,'erf.f'中的每个函数foo都会出现错误

  

错误:重新定义'foo'   错误:'foo'的先前定义在这里

当我查看提到的包含重新定义和先前定义的c文件时,似乎该函数存在两次。我只是不知道为什么?

有人知道如何解决这个问题吗?欢呼声。

编辑:我没有提及(因为我认为这是不必要的额外信息)numpy distutils正在使用f2py来创建扩展。我现在提到它的原因是我发现我可以使用f2py -c my_module.f90 -m mod创建扩展名,但是在运行python setup.py install时,我得到了上面详述的错误。那么当通过distutils运行时,f2py的作用有何不同?

编辑#2:如果我将外部erf函数文件的所有内容放入与我的模块相同的文件中,那么一切正常。我真的不想这样做,因为展望未来我会有一个文件的怪异,但它现在可以工作,直到我得到这个问题的答案。

1 个答案:

答案 0 :(得分:0)

一个解决方案是创建一个模块erf.f90并使用use erf(或其名称)将其导入主代码中。

f2py导入以.f扩展名命名的模块时出现了一些奇怪的问题,您可以通过将erf.f重命名为erf.f90来使其工作正常使用-ffixed-form进行编译时指定gfortran

修改

如果您使用use导入模块,则无需使用includeinclude基本上包含了主代码源中erf.f的实际代码(尽管如您所知,它与将erf.f直接键入主文件的行为完全不同),use告诉编译器寻找预编译的模块。

我发现use在使用模块和f2py时对我很有用。 (我的代码基本上是固定形式的Fortran 90)。假设主文件main.f和模块subs.f90(确保module...end module中有subs.f90,我将使用以下序列进行编译:

gfortran -ffixed-form -c subs.f90
f2py.py -c -m main -I/path/to/subs /path/to/subs/subs.f90 main.f

请注意,您可能需要为f2py指定其他选项,具体取决于您的系统。对我来说,在Windows上使用MinGW,我需要--compiler=mingw32,因为f2py似乎无法找到C编译器。