PGI User Forum
 SearchSearch   MemberlistMemberlist     RegisterRegister   ProfileProfile    Log inLog in 

Free OpenACC Webinar

Pass declared var types: F90 to C

 
Post new topic   Reply to topic    PGI User Forum Forum Index -> Programming and Compiling
View previous topic :: View next topic  
Author Message
dab143



Joined: 28 Nov 2004
Posts: 4

PostPosted: Sun Nov 28, 2004 6:54 pm    Post subject: Pass declared var types: F90 to C Reply with quote

I've read Chapters 9 and 10 of the PGI User's Manual as well as lots of other web sites on calling C from Fortran but still can't solve my particular problem of passing a declared variable type from Fortran 90 to C. The declared variable type also contains several pointers, which may be contributing to my problem.

I tried adding the SEQUENCE parameter to the declared variable, but that didn't seem to make a difference. As shown below, the major symptom appears to be that not all of the pointer addresses make it through to the C function.

The Fortran 90 main code looks like this:
Code:

! =================================
  PROGRAM test
! =================================

  integer,parameter :: rd = SELECTED_REAL_KIND(p=12,r=37)

  TYPE :: gen_vertex
    SEQUENCE
    real(kind=rd) :: x
    real(kind=rd) :: y
  END TYPE gen_vertex

  TYPE :: gen_vertex_list
    SEQUENCE
    integer :: num_vertices
    type(gen_vertex),pointer,dimension(:) :: vertex
  END TYPE gen_vertex_list

  TYPE :: gen_polygon
    SEQUENCE
    integer :: num_contours
    integer,pointer,dimension (:) :: hole
    type(gen_vertex_list),pointer,dimension (:) :: contour
  END TYPE gen_polygon

  TYPE(gen_polygon) :: spoly


! DEFINE POLYGON

  spoly%num_contours = 2
  allocate(spoly%hole(spoly%num_contours))
  allocate(spoly%contour(spoly%num_contours))

  spoly%hole(1) = 1
  spoly%contour(1)%num_vertices = 3
  allocate(spoly%contour(1)%vertex(spoly%contour(1)%num_vertices))
  spoly%contour(1)%vertex(1)%x = 0.0d0
  spoly%contour(1)%vertex(1)%y = 0.0d0
  spoly%contour(1)%vertex(2)%x = 1.0d0
  spoly%contour(1)%vertex(2)%y = 0.0d0
  spoly%contour(1)%vertex(3)%x = 1.0d0
  spoly%contour(1)%vertex(3)%y = 1.0d0
  spoly%hole(2) = 0
  spoly%contour(2)%num_vertices = 3
  allocate(spoly%contour(2)%vertex(spoly%contour(2)%num_vertices))
  spoly%contour(2)%vertex(1)%x = 0.0d0
  spoly%contour(2)%vertex(1)%y = 0.0d0
  spoly%contour(2)%vertex(2)%x = 2.0d0
  spoly%contour(2)%vertex(2)%y = 0.0d0
  spoly%contour(2)%vertex(3)%x = 2.0d0
  spoly%contour(2)%vertex(3)%y = 2.0d0


! CALL GPC (THE SCENIC ROUTE)
  call gen_test( spoly )


END PROGRAM test


The C routine looks like this:
Code:

#include <stdlib.h>

typedef struct
{
  double              x;
  double              y;
} gen_vertex;

typedef struct
{
  int                 num_vertices;
  gen_vertex         *vertex;
} gen_vertex_list;

typedef struct
{
  int                 num_contours;
  int                *hole;
  gen_vertex_list    *contour;
} gen_polygon;

void gen_test_(gen_polygon *subj )
{
   int i,j;

   printf("\n output from the C routine\n");
   printf(" address of subj = %p\n",subj );
   printf(" address of subj->hole = %p\n",subj->hole );
   printf(" address of subj->contour = %p\n",subj->contour );
   printf(" num_contours = %d\n",subj->num_contours );

   for (i=0; i < subj->num_contours; i++) {
      printf(" num_vertices = %d\n",subj->contour[i].num_vertices );
      printf(" hole         = %d\n",subj->hole[i] );

     for (j=0; j < subj->contour[i].num_vertices; j++) {
         printf(" vertex[%d].x  = %f\n",j,subj->contour[i].vertex[j].x );
         printf(" vertex[%d].y  = %f\n",j,subj->contour[i].vertex[j].y );
     }
   }

   return;
}


The compilation (using version 5.2-1 for both pgf90 and pgcc) looks like this:
Code:

pgcc -c testc.c
pgf90 test.f90 testc.o -o test


Finally, the output looks like this:
Code:

 output from the C routine
 address of subj = 0x520b30
 address of subj->hole = 0x524850
 address of subj->contour = (nil)
 num_contours = 2
Segmentation fault


Any help --- either specific or generally relating to passing declared variable types and/or pointers from Fortran90 to C --- would be greatly appreciated. I similarly struggled with a different approach where I tried to pass just one pointer to an integer array to a C routine, free and re-allocate the pointer within the C routine, and then pass it back, so if anyone can suggest further reading on passing pointers back and forth between Fortran90 and C, that would be great too!

Sorry for the long post!

David

[/code]
Back to top
View user's profile
mkcolg



Joined: 30 Jun 2004
Posts: 6213
Location: The Portland Group Inc.

PostPosted: Mon Nov 29, 2004 5:17 pm    Post subject: Reply with quote

Hi David,

You need to account for the Fortran descriptor and put some padding in your C structs.

Your testc.c should be changed to the following.
Code:
#include <stdlib.h>
#ifdef __x86_64__
#define DESC_LEN 19
#else
#define DESC_LEN 17
#endif

typedef struct
{
  double              x;
  double              y;
} gen_vertex;

typedef struct
{
  int                 num_vertices;
  gen_vertex         *vertex;
  int                 v_desc[DESC_LEN];
} gen_vertex_list;

typedef struct
{
  int                 num_contours;
  int                *hole;
  int                h_desc[DESC_LEN];
  gen_vertex_list    *contour;
  int                c_desc[DESC_LEN];
} gen_polygon;


While this will work for this case, it is definately not portable. Also note that the descriptor length may change with each new release of the compiler. I determined the descriptor length by running a.out in pgdbg and printing spoly.

- Mat
Back to top
View user's profile
Display posts from previous:   
Post new topic   Reply to topic    PGI User Forum Forum Index -> Programming and Compiling All times are GMT - 7 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © phpBB Group