From: Eli Osherovich on
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
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
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
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
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