Matlab crashes while running MEX Fortran 90 routine
Show older comments
I compiled a Fortran mex file based off someone's code in Matlab 2019a using Intel fortran compiler 2019 and Microsoft visual studio 2017. Everytime Matlab uses the mex file to run the FortraN routine, it crashes. I am not sure if there is some error in the way I compiled the mex file or some issue with the code.
To compile the mex file, I used the command "mex('-largeArrayDims','-silent','-f','intel_fortran_19_vs2017.xml', 'mvndstpack.F90')" in Matlab 2019a (I have . Here is my code:
#include "fintrf.h"
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
! Declarations
implicit none
! mexFunction argument
mwPointer plhs(*), prhs(*)
integer*4 nlhs, nrhs
! Function declarations
mwSize mxGetN
mwpointer mxGetPr, mxCreateNumericArray, mxGetDimensions
double precision mxGetScalar
integer*4 mxClassIDFromClassName
! Pointers to input/output mxArrays
mwpointer x8_pr,x9_pr
mwpointer pf1_pr,pf2_pr,pf3_pr
mwpointer o1_pr,o2_pr,o3_pr
! Array information
mwSize nx1,nx2,nx3,nx4,nx5,nx6,nx7,nx8,nx9,nodes
integer*4 myclassid
double precision, allocatable, dimension(:) :: x8,x9
double precision x8i,x9i
double precision, allocatable, dimension(:,:,:,:,:,:,:,:,:) :: pf1,pf2,pf3
double precision, allocatable, dimension(:,:,:,:,:,:,:) :: o1,o2,o3
! Load Inputs
nx1 = mxGetScalar(prhs(1))
nx2 = mxGetScalar(prhs(2))
nx3 = mxGetScalar(prhs(3))
nx4 = mxGetScalar(prhs(4))
nx5 = mxGetScalar(prhs(5))
nx6 = mxGetScalar(prhs(6))
nx7 = mxGetScalar(prhs(7))
nx8 = mxGetScalar(prhs(8))
nx9 = mxGetScalar(prhs(9))
nodes = nx1*nx2*nx3*nx4*nx5*nx6*nx7*nx8*nx9
allocate(x8(nx8))
allocate(x9(nx9))
x8_pr = mxGetPr(prhs(10))
x9_pr = mxGetPr(prhs(11))
call mxCopyPtrToReal8(x8_pr,x8,nx8)
call mxCopyPtrToReal8(x9_pr,x9,nx9)
! Point to evaluate
x8i = mxGetScalar(prhs(12))
x9i = mxGetScalar(prhs(13))
! Policy functions
allocate(pf1(nx1,nx2,nx3,nx4,nx5,nx6,nx7,nx8,nx9))
allocate(pf2(nx1,nx2,nx3,nx4,nx5,nx6,nx7,nx8,nx9))
allocate(pf3(nx1,nx2,nx3,nx4,nx5,nx6,nx7,nx8,nx9))
pf1_pr = mxGetPr(prhs(14))
pf2_pr = mxGetPr(prhs(15))
pf3_pr = mxGetPr(prhs(16))
call mxCopyPtrToReal8(pf1_pr,pf1,nodes)
call mxCopyPtrToReal8(pf2_pr,pf2,nodes)
call mxCopyPtrToReal8(pf3_pr,pf3,nodes)
!Create array for return argument
myclassid = mxClassIDFromClassName('double')
allocate(o1(nx1,nx2,nx3,nx4,nx5,nx6,nx7))
allocate(o2(nx1,nx2,nx3,nx4,nx5,nx6,nx7))
allocate(o3(nx1,nx2,nx3,nx4,nx5,nx6,nx7))
plhs(1) = mxCreateNumericArray(7,[nx1,nx2,nx3,nx4,nx5,nx6,nx7],myclassid,0)
plhs(2) = mxCreateNumericArray(7,[nx1,nx2,nx3,nx4,nx5,nx6,nx7],myclassid,0)
plhs(3) = mxCreateNumericArray(7,[nx1,nx2,nx3,nx4,nx5,nx6,nx7],myclassid,0)
o1_pr = mxGetPr(plhs(1))
o2_pr = mxGetPr(plhs(2))
o3_pr = mxGetPr(plhs(3))
! Call subroutine for assignment
call allterp( nx1,nx2,nx3,nx4,nx5,nx6,nx7,nx8,nx9, &
x8,x9, &
x8i,x9i, &
pf1,pf2,pf3, &
o1,o2,o3)
! Load Fortran array to pointer (output to MATLAB)
call mxCopyReal8ToPtr(o1,o1_pr,nx1*nx2*nx3*nx4*nx5*nx6*nx7)
call mxCopyReal8ToPtr(o2,o2_pr,nx1*nx2*nx3*nx4*nx5*nx6*nx7)
call mxCopyReal8ToPtr(o3,o3_pr,nx1*nx2*nx3*nx4*nx5*nx6*nx7)
! Deallocate arrays
deallocate(x8)
deallocate(x9)
deallocate(pf1)
deallocate(pf2)
deallocate(pf3)
deallocate(o1)
deallocate(o2)
deallocate(o3)
end subroutine mexFunction
subroutine allterp( nx1,nx2,nx3,nx4,nx5,nx6,nx7,nx8,nx9, &
x8,x9, &
x8i,x9i, &
pf1,pf2,pf3, &
o1,o2,o3)
implicit none
mwSize :: nx1,nx2,nx3,nx4,nx5,nx6,nx7,nx8,nx9
double precision :: x8i,x9i,x8(nx8),x9(nx9)
double precision, dimension(nx1,nx2,nx3,nx4,nx5,nx6,nx7,nx8,nx9) :: pf1,pf2,pf3
double precision, dimension(nx1,nx2,nx3,nx4,nx5,nx6,nx7) :: o1,o2,o3
double precision :: s8, s9
double precision :: x8i_min, x9i_min
mwSize loc8, loc9
double precision, dimension(2) :: xi, xi_left, xi_right, w_2, w_1
double precision, dimension(2) :: w8, w9
mwSize :: m8, m9
double precision :: wtemp
s8 = x8(2) - x8(1)
s9 = x9(2) - x9(1)
x8i_min = x8i - x8(1)
loc8 = min(nx8-1,max(1,floor(x8i_min/s8) + 1))
x9i_min = x9i - x9(1)
loc9 = min(nx9-1,max(1,floor(x9i_min/s9) + 1))
xi = [x8i, x9i]
xi_left = [x8(loc8), x9(loc9)]
xi_right = [x8(loc8+1), x9(loc9+1)]
w_2 = (xi - xi_left)/(xi_right - xi_left)
w_1 = 1 - w_2
w8 = [w_1(1), w_2(1)]
w9 = [w_1(2), w_2(2)]
o1 = 0.d0
o2 = 0.d0
o3 = 0.d0
do m9 = 0,1
do m8 = 0,1
wtemp = w8(m8+1)*w9(m9+1)
o1 = o1 + wtemp*pf1(:,:,:,:,:,:,:,loc8+m8,loc9+m9)
o2 = o2 + wtemp*pf2(:,:,:,:,:,:,:,loc8+m8,loc9+m9)
o3 = o3 + wtemp*pf3(:,:,:,:,:,:,:,loc8+m8,loc9+m9)
end do
end do
end subroutine allterp
The code is a part of an optimization routine to interpolate policy functions. This is the first time I have tried to compile a mex file. Any help would be greatly appreciated.
1 Comment
Manuel Antonio Sanchez Garcia
on 23 Aug 2020
Thank you for posting your code, it has helped me a lot reading it alone!
Accepted Answer
More Answers (0)
Categories
Find more on Write C Functions Callable from MATLAB (MEX Files) in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!