我想在Visual Studio中使用matlab,mex,intel fortran等,并使用标量的3 * 3矩阵的简单乘积,请参阅:
Strange values at debug for fortran mex code
基本上,您输入一个标量和一个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
在编译时出现以下错误:
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)
所有错误都发生在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,我尝试使用Parallel Studio XE 2018 Update 5和2019 Update 3的Intel Visual Fortran。)