using BLAS function in a computational routine in mex
2 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
I am using Matlab R2013a 64bit. I am writing a mex function in fortran. I am using the Intel Visual Fortran 14.0 compiler. I am calling a BLAS function. I have the following problem: when I call the BLAS function from the main body of the mex function, it works; but when I call it from a different routine, it crashes Matlab. The following is a minimal code showing this problem, calling the BLAS function dnrm2.
#include "fintrf.h"
!============================================================================
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
implicit none
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
mwPointer mxCreateDoubleScalar, mxGetPr, mxGetM
integer n
mwPointer x
double precision norm1x, norm2x
double precision dnrm2, compute_norm
integer complexFlag
complexFlag = 0
n = int4(mxGetM(prhs(1)))
x = mxGetPr(prhs(1))
norm1x = dnrm2(n, %val(x), 1) ! WORKS
plhs(1) = mxCreateDoubleScalar(norm1x)
norm2x = compute_norm(n, %val(x)) ! DOES NOT WORK
plhs(2) = mxCreateDoubleScalar(norm2x)
end subroutine mexFunction
!============================================================================
function compute_norm(n, x)
implicit none
integer n
double precision x(n)
double precision compute_norm, dnrm2
compute_norm = dnrm2(n, x, 1)
end function compute_norm
To build, I use
mex -v -largeArrayDims mynorm.F90 'C:\Program Files\MATLAB\R2013a\extern\lib\win64\microsoft\libmwblas.lib'
I am wondering what might be the reason. Thank you.
0 commentaires
Réponse acceptée
James Tursa
le 7 Mai 2015
Modifié(e) : James Tursa
le 7 Mai 2015
For -largeArrayDims I might expect the BLAS integer arguments to be 64-bit. You are passing 32-bit constant 1's in the 3rd argument. You can get away with this in C/C++ where arguments are automatically type promoted, but you can't get away with this in Fortran if there is a mismatch since there is no automatic type promotion in Fortran. In general, always use variables to pass values to BLAS routines so your code can be robust across different platforms. I would try this as a first guess at a fix:
mwSignedIndex :: ONE = 1
:
norm1x = dnrm2(n, %val(x), ONE)
and similarly in the compute_norm function:
mwSignedIndex :: ONE = 1
:
compute_norm = dnrm2(n, x, ONE)
As to why the dnrm2 call in mexFunction worked whereas the dnrm2 call in compute_norm crashed, it may be just luck based on the current state of stack memory because of the calling sequence just prior to the dnrm2 call.
Another possibility is that you only called the mex routine with 1 requested output. In that case the plhs array is only sized for 1 return value, and plhs(2) is writing off the end of the array which will seg fault. You should have protections in your code for this. E.g.,
if( nlhs >= 2 )
norm2x = compute_norm(n, %val(x)) ! DOES NOT WORK
plhs(2) = mxCreateDoubleScalar(norm2x)
endif
You should also have something at the beginning of your code to check the input argument. E.g.,
if( nrhs /= 1 ) then
call mexErrMsgTxt("Need exactly one double vector input")
endif
if( mxIsDouble(prhs(1)) == 0 ) then
call mexErrMsgTxt("Need exactly one double vector input")
endif
if( mxGetM(prhs(1)) /= 1 .AND. mxGetN(prhs(1)) /= 1 ) then
call mexErrMsgTxt("Need exactly one double vector input")
endif
5 commentaires
James Tursa
le 8 Mai 2015
If you link with the MATLAB supplied BLAS library, you should always be able to use mwSignedIndex for the integer arguments. What the mwSignedIndex maps to (integer*4 or integer*8) is supposed to all happen automatically for you correctly via the mex command depending on whether your installation is 32-bit or 64-bit and the largeArrayDims flag setting.
That being said, I have not personally tried all of these combinations. There may be some combination that doesn't work that I am not aware of, in which case one would have to manually set the integer argument types directly instead of using the mwSignedIndex macro.
If you link with a 3rd party BLAS library, it is probably best to hard code the integer type depending on that 3rd party doc, and not use mwSignedIndex.
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Write C Functions Callable from MATLAB (MEX Files) dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!