这是我的第一个问题,所以对我好一点。
我正在使用 numpy 1.6.1 中的 f2py。我有一个 fortran 模块,其中包含几个子例程,可以很好地编译(和工作)。然而,其中一个使用 erf(x) 函数,它是一个 GNU 扩展。对于我的目的来说,它不够准确,所以我正在尝试使用外部 erf 实现。
我正在尝试使用 fortran 77 中的数字配方中的一个 - 我将所有相关函数复制到与我的模块位于同一文件夹中的一个名为"erf.f"的文件中。我在模块文件的顶部使用include 'erf.f'
。我更改为"derf"的erf函数的实际名称,因此它不会与gfortran erf扩展冲突。
但是,当我尝试通过 f2py 编译时,"erf.f"中foo
的每个函数都会出错
错误:"FOO"的重新定义 错误:以前对"FOO"的定义在这里
当我查看提到包含重定义和先前定义的 c 文件时,似乎该函数确实存在两次。我只是不知道为什么?
有人知道如何解决这个问题吗?干杯。
编辑:我没有提到(因为我认为这是不必要的额外信息)numpy distutils正在使用f2py来创建扩展。我现在提到它的原因是我发现我可以用 f2py -c my_module.f90 -m mod
很好地创建扩展,但是当运行python setup.py install
时,我收到上面详述的错误。那么 f2py 在通过 distutils 运行时有什么不同呢?
编辑#2:如果我将外部erf函数文件的所有内容放入与模块相同的文件中,那么一切正常。我真的不想这样做,因为展望未来,我将拥有一个庞大的文件,但它现在会起作用,直到我得到这个问题的答案。
一种解决方案是创建一个模块erf.f90
并使用use erf
(或任何名称)将其导入主代码中。
我在导入以.f
扩展名命名的模块时遇到了一些奇怪的问题f2py
,您只需将erf.f
重命名为 erf.f90
并在使用 gfortran
编译时指定-ffixed-form
即可使其工作。
编辑:
如果使用 use
导入模块,则不需要同时使用 include
。 include
基本上是在主代码的源代码中包含erf.f
的实际代码(尽管正如您所注意到的,它的行为与直接在主文件中键入erf.f
并不完全相同),而use
告诉编译器查找预编译的模块。
我发现在使用模块和f2py
时use
对我来说效果很好。 (我的代码基本上是固定的Fortran 90)。 假设一个主文件main.f
,并且subs.f90
一个模块(确保subs.f90
中有module...end module
,我将使用以下顺序进行编译:
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编译器。