[EDIT: 20110523 19:35 CDT – reformat – WDR]
On 64-bit Windows 7 and 64-bit matlab, I have the following problem. When I pass a 2D array of type single (float32) and size (43500, 29200) from matlab to a mex function, only the first 196458176 values are passed to the mex function correctly. The same problem occurred when I passed a 2D array of type single and size (43500, 29200) from the mex function to matlab. The mex function is written in Fortran and the code was compiled by the Intel 64 Fortran compiler XE version 12.0.4.196 Build 20110427.
I can send you the Fortran code (io_64bit.f) for the mex function. I test the mex function by the following script:
nC = 43500;nR = 29200;din = ones(nC, nR, 'single');[dout1, dout2] = io_64bit(din);sdin = sum(sum( int32(din) ));sdout1 = sum(sum( int32(dout1) ));sdout2 = sum(sum( int32(dout2) ));
If all goes well, sdout1 = sdin = – sdout2 = 1270200000 (= nC * nR)
Following is the Fortran code:
c***********************************************************************cc Check fidelity of large array passed from Matlab to mex functionc and vice versa.cc [dout1, dout2] = io_64bit(din)cc***********************************************************************cc Original: 18 May 2011 Final: 18 May 2011cc*********************************************************************** subroutine mexFunction(nlhs, plhs, nrhs, prhs) implicit none integer*4 nlhs, nrhs c <----------------------------------------------------------------- c For 32-bit OS, change following to integer*4 c -------------------------------------------- integer*8 plhs(*), prhs(*) integer*8 mxGetCell, mxGetM, mxGetN, mxGetPr integer*8 mxGetNumberOfElements, mxClassIDFromClassName integer*8 mxCreateNumericArray, mxCreateNumericMatrix integer*8 mxIsInt8, mxIsInt32, mxIsSingle integer*8 mexPrintf integer*8 nCol, nRow, din_p, dout1_p, dout2_p integer*8 n, ClassID, ComplexFlag c -----------------------------------------------------------------> character (len = 48) eMsg integer i, iStatus real xmin, xmax real, allocatable :: din(:,:) logical, parameter :: lDebug = .true.c ------------------------------------------------------------------ if(nrhs /= 1) call mexerrmsgtxt('1 input argument is required') if(nlhs /= 2) call mexerrmsgtxt('2 outputs are produced') nCol = mxGetM(prhs(1)) nRow = mxGetN(prhs(1)) n = mxGetNumberOfElements(prhs(1)) if(lDebug) then open(1,file='mex_io.log',status='unknown') write(1,*) nCol, nRow, n endif if(n /= nCol*nRow) then call mexErrMsgTxt('Cannot determine size of 2D array dem') endifc -------------------------------- Check inputs are of correct types eMsg = 'Argument x must be of type single / float32' do i=1, 1 if(mxIsSingle(prhs(i)) == 0) then write(eMsg(10:10),'(i1)') i call mexErrMsgTxt(eMsg) endif enddoc -------------------------------- Allocate memory and setup pointer allocate(din(nCol,nRow),stat=iStatus) call check_allocation(iStatus, 'din') din = 0.0 if(lDebug) write(1,*) 'Done memory allocation' din_p = mxGetPr(prhs(1)) if(lDebug) write(1,*) 'Done pointer ', din_pc -------------------------------------------- Copy data from Matlab call mxCopyPtrToReal4(din_p, din, n) if(lDebug) then write(1,*) 'Done copy ptr to real' call minmax(n, din, xmin, xmax) write(1,*) xmin, xmax endifc ------------------------------ Create output matrix of type single ClassID = mxClassIDFromClassName('single') ComplexFlag = 0 plhs(1) = mxCreateNumericMatrix(nCol, nRow, ClassID, ComplexFlag) plhs(2) = mxCreateNumericMatrix(nCol, nRow, ClassID, ComplexFlag) dout1_p = mxGetPr(plhs(1)) dout2_p = mxGetPr(plhs(2)) if(lDebug) then write(1,*) ClassID close(1) endifc -------------------------------------------- Copy data 1 to Matlab call mxCopyReal4ToPtr(din, dout1_p, n)c -------------------------------------------- Copy data 2 to Matlab din = -1.0 call mxCopyReal4ToPtr(din, dout2_p, n) deallocate(din) return end subroutine mexFunction c c======================================================================= c subroutine minmax(n, x, xmin, xmax) integer*8 n real xmin, xmax, x(n) integer i, ix, m xmin = huge(xmin) xmax = -xmin m = 0 do i=1, n xmin = min(xmin, x(i)) xmax = max(xmax, x(i)) if(x(i) /= 0.0) ix = i if(x(i) == 0.0) m = m + 1 enddoc ------------------------------------------------------------------c ix = no of values passed from Matlab correctlycc m = no of no-values from Matlabcc (n - m) should = ixcc ------------------------------------------------------------------ write(1,*) ix, m, n - m return end subroutine minmax c c======================================================================= c subroutine check_allocation(iStatus, name) integer iStatus character*(*) name if(iStatus /= 0) then call mexErrMsgTxt('Cannot allocate memory for array '//name) stop endif return end subroutine check_allocation
Best Answer