Mex-файл Fortran для матричного продукта: от нераспределяемого к распределяемому - PullRequest
1 голос
/ 08 мая 2019

Я играл с Matlab, Mex, Intel Fortran в Visual Studio и т. Д. С простым скалярным произведением матрицы 3 * 3, см .:

Странные значения при отладке для кода Fortran Mex

В основном вы вводите скаляр и матрицу 3 * 3, и возвращается их произведение, матрица 3 * 3. Я сейчас пытаюсь закодировать общий матричный продукт. Сначала я хочу положиться на matmul, чтобы иметь возможность проверить все слои мекс-интерфейса.Следовательно, базовая процедура:

    subroutine mymatmul(A, B, C, m, n, p)
        real*8, allocatable, dimension(:,:) :: A, B, C
        integer m, n, p
        allocate( A(m,n), B(n,p), C(m,p) )
        C = matmul(A,B)
    end

Код переноса, который должен создать файл mexw64, на данный момент:

#include <fintrf.h>
C     The gateway routine
    subroutine mexFunction(nlhs, plhs, nrhs, prhs)

    mwPointer mxGetM, mxGetN, mxIsNumeric
    mwPointer mxCreateDoubleMatrix
    mwPointer plhs(*), prhs(*)
    mwPointer A_pr, B_pr, C_pr
    integer nlhs, nrhs
    mwSize m, n, p, q
    mwSize size1, size2, size3
    real*8  x(3,3), 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 array.')
    elseif (mxIsNumeric(prhs(2)) .ne. 1) then
        call mexErrMsgTxt('Input #2 is not a numeric array.')
    endif

C     Get the size of the input matrix #1.
    m = mxGetM(prhs(1))
    n = mxGetN(prhs(1))

C     Get the size of the input matrix #2.
    p = mxGetM(prhs(2))
    q = mxGetN(prhs(2))

C     Check that the sizes are compatible for a matrix product
    if (n .ne. p) then
        call mexErrMsgTxt('nbcol1 should be equal to nbrow2.')
    endif

    size1 = m*n
    size2 = p*q

C     Create matrix for the return argument.
    plhs(1) = mxCreateDoubleMatrix(m, q, 0)
    A_pr = mxGetPr(prhs(1))
    B_pr = mxGetPr(prhs(2))
    C_pr = mxGetPr(plhs(1))

C     Load the data into Fortran arrays.
    call mxCopyPtrToReal8(A_pr, x, size1)
    call mxCopyPtrToReal8(B_pr, y, size2)

C     Call the computational subroutine.
    call mymatmul(x, y, z, m, n, q)

C     Load the output into a MATLAB array.
    call mxCopyReal8ToPtr(z, C_pr, size3)

    return
    end

и при компиляции у меня возникают следующие ошибки:

1>C:\path\to\mymatmulg.F(55): warning #6075: The data type of the actual argument does not match the definition.   [M]
1>C:\path\to\mymatmulg.F(55): warning #6075: The data type of the actual argument does not match the definition.   [N]
1>C:\path\to\mymatmulg.F(55): warning #6075: The data type of the actual argument does not match the definition.   [Q]
1>C:\path\to\mymatmulg.F(55): error #7976: An allocatable dummy argument may only be argument associated with an allocatable actual argument.   [X]
1>C:\path\to\mymatmulg.F(55): error #7976: An allocatable dummy argument may only be argument associated with an allocatable actual argument.   [Y]
1>C:\path\to\mymatmulg.F(55): error #7976: An allocatable dummy argument may only be argument associated with an allocatable actual argument.   [Z]
1>C:\path\to\mymatmulg.F(55): error #8055: The procedure has a dummy argument that has the ALLOCATABLE, ASYNCHRONOUS, OPTIONAL, POINTER, TARGET, VALUE or VOLATILE attribute. Required explicit interface is missing from original source.   [X]
1>C:\path\to\mymatmulg.F(55): error #8055: The procedure has a dummy argument that has the ALLOCATABLE, ASYNCHRONOUS, OPTIONAL, POINTER, TARGET, VALUE or VOLATILE attribute. Required explicit interface is missing from original source.   [Y]
1>C:\path\to\mymatmulg.F(55): error #8055: The procedure has a dummy argument that has the ALLOCATABLE, ASYNCHRONOUS, OPTIONAL, POINTER, TARGET, VALUE or VOLATILE attribute. Required explicit interface is missing from original source.   [Z]
1>compilation aborted for C:\path\to\mymatmulg.F (code 1)

Все ошибки происходят в строке 55 кода переноса mex, которая является строкой:

  call mymatmul(x, y, z, m, n, q)

, где я вызываю подпрограмму fortran.

Я понимаю ошибки: подпрограмме, по построению, нужны выделяемые массивы, тогда как массивы, которые я передаю ей, x, y и z, объявленные в строке

  real*8  x(3,3), y(3,3), z(3,3)

, явно не выделяются.

Как я могу адаптировать существующий код переноса mex, чтобы он работал?

(Подробности: у меня последнее обновление visual studio 2017, matlab 2018b, и я пробовал с intel visual fortran из параллельной студии xe 2018обновление 5, а также 2019 обновление 3.)

...