All integers passed to the BLAS & LAPACK routines need to be MWSIGNEDINDEX type. And you need to pay closer attention to the signature of the MATLAB API functions you are calling. E.g.,
> SUBROUTINE MEXFUNCTION(NLHS, PLHS, NRHS, PRHS)
> MWPOINTER PLHS(*), PRHS(*)
> INTEGER NLHS, NRHS, INFO, LWORK
The doc says the signature is:
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
integer*4 nlhs, nrhs
mwPointer plhs(*), prhs(*)
Now, even on a 64-bit system I would typically expect INTEGER to be INTEGER*4, but why depend on this? Also, INFO and LWORK are passed into LAPACK routines, so they definitely should be MWSIGNEDINDEX. E.g., change the above to:
SUBROUTINE MEXFUNCTION(NLHS, PLHS, NRHS, PRHS)
MWPOINTER PLHS(*), PRHS(*)
INTEGER*4 NLHS, NRHS
MWSIGNEDINDEX INFO, LWORK ! probably 8-byte integers on your system
Then consider this declaration:
> MWSIGNEDINDEX MXGETM, MXGETN
The doc says these are supposed to be MWPOINTER (essentially a size_t behind the scenes), so go ahead and use that. E.g.,
MWPOINTER, EXTERNAL :: MXGETM, MXGETN
Then consider this declaration:
> mwSize MX, NX, NN, MM
You use these variables two different ways. One way is as integer arguments to MATLAB API functions like MXCREATEDOUBLEMATRIX (which wants MWSIZE type inputs), and then you also use them in the LAPACK calls to DGESVD (which wants MWSIGNEDINDEX type inputs). So here is another potential for mismatch. Fix this up, probably by using two sets of variables (one typed MWSIZE and another typed MWSIGNEDINDEX).
Then consider this call:
> CALL dgesvd('S','N',MX,NX,A,MX,B,C,MX,VT,1,WORK,-1,INFO)
You pass constants in the arguments (1 and -1). You can get away with this in C/C++ where arguments automatically get promoted to the expected type, but you can't get away with this in Fortran where things are passed by reference. These constant integers are probably 4-bytes each and the routine is probably expecting 8-byte integers. Never use constants as arguments to BLAS or LAPACK routines in Fortran, always use variables. E.g., the above should be something like:
MWSIGNEDINDEX :: PLUS_ONE = 1
MWSIGNEDINDEX :: MINUS_ONE = -1
:
CALL dgesvd('S','N',MX,NX,A,MX,B,C,MX,VT,PLUS_ONE,WORK,MINUS_ONE,INFO)
And for these lines:
> PLHS(1) = MXCREATEDOUBLEMATRIX(MX, NN, 0.0)
> CALL MXCOPYREAL8TOPTR(C,PLHS(1),MX*NN)
> PLHS(2) = MXCREATEDOUBLEMATRIX(NN, 1, 0.0)
> CALL MXCOPYREAL8TOPTR(B,PLHS(2),NN)
just scrub them to replace all constants with variables of the correct type, and make sure the variables you are passing are the correct type as well (e.g., MWSIZE).
James Tursa