- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[fortran]module IPP use, intrinsic :: iso_c_binding implicit none integer, parameter :: IPPI_INTER_NN = 1 integer, parameter :: IPPI_INTER_LINEAR = 2 integer, parameter :: IPPI_INTER_CUBIC = 4 integer, parameter :: IPPI_INTER_SUPER = 8 integer, parameter :: IPPI_INTER_LANCZOS = 16 ! -------------------------------------------------- type, bind(c) :: IppiRect integer :: x integer :: y integer :: width integer :: height end type IppiRect ! --------------------------------------------------- type, bind(c) :: IppiSize integer :: width integer :: height end type IppiSize ! -------------------------------------------------- interface function ippiResizeGetBufSize(srcROI, dstROI, nChannels, interpolation, bufsize) bind(c) ! N.B. 'bind(c)' implies 'external' type(IppiRect), intent(in) :: srcROI, dstROI integer, value :: nChannels, interpolation integer, intent(out) :: bufsize integer :: ippiResizeGetBufSize end function ippiResizeGetBufSize end interface ! --------------------------------------------------
interface function ippiResizeSqrPixel_64f_C1R(pSrc, srcSize, srcStep, srcROI, pDst, dstStep, dstROI, & xFactor, yFactor, xShift, yShift, interpolation, pBuffer) bind(c) ! N.B. 'bind(c)' implies 'external' real(c_double), intent(in), dimension(srcROI%width, srcROI%height) :: pSrc type(IppiSize), value :: srcSize integer, value :: srcStep type(IppiRect), value :: srcROI real(kind(1d0)), intent(out), dimension(dstROI%width, dstROI%height) :: pDst integer, value :: dstStep type(IppiRect), value :: dstROI real(c_double), value :: xFactor, yFactor, xShift, yShift integer, value :: interpolation character, intent(inout), dimension(1) :: pBuffer integer :: ippiResizeSqrPixel_64f_C1R end function ippiResizeSqrPixel_64f_C1R end interface end module IPP[/fortran]
The reasons that this doesn't work have surprised and, so far, baffled me. The interface blocks don't seem to be able to make use of the derived types which are defined immediately above them in the same module. Specifically, here are my compilation error messages:
[bash]IPP.f90(38): error #6457: This derived type name has not been declared. [IPPIRECT] IPP.f90(35): warning #6717: This name has not been given an explicit type. [SRCROI] IPP.f90(35): warning #6717: This name has not been given an explicit type. [DSTROI] IPP.f90(54): warning #6717: This name has not been given an explicit type. [SRCROI] IPP.f90(54): error #6535: This variable or component must be of a derived or structure type [SRCROI] IPP.f90(54): error #6460: This is not a field name that is defined in the encompassing structure. [WIDTH] IPP.f90(54): error #6223: A specification expression is invalid. [WIDTH] IPP.f90(54): error #6460: This is not a field name that is defined in the encompassing structure. [HEIGHT] IPP.f90(54): error #6223: A specification expression is invalid. [HEIGHT] IPP.f90(55): error #6457: This derived type name has not been declared. [IPPISIZE] IPP.f90(57): error #6457: This derived type name has not been declared. [IPPIRECT] IPP.f90(58): warning #6717: This name has not been given an explicit type. [DSTROI] IPP.f90(58): error #6535: This variable or component must be of a derived or structure type [DSTROI] IPP.f90(58): error #6223: A specification expression is invalid. [WIDTH] IPP.f90(58): error #6223: A specification expression is invalid. [HEIGHT] IPP.f90(60): error #6457: This derived type name has not been declared. [IPPIRECT] IPP.f90(54): warning #6717: This name has not been given an explicit type. [WIDTH] IPP.f90(54): warning #6717: This name has not been given an explicit type. [HEIGHT] IPP.f90(50): warning #6717: This name has not been given an explicit type. [SRCSIZE][/bash]
So far there's nothing IPP-specific in any of this - I haven't tried linking the libraries themselves in yet - so these are entirely generic Fortran errors. I would expect this to compile though, so what have I missed?
Thanks,
Stephen.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To bring a type (or parameter, etc) in from the parent scope you can either repeat the definition of the the type definition (only if it is a BIND(C) or SEQUENCE type); or put the type definition in a separate module and then USE that module inside the interface body (also applicable to the entities from ISO_C_BINDING) and the parent scope; or your can use the IMPORT statement introduced with Fortran 2003.
For example:
[fortran] interface function ippiResizeGetBufSize(srcROI, dstROI, nChannels, interpolation, bufsize) bind(c) ! N.B. 'bind(c)' implies 'external' import :: IppiRect implicit none type(IppiRect), intent(in) :: srcROI, dstROI integer, value :: nChannels, interpolation integer, intent(out) :: bufsize integer :: ippiResizeGetBufSize end function ippiResizeGetBufSize end interface [/fortran]On a separate note - be mindful that without a NAME= clause the binding label for a procedure will be an all lower version of your procedure name - not the mixed case that you've used in your function statements. I don't know whether you want the mixed or lower case variant.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To bring a type (or parameter, etc) in from the parent scope you can either repeat the definition of the the type definition (only if it is a BIND(C) or SEQUENCE type); or put the type definition in a separate module and then USE that module inside the interface body (also applicable to the entities from ISO_C_BINDING) and the parent scope; or your can use the IMPORT statement introduced with Fortran 2003.
For example:
[fortran] interface function ippiResizeGetBufSize(srcROI, dstROI, nChannels, interpolation, bufsize) bind(c) ! N.B. 'bind(c)' implies 'external' import :: IppiRect implicit none type(IppiRect), intent(in) :: srcROI, dstROI integer, value :: nChannels, interpolation integer, intent(out) :: bufsize integer :: ippiResizeGetBufSize end function ippiResizeGetBufSize end interface [/fortran]On a separate note - be mindful that without a NAME= clause the binding label for a procedure will be an all lower version of your procedure name - not the mixed case that you've used in your function statements. I don't know whether you want the mixed or lower case variant.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Here is the version that compiles without error:
[fortran]odule IPP use, intrinsic :: iso_c_binding implicit none integer, parameter :: IPPI_INTER_NN = 1 integer, parameter :: IPPI_INTER_LINEAR = 2 integer, parameter :: IPPI_INTER_CUBIC = 4 integer, parameter :: IPPI_INTER_SUPER = 8 integer, parameter :: IPPI_INTER_LANCZOS = 16 ! ----------------------------------------------- type, bind(c) :: IppiRect integer :: x integer :: y integer :: width integer :: height end type IppiRect ! ----------------------------------------------- type, bind(c) :: IppiSize integer :: width integer :: height end type IppiSize ! ----------------------------------------------- interface function ippiResizeGetBufSize(srcROI, dstROI, nChannels, interpolation, bufsize) & bind(c, name='ippiResizeGetBufSize') ! N.B. 'bind(c)' implies 'external' use, intrinsic :: iso_c_binding import :: IppiRect implicit none type(IppiRect), intent(in) :: srcROI, dstROI integer, value :: nChannels, interpolation integer, intent(out) :: bufsize integer :: ippiResizeGetBufSize end function ippiResizeGetBufSize end interface ! ----------------------------------------------- interface function ippiResizeSqrPixel_64f_C1R(pSrc, srcSize, srcStep, srcROI, pDst, dstStep, dstROI, & xFactor, yFactor, xShift, yShift, interpolation, pBuffer) & bind(c, name='ippiResizeSqrPixel_64f_C1R') ! N.B. 'bind(c)' implies 'external' use, intrinsic :: iso_c_binding import :: IppiRect, IppiSize implicit none integer, value :: srcStep type(IppiRect), value :: srcROI type(IppiSize), value :: srcSize real(c_double), intent(in), dimension(srcROI%width, srcROI%height) :: pSrc integer, value :: dstStep type(IppiRect), value :: dstROI real(c_double), intent(out), dimension(dstROI%width, dstROI%height) :: pDst real(kind(1d0)), value :: xFactor, yFactor, xShift, yShift integer, value :: interpolation character, intent(inout), dimension(1) :: pBuffer integer :: ippiResizeSqrPixel_64f_C1R end function ippiResizeSqrPixel_64f_C1R end interface end module IPP[/fortran]
All I have to do now is to get the linking right, and check that it all works.
Regards,
Stephen.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
(hollow laughter)
Sometimes, you just know you're on a hiding to nothing. Nothing I've tried so far has enabled my Fortran linker to find the IPP functions, and even Intel Premier Support say "sorry, we don't support this". There are in existence some examples of IPP cryptography functions being called from Fortran without ISO_C_BINDING but with many lines of !DEC$ ATTRIBUTES and !MS$ATRIBUTES declarations(which I've never seen before), but I haven't been able to imitate these successfully.
I guess it's time to find another solution, without the IPP.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
ipp is an optional component of icc installation or icc redistributable library. If you have the same version of icc and ifort, the environment script should put the ipp libraries on the search path, so -lipp..... should find them (in the path under /ipp/lib in the directory which contains the ifort /lib/).
There's no move to support .mod files to take care of the ISO_C INTERFACE or automatic choice of the relevant ipp libraries under ifort, so this involves significant hassle.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
There is a cryptography example that shows how to call IPP from Fortran (you may have seen this).
But ultimately you need to figure out based on the IPP definition files for the parameters how to specify them in the FORTRAN for MIxed Language calls. The section of the Fortran Documentation that discusses this is:
Mixed Language Programming
------
Wendy
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have come up with a solution that works for me, for now, though. As my Fortran code is a library that is called from a C++ application which itself makes use of IPP routines, I have put the C functions with simplified interfaces into my main application code, and then passed pointers to them as 'callbacks' alongside the other parameters being passed to the Fortran routines. When the Fortran routines need to access the IPP, they just call the callback functions they've been provided with. This works fine. Although it makes the source code a little more convoluted than I'd like, ithas the big advantage thatI don't need to touch my makefiles.This is useful as this suite gets compiled on various different platforms. It also confirms that my C interfaces are fine, so there's obviously some other reason why I can't seem to do the linking from Fortran.
Stephen.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
...
I know nothing of IPP, but this C interface layer seems a reasonable approach. Getting Fortran code that you control to talk to C code that you control should be relatively straight forward. Perhaps post the C function declaration and C compiler options along with what you used to define the interface on the Fortran side.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The IPP routines all have C++ interfaces, and that's not covered by ISO_C_BINDING, because of the name
mangling among other things.
-- Lorri
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Stephen.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page