Stop python code in module (Fortran) using f2py?

I am creating a Python module in Fortran using f2py . I want to get an error (including an error message) in a Python program if an error is detected in the Fortran module. Consider the following example:

Fortran Code (test.f):

 subroutine foo(a,m) integer :: m,i integer, dimension(m) :: a !f2py intent(in) :: m !f2py intent(in,out) :: a !f2py intent(hide), depend(a) :: m=shape(a) do i = 1,m if ( a(i) .eq. 0 ) then print*, 'ERROR HERE..?' end if a(i) = a(i)+1 end do end subroutine 

This simple program adds 1 to each element of a . But an error should occur if a(i) is zero. The accompanying Python code:

 import test print test.foo(np.array([1,2],dtype='uint32')) print test.foo(np.array([0,2],dtype='uint32')) 

Now the conclusion:

 [2 3] ERROR HERE..? [1 3] 

But I want the Python program to keep the error . Please, help.

Answer

The stop command in Fortran does just that. Consider the updated Fortran code:

 subroutine foo(a,m) integer :: m,i integer, dimension(m) :: a !f2py intent(in) :: m !f2py intent(in,out) :: a !f2py intent(hide), depend(a) :: m=shape(a) do i = 1,m if ( a(i) .eq. 0 ) then print*, 'Error from Fortran' stop end if a(i) = a(i)+1 end do end subroutine 

Now the conclusion:

 [2 3] Error from Fortran 

those. Python code will not continue after an error.

+7
python fortran f2py
source share
2 answers

f2py provides some instructions that you can use to create exceptions. See here for more details:

http://cens.ioc.ee/projects/f2py2e/usersguide/#statements

In particular, see the callstatement for a description of how to add f2py_success = 0 , which will throw an exception.

I'm not sure if this helps you debug the internals of the fortran library, but at least this is the beginning.

+1
source share

I suggested to the numpy community to add the addition of an additional f2py extension ( raise_python_exception ), which allows you to define a string variable in Fortran, which, if not empty, will cause Python to raise an exception after the function returns.

So in Fortran you should write something like:

 subroutine calc_dq(q, temp, dq, error_mesg) !f2py raise_python_exception error_mesg real, intent(in) :: q, temp real, intent(out) :: dq character(len=100), intent(out) :: error_mesg if (.not. init_called()) then error_mesg = "`init` hasn't been called." else call q_flux_function(q, temp, dq) endif end subroutine calc_dq 

And the contents of the variable error_mesg are called from Python error_mesg used as the contents of the exception:

 In [2]: calc_dq(1.0, 300.) --------------------------------------------------------------------------- Exception Traceback (most recent call last) <ipython-input-8-c0ce0cb9cda1> in <module>() ----> 1 calc_dq(1.0, 300.) Exception: `init` hasn't been called. 

I think this is a pretty convenient way to catch exceptions from Fortran, since it makes it easy to define an exception message. I put the sentence on github .

+1
source share

All Articles