Matlab crashes when running a specific Fortan MEX file under MacOS
조회 수: 2 (최근 30일)
이전 댓글 표시
I succesfully compile a MEX file from two Fortran files using Intel Fortran Composer XE but Matlab crashes when I tried to run the MEX (mexmaci64) file. The person who originally coded the gateway was running it on Windows (probably Matlab 2020b) and it was all working fine, so I suspect there might be a compatiblity issue. I am using Matlab 2022b on MacOS Ventura 13.0.1.
I have tested with another file (https://es.mathworks.com/help/matlab/matlab_external/create-fortran-source-mex-file.html) and I managed to compile and run it smoothly.
Here is the gateway code (I can't provide the other file):
#include <fintrf.h>
SUBROUTINE mexFunction(nlhs, plhs, nrhs, prhs)
!!!pointers to input data: prhs and output: plhs
mwPointer plhs(*), prhs(*)
!!!number of inputs on right and left hand side
INTEGER nlhs, nrhs
!!!pointers to intrinsic functions of the matlab library
mwPointer mxgetpr,mxgetscalar!!, mxCreateString
mwPointer mxgetm, mxgetn, mxCreateDoubleMatrix
mwPointer mxCreateCharMatrixFromStrings
C Array information:
mwSize v_size, cblk_size !!, pname_size, props_size, psys_size
C Arguments for computational routine:
include 'parameters.h'
double precision cblk_i(k5)!! k5 = 12
double precision v_i(l2)!!l2 = 5
c double precision props_o(k5,12+k5)
c double precision psys_o(1,10+k5)
double precision props_o(k5,9+k5) !! double precision props_o(k5,12+k5)
double precision psys_o(1,9+k5)
c character*14 names(k5)
character*14 pname_o(k5)
double precision iPs, ido
integer props_r, props_c, psys_r, psys_c !!, pname_r, pname_c
integer props_s, psys_s, iPs_s, idead_s !!, pname_s
C Get the sizes of the input arrays.
v_row = mxgetm(prhs(1))
v_col = mxgetn(prhs(1))
v_size = v_row*v_col
CALL mxCopyPtrToReal8(mxGetPr(prhs(1)), v_i, v_size)
cblk_row = mxgetm(prhs(2))
cblk_col = mxgetn(prhs(2))
cblk_size = cblk_row*cblk_col
CALL mxCopyPtrToReal8(mxGetPr(prhs(2)), cblk_i, cblk_size)
c Call the FORTRAN routine
CALL main(pname_o,props_o,psys_o,iPs,ido,v_i,cblk_i)
c Creating null matrices as default output
c pname_r = 1
c pname_c = k5
c pname_s = pname_r*pname_c
plhs(1) = mxCreateCharMatrixFromStrings(k5, pname_o)
props_r = size(props_o,1)
props_c = size(props_o,2)
props_s = props_r*props_c
plhs(2)= mxCreateDoubleMatrix(props_r, props_c, 0)
psys_r = size(psys_o,1)
psys_c = size(psys_o,2)
psys_s = psys_r*psys_c
plhs(3)= mxCreateDoubleMatrix(psys_r, psys_c, 0)
plhs(4) = mxCreateDoubleMatrix(1, 1, 0)
plhs(5) = mxCreateDoubleMatrix(1, 1, 0)
c Copy output data from local variables to matlab output variables
c CALL mxCopyCharacterToPtr(pname_o,mxGetData(plhs(1)),pname_s)
CALL mxCopyReal8ToPtr(props_o, mxGetPr(plhs(2)), props_s)
CALL mxCopyReal8ToPtr(psys_o, mxGetPr(plhs(3)), psys_s)
CALL mxCopyReal8ToPtr(iPs, mxGetPr(plhs(4)), 1)
CALL mxCopyReal8ToPtr(ido, mxGetPr(plhs(5)), 1)
return
end
The MEX is compiled as follows (I can provide the verbose report):
mex -v gateway.F main.f
It is then run from two double variable inputs as follows (that's where it crashes - I can provide the crash log):
[a,b,c,d,e]=gateway(v,cblk);
Any help would be greatly appreciated!
댓글 수: 1
James Tursa
2023년 5월 9일
Be very wary of the timestwo.f example given in the MATLAB doc. This code has several serious errors in it and I have been unable to get TMW to fix their doc. In particular, the code doesn't do variable type or size checks properly, so you can easily crash MATLAB by doing something as simple as passing in an array instead of a scalar.
답변 (1개)
James Tursa
2023년 5월 9일
The MATLAB Fortran API interface needs to be treated as a pass-by-reference interface. That means you need to have the exact types in the arguments or things will not work properly. The only way to ensure this, especially across different platforms, is to always use variables for arguments, and never use literal constants. You just can't be sure that the integer sizes are going to match. So, first thing you should do before doing any more debugging is replacing all of the literal constant arguments with variables that match the API signatures exactly.
E.g., take this line:
plhs(4) = mxCreateDoubleMatrix(1, 1, 0)
Those literal 1's and 0 should never be used in Fortran calls to API functions. Instead, first look at the signature in the doc:
#include "fintrf.h"
mwPointer mxCreateDoubleMatrix(m, n, ComplexFlag)
mwSize m, n
integer*4 ComplexFlag
Then use those exact variable types in your call. E.g., the above code should look something like this instead:
mwSize :: ONE = 1
integer*4 :: ComplexFlag = 0
:
plhs(4) = mxCreateDoubleMatrix(ONE,ONE,ComplexFlag)
Do this for every single API call that you currently have constants for arguments. Only then can you reliably start any further debugging that is needed, such as checking input variable sizes and types, etc.
Also, I am going to knock the original programmer for not using IMPLICIT NONE in their code. Seriously, this is one of the few helps that the compiler has available to you for detecting variable type mismatches etc. IMO this should always be used in Fortran code.
댓글 수: 6
참고 항목
카테고리
Help Center 및 File Exchange에서 Troubleshooting in MATLAB Compiler SDK에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!