Visual studio 矩阵产品的Fortran mex文件:从不可分配到可分配

Visual studio 矩阵产品的Fortran mex文件:从不可分配到可分配,visual-studio,matlab,fortran,mex,intel-fortran,Visual Studio,Matlab,Fortran,Mex,Intel Fortran,我在visual studio中玩matlab、mex、intel fortran等,用3*3矩阵乘以标量的简单乘积,请参见: 基本上,你输入一个标量和一个3*3矩阵,然后返回它们的乘积,一个3*3矩阵我现在尝试编写一个通用矩阵产品。首先,我想依靠matmul来验证所有mex接口层。因此,基本例程是: subroutine mymatmul(A, B, C, m, n, p) real*8, allocatable, dimension(:,:) :: A, B, C

我在visual studio中玩matlab、mex、intel fortran等,用3*3矩阵乘以标量的简单乘积,请参见:

基本上,你输入一个标量和一个3*3矩阵,然后返回它们的乘积,一个3*3矩阵我现在尝试编写一个通用矩阵产品。首先,我想依靠
matmul
来验证所有mex接口层。因此,基本例程是:

    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
所有错误都发生在mex包装代码的第55行,即:

  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,我尝试了并行studio xe 2018更新5和2019更新3中的英特尔visual fortran。)

我不会对matlab fortran接口发表评论,但子程序
mymatmul
几乎肯定不是您想要的<代码>分配(A(m,n),B(n,p),C(m,p));C=matmul(A,B)已损坏。我不知道你为什么希望参数是可分配的,但如果它们是可分配的,你就不能这样处理它们。@francescalus我提出它是因为我想能够对任何(合法)大小的矩阵进行多重化,因此是可分配的,但显然这不是我应该做的。你会推荐什么?因为你在调用
mymatmul
之前已经验证了这些形状,你可以简单地假设参数的形状(甚至是显式形状)。我承认我并没有真正遵循链接的问题,但对于显式形状参数:
整数m,n,p;实数*8a(m,n),B(n,p),C(m,p)
,或对于假定形状:
实数*8a(:,:),B(:,:),C(:,:)
。后者无法解决您看到的“显式接口”错误。如果您找到这两本书中的任何一本,我们可以为您提供解释。您可以在
mexFunction
中使
x
y
z
可分配。这并不要求
mymatmul
的参数是可分配的。我不会评论Matlab Fortran接口,但子例程
mymatmul
几乎肯定不是您想要的<代码>分配(A(m,n),B(n,p),C(m,p));C=matmul(A,B)已损坏。我不知道你为什么希望参数是可分配的,但如果它们是可分配的,你就不能这样处理它们。@francescalus我提出它是因为我想能够对任何(合法)大小的矩阵进行多重化,因此是可分配的,但显然这不是我应该做的。你会推荐什么?因为你在调用
mymatmul
之前已经验证了这些形状,你可以简单地假设参数的形状(甚至是显式形状)。我承认我并没有真正遵循链接的问题,但对于显式形状参数:
整数m,n,p;实数*8a(m,n),B(n,p),C(m,p)
,或对于假定形状:
实数*8a(:,:),B(:,:),C(:,:)
。后者无法解决您看到的“显式接口”错误。如果您找到这两本书中的任何一本,我们可以为您提供解释。您可以在
mexFunction
中使
x
y
z
可分配。这并不要求
mymatmul
的参数是可分配的。
  real*8  x(3,3), y(3,3), z(3,3)