我正在玩Visual Studio中的matlab,mex,intel fortran等。我从here复制了一个例程,将矩阵乘以标量:
C Computational subroutine
subroutine xtimesy(x, y, z, m, n)
real*8 x, y(3,3), z(3,3)
integer m, n
do 20 i=1,m
do 10 j=1,n
z(i,j) = x*y(i,j)
10 continue
20 continue
return
end
initial wrapping code supposed to produce the mexw64 file在elseif (mxIsNumeric(prhs(2)) .ne. 1) then
上崩溃,因此我对其进行了如下修改:
#include <fintrf.h>
C The gateway routine
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
mwPointer mxGetM, mxGetN, mxIsNumeric
mwPointer mxCreateDoubleMatrix
mwPointer plhs(*), prhs(*)
integer x_pr, y_pr, z_pr
integer nlhs, nrhs
integer m, n, size
real*8 x, y(3,3), z(3,3)
C Check for proper number of arguments.
if (nrhs .ne. 2) then
call mexErrMsgTxt('Two inputs required.')
elseif (nlhs .ne. 1) then
call mexErrMsgTxt('One output required.')
endif
C Check to see both inputs are numeric.
if (mxIsNumeric(prhs(1)) .ne. 1) then
call mexErrMsgTxt('Input #1 is not a numeric.')
elseif (mxIsNumeric(prhs(2)) .ne. 1) then
call mexErrMsgTxt('Input #2 is not a numeric array.')
endif
C Check that input #1 is a scalar.
m = mxGetM(prhs(1))
n = mxGetN(prhs(1))
if(n .ne. 1 .or. m .ne. 1) then
call mexErrMsgTxt('Input #1 is not a scalar.')
endif
C Get the size of the input matrix.
m = mxGetM(prhs(2))
n = mxGetN(prhs(2))
size = m*n
C Create matrix for the return argument.
plhs(1) = mxCreateDoubleMatrix(m, n, 0)
x_pr = mxGetPr(prhs(1))
y_pr = mxGetPr(prhs(2))
z_pr = mxGetPr(plhs(1))
C Load the data into Fortran arrays.
call mxCopyPtrToReal8(x_pr, x, 1)
call mxCopyPtrToReal8(y_pr, y, size)
C Call the computational subroutine.
call xtimesy(x, y, z, m, n)
C Load the output into a MATLAB array.
call mxCopyReal8ToPtr(z, z_pr, size)
return
end
在Visual Studio中进行调试时,函数的第一个和第二个输入具有正确的尺寸(分别为1x1和3x3),但是prhs
很奇怪。精确地,对于matlab中的此输入:
在Visual Studio的调试中,我看到了:
我发现奇怪的是,phrs
是两个指向数组的指针的包含/指向的数组,具有“类型” (1:1)
。我在设置断点的那一行之前运行了这些行,这些行涉及prhs(2)
,并且在它们上没有错误。另外,prhs(1)
和prhs(2)
的值很奇怪。我怀疑以某种方式我在变量中填充了一些值,这些值可以转换为对于所涉及的变量类型而言太大的整数,但是我找不到位置。
如果我执行断点行的断言并在matlab中显示以下消息,则会崩溃:
Error using doubleMatrixMultiplication
Requested 14757395255531667459x14757395255531667459 (17179869184.0GB) array exceeds maximum array size preference. Creation of
arrays greater than this limit may take a long time and cause MATLAB to become unresponsive. See array size limit or preference
panel for more information.
详细信息:我有Visual Studio 2017的最新更新,Matlab 2018b,我尝试使用Parallel Studio XE 2018 Update 5和2019 Update 3的Intel Visual Fortran。
编辑。 (2019年5月8日)
mex部分的正确代码终于是:
#include <fintrf.h>
C The gateway routine
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
mwPointer mxGetM, mxGetN, mxIsNumeric
mwPointer mxCreateDoubleMatrix
mwPointer plhs(*), prhs(*)
mwPointer x_pr, y_pr, z_pr
integer nlhs, nrhs
mwSize m, n, size
real*8 x, y(3,3), z(3,3)
C Check for proper number of arguments.
if (nrhs .ne. 2) then
call mexErrMsgTxt('Two inputs required.')
elseif (nlhs .ne. 1) then
call mexErrMsgTxt('One output required.')
endif
C Check to see both inputs are numeric.
if (mxIsNumeric(prhs(1)) .ne. 1) then
call mexErrMsgTxt('Input #1 is not a numeric.')
elseif (mxIsNumeric(prhs(2)) .ne. 1) then
call mexErrMsgTxt('Input #2 is not a numeric array.')
endif
C Check that input #1 is a scalar.
m = mxGetM(prhs(1))
n = mxGetN(prhs(1))
if(n .ne. 1 .or. m .ne. 1) then
call mexErrMsgTxt('Input #1 is not a scalar.')
endif
C Get the size of the input matrix.
m = mxGetM(prhs(2))
n = mxGetN(prhs(2))
size = m*n
C Create matrix for the return argument.
plhs(1) = mxCreateDoubleMatrix(m, n, 0)
x_pr = mxGetPr(prhs(1))
y_pr = mxGetPr(prhs(2))
z_pr = mxGetPr(plhs(1))
C Load the data into Fortran arrays.
call mxCopyPtrToReal8(x_pr, x, 1)
call mxCopyPtrToReal8(y_pr, y, size)
C Call the computational subroutine.
call xtimesy(x, y, z, m, n)
C Load the output into a MATLAB array.
call mxCopyReal8ToPtr(z, z_pr, size)
return
end