Visual studio 矩阵产品的Fortran mex文件:从不可分配到可分配
我在visual studio中玩matlab、mex、intel fortran等,用3*3矩阵乘以标量的简单乘积,请参见: 基本上,你输入一个标量和一个3*3矩阵,然后返回它们的乘积,一个3*3矩阵我现在尝试编写一个通用矩阵产品。首先,我想依靠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
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)