Странные значения при отладке для кода Fortran Mex - PullRequest
1 голос
/ 06 мая 2019

Я играю с Matlab, Mex, Intel Fortran в Visual Studio и т. Д. Я скопировал подпрограмму из здесь , умножив матрицу на скаляр:

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

исходный код переноса, который должен был генерировать файл mexw64 зависал на 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:

enter image description here

при отладке в Visual Studio я вижу:

enter image description here

и я нахожу странным, что phrs, который является массивом из двух указателей на массивы, содержит / points, имеет "тип" (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, и я попробовал с intel visual fortran из параллельной студии xe 2018 обновление 5, а также обновление 2019 3.

Редактировать.(8 мая 2019 г.)

Наконец, правильный код для мекс-части:

#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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...