[英]f2py: strange behaviour for constants in module
I found some strange behaviour for f2py when working with global constants in a Fortran module. 在Fortran模块中使用全局常量时,我发现f2py有一些奇怪的行为。
Let's say I have a file test.f90, which looks like 假设我有一个文件test.f90,看起来像
module test1
real, parameter :: a = 12345.
end module test1
module test2
real*8, parameter :: a = 6789.
end module test2
If I wrap this with f2py using 如果我用f2py包装
f2py -c -m mymod test.f90
and running 并运行
python -c "import mymod as m; print m.test1.a; print m.test2.a"
I get 我懂了
12345.0
6789.0
which is pretty much you would expect. 这是您所期望的。 Both real and real*8 statements behave the same way. real和real * 8语句的行为相同。
For my actual project I need to compile my Fortran code with compiler flags, specifying explicit usage of double precision. 对于我的实际项目,我需要使用编译器标志来编译我的Fortran代码,并指定双精度的显式用法。 In Fortran, this works fine. 在Fortran中,这可以正常工作。 When I compile the above code as 当我将上面的代码编译为
f2py --f90flags="-fdefault-double-8 -fdefault-integer-8 -fdefault-real-8" -c -m mymod test.f90
I get as result 我得到的结果
python -c "import mymod as m; print m.test1.a; print m.test2.a"
0.0
6789.0
This is actually weird. 这实际上很奇怪。 The global variable is not initialized in the first case, it's value is zero. 在第一种情况下,全局变量未初始化,其值为零。 Is this a bug or is there a different way to specify explicit handling of double precision in f2py? 这是错误还是在f2py中指定了显式处理双精度的方法?
You're not specifying "explicit use of double precision" -- I would argue that you're specifying "implicit use of double precision" and numpy/f2py has no way of knowing the datatype. 您不是在指定“显式使用双精度”,而是要在您指定“隐式使用双精度”,而numpy / f2py无法得知数据类型。 In this case, it is likely that f2py is guessing the datatype is float32, so only the first 32 bits of your (64-bit) parameter are actually being interpreted. 在这种情况下,很可能f2py猜测数据类型为float32,因此实际上仅解释了(64位)参数的前32位。 You can see the same effect if you pass a double precision number to a function which expects a float: 如果将双精度数字传递给需要浮点数的函数,则可以看到相同的效果:
program main
real*8 :: foo
foo = 12345.
call printme(foo)
end program
subroutine printme(foo)
real foo
print*, foo
end subroutine printme
compile and run: 编译并运行:
gfortran test2.f90
./a.out #prints 0.00000
The take-away here is that you're expecting f2py
to know how to interpret fortran code and also how to interpret commandline arguments for a particular compiler. 这里的f2py
是,您期望f2py
知道如何解释fortran代码以及如何解释特定编译器的命令行参数。 We might be able to argue that this type of support would be useful for a small set of compilers -- Unfortunately, it is currently not supported by f2py
. 我们也许可以争辩说,这种支持类型对少量编译器将很有用-不幸的是, f2py
目前不支持这种支持。
You need to declare all of your parameters and arguments to be a specific type and changing them on the command line will likely result in the kinds of errors that you see above. 您需要将所有参数和参数声明为特定类型,并且在命令行上更改它们可能会导致您在上面看到的各种错误。
I found a workaround so far. 到目前为止,我找到了一种解决方法。 The problem is that f2py does not recognize that it should map a fortran real
to a C-type double
when appropriate double precision compiler flags are provided. 问题在于,当提供适当的双精度编译器标志时,f2py无法识别它应将fortran real
映射到C类型的double
。
The solution is to tell f2py explicitly how to do the mapping of different data types. 解决方案是明确告诉f2py如何进行不同数据类型的映射。 This can be achieved by creating a file .f2py_f2cmap
which contains a python dictionary specifying the data type mapping. 这可以通过创建文件.f2py_f2cmap
来实现,该文件包含一个指定数据类型映射的python字典。 For details see here . 有关详细信息,请参见此处 。
In my case the following entry solved the problem 就我而言,以下条目解决了问题
{'real':{'':'double'},'integer':{'':'long'},'real*8':{'':'double'}}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.