fortran mex代码在调试时的奇怪值

时间:2019-05-06 17:40:53

标签: visual-studio matlab fortran mex intel-fortran

我正在玩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 fileelseif (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中的此输入:

enter image description here

在Visual Studio的调试中,我看到了:

enter image description here

我发现奇怪的是,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

0 个答案:

没有答案