MATLAB Answers

0

Incorrect number of arguments into mex file

Asked by Etienne Coetzee on 6 May 2017
Latest activity Commented on by Etienne Coetzee on 10 May 2017
Hi All
I have a mex file that has worked for the last 10 years (up to R2015b) and now is giving me problems since I have upgraded my Matlab version. The problem is that I check the number of input arguments and when it is not equal to two it throws an error. When I call the mex function it now sometimes throws an error, where it does not seem to pass any arguments in. When I run through the debugger, stop at the mex function call, and then call, it seems to work. I am definitely passing in the correct arguments. The problem seems to be spurious and does not always show up. It seems to be some or other initialisation problem or something like this.
Any help would be appreciated
Etienne

  3 Comments

Here is the code snippet. The problem I have is that sometimes NRHS is equal to zero, even though I am passing the two correct objects into the mex function. An error is thrown about the number of arguments according to the error checks. The question is why would no arguments be passed if the function call from the m-file function is explicitly calling this mex file with the two correct objects as inputs?
SUBROUTINE MEXFUNCTION(NLHS, PLHS, NRHS, PRHS)
!
!
!$ USE OMP_LIB
IMPLICIT NONE
MWPOINTER PLHS(*), PRHS(*), mxDuplicateArray
MWSIZE NLHS, NRHS
CHARACTER(LEN=63) :: mxGetClassName
EXTERNAL AUTOSTOPWITHOUTERROR
MWSIZE mexAtExit
MWSIZE k
CHARACTER(LEN=100) :: NUMPROCSTR
!---------------------------------------------------------------------
! AVOID ERRORS WHEN DIVIDING BY ZERO ON WINDOWS PLATFORM
!---------------------------------------------------------------------
! This resets the floating point exception to allow divide by zero,
! overflow and invalid numbers.
!
#ifdef MSWIND
MWSIZE CONTROL
CALL GETCONTROLFPQQ(CONTROL)
CONTROL = CONTROL .OR. FPCW$ZERODIVIDE
CONTROL = CONTROL .OR. FPCW$INVALID
CONTROL = CONTROL .OR. FPCW$OVERFLOW
CALL SETCONTROLFPQQ(CONTROL)
#endif
! Set number of processors if not defined
#ifndef OMP_NUM_THREADS
# define OMP_NUM_THREADS 1
#endif
! WRITE(NUMPROCSTR,1001)OMP_NUM_THREADS
!1001 FORMAT('fprintf(''\\n\\n NUMBER OF PROCESSORS : ',I2,'\\n\\n'')')
! CALL MEXEVALSTRING(NUMPROCSTR)
!---------------------------------------------------------------------
! CHECK NUMBER OF INPUT ARGUMENTS AS WELL AS TYP OF OBJECTS BEING PASSED IN
!---------------------------------------------------------------------
if( NRHS /= 2 ) then
call mexErrMsgTxt("Two input arguments required into gateway function")
k=mexAtExit(AUTOSTOPWITHOUTERROR)
endif
if( mxGetClassName(PRHS(1)) /= "autofiles" ) then
call mexErrMsgTxt("Make sure a FileNames object is being passed as the first argument into the AUTO07gateway function")
k=mexAtExit(AUTOSTOPWITHOUTERROR)
endif
if( mxGetClassName(PRHS(2)) /= "autoinitcon" ) then
call mexErrMsgTxt("Make sure an InitialConditions object is being passed as the second argument into the AUTO07gateway function")
k=mexAtExit(AUTOSTOPWITHOUTERROR)
endif
CALL GETSIMOPTS(PRHS)
CALL RUN(NRHS, PRHS)
k=mexAtExit(AUTOSTOPWITHOUTERROR)
RETURN
END
!---------------------------------------------------------------------
! RUN IN 07P MODE
!---------------------------------------------------------------------
SUBROUTINE RUN(NRHS, PRHS)
USE AUTO_CONSTANTS
USE INTERFACES
IMPLICIT NONE
MWPOINTER PRHS(*)
MWSIZE NRHS
EXTERNAL AUTOSTOPWITHOUTERROR
MWSIZE mexAtExit
MWSIZE k
CHARACTER*63 FCNSTR
CALL COPYDSTOBJECTSTOAUTO(PRHS)
!
! Run the main continuation package "AUTO"
!
CALL AUTO()
!
!
RETURN
END
I think were going to need a bit more information here. What platform(s) are you using? are both tested versions the same bit width? When you say it works when debugging do you mean the MATLAB debugger or a FORTRAN debugger?
If using the MATLAB debugger makes a difference we are going to need to see some MATLAB code from the call site and I suggest you add some test code in your MATLAB code to examine the arguments being passed from MATLAB when the debugger is not running.
Hi Philip
It is on a 64 bit machine and I mean the Matlab debugger. I will have to set up a test script and then post it. The only thing that has changed is the Matlab version. Everything else is the same. Same Fortran compiler etc.
Regards
Etienne

Sign in to comment.

Products

1 Answer

James Tursa 님의 답변 8 May 2017
 채택된 답변

Particularly for Fortran, you should always use the exact signature that is in the doc. Sometimes that signature changes from release to release, or maybe the default compiler options for mexing have changed. Either one of these can trip you up. E.g., look at this from your code:
SUBROUTINE MEXFUNCTION(NLHS, PLHS, NRHS, PRHS)
!
!
!$ USE OMP_LIB
IMPLICIT NONE
MWPOINTER PLHS(*), PRHS(*), mxDuplicateArray
MWSIZE NLHS, NRHS
The signature from the doc is:
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
integer nlhs, nrhs
mwPointer plhs(*), prhs(*)
You've got NLHS and NRHS typed as MWSIZE, but the signature in the doc says the type should be integer. This could be a mismatch, since MWSIZE might be defined as an integer*8 but a default integer might be an integer*4. There is no automatic type promotion in Fortran like there is in C/C++, so this might cause a problem. It would be best to type NLHS and NRHS exactly like the doc states.

  2 Comments

Thanks James. I will give that a try.
James, it worked a treat. Thanks! Made my day!

Sign in to comment.