Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Any fortran 90/95 wizards out there? Need help
Hi,
I have a programming task that I've been unable to solve using
standard
fortran 90/95 language (although I was able to get it to work using
Cray-style
pointers.  Can anyone think of an approach?

I'm trying to write a general-purpose search routine to convert one
set of
codes to another.  The conversion table is located on a tab-delimited
file.

The overall approach is:
On first call, determine the length of the old code, length of the
new
code, and number of codes and dynamically allocate, fill, and sort
the
conversion table.
On first and subsequent call, do a binary search on the table in
memory to   obtain the
conversion information.

The problem I've run into is the dynamically allocated table
disappears
between calls.  When I add the SAVE attribute, I get an error message
(using the Intel Fortran compiler).

Any help will be greatly appreciated,

Ron

etQpredX@hotmail.com
r e m o v e  the Q and X






Subroutine Convert(FieldOld,FieldNew,FilNam)
Character(*) FieldOld,FieldNew,FilNam
c
c          Stub to allow dynamic allocation of table
c          (since the length of passed parameters
c           must be known at time of routine entry)
c
LO = Len(FieldOld)
LN = Len(FieldNew)
Call Convert2 (FieldOld,FieldNew,FilNam,LO,LN)
Return
End
c
c            The real subroutine
c

Subroutine Convert2 (FieldOld,FieldNew,FilNam,LO,LN)
Character(*)  FieldOld, FieldNew
Character(*)  FilNam
Character(LO), Allocatable :: OldFieldTable(:)
Character(LN), Allocatable :: NewFieldTable(:)
c       NOTE:  Character(LN), Allocatable, Save :: NewFieldTable(:)
c              gets an error
Data     iFTS/1/     ! First time switch
c
If (iFTS.eq.0) go to 300        ! Check for first time procedure
iFTS = 0
c
c            Count number of records
Call CountNumberOfRecords (NumRec)
c
Allocate (OldFieldTable(NumRec))    ! Allocate memory
Allocate (NewFieldTable(NumRec))    ! Allocate memory
c
c
c            Load Table
c
Call   LoadTable(NumRec, FilNam, OldFieldTable, NewFieldTable)
c
c           Sort table
c
Call CSORT (OldFieldTable,NewFieldTable,NumRec)
c
c         Do binary search
c
300   Continue
c
Call BSearch (NumRec, IndexMatch, FieldOld, OldFieldTable)
FieldNew = NewFieldTable (IndexMatch)
c
c
Return
End

Report this thread to moderator Post Follow-up to this message
Old Post
Mix1009
10-18-04 09:00 PM


Re: Any fortran 90/95 wizards out there? Need help
Mix1009 wrote:

<snip>

>       Subroutine Convert2 (FieldOld,FieldNew,FilNam,LO,LN)
>       Character(*)  FieldOld, FieldNew
>       Character(*)  FilNam
>       Character(LO), Allocatable :: OldFieldTable(:)
>       Character(LN), Allocatable :: NewFieldTable(:)
> c       NOTE:  Character(LN), Allocatable, Save :: NewFieldTable(:)
> c              gets an error

I'm not sure of the particular part of the Fortran standard that
prohibits this; but I'm guessing that your problems come from the fact
that newFieldTable has a variable character length LN. If this array is
SAVEd over subroutine calls, what happens then Convert2() is called with
a different value of LN than previously? That there is ambiguity here,
is a sure sign that you are doing something counter to the standard.

Two possible fixes come to mind:

a) use a constant for the character length.

or

b) declare NewFieldTable to be of type(VARYING_STRING), as defined in
Part II (Varying length character strings) of the Fortran 95 standard.
If you decide to do this, you will need an implementation of the
ISO_VARYING_STRING module defined in Part II; you can download one such
implementation (written by myself, bug reports welcome!) from:

http://www.fortran.com/fortran/iso_varying_string.f95

cheers,

Rich

