From: Tobias Burnus on
> On Nov 24, 10:30 am, James Tursa <aclassyguywithakno...(a)hotmail.com>
> wrote:
>> The non-standard %LOC() and %VAL() constructs are available in the
>> Intel Fortran and Compaq Fortran compilers that I have (32-bit,
>> WinXP). Are these constructs available in other compilers such as
>> gfortran, f95, etc? What about linux, mac, etc.? If not, is there a
>> workaround for this functionality? I am writing a package for others
>> to use and would like it to run in other environments out of the box
>> if possible. Thanks.
>
> See the gfortran documentation for information concerning its
> implementation of these constructs.

Short: gfortran supports %LOC(), %VAL() and %REF(), see
http://gcc.gnu.org/onlinedocs/gfortran/Argument-list-functions.html and
GCC/gfortran runs on a large variety of systems (Sparc, x86, arm, mips,
PowerPC, ia64, x86-64, s390, ...) and operating systems (FreeBSD, Linux,
Windows, Darwin (Mac), AIX, Solaris, HPUX, ...). [And the Intel compiler
you mention also runs on (x86 and x86-64) Windows, Linux and Mac.] Note,
however, that those are only supported as arguments in procedure calls
and not on their own (cf. "LOC()"). Note further that these all are
vendor extensions, which are relatively common but by far not supported
by all compilers.

As others have pointed out before, using the C binding support is the
better alternative. See, e.g.,
http://gcc.gnu.org/onlinedocs/gfortran/Interoperability-with-C.html and
especially
http://gcc.gnu.org/onlinedocs/gfortran/Interoperable-Subroutines-and-Functions.html
for an introduction, which should be relatively vendor agnostic.
The C binding support - as defined in the Fortran 2003 standard - is
present is a number of recent compilers, but older ones do not have it.

It depends on your users whether it is more likely that they have
compilers with %LOC, %VAL or with C binding support. But if you have the
choice, I would go for the latter. Advantages: (a) C bindings are well
defined (Fortran standard; vendor extensions tend to differ slightly
between vendors and even different versions). (b) I think the syntax is
also easier: You define what the procedure wants to get (e.g. a
pass-by-value argument) and then you simply pass the variable in the
call without having to care whether it should be a %VAL or a %REF or
%LOC. (c) The market share of older compilers is decreasing thus C
binding support should become more and more common.

Example for compilers not supporting %VAL: NAG f95. Example for not
supporting C bindings: Open64, g77. Examples for supporting both: ifort,
gfortran, sunf95, g95.

Tobias
From: James Van Buskirk on
"James Tursa" <aclassyguywithaknotac(a)hotmail.com> wrote in message
news:qkdog5dkqki843rqqrprp91qn0qisn2j7s(a)4ax.com...

> function fpGetPr2Double( mx ) result(fp)
> implicit none
> real(8), pointer :: fp(:,:)
> !-ARG
> mwPointer, intent(in) :: mx
> !-COM
> real(8), pointer :: Apx2(:,:)
> common /MatlabAPI_COMA2/ Apx2
> !-LOC
> mwSize, parameter :: stride = 1
> mwPointer :: pr
> mwSize, pointer :: dims(:)
> !-----
> if( mxIsDouble(mx) == 1 .and. mxIsSparse(mx) == 0 .and. &
> & mxGetNumberOfDimensions(mx) == 2 ) then
> pr = mxGetPr( mx )
> dims => fpGetDimensions( mx )
> call MatlabAPI_COM_Apx2( %VAL(pr), stride, dims )
> fp => Apx2
> else
> nullify( fp )
> endif
> return
> end function fpGetPr2Double
> !----------------------------------------------------------------------
> subroutine MatlabAPI_COM_Apx2( A, stride, DIMS )
> implicit none
> !-ARG
> mwSize, intent(in) :: stride, DIMS(2)
> real(8), target, intent(in) :: A(stride,DIMS(1),DIMS(2))
> !-COM
> real(8), pointer :: Apx2(:,:)
> common /MatlabAPI_COMA2/ Apx2
> !-----
> Apx2 => A(1,:,:)
> return
> end subroutine MatlabAPI_COM_Apx2

When I look at the above, the first thing that comes to my mind is:

