Asked by Zaikun Zhang
on 29 Jul 2019

(The same question is asked here: https://stackoverflow.com/questions/57244555/portable-declaration-of-real-variables-in-mex-gateway-for-fortran)

I am writing a mex gateway for a piece of Fortran code.

In the Fortran code, for portability, the floating-point variables are declared as

REAL(kind(0.0D0)) :: x, y, etc

(BTW, I am aware that there are better ways to do it, as discussed at

https://stackoverflow.com/questions/3170239/fortran-integer4-vs-integer4-vs-integerkind-4,

https://stackoverflow.com/questions/10520819/what-does-real8-mean?noredirect=1&lq=1, and

https://software.intel.com/en-us/blogs/2017/03/27/doctor-fortran-in-it-takes-all-kinds )

However, it seems to me that mex supports only REAL*8 and REAL*4, the former being Double, the latter being Single. I got this impression from the following functions/subroutines:

mxIsDouble, mxIsSingle, mxCopyPtrToReal8, mxCopyReal8ToPtr, mxCopyPtrToReal4, mxCopyReal4ToPtr

My questions are as follows.

- Is it true that mex supports only REAL*8 and REAL*4?
- Are REAL*8 and/or REAL*4 supported on all platforms? If no, does this mean that MATLAB mex is intrinsically unportable?
- What is the best way to specify the kind of floating-point variables in mex gateways for Fortran code?
- Does it improve the portability of the mex gateway if I declare double-precision floating-point variables as

REAL(kind(0.0D0)) :: x, y, etc

or even

integer, parameter :: dp = selected_real_kind(15, 307)

real(kind=dp) :: x, y, etc

Or should I simply declare

REAL*8 :: x, y, etc

Thank you very much!

The following code is an example. See the declaration of x, y, and xs.

#include "fintrf.h"

subroutine mexFunction(nlhs, plhs, nrhs, prhs)

C y = square (x)

C x: a floating point scalar

C y: x^2

implicit none

C mexFunction arguments

integer, intent(in) :: nlhs, nrhs

mwPointer, intent(in) :: prhs(nrhs)

mwPointer, intent(inout) :: plhs(nlhs)

C function declarations:

mwPointer, external :: mxCreateDoubleScalar, mxGetPr

mwSize, external :: mxGetM, mxGetN

integer*4, external :: mxIsDouble, mxIsSingle

C variables

mwSize, parameter :: mwOne = 1

integer, parameter :: dKind = kind(0.0D0)

integer, parameter :: sKind = kind(0.0)

real(kind=dKind) :: x, y ! Does this improve the portablity?

real(kind=sKind) :: xs ! Does this improve the portablity?

C validate number of arguments

if (nrhs .ne. 1) then

call mexErrMsgIdAndTxt ('mex:nInput', '1 input required.')

endif

if (nlhs .gt. 1) then

call mexErrMsgIdAndTxt ('mex:nOutput', 'At most 1 output.')

endif

C validate input

if (mxIsDouble(prhs(1)) .ne. 1 .and. mxIsSingle(prhs(1)) .ne. 1)

! What if the input is a floating point number but neither Double nor Single?

+ then

call mexErrMsgIdAndTxt ('mex:Input', 'Input a real number.')

endif

if (mxGetM(prhs(1)) .ne. 1 .or. mxGetN(prhs(1)) .ne. 1) then

call mexErrMsgIdAndTxt ('mex:Input', 'Input a scalar.')

endif

C read input

if (mxIsDouble(prhs(1)) .eq. 1) then

call mxCopyPtrToReal8(mxGetPr(prhs(1)), x, mwOne)

else

call mxCopyPtrToReal4(mxGetPr(prhs(1)), xs, mwOne)

x = real(xs, dKind)

! What if the input is a floating point number but neither REAL*8 nor REAL*4

endif

C do the calculation

y = x**2

C write output

plhs(1) = mxCreateDoubleScalar(y)

return

end subroutine mexFunction

Answer by James Tursa
on 29 Jul 2019

Edited by James Tursa
on 29 Jul 2019

Zaikun Zhang
on 30 Jul 2019

Thank you, James, for the informative answer. I agree that the REAL(kind(0.0D0)) vs REAL*8 discussion is a comipler issue. The mex issue is why MATLAB insists on the nonstandard REAL*8/REAL*4/INTEGER*4, and, with such nonstandard features, how we could write mex gateways that both meet the Fortran standards and work correctly with all supported compilers/OS's.

Maybe the "right" thing to do is just write REAL*8/REAL*4/INTEGER*4 as in the MATLAB documents and forget about the Fortran standards?

Thank you very much!

James Tursa
on 30 Jul 2019

Zaikun Zhang
on 30 Jul 2019

Sign in to comment.

Opportunities for recent engineering grads.

Apply Today
## 0 Comments

Sign in to comment.