Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem with a generic interface

119 views
Skip to first unread message

\"Vladimír Fuka <"name.surnameat

unread,
Apr 25, 2012, 10:03:56 AM4/25/12
to
Hello, I have a problem with a generic interface and C binding, as
demonstrated in a following program. I am receiving compile time error in
the second call. As I understand it, it is because of the assumed size
array. Is there any way to fix it? (At least because of theoretical
reasons, I can live without the generic interface.)

Vladimir




"ge.f90", Line = 37, Column = 6: ERROR: Incorrect argument rank in generic
procedure call "FFTW_PLAN_GEN"

or

Error: There is no specific function for the generic 'fftw_plan_gen' at (1)




program test
use iso_c_binding
implicit none

integer, parameter :: C_FFTW_R2R_KIND = C_INT32_T

interface fftw_plan_gen
type(C_PTR) function fftw_plan_r2r_1d(n,in,out,kind,flags) bind(C,
name='fftw_plan_r2r_1d')
import
integer(C_INT), value :: n
real(C_DOUBLE), dimension(*), intent(out) :: in
real(C_DOUBLE), dimension(*), intent(out) :: out
integer(C_FFTW_R2R_KIND), value :: kind
integer(C_INT), value :: flags
end function fftw_plan_r2r_1d

type(C_PTR) function fftw_plan_r2r_2d(n0,n1,in,out,kind0,kind1,flags)
bind(C, name='fftw_plan_r2r_2d')
import
integer(C_INT), value :: n0
integer(C_INT), value :: n1
real(C_DOUBLE), dimension(*), intent(out) :: in
real(C_DOUBLE), dimension(*), intent(out) :: out
integer(C_FFTW_R2R_KIND), value :: kind0
integer(C_FFTW_R2R_KIND), value :: kind1
integer(C_INT), value :: flags
end function fftw_plan_r2r_2d
end interface fftw_plan_gen

type(c_ptr) :: p
real(c_double), dimension(1,1) :: a


p= fftw_plan_r2r_2d(1_c_int,1_c_int, a, a, 0_c_int32_t, 0_c_int32_t,
0_c_int)

p= fftw_plan_gen(1_c_int,1_c_int, a, a, 0_c_int32_t, 0_c_int32_t,
0_c_int)

write (*,*) transfer(p,1_c_size_t)
end program test

\"Vladimír Fuka <"name.surnameat

unread,
Apr 25, 2012, 10:38:03 AM4/25/12
to
Seems, that I have to change the interface provided by FFTW to something
like dimension(n0,*).

Vladimir

Dne Wed, 25 Apr 2012 16:03:56 +0200 """Vladimír Fuka <""name.surname at
<mffDOTcuniDOTcz">> napsal(a):
--
Tato zpráva byla vytvořena převratným poštovním klientem Opery:
http://www.opera.com/mail/

glen herrmannsfeldt

unread,
Apr 25, 2012, 11:06:19 AM4/25/12
to
\"Vladimír Fuka <\"name.surname at <mffDOTcuniDOTcz">> wrote:

> Hello, I have a problem with a generic interface and C binding, as
> demonstrated in a following program. I am receiving compile time error in
> the second call. As I understand it, it is because of the assumed size
> array. Is there any way to fix it? (At least because of theoretical
> reasons, I can live without the generic interface.)

Assumes size array should be fine.

> "ge.f90", Line = 37, Column = 6: ERROR: Incorrect argument rank in generic
> procedure call "FFTW_PLAN_GEN"
(snip)
> Error: There is no specific function for the generic 'fftw_plan_gen' at (1)

(snip)
> interface fftw_plan_gen

(snip of 1D case)

> type(C_PTR) function fftw_plan_r2r_2d(n0,n1,in,out,kind0,kind1,flags)
> bind(C, name='fftw_plan_r2r_2d')
> import
> integer(C_INT), value :: n0
> integer(C_INT), value :: n1
> real(C_DOUBLE), dimension(*), intent(out) :: in
> real(C_DOUBLE), dimension(*), intent(out) :: out
> integer(C_FFTW_R2R_KIND), value :: kind0
> integer(C_FFTW_R2R_KIND), value :: kind1
> integer(C_INT), value :: flags
> end function fftw_plan_r2r_2d
> end interface fftw_plan_gen

> type(c_ptr) :: p
> real(c_double), dimension(1,1) :: a

Yes, the 2D array a won't match the dimension(*) array, even
though it is legal for an assumed size array.

Exactly what Fortran does with assumed size isn't so obvious,
but the usual implementation passes the address of the first element.
If you instead dimension(1,*) or, as you note later (n0,*), then
it should work.

I am not sure if you can get away with two different ones with
the same name and different rank inside the generic. (In case
you want to allow either 1D or 2D passed to fftw_plan_r2r_2d.)
More likely, though, you can give them different names, but the
same bind(name='name') and it will allow it through.

> p= fftw_plan_r2r_2d(1_c_int,1_c_int, a, a, 0_c_int32_t, 0_c_int32_t,
> 0_c_int)

> p= fftw_plan_gen(1_c_int,1_c_int, a, a, 0_c_int32_t, 0_c_int32_t,
> 0_c_int)

Another possibility is to pass a c_ptr to the function, and put
c_loc(a) for each array argument. That is assuming that you don't
want it to select the generic based on rank.

-- glen

Paul Anton Letnes

unread,
Apr 26, 2012, 1:48:01 AM4/26/12
to
Are you trying to make Fortran bindings to the FFTW library? Because
FFTW includes those by default. Or am I missing something?

Paul

\"Vladimír Fuka <"name.surnameat

unread,
Apr 26, 2012, 3:42:08 AM4/26/12
to
No, I am not making it. I am just adding some generic interfaces to my
program in order to have less preprocessor macros. I include the same
subroutine body for complex and real versions x 3 different dimensions and
x 2 (possibly 3) precisions. Now if I specify the dimension or use other
approach recommended by Glen, that even enables different kinds, the
generic name works without change in all of these.

Vladimir

Dne Thu, 26 Apr 2012 07:48:01 +0200 Paul Anton Letnes
<paul.ant...@nospam.gmail.kthxbai.com> napsal(a):

\"Vladimír Fuka <"name.surnameat

unread,
Apr 26, 2012, 3:47:48 AM4/26/12
to
Thanks. I will probably not need more versions for various array ranks. I
think that possibility of two different bindings for the same C symbol is
possible only in some TS addendum to Fortran 2008 and not widely
implemented. At least my compilers cannot use it. But I will remember the
solution to pass just the pointer, if I need it.

Vladimir


Dne Wed, 25 Apr 2012 17:06:19 +0200 glen herrmannsfeldt
<g...@ugcs.caltech.edu> napsal(a):

>
> I am not sure if you can get away with two different ones with
> the same name and different rank inside the generic. (In case
> you want to allow either 1D or 2D passed to fftw_plan_r2r_2d.)
> More likely, though, you can give them different names, but the
> same bind(name='name') and it will allow it through.
>
>> p= fftw_plan_r2r_2d(1_c_int,1_c_int, a, a, 0_c_int32_t, 0_c_int32_t,
>> 0_c_int)
>
>> p= fftw_plan_gen(1_c_int,1_c_int, a, a, 0_c_int32_t, 0_c_int32_t,
>> 0_c_int)
>
> Another possibility is to pass a c_ptr to the function, and put
> c_loc(a) for each array argument. That is assuming that you don't
> want it to select the generic based on rank.
>
> -- glen


0 new messages