Fortran MEX file memory problem
Ältere Kommentare anzeigen
Dear all,
I implemented an iterative solver, to solve the generic complex linear system A*x = b, by using a Fortran subroutine, while my main program is all written in Matlab (actually I'm using Matlab R2010b). Now, when my A matrix exceeds a certain dimension (about 1500x900 double complex values) I receive this message from the Matlab editor:
Caught MathWorks::System::FatalException
I made also a fortran implementation of my main and, after increasing the stack size (under properties --> Linker --> System --> Stack Reserve size) on my Microsoft Visual Studio 2008 everything works fine (with any dimension of A matrix). But I can't do this when I generate my mex file by using Matlab.
In the following the Gateway routine which call my fortran subroutine:
if true #include "fintrf.h"
!======================================================================
#if 0
!
! z_gatewayGMRES.f
! .f file needs to be preprocessed to generate .for equivalent
!
#endif
!
!======================================================================
!
! Gateway routine
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
! Declarations
implicit none
!
!----------------------------------------------------------------------
! mexFunction arguments:
! (pointer) Replace integer by integer*8 on 64-bit platforms
integer*8 PLHS(*)
integer*8 PRHS(*)
!
integer*8 nlhs
integer*8 nrhs
!
!----------------------------------------------------------------------
! Function declarations:
! (pointer) Replace integer by integer*8 on 64-bit platforms
integer*8 mxCreateDoubleMatrix
integer*8 mxCreateNumericMatrix
integer*8 mxGetData
integer*8 mxGetPr, mxGetPi
integer*8 mxGetM, mxGetN
integer*8 mxClassIDFromClassName
!
!----------------------------------------------------------------------
! I/O & LOCAL VARIABLE DEFINITIONS
! ---------------------------------------------------------------------
!
INTEGER*8 mA, nA, sizeA, mb
INTEGER*8 maxoutPin, tolPin, omgPin
INTEGER*8 ApIn, bPin, nbinPin
! Input --------------------------------------------------------------- C
COMPLEX*16, ALLOCATABLE :: A(:,:), b(:)
INTEGER*8 nbin, maxout
REAL*8 nbinR, maxoutR
REAL*8 tol, omg
REAL*8 t_in, t_out
! Output -------------------------------------------------------------- C
INTEGER*8 conv, nbout
COMPLEX*16, ALLOCATABLE :: x(:)
REAL*8, ALLOCATABLE :: res(:)
! Local Variables
INTEGER*8 classid
INTEGER*8 complexflag
INTEGER*8 r_datasize, z_datasize
INTEGER*8 m, n
!
! --------------------------------------------------------------------- C
!
#if defined MSWIND
! For Windows only!
! This resets the floating point exception to allow divide by zero,
! overflow and invalid numbers.
!
INTEGER(2) CONTROL
CALL GETCONTROLFPQQ(CONTROL)
CONTROL = CONTROL .OR. FPCW$ZERODIVIDE
CONTROL = CONTROL .OR. FPCW$INVALID
CONTROL = CONTROL .OR. FPCW$OVERFLOW
CALL SETCONTROLFPQQ(CONTROL)
#endif
!
! CHECK THE DIMENSIONS
!
mA = mxGetM(PRHS(1))
nA = mxGetN(PRHS(1))
sizeA = mA*nA
!
mb = mxGetM(PRHS(2))
!
IF( mA .NE. mb ) THEN
CALL mexErrMsgTxt('The number of rows is not the same')
ELSE
m = mA
n = nA
ENDIF
!
! ----------------------------------------------------------------------------
!
r_datasize = 8
z_datasize = 16
!
! ASSIGN POINTERS TO THE INPUT PARAMETERS
!
nbinPin = mxGetData(PRHS(3))
maxoutPin = mxGetData(PRHS(4))
tolPin = mxGetData(PRHS(5))
omgPin = mxGetData(PRHS(6))
!
! INITIALIZE HEAP MEMORY FOR INPUT MATRIX/ARRAYS
!
ALLOCATE(A(m,n))
ALLOCATE(b(m))
!
! ----------------------------------------------------------------------------
! COPY RIGHT HAND ARGUMENTS TO LOCAL ARRAYS OR VARIABLES
!
CALL mxCopyPtrToReal8(nbinPin, nbinR, 1)
CALL mxCopyPtrToReal8(maxoutPin, maxoutR, 1)
nbin = INT(nbinR)
maxout = INT(maxoutR)
CALL mxCopyPtrToReal8(tolPin, tol, 1)
CALL mxCopyPtrToReal8(omgPin, omg, 1)
!
CALL mxCopyPtrToComplex16( mxGetPr(prhs(1)), &
mxGetPi(prhs(1)),A,sizeA)
CALL mxCopyPtrToComplex16( mxGetPr(prhs(2)), &
mxGetPi(prhs(2)),b,m)
!
! ----------------------------------------------------------------------------
! INITIALIZE HEAP MEMORY FOR LEFT HAND ARGUMENTS
!
ALLOCATE(x(n))
ALLOCATE(res(maxout))
! ----------------------------------------------------------------------------
! Iterative solver
!
CALL It_solver(m, n, &
A, b, tol, &
nbin, maxout, omg, &
x, conv, res, nbout, &
t_in, t_out )
!
! ----------------------------------------------------------------------------
! CREATE RETURN ARGUMENT ARRAYS
!
classid = mxClassIDFromClassName('int64')
complexflag = 1
PLHS(1) = mxCreateDoubleMatrix(n, 1, complexflag)
complexflag = 0
PLHS(2) = mxCreateNumericMatrix(1, 1, classid, complexflag)
PLHS(3) = mxCreateDoubleMatrix(maxout, 1, complexflag)
PLHS(4) = mxCreateNumericMatrix(1, 1, classid, complexflag)
!
! Load the output into a MATLAB array.
!
CALL mxCopyComplex16ToPtr(x, mxGetPr(PLHS(1)), &
mxGetPi(PLHS(1)),n)
CALL mxCopyInteger4ToPtr(conv, mxGetData(PLHS(2)), 1)
CALL mxCopyReal8ToPtr(res,mxGetPr(PLHS(3)),maxout)
!
! ----------------------------------------------------------------------------
!
DEALLOCATE(A)
DEALLOCATE(b)
DEALLOCATE(x)
DEALLOCATE(res)
!
! ----------------------------------------------------------------------------
!
RETURN
END
% code
end
Any suggestion will be really appreciated.
Thank you very much in advance,
Giorgio
Akzeptierte Antwort
Weitere Antworten (0)
Kategorien
Mehr zu Fortran with MATLAB finden Sie in Hilfe-Center und File Exchange
Produkte
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!