--
Dr Richard H D Townsend
Bartol Research Institute
University of Delaware

[ Delete VOID for valid email address ]

Report this thread to moderator Post Follow-up to this message
Old Post
Rich Townsend
10-18-04 09:00 PM


Re: Any fortran 90/95 wizards out there? Need help
etpred@nocharge.com (Mix1009) writes:

> The problem I've run into is the dynamically allocated table
> disappears between calls.

Yep.  Non-saved things do that.  With allocatable, they are *REQUIRED*
to do that - it isn't up to the compiler.

>  When I add the SAVE attribute, I get an error message

General advice. When reporting an error message, quote what it says
instead of just saying "an eror message".  In this case, I can deduce
the problem anyway, but keep the advice in mind for the future.

>       Subroutine Convert2 (FieldOld,FieldNew,FilNam,LO,LN)
...
>       Character(LO), Allocatable :: OldFieldTable(:)

The reason you get an error message when you add SAVE is (presumably)
because OldFieldTable is an automatic variable - that is it depends on
dummy arguments (LO).  You can't have something that is both automatic
and saved - they are contradictory. Automatic things are allocated
with each subroutine call.  The problem is that, in general, LO might
be different from one call to another, in which case there would be a
conflict between the saved data and the new declaration. True, your
particular calls might happen to retain the same value of LO, but
neither the compiler nor the standard treats that as a special case -
it has to make sense in general.

There is a fine solution in f2003.  F2003 allows allocatable character
length, so you could declare

Character(:), Allocatable :: OldFieldTable(:)

Now oldfieldtable is no longer automatic (we got rid of the dependence
on LO - at least we moved it out of the declaration, which is what counts).
Then specify the length in the allocate as

Allocate (character(LO):: OldFieldTable(NumRec))

But that syntax for allocate is new to f2003; probably won't work in
current compilers (unless they happen to have already implemented that
f2003 feature - none have to my knowledge).

For now, only 2 solutions occur to me off the top of my head.  Neither
seems particularly satisfactory, though probably either could be made
to work.

1. Use a hard-wired character length instead of a dynamic one.  You
can still make the numrec dynamic - that's not the problem.

This will work if you can specify some length that is both large
enough so that it will work for all practical cases and small
enough so that the memory cost won;t be excessive.

You can still carry around the LO (and LN) variables so that you
can refer to the substrings (1:LO) and (1:LN) when needed.

2. Use an array of characters instead of a character string.  In your
case, you have an array of strings, so turn that into a rank 2 array
of characters (each of hard-wired length 1).  Allocating arrays is
fine in f90/f95. It is allocating character length that you can't
do until f2003, so turn the character length into an array.

While it can certainly work, this has the divantage that you can't
use many of the handy string intrinsics on arrays of character.  Also,
you'd have to correspondingly change declarations elsewhere, which might
be a bother, depending how many places that is.

Oh yes... in writing the second option above, a 3rd one ocurred to me..

3. Allocate as a rank 2 array of character*1, as in option 2.  Then use
sequence association to pass this allocated array as an actual argument
to a dummy declared as a rank 1 array of strings. In  order for the
sequence association trick to work, the dummy has to be declared with
adjustable array bounds and character length - do not use * as a
character length and do not use assumed shape.  I.e. the dummy
declaration has to look something like

Character(LO) :: OldFieldTable(numRec)

where LO and numRec are both dummy args; you'd have to add LO (and LN)
as args to a few of your lower-level routines.

I consider this a bit of a hack, but it ought to work.  Note that it
does mean that the oldfieldtable is still a rank 2 array in the
subroutine that allocate it - only in lower-level subroutines can you
look at it as a rank 1 array of strings.  Well... you might be able
to hack up a trick with pointers, but that gets pretty subtle...enough
so that I'd have to think a while to be sure it could work in this
case.

A lot simpler to just rewrite the one statement setting newfieldrec;
that looks to be the only one really hit by this in the code you showed.

