我尝试在我的Fortran mex文件中使用BLAS函数,但它没有用。以下是我使用DGEMM的代码之一的示例:
#include "fintrf.h"
C Gateway subroutine
subroutine mexfunction(nlhs, plhs, nrhs, prhs)
C Declarations
implicit none
C mexFunction arguments:
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
C Function declarations:
mwPointer mxGetPr
mwPointer mxCreateDoubleMatrix
mwsize mxGetM,mxGetN
C Pointers to input/output mxArrays:
mwPointer pr_A, pr_B, pr_C
mwSize :: sizea,sizeb
C Array information:
real*8, allocatable :: A(:,:),B(:,:),C(:,:)
C Get the size of the input array.
sizea = mxGetM(prhs(1))
sizeb = mxGetN(prhs(2))
allocate(A(sizea,sizea),B(sizea,sizeb),C(sizea,sizeb))
C Create Fortran array from the input argument.
pr_A = mxGetPr(prhs(1))
pr_B = mxGetPr(prhs(2))
call mxCopyPtrToReal8( pr_A, A, sizea**2 )
call mxCopyPtrToReal8( pr_B, B, sizea*sizeb )
call MUL(A,B,C,sizea,sizeb)
C Create matrix for the return argument.
plhs(1) = mxCreateDoubleMatrix(sizea, sizeb, 0)
pr_C = mxGetPr(plhs(1))
call mxCopyReal8ToPtr(C , pr_C, sizea*sizeb )
return
end
subroutine MUL(A,B,C,sizea,sizeb)
implicit none
mwSize :: sizea,sizeb
real*8 :: A(sizea,sizea),B(sizea,sizeb),C(sizea,sizeb),alpha,beta
integer*4 :: M,N,K
character ch1, ch2
ch1 = 'N'
ch2 = 'N'
M=size(A,1)
N=size(B,2)
K=size(A,2)
Alpha=1.
Beta=0.
CALL DGEMM(ch1,ch2,M,N,K,ALPHA,A,M,B,K,BETA,C,M)
return
end subroutine MUL
我使用以下行创建一个mex文件:
mex -lmwblas Test.F
mex文件构建没有任何错误,但是当我尝试使用该函数时,matlab关闭时没有任何错误消息。我将Matlab R2016a与英特尔Visual Fortran Composer XE 2013 一起使用 Microsoft Visual Studio 2012 。
答案 0 :(得分:0)
您没有正确调用DGEMM。您的所有参数都是real*8
,但其中许多都应该是integer
s。
彻底检查DGEMM的文档并在参数后检查您的调用参数,以完全遵循接口。我非常确信传递值1而不是sizea
K
也是错误的。但实际上,你必须检查每一个论点。
我建议在纯Fortran中测试你的子程序,并且只有在他们正确地使用它们从Matlab中使用它们之后。
答案 1 :(得分:0)
这是解决方案:
#include "fintrf.h"
C Gateway subroutine
subroutine mexfunction(nlhs, plhs, nrhs, prhs)
C Declarations
implicit none
C mexFunction arguments:
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
C Function declarations:
mwPointer mxGetPr
mwPointer mxCreateDoubleMatrix
mwsize mxGetM,mxGetN
C Pointers to input/output mxArrays:
mwPointer pr_A, pr_B, pr_C
mwSignedIndex :: sizea,sizeb
C Array information:
real*8, allocatable :: A(:,:),B(:,:),C(:,:)
C Get the size of the input array.
sizea = mxGetM(prhs(1))
sizeb = mxGetN(prhs(2))
allocate(A(sizea,sizea),B(sizea,sizeb),C(sizea,sizeb))
C Create Fortran array from the input argument.
pr_A = mxGetPr(prhs(1))
pr_B = mxGetPr(prhs(2))
call mxCopyPtrToReal8( pr_A, A, sizea**2 )
call mxCopyPtrToReal8( pr_B, B, sizea*sizeb )
call MUL(A,B,C,sizea,sizeb)
C Create matrix for the return argument.
plhs(1) = mxCreateDoubleMatrix(sizea, sizeb, 0)
pr_C = mxGetPr(plhs(1))
call mxCopyReal8ToPtr(C , pr_C, sizea*sizeb )
return
end
subroutine MUL(A,B,C,sizea,sizeb)
implicit none
mwSignedIndex :: sizea,sizeb
real*8 :: A(sizea,sizea),B(sizea,sizeb),C(sizea,sizeb),alpha,beta
mwSignedIndex :: M,N,K
character ch1, ch2
ch1 = 'N'
ch2 = 'N'
M=size(A,1)
N=size(B,2)
K=size(A,2)
Alpha=1.0
Beta=0.0
CALL DGEMM(ch1,ch2,M,N,K,ALPHA,A,M,B,K,BETA,C,M)
return
end subroutine MUL
并使用
构建mex文件mex -largeArrayDims -lmwblas Test.F