From: Tobias Burnus on 24 Nov 2009 18:33 > 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 24 Nov 2009 22:12 "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 25 Nov 2009 02:32 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 25 Nov 2009 05:16 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 25 Nov 2009 09:56
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. |