THYC Dear all, I'm working with some large inherited F90 code that needs to be wrapped in Python. if the code base itself cannot be modified (it's a static archive), some additional F90 files were written to help the interaction with the code. Writing a python extension combining the archive and these additional files is rather straightforward using F2PY, the extension loads, all is well but... ...when a problem occurs in a subroutine deep in the base code, it calls another routine (say, ENDRUN) which itself uses a STOP statement. As you know, this statement not only exits the fortran code, but makes the extension and then the interpreter crash... I patched ENDRUN use STOP, I tried to call a C external function instead of using STOP: """ *- ENDRUN.f90 -* subroutine ENDRUN(C_NOM) use endrun_wrap Implicit none character(LEN=*), intent(in) :: C_NOM ! write(*, *) C_NOM ! stop call pyraise_runtime(C_NOM) end subroutine ENDRUN *- ENDRUNWRAP.f90 -* module endrun_wrap interface subroutine pyraise_runtime(message) character(LEN=*), intent(in) :: message end subroutine pyraise_runtime end interface end module endrun_wrap *- pyraise_runtime.c -* #include <Python.h> void pyraise_runtime_(char *message); void pyraise_runtime_(char *message) { printf("calling PyErr_SetString(PyExc_RuntimeError, message)\n"); PyErr_SetString(PyExc_RuntimeError, message); } """ Alas, the RuntimeError doesn't look like it's passed back to the interpreter, which still crashes. (Adding a Py_Exit(-1) at the end of pyraise_runtime at least let the interpreter do some extra cleaning after the fortran code stopped, but still...) Note that ENDRUN is never supposed to be called directly by the user (so no point to define a callback function via f2py, right ?). Any idea would be quite welcome. Thanks an awful lot in advance. P. PS: Oh, BTW, I'm limited to numpy 1.4.1 and the f2py that comes with it...
14.03.2012 14:28, Pierre GM kirjoitti: [clip]
Alas, the RuntimeError doesn't look like it's passed back to the interpreter, which still crashes. (Adding a Py_Exit(-1) at the end of pyraise_runtime at least let the interpreter do some extra cleaning after the fortran code stopped, but still...)
Note that ENDRUN is never supposed to be called directly by the user (so no point to define a callback function via f2py, right ?).
The crash maybe occurs because if the code is not stopped, it writes out of bounds or something? You can try to use longjmp in ENDRUN to jump back to the beginning, and return an error code. YMMV, this probably plays all hell with cleanup etc. Or, maybe the whole Fortran stuff can be run in a separate process, so that crashing doesn't matter. Pauli
On Wed, Mar 14, 2012 at 9:25 AM, Pauli Virtanen <pav@iki.fi> wrote:
Or, maybe the whole Fortran stuff can be run in a separate process, so that crashing doesn't matter.
That's what I was going to suggest -- even if you can get it not to crash, it may well be in a bad state -- memory leaks, and who know what else. We did something similar with some C code that called the system exit() function when it encountered errors -- it may not have been too hard to replace those calls, but making sure the memory was all cleaned up was going to be a trick -- so we just used the multiprocess module to call it in another process. HTH, -Chris -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov
Pauli, Chris, Thanks for your inputs. Pauli, I think that when f2py encounters a STOP statement, it just stops the execution of the process. Alas, it's the same process as the interpreter... So we need a trick not to interrupt the whole process. I eventually resorted to patching f2py as suggested in http://article.gmane.org/gmane.comp.python.f2py.user/1204/ which amounts to let f2py trap the SIGINT. That's good enough for what I need. However, that stresses the need to have a more robust way to deal with these interruptions and make sure that several objects calling one (or several temporary) fortran extension don't interact the ones with the others. And I'm coming to the same conclusion as Chris', that I have to use the `multiprocessing` module, with several processes calling their own fortran extension. But that's another story. Thanks y'all for your help P. On 3/14/12, Chris Barker <chris.barker@noaa.gov> wrote:
On Wed, Mar 14, 2012 at 9:25 AM, Pauli Virtanen <pav@iki.fi> wrote:
Or, maybe the whole Fortran stuff can be run in a separate process, so that crashing doesn't matter.
That's what I was going to suggest -- even if you can get it not to crash, it may well be in a bad state -- memory leaks, and who know what else.
We did something similar with some C code that called the system exit() function when it encountered errors -- it may not have been too hard to replace those calls, but making sure the memory was all cleaned up was going to be a trick -- so we just used the multiprocess module to call it in another process.
HTH,
-Chris
--
Christopher Barker, Ph.D. Oceanographer
Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker@noaa.gov _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion
participants (3)
-
Chris Barker -
Pauli Virtanen -
Pierre GM