2013-08-02 3 views
7

Я создаю модуль Python в Фортране, используя f2py. Я хочу получить ошибку (включая сообщение об ошибке) в программе Python, если в модуле Fortran обнаружена ошибка. Рассмотрим следующий пример:Остановить код python в (Fortran) с помощью f2py?

код Fortran (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 

Это очень простая программа добавляет 1 каждому элементу a. Но должно возникнуть ошибка, если a(i) равна нулю. Сопутствующий код Python:

import test 

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

выход теперь:

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

Но Я хочу, чтобы программа Python держать на ошибку. Пожалуйста помоги.

Ответ

stop команды в Fortran делает именно это. Рассмотрим обновленный Fortran код:

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 

Выход теперь:

[2 3] 
Error from Fortran 

Т.е. код Python не будет продолжен после ошибки.

+1

Вы пытаетесь поднять исключение Python из модуля Fortran? – user2357112

+1

Да, это именно то, что я пытаюсь сделать. –

+3

Одним из способов было бы переустановить код ошибки из Fortran, проверить его на стороне python и вызвать исключение, если возникла ошибка. –

ответ

1

f2py действительно содержит некоторые утверждения, которые можно использовать для создания исключений. Подробнее здесь:

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

В частности, обратите внимание на callstatement, который описывает, как добавить f2py_success = 0, которая вызовет исключение.

Я не уверен, что это поможет вам отладить внутренности библиотеки fortran, но, по крайней мере, это начало.

1

Я предлагаю сообществу numpy добавить дополнительный f2py «усовершенствование» (raise_python_exception), что позволяет определить строковую переменную в Fortran, что если непустое приведет к возникновению исключения Python после того, как функция возвращается.

Так Fortran можно было бы написать что-то вроде:

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 

И вызывается из Python содержание переменной error_mesg используется как содержание, за исключением:

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. 

Я думаю, что это довольно удобный способ создания исключений из Fortran, поскольку он позволяет легко определить сообщение об исключении. Я положил свой suggestion on github.

+0

Значение 'error_mesg' не определено в вашем примере в другой условной ветви. –

Смежные вопросы