Prev: Fortran problem
Next: Multi dimension char array
From: Eli Osherovich on 7 Jul 2010 06:18 Hello, I am not sure this is a FORTRAN problem. But I have a strange crash when I try to load a dynamic library compiled from FORTRAN source. MATLAB allows to load libraries dynamically with 'loadlibrary' function. The function receives a library name and an H-file (C header file) with a description of library functions. I was trying to use some NETLIB sources this way. Simple examples work very well, however, when I try something real (but still simple) MATLAB crashes. For example, I tried function 'getfun' with MODE = -1 form this file http://www.netlib.org/uncon/data/almost.f but MATLAB crashes reporting stack corruption. However, if I add a 'return' statement after the line .... if (mode .eq. -2) goto 30 .... Then everything works OK (M and N get their values). The problem is that this extra 'return' should never be executed... Probably, I missed something. Will be glad to get any help. Thank you.
From: Ian Harvey on 7 Jul 2010 17:56 Please show the prototypes (either as described by the header file, or alternatively as described by a matlab function handle, that are passed to the loadlibrary call) that you are using on the matlab side. I'll note that your fortran code doesn't have the BIND(C, ...) clause on the subroutine statement. As a result you are going to have to be very mindful of your compiler's calling conventions. My preference is to give the fortran procedure a C binding name and then explicitly marking the fortran procedure as cdecl on the Matlab side - this is more robust to platform and compiler changes. Mismatches in calling convention can cause stack corruption, program crashes and various marital difficulties. On 7/07/2010 8:18 PM, Eli Osherovich wrote: > Hello, > > I am not sure this is a FORTRAN problem. But I have a strange crash > when I try to load a dynamic library compiled from FORTRAN source. > > MATLAB allows to load libraries dynamically with 'loadlibrary' > function. The function receives a library name and an H-file (C header > file) with a description of library functions. I was trying to use > some NETLIB sources this way. Simple examples work very well, > however, when I try something real (but still simple) MATLAB crashes. > For example, I tried function 'getfun' with MODE = -1 form this file > http://www.netlib.org/uncon/data/almost.f > but MATLAB crashes reporting stack corruption. However, if I add a > 'return' statement after the line > .... > if (mode .eq. -2) goto 30 > .... > Then everything works OK (M and N get their values). > > The problem is that this extra 'return' should never be executed... > > Probably, I missed something. Will be glad to get any help. > > Thank you.
From: Eli Osherovich on 8 Jul 2010 05:39 On Jul 8, 12:56 am, Ian Harvey <ian_har...(a)bigpond.com> wrote: > Please show the prototypes (either as described by the header file, or > alternatively as described by a matlab function handle, that are passed > to the loadlibrary call) that you are using on the matlab side. > > I'll note that your fortran code doesn't have the BIND(C, ...) clause on > the subroutine statement. As a result you are going to have to be very > mindful of your compiler's calling conventions. My preference is to > give the fortran procedure a C binding name and then explicitly marking > the fortran procedure as cdecl on the Matlab side - this is more robust > to platform and compiler changes. Mismatches in calling convention can > cause stack corruption, program crashes and various marital difficulties. Ian, thank you for your reply. The prototype is pretty simple: void getfun_( double *x, int *n, double *f, int *m, double *ftf, double *fj, int *lfj, double *g, int *mode); And it seems that I manged to overcome the difficulties. There were two reasons for crashes: 1) One should be careful with unused arguments, as MATALAB is not smart enough when creates its wrapper. 2) Some of the Fortran routines had bugs (not all variables were SAVEd) - I shall try to contact the author and check whether it is possible to update NETLIB's repository.
From: Gib Bogle on 12 Jul 2010 23:56 Ian Harvey wrote: > Please show the prototypes (either as described by the header file, or > alternatively as described by a matlab function handle, that are passed > to the loadlibrary call) that you are using on the matlab side. > > I'll note that your fortran code doesn't have the BIND(C, ...) clause on > the subroutine statement. As a result you are going to have to be very > mindful of your compiler's calling conventions. My preference is to > give the fortran procedure a C binding name and then explicitly marking > the fortran procedure as cdecl on the Matlab side - this is more robust > to platform and compiler changes. Mismatches in calling convention can > cause stack corruption, program crashes and various marital difficulties. Including premature ejaculations.
From: Eli Osherovich on 14 Jul 2010 16:21 On Jul 8, 12:39 pm, Eli Osherovich <eli.osherov...(a)gmail.com> wrote: > On Jul 8, 12:56 am, Ian Harvey <ian_har...(a)bigpond.com> wrote: > > > Please show the prototypes (either as described by the header file, or > > alternatively as described by a matlab function handle, that are passed > > to the loadlibrary call) that you are using on the matlab side. > > > I'll note that your fortran code doesn't have the BIND(C, ...) clause on > > the subroutine statement. As a result you are going to have to be very > > mindful of your compiler's calling conventions. My preference is to > > give the fortran procedure a C binding name and then explicitly marking > > the fortran procedure as cdecl on the Matlab side - this is more robust > > to platform and compiler changes. Mismatches in calling convention can > > cause stack corruption, program crashes and various marital difficulties. > > Ian, thank you for your reply. > > The prototype is pretty simple: > > void > getfun_( double *x, int *n, double *f, int *m, double *ftf, double > *fj, > int *lfj, double *g, int *mode); > > And it seems that I manged to overcome the difficulties. > > There were two reasons for crashes: > 1) One should be careful with unused arguments, as MATALAB is not > smart enough when creates its wrapper. > 2) Some of the Fortran routines had bugs (not all variables were > SAVEd) - I shall try to contact the author and check whether it is > possible to update NETLIB's repository. Maybe I was too enthusiastic about my success. The code works on one machine and fails on another. Both the computers are Intel x86-64 systems. MATLAB versions are slightly different: 2010a and 2009b. So, before I try to install a newer version of MATLAB I want to be sure that the Fortran part is ok. Below is a simple example that demonstrates the problem testfun.f90: ---------------- subroutine testfun (n, x, y) integer, intent(in) :: n double precision, intent(in) :: x(n) double precision, intent(out) :: y double precision ddot y = ddot(n, x, 1, x, 1) end subroutine testfun testfun.h: -------------- void testfun_(int *n, double *x, double *y); To compile, I use the following command: gfortran -shared -fPIC -lblas testfun.f90 -o testfun.so Now, in Matlab: >> loadlibrary testfun >> x = rand(10,1) x = 0.6557 0.0357 0.8491 0.9340 0.6787 0.7577 0.7431 0.3922 0.6555 0.1712 >> n = numel(x) n = 10 >> y = 1 y = 1 >> [n, x, y] = calllib('testfun', 'testfun_', n, x, y) n = 10 x = 0.6557 0.0357 0.8491 0.9340 0.6787 0.7577 0.7431 0.3922 0.6555 0.1712 y = 0 >> For some reason y = 0 ... On another machine the same *.so file works as expected. Do I do something wrong? Thank you.
|
Pages: 1 Prev: Fortran problem Next: Multi dimension char array |