Re: Call Array valued Fortran function from C



"FX" <coudert@xxxxxxxxxxxxx> wrote in message
news:fudrd5$9ts$1@xxxxxxxxxxxxx

But you should ask the gfortran folks if they can round up some
documentation about gfortran array descriptors for you. They are
different in every compiler.

Yep, that's on the TODO list. Here's the short version (in C syntax).

Thanks for the documentation, FX! Since I can never seem to get all
my ducks in a row on the first attempt, I tried a pure Fortran test
of my initial recommendation and found some syntax errors. After
fixing them up I got:

C:\gfortran\clf\repeatdouble>type repeatdouble.f90
function repeatdouble( N, d ) result( array )
use iso_c_binding
implicit none
integer, intent( in ) :: N
double precision, dimension( N ) :: array
double precision, intent( in ) :: d
integer I
print *, "repeat ", N, " times ..."
print *, "double ", d, "."
print *, "array :", array
do I = 1,N
print *, "making copy nb", i, " of ", N
array(I) = d
end do
end function repeatdouble

C:\gfortran\clf\repeatdouble>type test3.f90
program main
use ISO_C_BINDING
implicit none
type, bind(C) :: descr
type(C_PTR) address
integer(C_INTPTR_T) unknown1
integer(C_INTPTR_T) unknown2
integer(C_INTPTR_T) stride
integer(C_INTPTR_T) unknown3
integer(C_INTPTR_T) last_element
end type descr
interface
subroutine repeatdouble(DD,n,d) bind(C,name='repeatdouble_')
use ISO_C_BINDING
import descr
implicit none
type(descr) DD
integer(C_INT) n
real(C_DOUBLE) d
end subroutine repeatdouble
end interface
type(descr) DD
double precision, target :: buf(9)
double precision d
integer n

buf = [(n,n=1,9)]
d = 3.141592654
n = 4

DD = descr(C_LOC(buf), 0, 537, 1, 0, n-1)
call repeatdouble(DD, n, d)
write(*,'(9(f4.1))') buf
end program main

C:\gfortran\clf\repeatdouble>c:\gcc_equation\bin\x86_64-pc-mingw32-gfortran
-c r
epeatdouble.f90

C:\gfortran\clf\repeatdouble>c:\gcc_equation\bin\x86_64-pc-mingw32-gfortran
test
3.f90 repeatdouble.o -otest3

C:\gfortran\clf\repeatdouble>test3
repeat 4 times ...
double 3.1415927410125732 .
array :
making copy nb 1 of 4

So the test failed. I found the reason in test3.f90:

C:\gfortran\clf\repeatdouble>type test3.f90
program main
use ISO_C_BINDING
implicit none
type, bind(C) :: descr
type(C_PTR) address
integer(C_INTPTR_T) unknown1
integer(C_INTPTR_T) unknown2
integer(C_INTPTR_T) stride
integer(C_INTPTR_T) unknown3
integer(C_INTPTR_T) last_element
end type descr
interface
subroutine repeatdouble(DD,n,d) bind(C,name='repeatdouble_')
use ISO_C_BINDING
import descr
implicit none
type(descr) DD
integer(C_INT) n
real(C_DOUBLE) d
end subroutine repeatdouble
end interface
type(descr) DD
double precision, target :: buf(9)
double precision d
integer n

buf = [(n,n=1,9)]
d = 3.141592654
n = 4

DD = descr(C_LOC(buf), 0, 537, 1, 0, n-1)
! Shows the error: start
write(*,*) DD
write(*,*) C_LOC(buf)
DD%address = C_LOC(buf)
write(*,*) DD
! Shows the error: end
call repeatdouble(DD, n, d)
write(*,'(9(f4.1))') buf
end program main

C:\gfortran\clf\repeatdouble>c:\gcc_equation\bin\x86_64-pc-mingw32-gfortran
-c r
epeatdouble.f90

C:\gfortran\clf\repeatdouble>c:\gcc_equation\bin\x86_64-pc-mingw32-gfortran
test
3.f90 repeatdouble.o -otest3

C:\gfortran\clf\repeatdouble>test3
0 0 537
1 0 3
2293200
2293200 0 537
1 0 3
repeat 4 times ...
double 3.1415927410125732 .
array : 1.00000000000000000 2.0000000000000000
3.000000000000000
0 4.0000000000000000
making copy nb 1 of 4
making copy nb 2 of 4
making copy nb 3 of 4
making copy nb 4 of 4
3.1 3.1 3.1 3.1 5.0 6.0 7.0 8.0 9.0

So it seems that the structure constructor for type(descr) isn't
assigning that first member, address. If you do it by hand
everything works. This is a pretty recent version of gfortran,
so I think that the above example shows a bug in the compiler.

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


.



Relevant Pages

  • Re: SNGL intrinsic question
    ... You have initialized an array of double- ... precision numbers with single-precision literals. ... The compiler bug ...
    (comp.lang.fortran)
  • Re: What is wrong with this code?
    ... Uh, yeah, for me on this compiler, just a warning, I think. ... ridiculous contortions to avoid using a pointer to an ARRAY. ... The use of a global struct is another unnecessary design flaw. ... the extra precision. ...
    (comp.lang.c)
  • Re: Fast integer distance formula
    ... array of signed 16-bit numbers, but x and y themselves are 32-bit numbers in the ... stored back into an array of 16-bit integers, since the distance formula can ... It is likely more accurate than you need, but I think you can simply truncate the algorithm sooner for less precision. ...
    (comp.dsp)
  • Re: Desirable Usage of Fortran Modules
    ... suppose we want to cast a character array as ... A function that returns a string ... array of double precision numbers: ...
    (comp.lang.fortran)
  • Re: Call Array valued Fortran function from C
    ... a Fortran function that returns an array containing ... n-copy's of a given double precision number. ... arrayin the Fortran code). ... Disassembling a gfortran call to a similar function, ...
    (comp.lang.fortran)