У меня есть эта подпрограмма:
subroutine FotranDgemmMatrixMultiplication(A, B, C, m, n, p, mkl)
integer m, n, p
real*8 mkl
real*8 A(m,n), B(n,p), C(m,p)
if (mkl .ne. 1) then
C = matmul(A,B)
else
C = matmul(B,A)
endif
end
, которую я использую в файле mex gateway следующим образом:
#include <fintrf.h>
C The gateway routine
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
implicit none
mwPointer mxGetM, mxGetN, mxIsNumeric, mxIsLogical
mwPointer mxCreateDoubleMatrix
mwPointer plhs(*), prhs(*)
mwPointer A_pr, B_pr, C_pr, mkl_pr
mwPointer mxGetPr
integer nlhs, nrhs
real*8, allocatable, dimension(:,:) :: x, y, z
real*8 mkl
mwSize m, n, p, q, r, s
mwSize size1, size2, size3
C Check for proper number of arguments.
if (nrhs .ne. 3) then
call mexErrMsgTxt('Three 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.')
elseif (mxIsNumeric(prhs(3)) .ne. 1) then
call mexErrMsgTxt('Input #3 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 Check that the input #3 is a scalar
r = mxGetM(prhs(3))
s = mxGetN(prhs(3))
if(r .ne. 1 .or. s .ne. 1) then
call mexErrMsgTxt('Input #3 is not a scalar.')
endif
C Create matrix for the return argument.
plhs(1) = mxCreateDoubleMatrix(m, q, 0)
A_pr = mxGetPr(prhs(1))
B_pr = mxGetPr(prhs(2))
mkl_pr = mxGetPr(prhs(3))
C_pr = mxGetPr(plhs(1))
allocate( x(m,n), y(p,q), z(m,q) )
C Load the data into Fortran arrays.
call mxCopyPtrToReal8(A_pr, x, size1)
call mxCopyPtrToReal8(B_pr, y, size2)
call mxCopyPtrToReal8(mkl_pr, mkl, 1) ! suspicious line
C Call the computational subroutine.
call FotranDgemmMatrixMultiplication(x, y, z, m, n, q, mkl) ! crash here
C Load the output into a MATLAB array.
size3 = m*q
call mxCopyReal8ToPtr(z, C_pr, size3)
!deallocate(x,y,z)
return
end
, которая выполняется так, как задумано при отладке, но при сбое при выпускесбой в строке:
call FotranDgemmMatrixMultiplication(x, y, z, m, n, q, mkl)
Если я добавлю mwSize sizeOne
на sizeOne = 1
и заменим подозрительную строку (см. код) на:
call mxCopyPtrToReal8(mkl_pr, mkl, sizeOne)
, то сбой не произойдетбольше не происходит.Я не понимаю, что происходит, поскольку в x64
«тип» mwSize
определяется (в fintrf.h
) как mwpointer
, что само по себе определяется как integer*4
, что должно относиться к «константе» 1
правильно нормально.