--
Richard Maine                       |  Good judgment comes from experience;
email: my first.last at org.domain  |  experience comes from bad judgment.
org: nasa, domain: gov              |        -- Mark Twain

Report this thread to moderator Post Follow-up to this message
Old Post
Richard E Maine
10-18-04 09:00 PM


Re: Any fortran 90/95 wizards out there? Need help
Rich Townsend <rhdt@barVOIDtol.udel.edu> writes:

> b) declare NewFieldTable to be of type(VARYING_STRING)...

I forgot to mention that option.

I might note that it is a variant of the general option of using an
array of characters to replace a character string, but it has extra
"stuff" (to use a technical term :-)) wrapped around it so that most
of the nice character operations do sensible things.  And implementors
(such as Rich Townsend) have done the work involved in that extra
stuff.

--
Richard Maine                       |  Good judgment comes from experience;
email: my first.last at org.domain  |  experience comes from bad judgment.
org: nasa, domain: gov              |        -- Mark Twain

Report this thread to moderator Post Follow-up to this message
Old Post
Richard E Maine
10-18-04 09:00 PM


Re: Any fortran 90/95 wizards out there? Need help

Richard E Maine wrote:

> etpred@nocharge.com (Mix1009) writes:
 

> Yep.  Non-saved things do that.  With allocatable, they are *REQUIRED*
> to do that - it isn't up to the compiler.

I was going to ask last w if allocatable arrays could be
allocated in one subroutine, and deallocated in a called subroutine,
or the other way around.  It would seem from that that the second
case doesn't work.

For discussion purposes only, and not to get into any arguments,
PL/I CONTROLLED (like allocatable) can be allocated/deallocated
at any level (of subroutine nesting).   Sort of like C's
malloc/free, except that dimension information is also included.

The question about contiguous allocation came from forgetting
how assumed size and assumed shape work, and which one allocatable
would be more like.

-- glen


Report this thread to moderator Post Follow-up to this message
Old Post
glen herrmannsfeldt
10-18-04 09:00 PM


Re: Any fortran 90/95 wizards out there? Need help
On 18 Oct 2004 10:17:37 -0700, etpred@nocharge.com (Mix1009) wrote:

>The problem I've run into is the dynamically allocated table
>disappears
>between calls.  When I add the SAVE attribute, I get an error message
>(using the Intel Fortran compiler).

The particular issue you ran into is that the variable in question is
"automatic" diue to the character length being dependent on a dummy argument
.
Automatic variables cannot be SAVEd.  Fortran 95 doesn't provide exactly wha
t
you want, which is a persistent array of run-time length character elements.
I'll let others offer suggested alternatives.


Steve Lionel
Software Products Division
Intel Corporation
Nashua, NH

User communities for Intel Software Development Products
http://softwareforums.intel.com/
Intel Fortran Support
http://developer.intel.com/software/products/support/

Report this thread to moderator Post Follow-up to this message
Old Post
Steve Lionel
10-18-04 09:00 PM


Re: Any fortran 90/95 wizards out there? Need help
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:

> Richard E Maine wrote:
 
>
> I was going to ask last w if allocatable arrays could be
> allocated in one subroutine, and deallocated in a called subroutine,
> or the other way around.  It would seem from that that the second
> case doesn't work.

