Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Recasting Fortran pointers
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  8 messages - Collapse all  -  Translate all to Translated (View all originals)
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
Adrian Ferramosca  
View profile  
 More options Nov 14 2001, 9:47 am
Newsgroups: comp.lang.fortran
From: "Adrian Ferramosca" <adr...@bjahouston.com>
Date: Wed, 14 Nov 2001 08:47:34 -0600
Local: Wed, Nov 14 2001 9:47 am
Subject: Recasting Fortran pointers
I would like to enquire whether anyone has been able to performs some tricks with F90/F95 pointers to be able to recast them at
runtime.  For example, I would like to set up the following data structure:

 type Test
    sequence
    integer(4) :: ptype
    type(xxx), pointer :: p
 end type

where xxx is one of a number of predefined types.  At runtime, if ptype is 0, then p points to a variable of type xxx0 while if
ptype is 1 it points to another variable different type xxx1.

I am using CVF 6.6.

Adrian


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Michel OLAGNON  
View profile  
 More options Nov 14 2001, 10:11 am
Newsgroups: comp.lang.fortran
From: molag...@ifremer.fr (Michel OLAGNON)
Date: 14 Nov 2001 15:02:37 GMT
Local: Wed, Nov 14 2001 10:02 am
Subject: Re: Recasting Fortran pointers

In article <iuvI7.2656$Oh1.31416@insync>, "Adrian Ferramosca" <adr...@bjahouston.com> writes:
>I would like to enquire whether anyone has been able to performs some tricks
>with F90/F95 pointers to be able to recast them at
>runtime.  For example, I would like to set up the following data structure:

> type Test
>    sequence
>    integer(4) :: ptype
>    type(xxx), pointer :: p
> end type

>where xxx is one of a number of predefined types.  At runtime, if ptype is 0,
>then p points to a variable of type xxx0 while if
>ptype is 1 it points to another variable different type xxx1.

Fortran pointers are not recastable. Their types are defined at compile time.
In your example, you need:
 type Test
    integer(4) :: ptype
    type(xxx), pointer :: p
    type(xxx1), pointer :: p1
    type(xxx2), pointer :: p2
    type(xxx3), pointer :: p3
   .....
 end type

Michel

--
 Michel OLAGNON                       email : Michel.Olag...@ifremer.fr
 http://www.ifremer.fr/metocean/group/michel/michel_olagnon.htm
 http://www.fortran-2000.com/


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Richard Maine  
View profile  
 More options Nov 14 2001, 11:24 am
Newsgroups: comp.lang.fortran
From: Richard Maine <nos...@see.signature>
Date: 14 Nov 2001 08:19:25 -0800
Local: Wed, Nov 14 2001 11:19 am
Subject: Re: Recasting Fortran pointers

"Adrian Ferramosca" <adr...@bjahouston.com> writes:
> I would like to enquire whether anyone has been able to performs some tricks with F90/F95 pointers to be able to recast them at
> runtime.  For example, I would like to set up the following data structure:

>  type Test
>     sequence
>     integer(4) :: ptype
>     type(xxx), pointer :: p
>  end type

> where xxx is one of a number of predefined types.  At runtime, if ptype is 0, then p points to a variable of type xxx0 while if
> ptype is 1 it points to another variable different type xxx1.

This is a form of polymorphism.  In f2k there is support for this kind
of thing, but in f90/f95, you have to roll your own, which can be
quite messy.  I used to have some code to do something for this with
TRANSFER.  Can be done, but it is *VERY* messy.  Whatever you can
imagine, it's worse than that.  It also tends to break compilers.
Long ago, I redid my code that used the idea because I got tired of
continually debugging compilers.

You'd need to start with the "usual" trick for many "hacks" with
pointers.  Make a derived type with a single pointer component.
This will will give you something where you can "get at" the
pointer itself instead of the target.  If you write a pointer p
as an argument to intrinsics not specifically expecting a pointer,
what gets passed is the pointer's target; to work with the
pointer dope vector, you need to do something like the derived type
trick.  Then you can TRANSFER to and from the derived type.

But a *BIG* complication is that pointers to different types may
take up different amounts of space.  In practice, there are only
a few variations you will see, but in pinciple, every combination
of type, type parameters, and rank could be a different pointer
size.  To accomodate that, you can't use your "type(xxx), pointer..."
because you don't know whether a pointer to type(xxx) is big enough.
Indeed, there is no fixed thing that you know apriori is big
enough.  What I did is use an array of some arbitrary type.  My
favorite arbitrary type is default integer.  The array "wants" to
be allocatable, but that's not (yet) an option (unless you restrict
yourself to compilers supporting the allocatable stuff TR), so it
ends up being an array pointer.  You need to do the TRANSFER twice;
once as an argument to SIZE to figure out how big the result is,
and then again after you have allocated a target of sufficient
size to hold the result.  All very messy, impossible to follow
unless adorned with extensive comments, and prone to break
compilers.  I think the SIZE(TRANSFER(...)) bit was one of the parts
that many compilers choked on, but its been a long time and I
forget all the details of the compiler bugs.