function fpGetPr2Double( mx ) result(fp)
use ISO_C_BINDING
implicit none
real(C_DOUBLE), pointer :: fp(:,:)
!-ARG
type(C_PTR), intent(in) :: mx ! Or we could use integer(C_INTPTR_T)
!-LOC
integer(C_SIZE_T), parameter :: stride = 1
type(C_PTR) :: pr
integer(C_SIZE_T), pointer :: dims(:)
real(C_DOUBLE), pointer :: A(:,:,:)
!-FUN
interface
function mxGetPr(mx) bind(C,name='mxGetPr')
use ISO_C_BINDING
implicit none
type(C_PTR) mxGetPr
type(C_PTR), value :: mx
end function mxGetPr
function mxIsDouble(mx) bind(C,name='mxIsDouble')
use ISO_C_BINDING
implicit none
integer(C_INT) mxIsDouble
type(C_PTR), value :: mx
end function mxIsDouble
function mxIsSparse(mx) bind(C,name='mxIsSparse')
use ISO_C_BINDING
implicit none
integer(C_INT) mxIsSparse
type(C_PTR), value :: mx
end function mxIsSparse
function mxGetNumberOfDimensions(mx) bind(C,name= &
'mxGetNumberOfDimensions')
use ISO_C_BINDING
implicit none
integer(C_SIZE_T) mxGetNumberOfDimensions
type(C_PTR), value :: mx
end function mxGetNumberOfDimensions
function mxGetDimensions(mx) bind(C,name='mxGetDimensions')
use ISO_C_BINDING
implicit none
type(C_PTR) mxGetDimensions
type(C_PTR), value :: mx
end function mxGetDimensions
end interface
!-----
if( mxIsDouble(mx) == 1 .and. mxIsSparse(mx) == 0 .and. &
& mxGetNumberOfDimensions(mx) == 2 ) then
pr = mxGetPr( mx )
call C_F_POINTER(mxGetDimensions( mx ), dims, [2])
call C_F_POINTER(pr, A, [stride,dims(1),dims(2)])
fp => A(1,:,:)
nullify(A)
else
nullify( fp )
endif
return
end function fpGetPr2Double

Read Section 15 of N1601.pdf. It makes a real difference when you
face interoperability issues.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


From: James Tursa on
On Tue, 24 Nov 2009 20:12:36 -0700, "James Van Buskirk"
<not_valid(a)comcast.net> wrote:
>
>When I look at the above, the first thing that comes to my mind is:
>
> function fpGetPr2Double( mx ) result(fp)

(snip)

> end function fpGetPr2Double
>
>Read Section 15 of N1601.pdf. It makes a real difference when you
>face interoperability issues.

Wow ... that's the *first* thing that comes to your mind? It's going
to take me awhile to digest all of that! Thanks for the post. Bottom
line for me is I want to support people with older compilers as well
as newer compilers, so I will look into creating another version of my
package using the C interop facilities, particularly the C_LOC and
C_F_POINTER routines. But I don't have the latest Intel compiler, so I
will have to look into getting an upgrade or getting another compiler
that supports this.

James Tursa
From: Ian Harvey on
I acknowledge that not all compilers support this part of F2003, but I'd
just like to strongly second James Van Buskirk's approach.

If you want to work with Matlab, C-interop is the way to go. It's
pretty easy to read the documentation/header files for the (more
capable) C interface api and write out the relevant interface blocks.
Supplement those with a few parameters for kinds and some utility
functions (like your specific pointer example) whack it all into a
module or two and away you go.

So much cleaner and simpler than the non-standard, archaic, preprocessor
based interface that the Mathworks provides for working with Fortran code.

James Tursa wrote:
> On Tue, 24 Nov 2009 20:12:36 -0700, "James Van Buskirk"
> <not_valid(a)comcast.net> wrote:
>> When I look at the above, the first thing that comes to my mind is:
>>
>> function fpGetPr2Double( mx ) result(fp)
>
> (snip)
>
>> end function fpGetPr2Double
>>
>> Read Section 15 of N1601.pdf. It makes a real difference when you
>> face interoperability issues.
>
> Wow ... that's the *first* thing that comes to your mind? It's going
> to take me awhile to digest all of that! Thanks for the post. Bottom
> line for me is I want to support people with older compilers as well
> as newer compilers, so I will look into creating another version of my
> package using the C interop facilities, particularly the C_LOC and
> C_F_POINTER routines. But I don't have the latest Intel compiler, so I
> will have to look into getting an upgrade or getting another compiler
> that supports this.
>
> James Tursa
From: GaryScott on
On Nov 25, 4:16 am, Ian Harvey <ian_har...(a)bigpond.com> wrote:
> I acknowledge that not all compilers support this part of F2003, but I'd
> just like to strongly second James Van Buskirk's approach.
>
> If you want to work with Matlab, C-interop is the way to go.   It's
> pretty easy to read the documentation/header files for the (more
> capable) C interface api and write out the relevant interface blocks.
> Supplement those with a few parameters for kinds and some utility
> functions (like your specific pointer example) whack it all into a
> module or two and away you go.
>
> So much cleaner and simpler than the non-standard, archaic, preprocessor
> based interface that the Mathworks provides for working with Fortran code..
>
>
>
> James Tursa wrote:
> > On Tue, 24 Nov 2009 20:12:36 -0700, "James Van Buskirk"
> > <not_va...(a)comcast.net> wrote:
> >> When I look at the above, the first thing that comes to my mind is:
>
> >>      function fpGetPr2Double( mx ) result(fp)
>
> > (snip)
>
> >>      end function fpGetPr2Double
>
> >> Read Section 15 of N1601.pdf.  It makes a real difference when you
> >> face interoperability issues.
>
> > Wow ... that's the *first* thing that comes to your mind? It's going
> > to take me awhile to digest all of that! Thanks for the post. Bottom
> > line for me is I want to support people with older compilers as well
> > as newer compilers, so I will look into creating another version of my
> > package using the C interop facilities, particularly the C_LOC and
> > C_F_POINTER routines. But I don't have the latest Intel compiler, so I
> > will have to look into getting an upgrade or getting another compiler
> > that supports this.
>
> > James Tursa- Hide quoted text -
>
> - Show quoted text -

:( would be better if matlab didn't treat Fortran as a second class
citizen and created a proper binding.