Strange values at debug for fortran mex code

假如想象 提交于 2020-01-05 03:59:30

问题


I am toying with matlab, mex, intel fortran in visual studio etc. I copied a routine from here doing the multiplication of a matrix by a scalar :

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

The initial wrapping code supposed to produce the mexw64 file was crashing on the elseif (mxIsNumeric(prhs(2)) .ne. 1) then so that I have adapted it as follows :

#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

At debug in visual studio, the first and second input to my function have the right dimensions (resp 1x1 and 3x3) but prhs is strange. Precisely, for this input in matlab :

at debug in visual studio I see :

and I find strange that the phrs which is an array of two pointer to arrays, contains/points has "type" (1:1). I ran the lines before the one where the breakpoint is set, lines involving prhs(2) and there was no mistake on them. Also, the value of prhs(1) and prhs(2) are strange. I suspect that somehow somewhere I filled variables with values that can be casted to integers that are too big for the types of the variables involved, but I cannot find where.

I crash if I execute the assertion of the breakpoint line, with the following message in 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.

Details : I have visual studio 2017 last update, matlab 2018b and I tried with intel visual fortran from parallel studio xe 2018 update 5 as well as 2019 update 3.

Edit. (May the 8th, 2019)

The correct code for the mex part is finally :

#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

来源:https://stackoverflow.com/questions/56009962/strange-values-at-debug-for-fortran-mex-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!