如何在Fortran mex文件中使用BLAS函数

时间:2017-04-15 16:59:58

标签: matlab fortran mex blas

我尝试在我的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

2 个答案:

答案 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