- 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