Basically, the integer pointer array is just a holder for the bits.
You always TRANSFER the bits out of it into a pointer of the
appropriate ttype before doing anything with them.

I can't really recommend that approach.  I dropped it and went
back to some simple-minded schemes that I'd label as f77 style.
They were adequate for the need, mostly because the number of
targets for each type was quite modest.  So for each type, I
made an array of pointers (using the "usual" trick again; I'm
assuming you've followed this group enough to understand it).
Where you have "type(xxx), pointer" above, I just substituted a
a scalar integer.  That scalar integer is an index into the
array of pointers for the appropriate type.  Not very "modern",
but it works fine, is reasonably easy to follow, etc.  It helped
a lot that I was sure to have a relatively small number of
targets, so I could get by with making the arrays of pointers
statically sized.  It also helped that targets were added and
deleted with relatively low frequency, so that the performance
issue of finding an "open" slot for a new one by searching
the array was not a problem.

I could probbaly drag out some sample code to illustrate if the
above words aren't enough, but probably not today.  Other commitments
are about to call.

--
Richard Maine                       |  Good judgment comes from experience;
email: my last name at host.domain  |  experience comes from bad judgment.
host: altair, domain: dfrc.nasa.gov |        -- Mark Twain


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Adrian Ferramosca  
View profile  
 More options Nov 14 2001, 12:40 pm
Newsgroups: comp.lang.fortran
From: "Adrian Ferramosca" <adr...@bjahouston.com>
Date: Wed, 14 Nov 2001 11:40:24 -0600
Local: Wed, Nov 14 2001 12:40 pm
Subject: Re: Recasting Fortran pointers

"Richard Maine" <nos...@see.signature> wrote in message news:uen11puxyq.fsf@altair.dfrc.nasa.gov...
> So for each type, I
> made an array of pointers (using the "usual" trick again; I'm
> assuming you've followed this group enough to understand it).

not sure what the "usual" trick is  :(

> Where you have "type(xxx), pointer" above, I just substituted a
> a scalar integer.  That scalar integer is an index into the
> array of pointers for the appropriate type.  Not very "modern",
> but it works fine, is reasonably easy to follow, etc.  It helped
> a lot that I was sure to have a relatively small number of
> targets, so I could get by with making the arrays of pointers
> statically sized.  It also helped that targets were added and
> deleted with relatively low frequency, so that the performance
> issue of finding an "open" slot for a new one by searching
> the array was not a problem.

> I could probbaly drag out some sample code to illustrate if the
> above words aren't enough, but probably not today.  Other commitments
> are about to call.

Great, whenever you have a spare moment...

Adrian


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jugoslav Dujic  
View profile  
 More options Nov 14 2001, 3:50 pm
Newsgroups: comp.lang.fortran
From: "Jugoslav Dujic" <jdu...@yahoo.com>
Date: Wed, 14 Nov 2001 21:55:11 +0100
Local: Wed, Nov 14 2001 3:55 pm
Subject: Re: Recasting Fortran pointers
"Adrian Ferramosca" <adr...@bjahouston.com> wrote in message

news:l0yI7.2662$Oh1.31441@insync...
|
| "Richard Maine" <nos...@see.signature> wrote in message
news:uen11puxyq.fsf@altair.dfrc.nasa.gov...
| > So for each type, I
| > made an array of pointers (using the "usual" trick again; I'm
| > assuming you've followed this group enough to understand it).
|
| not sure what the "usual" trick is  :(
|
| > Where you have "type(xxx), pointer" above, I just substituted a
| > a scalar integer.  That scalar integer is an index into the
| > array of pointers for the appropriate type.  Not very "modern",
| > but it works fine, is reasonably easy to follow, etc.  It helped
| > a lot that I was sure to have a relatively small number of
| > targets, so I could get by with making the arrays of pointers
| > statically sized.  It also helped that targets were added and
| > deleted with relatively low frequency, so that the performance
| > issue of finding an "open" slot for a new one by searching
| > the array was not a problem.
| >
| > I could probbaly drag out some sample code to illustrate if the
| > above words aren't enough, but probably not today.  Other commitments
| > are about to call.
|
| Great, whenever you have a spare moment...
|
| Adrian

Since I happen to know that you use CVF, you might as well stick
to Cray pointers, which are broadly supported in CVF as an extension.
(it even supports Cray pointers to functions). Unfortunately,
it seems that it's not easy to isolate code using crays in a
separate subroutine(s) which "improves" portability.

They're especially useful for lpUserData stuffs which can
be frequently found in Windoze API:

TYPE(MyWindowProperties):: tMWP
!Associate address of tMWP with the window
i = SetWindowLong(hMyWnd, GWL_USERDATA, LOC(tMWP))

!... somewhere else, miles away, in the code:
TYPE(MyWindowProperties):: tMWP; POINTER(pMWP,tMWP)
!..et voila, all associated data are restored:
pMWP = GetWindowLong(hMyWnd, GWL_USERDATA)

Now, it may look like I'm advocating them -- I dislike the
syntax and they can be really dangerous in kids' hands --
but the truth is that I can't live without them in Win32 API
stuff which is C-based and frequently the address
you get may point to quite a various stuff.

Jugoslav
________________________
www.geocities.com/jdujic


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Adrian Ferramosca  
View profile  
 More options Nov 14 2001, 4:30 pm
Newsgroups: comp.lang.fortran
From: "Adrian Ferramosca" <adr...@bjahouston.com>
Date: Wed, 14 Nov 2001 15:07:39 -0600
Local: Wed, Nov 14 2001 4:07 pm
Subject: Re: Recasting Fortran pointers
Yes, I saw them and they did work.  Unfortunately you can't use them in type definitions as far as I can tell.
Adrian


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Richard Maine  
View profile  
 More options Nov 14 2001, 5:15 pm
Newsgroups: comp.lang.fortran
From: Richard Maine <nos...@see.signature>
Date: 14 Nov 2001 14:10:59 -0800
Local: Wed, Nov 14 2001 5:10 pm
Subject: Re: Recasting Fortran pointers

"Adrian Ferramosca" <adr...@bjahouston.com> writes:
> "Richard Maine" <nos...@see.signature> wrote in message news:uen11puxyq.fsf@altair.dfrc.nasa.gov...
> > So for each type, I
> > made an array of pointers (using the "usual" trick again; I'm
> > assuming you've followed this group enough to understand it).

> not sure what the "usual" trick is  :(

Make a derived type with the pointer as a component,  as in

  type xxx_ptr_type
    type(xxx_type), pointer :: p
  end type

  type(xxx_ptr_type) :: p_ptr

What is going to physically be in the p_ptr structure is the
"dope vector" of the pointer component - you could think of this as
the pointer itself instead of the target.  It will typically have
things like the address and dimensions of the target.  Details are
vendor-dependent, but you don't usually need to know them, except
at a conceptual level.

You can now make an "array of pointers" by

  type(xxx_ptr_type) :: the_array(100)

This is really an array of 100 structures, each of which has
a pointer as it's sole component.  The n'th pointer is the_array(n)%p.
Note that if you tried to declare an array of pointers directly
without this trick, you'd probably try

  type(xxx_type), pointer :: wrong(100)

But this doesn't do what you want.  This is a single pointer to
an array.  This is not an array of pointers.

making a single-component derived type like this is the crux of
the "usual" trick.

My ugly transfer application is based on noting that the actual bits of
the pointer part are in the structure, and TRANSFER copies bits,
so something like

  TRANSFER(p_ptr, an_object_of_some_other_type)

will copy the bits that you really want (the pointer itself).  If
you had done just

  type(xxx_type), pointer :: p

  TRANSFER(p, an_object_of_some_other_type)

you'll end up copying the bits of the target of p instead of the
bits of the pointer; that isn't what you want.

> > Where you have "type(xxx), pointer" above, I just substituted a
> > a scalar integer.  That scalar integer is an index into the
> > array of pointers for the appropriate type....
> > I could probbaly drag out some sample code...
> Great, whenever you have a spare moment...

Assuming that I'm not dragged away before I get it adequately copied
into here...

  !--- Generic stuff applicable to multiple formats...
  !--- (This is in a different module).
  type gen_type
    .... a bunch of stuff not pertinent to the question
    !-- And there is a format_code elsewhere.  Could be a component
    !-- here, though it's actually in a separate structure for the
    !-- application I pulled this from.
    integer :: format_specific_index
         !-- This provides a place for format specific data.
         !-- I've slightly simplified an irrelevancy here;
         !-- hope I didn't miss making comparable changes elsewhere.
  end type

  !-- Declarations specific to cmp4.
  !-- There is simillar-looking stuff for the other formats.
  !-- I'll omit the details of cmp4_type here - not relevant,
  !-- except to note that it is very different from the other formats.

  type cmp4_ptr_type
    type(cmp4_type), pointer :: cmp4
  end type

  type(cmp4_ptr_type), save :: cmp4_ptrs(max_opens)
  logical, save :: initialized = .false.

  type(cmp4_type), pointer :: cmp4  !-- for scratch use only.  Not saved.
  ....

    !----- Here's where I allocate a new one.

    !-- Make sure things are initialized in case this is the first call.
    nullify(cmp4)
    iostat = 0
    if (.not. initialized) then
       do i = 1 , size(cmp4_ptrs)
         nullify(cmp4_ptrs(i)%cmp4)
       end do
       initialized = .true.
    end if

    !-- Find an unused "slot" and allocate it
    alloc_loop: do i = 1 , size(cmp4_ptrs)
      if (.not.associated(cmp4_ptrs(i)%cmp4)) exit alloc_loop
    end do alloc_loop
    if (i > size(cmp4_ptrs)) goto 8000
    gen%format_specific_index = i
    allocate(cmp4, stat=iostat)
    if (iostat /= 0) goto 8000
    cmp4_ptrs(i)%cmp4 => cmp4

    !-- And then later (in another subroutine), when we want to
    !-- get at the cmp4 data, we start with

    cmp4 => cmp4_ptrs(gen%format_specific_index)%cmp4

Ack.  I just got a call dragging me off, but I think I'm about
done anyway.  The above code is a bit out of context, and I may
have messed up something trivial in attempting to edit out
distractions, but I hope it illustrates the general idea.
The gen structure contains information common to all of the
formats.  The cmp4 atuff is just one of the possible types.

P.S. This stuff just *BEGS* for the object-oriented features of f2k.
I did this *BEFORE* I'd really figured out what object orientation was
about.  After I finally got an explanation (from John Cuthertson) of
OOP that made sense to me, suddenly the light dawned that I'd been
doing that for years...I didn't know that the language could actually
help me instead of get in my way.

--
Richard Maine                       |  Good judgment comes from experience;
email: my last name at host.domain  |  experience comes from bad judgment.
host: altair, domain: dfrc.nasa.gov |        -- Mark Twain


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Jugoslav Dujic  
View profile  
 More options Nov 14 2001, 5:16 pm
Newsgroups: comp.lang.fortran
From: "Jugoslav Dujic" <jdu...@yahoo.com>
Date: Wed, 14 Nov 2001 23:20:49 +0100
Local: Wed, Nov 14 2001 5:20 pm
Subject: Re: Recasting Fortran pointers
"Adrian Ferramosca" <adr...@bjahouston.com> wrote in message

news:E2BI7.2673$Oh1.31235@insync...
| Yes, I saw them and they did work.  Unfortunately you can't use them in type
definitions as far as I can tell.
| Adrian

You're right; we did use them for interop with C shells but the fortran
code is ugly, since it has to include a local Cray pointer to dereference
address:

!-Fortran receiver---------------------------------------------------
integer function AddBaseBa1(tBaseBa1) result (ierror)

type(T_DMSI_BASE_BA1), intent(in)::  tBaseBa1

type(T_DMSI_VOLT_RANGE)::  tVoltRange(*); pointer (pVoltRange, tVoltRange)
integer::                  i

iFrequency = tBaseBa1%iFrequency

pVoltRange = tBaseBa1%pVrange
do i=1, iBrVBaz
   VBaz(i) = tVoltRange(i)%fVBase
   Vmax(i) = tVoltRange(i)%fVmax
   Vmin1(i) = tVoltRange(i)%fVmin1
   Vmin2(i) = tVoltRange(i)%fVmin2
end do

ierror = 0

end function AddBaseBa1

!-Fortran header ------------------------------------------------

type T_DMSI_VOLT_RANGE
   real   fVbase               ! O1.2
   real   fVmax                ! O1.3
   real   fVmin1               ! O1.4
   real   fVmin2               ! O1.5
end type T_DMSI_VOLT_RANGE

type T_DMSI_BASE_BA1
   integer(PTR_SIZE) pVrange     ! Pointer to an array of iBrVBaz
T_DMSI_VOLT_RANGE structures
   integer(2)        iFrequency  ! O1.6
end type T_DMSI_BASE_BA1

!-C header ------------------------------------------------------

typedef struct T_DMSI_VOLT_RANGE {
   float   fVbase;               // O1.2
   float   fVmax;                // O1.3
   float   fVmin1;               // O1.4
   float   fVmin2;               // O1.5

} DMSI_VOLT_RANGE;

typedef struct T_DMSI_BASE_BA1 {
   DMSI_VOLT_RANGE*  pVrange;     // Pointer to an array of iBrVBaz
DMSI_VOLT_RANGE structures
   short    iFrequency;           // O1.6

} DMSI_BASE_BA1;

Jugoslav
________________________
www.geocities.com/jdujic

 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
End of messages
« Back to Discussions « Newer topic     Older topic »