Non-sequitur (I don't see the connection).

The answer to your question is that yes, an allocatable can be
allocated in one subroutine and deallocated in a called one, or
the other way around.  Both capabilities require the allocatable TR
(or f2003) in order to allow a dummy argument to have the allocatable
attribute. Or you can do it with the allocatable in a module or
with host association; those work even in f90 without the TR.

My "non-saved things do that" is a severe abbreviation of the actual
conditions.  Maybe you were taking it a bit more globally than I
intended.  Then I'd see the connection (but my statement isn't valid
in the relevant contexts).  To be more complete, I'd need to qualify
it as something like "local" non-saved things and the define what I
meant by local.  SAVE never applies to dummy arguments, and things are
a bit more complicated for variables in modules.  So no, an
allocatable dummy argument doesn't go away when you return just
because it is non-saved (and you can't declare a dummy to be saved).

--
Richard Maine                       |  Good judgment comes from experience;
email: my first.last at org.domain  |  experience comes from bad judgment.
org: nasa, domain: gov              |        -- Mark Twain

Report this thread to moderator Post Follow-up to this message
Old Post
Richard E Maine
10-18-04 09:00 PM


Re: Any fortran 90/95 wizards out there? Need help

Richard E Maine wrote:

> glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:

(snip)

> The answer to your question is that yes, an allocatable can be
> allocated in one subroutine and deallocated in a called one, or
> the other way around.  Both capabilities require the allocatable TR
> (or f2003) in order to allow a dummy argument to have the allocatable
> attribute.

For the allocatableness (probably not a word) to be passed to the
called subroutine?   Does the caller need to know if the dummy
has the allocatable attribute?

> Or you can do it with the allocatable in a module or
> with host association; those work even in f90 without the TR.

> My "non-saved things do that" is a severe abbreviation of the actual
> conditions.  Maybe you were taking it a bit more globally than I
> intended.  Then I'd see the connection (but my statement isn't valid
> in the relevant contexts).  To be more complete, I'd need to qualify
> it as something like "local" non-saved things and the define what I
> meant by local.  SAVE never applies to dummy arguments, and things are
> a bit more complicated for variables in modules.  So no, an
> allocatable dummy argument doesn't go away when you return just
> because it is non-saved (and you can't declare a dummy to be saved).

If I understood a previous post, he wanted to allocate and initialize
an array in a subroutine, and use it in the same routine called
later.   So, by adding it as a dummy argument and calling it with
the appropriate (but otherwise unused) argument it would stay allocated?

-- glen


Report this thread to moderator Post Follow-up to this message
Old Post
glen herrmannsfeldt
10-18-04 09:00 PM


Re: Any fortran 90/95 wizards out there? Need help
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:

> Richard E Maine wrote:
>
 
>
> For the allocatableness (probably not a word) to be passed to the
> called subroutine?   Does the caller need to know if the dummy
> has the allocatable attribute?

Yes.  Specifically, the interface of th ecalled subroutine needs to
be explicit (and that's why - so that the caller knows this.)

> If I understood a previous post, he wanted to allocate and initialize
> an array in a subroutine, and use it in the same routine called
> later.   So, by adding it as a dummy argument and calling it with
> the appropriate (but otherwise unused) argument it would stay allocated?

Yes.  Exactly.

--
Richard Maine                       |  Good judgment comes from experience;
email: my first.last at org.domain  |  experience comes from bad judgment.
org: nasa, domain: gov              |        -- Mark Twain

Report this thread to moderator Post Follow-up to this message
Old Post
Richard E Maine
10-19-04 01:56 AM


Re: Any fortran 90/95 wizards out there? Need help

Richard E Maine wrote:

> glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:

(snip)
 

> Yes.  Specifically, the interface of the called subroutine needs to
> be explicit (and that's why - so that the caller knows this.)

OK, same as PL/I.
 

> Yes.  Exactly.

OK, PL/I has CONTROLLED INTERNAL which go out of scope when
the routine ends.  I believe the user is responsible for the
FREE before return, though.    CONTROLLED EXTERNAL is the global
version, which stays allocated, and can be used from other routines
with the same declaration.   STATIC EXTERNAL is like Fortran COMMON.

-- glen


Report this thread to moderator Post Follow-up to this message
Old Post
glen herrmannsfeldt
10-19-04 01:56 AM


Sponsored Links




Last Thread Next Thread Next
Pages (2): [1] 2 »
Search this forum -> 
Post New Thread

Fortran archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 05:57 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.