From: steve on
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
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
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
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
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
 |  Next  |  Last
Pages: 1 2
Prev: MR&C chp 14
Next: Runge-Kutta method for solving IVPs