2013-08-02 10 views
7

Sto creando un modulo Python in Fortran utilizzando f2py. Vorrei produrre un errore (incluso il messaggio di errore) nel programma Python se si incontra un errore nel modulo Fortran. Si consideri il seguente esempio:Arresta il codice Python nell'errore del modulo (Fortran) usando f2py?

codice 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 

Questo semplice programma aggiunge 1 a ciascun elemento di a. Ma dovrebbe produrre un errore se a(i) uguale a zero. Il codice Python di accompagnamento:

import test 

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

L'uscita è ora:

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

Ma voglio il programma Python per tenere sull'errore. Per favore aiuto.

risposta

Il comando stop in Fortran fa esattamente questo. Si consideri il codice Fortran aggiornamento:

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 

L'uscita è ora:

[2 3] 
Error from Fortran 

Vale a dire il codice Python non continua dopo l'errore.

+1

Stai cercando di generare un'eccezione Python da un modulo Fortran? – user2357112

+1

Sì, questo è esattamente quello che sto cercando di fare –

+3

Un modo sarebbe quello di ritirare un codice di errore da Fortran, controllarlo in python side e generare un'eccezione se si verifica un errore. –

risposta

1

f2py fornisce alcune istruzioni che possono essere utilizzate per aumentare le eccezioni. Guarda i dettagli qui:

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

In particolare, guarda callstatement che descrive come aggiungere f2py_success = 0 che innescherà un'eccezione.

Non sono sicuro che questo ti aiuterà a eseguire il debug degli interni della libreria di fortran, ma almeno è un inizio.

1

Ho suggerito alla community numpy di aggiungere un ulteriore "potenziamento" f2py (raise_python_exception) che consente di definire una variabile stringa in Fortran che se non vuota farà sì che Python sollevi un'eccezione una volta che la funzione ritorna.

Quindi, in Fortran si potrebbe scrivere qualcosa di simile a:

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 

E chiamata da Python il contenuto della variabile error_mesg viene utilizzato come il contenuto di eccezione:

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. 

Penso che questo sia un modo abbastanza conveniente di generare eccezioni da Fortran in quanto consente di definire facilmente il messaggio di eccezione. Ho messo il mio suggestion on github.

+0

Il valore di 'error_mesg' non è definito nell'esempio nell'altro ramo condizionale. –

Problemi correlati