how to pass 2d array from C to Fortran?

how to pass 2d array from C to Fortran?

I need to pass 2d arrays from C to Fortran using interoperability features.

in C :
arrays are declared as

int ** ia;
float ** fa;
double **da;

int m, n;    // dimensions [m x n]

allocation is done as :

ia = (int **)malloc(sizeof(int *) * m);
for(i=0; i!=m; ++i) ia[i] = (int *) malloc(sizeof(int) * n);
.... 

// call fortran subroutine
fortran_call(ia, fa, da);

in FORTRAN:

subroutine fortran_call(ia, fa, da, m, n) bind(c)

use iso_c_binding

integer(c_int), intent(in)  :: ia(n,m)
real(c_float), intent(in)  :: fa(n,m) 
real(c_double), intent(in)  :: da(n,m) 

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!  the arrays are not passed to Fortran subroutine correctly !!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

end subroutine 

Could you explain me please how to pass 2d arrays (in form : iso_c_type **) to FORTRAN, please ?

Thank you so much !

4 Beiträge / 0 neu
Letzter Beitrag
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.

One way is to change your C allocation:

ia = (int **)malloc(sizeof(int *) * m);
iaBlob = (int*)malloc(sizeof(int) * m * n;
for(i=0; i!=m; ++i) ia[i] = &iaBlob[i*n];

Then pass the location of iaBlob (FORTRAN reference to iaBlob), together with m and n.

SUBROUTINE FOO(ia, m, n)
integer :: m, n
integer :: ia(n, m) ! or ia(0:n-1,0:m-1)

(note index swap)

Your current code would require you to pass an array of pointers (some more work on FORTRAN side)

Jim Dempsey

www.quickthreadprogramming.com

Quote:

coolweather wrote:

I need to pass 2d arrays from C to Fortran using interoperability features.

in C :
arrays are declared as


int ** ia;

float ** fa;

double **da;

int m, n;    // dimensions [m x n]

 // allocation is done as :

ia = (int **)malloc(sizeof(int *) * m);

for(i=0; i!=m; ++i) ia[i] = (int *) malloc(sizeof(int) * n); // .... 

// call fortran subroutine

fortran_call(ia, fa, da);

No prototype for fortran_call shown. This call has three arguments. ia here is an array of pointers to arrays of int. This allows what is known as a "ragged array" - ia[0] could point to an array of size 1, ia[2] could point to an array of size 100. (Note "could" - you've not done that, but the capability is there). The storage for the array pointed at by ia[0] and the storage for the array pointed at by ia[1] will probably not be adjacent in memory - they are separate "malloc's".

Quote:

in FORTRAN:

subroutine fortran_call(ia, fa, da, m, n) bind(c)

Five arguments. No declarations for m and n shown.

Quote:


use iso_c_binding

integer(c_int), intent(in)  :: ia(n,m)


ia here is a rectangular array (all rows must be the same length). In memory the data for the array is stored as a contiguous sequence. From a C point of view, this is equivalent to a single malloc, with the programmer then managing the concepts of rows and columns "ia[ix * ny + iy]". In terms of the matching C procedure the argument would be a "int *" (or equivalently an int[]). This is not consistent with the nature of the array and argument on the C side.

Quote:



real(c_float), intent(in)  :: fa(n,m)

real(c_double), intent(in)  :: da(n,m)

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!!!  the arrays are not passed to Fortran subroutine correctly !!!

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

end subroutine

Could you explain me please how to pass 2d arrays (in form : iso_c_type **) to FORTRAN, please ?

Thank you so much !

Do you want a ragged array, or a rectangular array?

A Fortran CONTIGUOUS 2D array is interoperable with a C array using only a single level of pointers, with explicit calculation of the address offset (e.g. the way it's done by the legacy f2c translator). As Jim said, you would need to handle each row individually if you use a ** in C. The lack of direct equivalence appears to be the reason why there isn't specific provision in iso_c_binding.
It looks like expanding on this subject might keep me busy a few months if I write a post-retirement book (no, I haven't committed to take the retirement offer yet).

Kommentar hinterlassen

Bitte anmelden, um einen Kommentar hinzuzufügen. Sie sind noch nicht Mitglied? Jetzt teilnehmen