Prev: MR&C chp 14
Next: Runge-Kutta method for solving IVPs
From: steve on 13 Jul 2010 01:56 On Jul 12, 10:20 pm, Uno <merrilljen...(a)q.com> wrote: > This is a bit of a repost. I wanted to clean up the context, refocus, > and thank parties who got me over the hump with my latest foray into > interop. Elliot helped me tremendously by giving me the proper query > syntax for google groups on c.l.f. I'll just show that again for > interested parties: > > interop zax keyword site:groups.google.com/group/comp.lang.fortran > > Erik managed to tell me -c without applying any of the flame opportunity > that existed. thx. > > I've really been enjoying a chapter of MR&C that I hadn't read closely. > Now that I've gotten one good result with interop, I want more. > > I believe that the declaration of pass on p. 259 is to enable the > passing of a 2-d array from C to fortran. Although a lot of this stuff > works in both directions, I am now focusing on C to fortran. > > Critical to this treatment is this struct (Richard is of course correct > that it is no subroutine. It's funny how a person gets crossed up > between syntaxes.): > > struct pass > { > int lenc, lenf; > float *c, f; > > }; > > Since I got Michael Metcalf to straighten me out once on this, I'm > hoping to get another good break. I really don't know much about how > fortran arrays look like underneath the hood; I've never had the need to > look. > > Anyways, this is what I've got now: > > $ gcc -c -lm c_mm3.c -o caller.o > $ gfortran -c -Wall -Wextra f_mm2.f03 -o pass.o > $ gcc pass.o caller.o -lgfortran -o out > $ ./out > vector[0][0] is 0.785398 > vector[0][1] is 2.107149 > vector[0][2] is 3.249046 > vector[0][3] is 4.325818 > vector[0][4] is 5.373401 > vector[0][5] is 6.405648 > vector[0][6] is 7.428899 > vector[1][0] is 2.107149 > vector[1][1] is 3.249046 > vector[1][2] is 4.325818 > vector[1][3] is 5.373401 > vector[1][4] is 6.405648 > vector[1][5] is 7.428899 > vector[1][6] is 8.446442 > vector[2][0] is 3.249046 > vector[2][1] is 4.325818 > vector[2][2] is 5.373401 > vector[2][3] is 6.405648 > vector[2][4] is 7.428899 > vector[2][5] is 8.446442 > vector[2][6] is 9.460139 > vector[3][0] is 4.325818 > vector[3][1] is 5.373401 > vector[3][2] is 6.405648 > vector[3][3] is 7.428899 > vector[3][4] is 8.446442 > vector[3][5] is 9.460139 > vector[3][6] is 10.471128 > vector[4][0] is 5.373401 > vector[4][1] is 6.405648 > vector[4][2] is 7.428899 > vector[4][3] is 8.446442 > vector[4][4] is 9.460139 > vector[4][5] is 10.471128 > vector[4][6] is 11.480137 > 0.78539819 2.1071486 3.2490458 4.3258176 > 5.3734007 > $ > > So, my C output doesn't look like my fortran output. In, particular, > the fortran output shows no dimensionality greater than one. > > Here are the source listings: > > $ cat c_mm3.c > #include <stdio.h> > #include <math.h> > #include <stdlib.h> > #define size1 5 > #define size2 7 > struct pass > { > int lenc, lenf; > float *c, f; > > }; > > void simulation (struct pass *arrays); > int > main () > { > > float vector[size1][size2]; > int i, j; > struct pass arrays; > > for (i = 0; i < size1; ++i) > for (j = 0; j < size2; ++j) > { > { > vector[i][j] = atan (1 + i + j) + i + j; > printf ("vector[%d][%d] is %f\n", i, j, vector[i][j]); > } > } > > arrays.lenc = size1; > arrays.lenf = size2; > arrays.c = &vector[0][0]; > // arrays.f = NULL; > > simulation (&arrays); > return 0; > > } > > // gcc -c -lm c_mm3.c -o caller.o > // gcc pass.o caller.o -lgfortran -o out > $ cat f_mm2.f03 > > subroutine simulation(arrays) bind(c) > use iso_c_binding > type, bind(c) :: pass > integer (c_int) :: lenc, lenf > type (c_ptr) :: c, f > end type pass > type (pass), intent(in) :: arrays > real (c_float), pointer :: c_array(:) > > ! associate c_array with an array allocated in C > call c_f_pointer( arrays%c, c_array, (/arrays%lenc/) ) > print *, c_array > end subroutine simulation > ! gfortran -c -Wall -Wextra f_mm2.f03 -o pass.o > $ > > Simple question: how do I get the fortran output to show the values > that the C output does *and* show up in the types of rows and columns > that a person wants who got an A in fortran 20 years ago and doesn't > feel like just taking a slopshot. > > Thanks for your comments, and cheers, > -- > Uno subroutine simulation(arrays) bind(c) use iso_c_binding type, bind(c) :: pass integer (c_int) :: lenc, lenf type (c_ptr) :: c real(c_float) :: f end type pass type (pass), intent(in) :: arrays real (c_float), pointer :: c_array(:) call c_f_pointer(arrays%c, c_array, & & (/arrays%lenc*arrays%lenf/) ) print *, c_array end subroutine simulation -- steve
From: Uno on 13 Jul 2010 02:31 steve wrote: > subroutine simulation(arrays) bind(c) > use iso_c_binding > type, bind(c) :: pass > integer (c_int) :: lenc, lenf > type (c_ptr) :: c > real(c_float) :: f > end type pass > type (pass), intent(in) :: arrays > real (c_float), pointer :: c_array(:) > call c_f_pointer(arrays%c, c_array, & > & (/arrays%lenc*arrays%lenf/) ) > print *, c_array > end subroutine simulation Cool. cool. $ gfortran -c -Wall -Wextra f_mm3.f03 -o pass.o $ gcc pass.o caller.o -lgfortran -o out $ ./out vector[0][0] is 0.785398 vector[0][1] is 2.107149 vector[0][2] is 3.249046 vector[0][3] is 4.325818 vector[0][4] is 5.373401 vector[0][5] is 6.405648 vector[0][6] is 7.428899 vector[1][0] is 2.107149 vector[1][1] is 3.249046 vector[1][2] is 4.325818 vector[1][3] is 5.373401 vector[1][4] is 6.405648 vector[1][5] is 7.428899 vector[1][6] is 8.446442 vector[2][0] is 3.249046 vector[2][1] is 4.325818 vector[2][2] is 5.373401 vector[2][3] is 6.405648 vector[2][4] is 7.428899 vector[2][5] is 8.446442 vector[2][6] is 9.460139 vector[3][0] is 4.325818 vector[3][1] is 5.373401 vector[3][2] is 6.405648 vector[3][3] is 7.428899 vector[3][4] is 8.446442 vector[3][5] is 9.460139 vector[3][6] is 10.471128 vector[4][0] is 5.373401 vector[4][1] is 6.405648 vector[4][2] is 7.428899 vector[4][3] is 8.446442 vector[4][4] is 9.460139 vector[4][5] is 10.471128 vector[4][6] is 11.480137 0.78539819 2.1071486 3.2490458 4.3258176 5.3734007 6.4056478 7.4288993 2.1071486 3.2490458 4.3258176 5.3734007 6.4056478 7.4288993 8.4464417 3.2490458 4.3258176 5.3734007 6.4056478 7.4288993 8.4464417 9.4601393 4.3258176 5.3734007 6.4056478 7.4288993 8.4464417 9.4601393 10.471128 5.3734007 6.4056478 7.4288993 8.4464417 9.4601393 10.471128 11.480137 $ cat f_mm3.f03 subroutine simulation(arrays) bind(c) use iso_c_binding type, bind(c) :: pass integer (c_int) :: lenc, lenf type (c_ptr) :: c real(c_float) :: f end type pass type (pass), intent(in) :: arrays real (c_float), pointer :: c_array(:) call c_f_pointer(arrays%c, c_array, & & (/arrays%lenc*arrays%lenf/) ) print *, c_array end subroutine simulation ! gfortran -c -Wall -Wextra f_mm3.f03 -o pass.o $ cat c_mm3.c #include <stdio.h> #include <math.h> #include <stdlib.h> #define size1 5 #define size2 7 struct pass { int lenc, lenf; float *c, f; }; void simulation (struct pass *arrays); int main () { float vector[size1][size2]; int i, j; struct pass arrays; for (i = 0; i < size1; ++i) for (j = 0; j < size2; ++j) { { vector[i][j] = atan (1 + i + j) + i + j; printf ("vector[%d][%d] is %f\n", i, j, vector[i][j]); } } arrays.lenc = size1; arrays.lenf = size2; arrays.c = &vector[0][0]; // arrays.f = NULL; simulation (&arrays); return 0; } // gcc -c -lm c_mm3.c -o caller.o // gcc pass.o caller.o -lgfortran -o out $ It's time for me to count sheep, but this is definitely a good step forward. Thx, steve. What I don't see at the moment is the need to declare f. For that matter, I don't know why the assignment of NULL to arrays.f drew an error, but that's not exactly fortran. -- Uno
From: steve on 13 Jul 2010 11:49 On Jul 12, 11:31 pm, Uno <merrilljen...(a)q.com> wrote: > What I don't see at the moment is the need to declare f. For that > matter, I don't know why the assignment of NULL to arrays.f drew an > error, but that's not exactly fortran. struct pass { int lenc, lenf; float *c, f; }; because 'f' is not a pointer. -- steve
From: Uno on 14 Jul 2010 15:30 steve wrote: > On Jul 12, 11:31 pm, Uno <merrilljen...(a)q.com> wrote: > >> What I don't see at the moment is the need to declare f. For that >> matter, I don't know why the assignment of NULL to arrays.f drew an >> error, but that's not exactly fortran. > > struct pass > { > int lenc, lenf; > float *c, f; > > }; > > because 'f' is not a pointer. Then what is f. The way it looks to me is that it's there to mimic lenc and lenf, and because of the way things are, it is extraneous. This part isn't shown in MR&C, so if the author would make the intent known, that would be swell. Thx for your comment, steve. -- Uno
From: steve on 14 Jul 2010 15:45
On Jul 14, 12:30 pm, Uno <merrilljen...(a)q.com> wrote: > steve wrote: > > On Jul 12, 11:31 pm, Uno <merrilljen...(a)q.com> wrote: > > >> What I don't see at the moment is the need to declare f. For that > >> matter, I don't know why the assignment of NULL to arrays.f drew an > >> error, but that's not exactly fortran. > > > struct pass > > { > > int lenc, lenf; > > float *c, f; > > > }; > > > because 'f' is not a pointer. > > Then what is f. The way it looks to me is that it's there to mimic lenc > and lenf, and because of the way things are, it is extraneous. > It is a float. In 'float *c, f;' the * is attached to 'c' not to float. You have essentially 'float *c; float f;' -- steve |