使用ctypes和共享库时,NaN陷阱存在一些问题。该库是用Fortran编写的,由子程序组成,该子程序的行为“被零除”:

nantest.f90

subroutine nantest
    real :: a, b, c
    a = 0.
    b = 0.
    c = a/b
    print *, c,a,b
end subroutine nantest

program main
    call nantest
end program main


我使用以下选项从中创建了一个共享库:

gfortran -o nantest.os -c -g -fbacktrace -ffpe-trap=invalid,zero,overflow -fPIC nantest.f90
gfortran -o libnantest.so -shared nantest.os


然后我直接从Python脚本加载该库:

from ctypes import *
lib = CDLL('./libnantest.so')
lib.nantest_()


它给我的输出没有任何异常:

          NaN   0.00000000       0.00000000


怎么了?是ctypes还是编译器选项问题?
顺便说一句,当我直接执行使用相同编译器选项构建的“ nantest”程序时,我得到了想要的:

Program received signal SIGFPE: Floating-point exception - erroneous arithmetic operation.
Backtrace for this error:
#0  0x7F4D08B6FE08
#1  0x7F4D08B6EF90
#2  0x7F4D087C04AF
#3  0x40080D in nantest_ at nantest.f90:7
#4  0x4008B9 in MAIN__ at nantest.f90:14
Floating point exception


那么,如何在共享库的情况下获取NaN例外?
有什么建议吗?

最佳答案

Python运行时设置其自己的FPE模式。您可以尝试使用Fortran 2003过程在所需的确切位置设置FPE例外。它们位于内部模块IEEE_EXCEPTIONS中,例如过程ieee_get_halting_mode()。另见GFortran equivalent of ieee_exceptions

-ffpe-trap=invalid,zero,overflow仅在编译Fortran程序时有用。

或使用Python功能(https://docs.python.org/2/library/fpectl.html)来确定是否有任何浮点异常正在发出信号,但是我不知道Python和库之间的接口是否保留了它们。

关于python - 在共享库中设置NaN陷阱,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41200386/

10-12 04:24
查看更多