For Programmers: Free Programming Magazines  


Home > Archive > Fortran > September 2004 > KIND related issues on NAGware f95 v 4.1









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author KIND related issues on NAGware f95 v 4.1
Madhusudan Singh

2004-09-27, 9:01 pm

Hi

I was porting some of my IFC/sun f95 friendly code over to NAG on an AMD
cluster, and found that I could not compile the following declarations :

integer, parameter :: qp = selected_real_kind(33,3000) ! Quad precision
integer, parameter :: qpc = KIND((1.0_qp,1.0_qp))
REAL(DP), PARAMETER :: EULER=0. 5772156649015328606065120900824024310422
_qp
....

KIND value (-3) does not specify a valid representation method
I initially had

integer, parameter :: qp = KIND(1.0Q0)

which yields errors :

: syntax error
detected at 1.0@Q0
***Invalid item in type declaration

How do I use quad precision variables with NAG ?

Thanks.
Paul Van Delst

2004-09-27, 9:01 pm

Madhusudan Singh wrote:
> Hi
>
> I was porting some of my IFC/sun f95 friendly code over to NAG on an AMD
> cluster, and found that I could not compile the following declarations :
>
> integer, parameter :: qp = selected_real_kind(33,3000) ! Quad precision
> integer, parameter :: qpc = KIND((1.0_qp,1.0_qp))
> REAL(DP), PARAMETER :: EULER=0. 5772156649015328606065120900824024310422
_qp
> ...
>
> KIND value (-3) does not specify a valid representation method
> I initially had
>
> integer, parameter :: qp = KIND(1.0Q0)
>
> which yields errors :
>
> : syntax error
> detected at 1.0@Q0
> ***Invalid item in type declaration
>
> How do I use quad precision variables with NAG ?


First question that popped into my head:
Does NAG support quad precision? A quick gander at the polyhedron.com comparison
page suggests it does not (whereas Intel does.)

Second question:
Why do you think you need them when you initialise a double precision parameter
with a quad precision literal constant? What's wrong with something like:
REAL(DP), PARAMETER :: EULER=0.5772156649015328_DP
?

The second question assumes you're only using quad precision in parameter initialisations
which is probably not true, but that's the code you posted.

cheers,

paulv
Madhusudan Singh

2004-09-27, 9:01 pm

Paul Van Delst wrote:

Thanks for your response.

> First question that popped into my head:
> Does NAG support quad precision? A quick gander at the polyhedron.com
> comparison page suggests it does not (whereas Intel does.)
>


That is odd. I thought that this ought to depend more on the underlying
hardware.

And the page :
http://www.nag.co.uk/nagware/NP/r41_doc/f90_kind.html

seems to suggest that quad *might* be available, though I would have to use
a module for this in some way.

Second, could I presumably use selected_real_kind with lower p and r
values ? What would be the upper limit ?

> Second question:
> Why do you think you need them when you initialise a double precision
> parameter with a quad precision literal constant? What's wrong with
> something like:
> REAL(DP), PARAMETER :: EULER=0.5772156649015328_DP
> ?
>
> The second question assumes you're only using quad precision in parameter
> initialisations which is probably not true, but that's the code you
> posted.
>


That is right. Quad precision is being used in one part of my code. EULER is
just being defined as quad as it is used there.
Richard E Maine

2004-09-27, 9:01 pm

Madhusudan Singh <spammers-go-here@spam.invalid> writes:

> KIND value (-3) does not specify a valid representation method


I suspect it is telling you the truth...

> I initially had
>
> integer, parameter :: qp = KIND(1.0Q0)
>
> which yields errors :


because it isn't standard syntax. The Q exponent letter is
a nonstandard extension from pre-f90 days when there was no
standard way to specify anything other than single or double
precision.

> How do I use quad precision variables with NAG ?


What leads you to believe that the version you have supports quad
precision? I'm not 100% sure which NAG port you are using. The
precisions supported should be documented in the stuff that came with
the compiler... lets's see, particularly in the TECHINFO file. Some
of the NAG ports support 128-bit reals and others don't. Looks like V
4.2 of the 32-bit Linux version does not; I did't check into the
64-bit versions (though those might not have even gone back to V 4.1,
so maybe that's irrelevant).

If the compiler supports quad precision, then I'm quite confident
that the standard syntax will get it. Your selected_real_kind looks
at least roughly right to me, but I didn't check the numbers. You
might try numbers a little lower than the very highest ones you
expect. Sometimes it is easy to get off by 1 (or 2) in terms of
what you think the number of digits is vs what is appropriate
for selected_real_kind. So just specify numbers known to be too
big for double precision, but not all the way up to the limit of
what you think quad should give.

If the compiler doesn't support quad precision, no syntax is going
to help. Your options become something like

1. use a multiple-precision package (portable, but slow, and sometimes
a little awkward).

2. get a compiler that supports quad directly

or

3. use an algorithm that doesn't need it.

I can't judge for you which of those would be more appropriate.

--
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
Richard E Maine

2004-09-27, 9:01 pm

Madhusudan Singh <spammers-go-here@spam.invalid> writes:

> integer, parameter :: qpc = KIND((1.0_qp,1.0_qp))


Oh. As an aside that I failed to notice in my post of just a minute ago...

The above statement is legal (assuming that qp is a valid kind
parameter for reals), but is a bit pointless. The standard guarantees
that the kind parameters for complex are the same as those for real.
Thus the above line is a rather long-winded way of saying

integer, parameter :: qpc = qc

as long as qc is a valid real kind parameter. And if qc isn't a valid
real kind parameter, then it is just a way of getting the compiler to
complain about the fact (but that would have happened soon afterwards
anyway).

--
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
Richard E Maine

2004-09-27, 9:01 pm

Madhusudan Singh <spammers-go-here@spam.invalid> writes:

> Paul Van Delst wrote:
>
> That is odd. I thought that this ought to depend more on the underlying
> hardware.


Nope. This is very much a software question. hardware can make it
simpler or harder (and thus more or less likely) to support a given
precision, but it is not the absolute determiner.

In practice, single and double precision are almost always something
supported natively by the hardware. They don't have to be in theory,
but in practice, they will be. Quad precision is a very different
matter.

In NAG's case in particular, the primary determiner is usually
the underlying C compiler. For example, note that NAG has 2
ports for Sun Solaris, differering in whether they use GCC
or Sun's C compiler. Same hardware. One of those NAG ports
supports 128-bit reals; the other doesn't.

--
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
Paul Van Delst

2004-09-27, 9:01 pm

Madhusudan Singh wrote:
> Paul Van Delst wrote:
>
> Thanks for your response.
>
>
>
>
> That is odd. I thought that this ought to depend more on the underlying
> hardware.
>
> And the page :
> http://www.nag.co.uk/nagware/NP/r41_doc/f90_kind.html
>
> seems to suggest that quad *might* be available, though I would have to use
> a module for this in some way.


"Might" is the operative word, since the site you listed above say "This is not available
on all systems" wrt Quad precision kind types.

> Second, could I presumably use selected_real_kind with lower p and r
> values ? What would be the upper limit ?


This is what I use in my Type_Kinds.f90 module:

INTEGER, PARAMETER, PUBLIC :: Single = SELECTED_REAL_KIND(6) ! Single precision
INTEGER, PARAMETER, PUBLIC :: Double = SELECTED_REAL_KIND(15) ! Double precision
INTEGER, PARAMETER, PRIVATE :: Quad_t = SELECTED_REAL_KIND(20) ! Quad precision
INTEGER, PARAMETER, PUBLIC :: Quad = ( ( ( 1 + SIGN( 1, Quad_t ) ) / 2 ) * Quad_t ) + &
( ( ( 1 - SIGN( 1, Quad_t ) ) / 2 ) * Double )

(the Quad precision gymnastics courtesy of James Van Buskirk)

and I test a partiucular system/compiler using:

PROGRAM Test_Type_Kinds
USE Type_Kinds
IMPLICIT NONE
! -- Output the kind types
WRITE( *, '( /5x, "Kind types: ", &
&/10x, "Byte integer kind type: ", i5, &
&/10x, "Short integer kind type: ", i5, &
&/10x, "Long integer kind type: ", i5, &
&/10x, "LLong integer kind type: ", i5, &
&/10x, "Single float kind type: ", i5, &
&/10x, "Double float kind type: ", i5, &
&/10x, "Quad float kind type: ", i5 )' ) &
Byte, Short, Long, LLong, &
Single, Double, Quad
END PROGRAM Test_Type_Kinds

If the Double and Quad kind types output are the same then Quad isn't available.

And, as to the value of 20 that I use for "p" in selected_real_kind(), that is sort of an
assumption that compilers aren't going to hand me anything *less* than a 16 byte real if I
specify a precision that a double precision variable can't handle. Obviously that's not a
very good assumption (I believe 10-byte floats are relatively common in some compilers),
but I use Quad so rarely that it's never been a problem (yet! :o).

> That is right. Quad precision is being used in one part of my code. EULER is
> just being defined as quad as it is used there.


I'm not sure if you meant "that is right" as in you *are* only using quad precision in the
parameter initialisation, or that my assumption about that is not true. If it's the
latter, then Richard Maine has already posted useful suggestions as to how to get around
no native NAG Support for Quad precision.

cheers,

paulv

Richard E Maine

2004-09-27, 9:01 pm

Madhusudan Singh <spammers-go-here@spam.invalid> writes:

> That is right. Quad precision is being used in one part of my code. EULER is
> just being defined as quad as it is used there.


Note that Euler is *NOT* defined as quad in the code you showed. Namely

> REAL(DP), PARAMETER :: EULER=0. 5772156649015328606065120900824024310422
_qp


The real(DP) bit defines it as of kind DP. The _qp used in the value
does *NOT* change that. Instead it just means that, after going to
the trouble of writing a quad value, you then tell the compiler to
convert it to double.

That's what Paul was talking about. (Though I'm not Paul, I'm
quite confident of that.)

--
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
Madhusudan Singh

2004-09-27, 9:01 pm

Richard E Maine wrote:

> Madhusudan Singh <spammers-go-here@spam.invalid> writes:
>
>
> Note that Euler is *NOT* defined as quad in the code you showed. Namely
>
>
> The real(DP) bit defines it as of kind DP. The _qp used in the value
> does *NOT* change that. Instead it just means that, after going to
> the trouble of writing a quad value, you then tell the compiler to
> convert it to double.
>
> That's what Paul was talking about. (Though I'm not Paul, I'm
> quite confident of that.)
>


I know. Its a typo. My cut and paste was not working, and I had to type it
all in :)
glen herrmannsfeldt

2004-09-27, 9:01 pm



Richard E Maine wrote:

(snip)

> because it isn't standard syntax. The Q exponent letter is
> a nonstandard extension from pre-f90 days when there was no
> standard way to specify anything other than single or double
> precision.


I believe the OS/360 Fortran H extended compiler, supporting
extended precision on the 360/85 and most 370's. Also,
emulated extended precision (by trapping the illegal
instruction) on other machines. Somewhere around 1968.

-- glen


Dick Hendrickson

2004-09-28, 4:12 pm

Others have given lots of good advice. But one thing to
try when porting to a new machine or compiler is a
simple loop to see what's going on. Something like:
Do I = 1,50
print *, I, selected_real_kind(I)
Enddo

You'll easily be able to see if a kind is supported or not.
Sometimes that's easier than finding the answer in the
documentation.

Dick Hendrickson


Madhusudan Singh wrote:

> Hi
>
> I was porting some of my IFC/sun f95 friendly code over to NAG on an AMD
> cluster, and found that I could not compile the following declarations :
>
> integer, parameter :: qp = selected_real_kind(33,3000) ! Quad precision
> integer, parameter :: qpc = KIND((1.0_qp,1.0_qp))
> REAL(DP), PARAMETER :: EULER=0. 5772156649015328606065120900824024310422
_qp
> ...
>
> KIND value (-3) does not specify a valid representation method
> I initially had
>
> integer, parameter :: qp = KIND(1.0Q0)
>
> which yields errors :
>
> : syntax error
> detected at 1.0@Q0
> ***Invalid item in type declaration
>
> How do I use quad precision variables with NAG ?
>
> Thanks.


glen herrmannsfeldt

2004-09-28, 4:12 pm



Dick Hendrickson wrote:

> Others have given lots of good advice. But one thing to
> try when porting to a new machine or compiler is a
> simple loop to see what's going on. Something like:
> Do I = 1,50
> print *, I, selected_real_kind(I)
> Enddo


Can you really do that ? I wouldn't have guessed.

-- glen

Michael Metcalf

2004-09-28, 4:12 pm


"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message
news:cjc8rt$skf$2@gnus01.u.washington.edu...
>
>
> Dick Hendrickson wrote:
>
>
> Can you really do that ? I wouldn't have guessed.
>
> -- glen
>


Sure. It returns -1 for any value of I that doesn't have a corresponding
kind available.

Regards,

Mike Metcalf


Richard E Maine

2004-09-28, 4:12 pm

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

> Dick Hendrickson wrote:
>
>
> Can you really do that ? I wouldn't have guessed.


Sure. No magic here. If you wouldn't have guessed this, then you
are probably thinking of selected_real_kind as something unique.
It isn't. Selected_real_kind is just a function. You can use it
just like you could use any other function. Because it is
intrinsic, there are extra places where you can also use it,
but it is not syntactically special.

It does happen that the places where selected_real_kind is most
useful are places where you couldn't use a "normal" function, so
you might be tricked into thinking there is something special
about it, but there really isn't.

Note that if you do something like

integer, parameter :: hp = selected_real_kind(1000000)
real(hp) :: x

it isn't the selected_real_kind reference that will cause the
compiler to XXXXX. The compiler will happily (one presumes :-))
return a negative value for the function result and assign that
value to hp (huge precision - no vendor name implied :-)). It
is not until the real(hp) that you'll get a XXXXX that this isn't
a valid kind value for the real type.

In most cases, an invocation of selected_real_kind is soon followed
by an attempt to use the result as a kind value, which will cause
an error message if it is an invalid value. (This is one of the
things that compilers are required to be able to diagnose). But it
is legal, and probably happens reasonably often, for a program to
use a general module that defines some kind parameters that turn
out to be invalid for some environments (128-bit reals and
64-bit integers are prime candidates for this). This is still
perfectly legal as long as the program doesn't actually try to
use the values in question as kind parameters.

--
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
glen herrmannsfeldt

2004-09-28, 9:28 pm



Richard E Maine wrote:

I wrote:

[color=darkred]
[color=darkred]
[color=darkred]
> Sure. No magic here. If you wouldn't have guessed this, then you
> are probably thinking of selected_real_kind as something unique.
> It isn't. Selected_real_kind is just a function. You can use it
> just like you could use any other function. Because it is
> intrinsic, there are extra places where you can also use it,
> but it is not syntactically special.


I was thinking of it as a compile time function, a little bit
like C's sizeof() which isn't really a function even though it
looks like one.

How about KIND, though. Is that not a function?


Now that we are this far in, the question I was thinking about
from another discussion, how to write programs that can be compiled
for different precision (KINDs).

Many library routines come in single and double precision, often
with a D at the beginning (or end) of the double precision name.
It is easier to maintain only one version of the source, and compile
it for the different versions. Some compiler options have been
suggested that will force all REAL variables to double precision,
hopefully also changing constants, but that doesn't seem very portable.

-- glen

beliavsky@aol.com

2004-09-28, 9:28 pm


glen herrmannsfeldt <gah@ugcs.caltech.edu> wrote:
>
>
>Richard E Maine wrote:
>
>I wrote:
>
>
>
>
>
>I was thinking of it as a compile time function, a little bit
>like C's sizeof() which isn't really a function even though it
>looks like one.
>
>How about KIND, though. Is that not a function?
>
>
>Now that we are this far in, the question I was thinking about
>from another discussion, how to write programs that can be compiled
>for different precision (KINDs).
>
>Many library routines come in single and double precision, often
>with a D at the beginning (or end) of the double precision name.
>It is easier to maintain only one version of the source, and compile
>it for the different versions. Some compiler options have been
>suggested that will force all REAL variables to double precision,
>hopefully also changing constants, but that doesn't seem very portable.


Glen,
You are obviously knowledgable about Fortran 77 and earlier versions of the
language, but a lot of your questions and wonderings about Fortran 90 and
later versions would be answered by simply reading a book or tutorial --
see http://www.dmoz.org/Computers/Progr...tran_90_and_95/
. There exist some free Fortran 95 compilers. Why not read about and then
experiment with something you are curious about?



----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
James Giles

2004-09-28, 9:28 pm

glen herrmannsfeldt wrote:
....
> I was thinking of it as a compile time function, a little bit
> like C's sizeof() which isn't really a function even though it
> looks like one.
>
> How about KIND, though. Is that not a function?


KIND is usually evaluated at compile time. SELECTED_REAL_KIND
may not be. The value of KIND is independent of the value of its
operand. Only the type and type parameter(s) of the operand are
relevant to the result of KIND, and those (so far in Fortran's design)
are always known at compile time. SELECTED_REAL_KIND
(or, the corresponding for integers) depends upon the value of
its operand(s). That value may not be known at compiler time,
so the result of applying the function may not be either. This means
that it can be applied (in the way suggested in this thread) to find out
how many KINDs are available, and what precisions or exponent
ranges those KINDs have.

> Now that we are this far in, the question I was thinking about
> from another discussion, how to write programs that can be compiled
> for different precision (KINDs).


On of my proposed features is like that. You would write a
procedure once and it would apply to all KINDs of the operands.
But, the feature would be (internally) implemented as statically
bound generics. SO, in any particular instance of the procedure's
use, the KIND would have been determined statically. The
syntax might be:

generic function average(a,b)
integer, inferred :: a_kind, b_kind
real(^a_kind), intent(in) :: a
real(^b_kind), intent(in) :: b
integer, inferred :: result_kind=kind(a+b)
real(result_kind) :: average
average = (a+b)/2.0_result_kind
return
end function average

The type attribute INFERRED means that you are declaring
a named constant that whose value is given by a specification
expression rather than an initialization expression and that you
can often determine that value using the "inferrence" syntax
above (where the value is the appropriate value that would
make the dummy argument's attributes match those of the actual
argument).

This function would work for REAL arguments of any KIND.
The internal implementation would probably be that four (or
more, if there's more REAL KINDs than two) specific instances
of AVERAGE would be built and the appropriate one called by
the usual static generic procedure resolution rules.

A further extension of these rules would permit:

generic function average(a,b)
type, inferred :: a_type, b_type
type(^a_type), intent(in) :: a -> {something}
type(^b_type), intent(in) :: b -> {something}
type, inferred :: result_type = type(a+b)
type(result_type) :: average
average = (a+b)/2
return
end function average

The similariy is obvious. The content of {something} is
a constraint on the type that A_TYPE or B_TYPE may be.
It can be as simple as a list of types (both intrinsic and
derived) that you wish to permit, or it could be a name of
a category of types that might be defined in some way.
Obviously, among the constraints on the argument types for
this particular example is that they must be types that can
be added, and the result of their sum must be divisible by
an integer. Again, this would really be interpreted by the
language implementation as a request that a large number of
instances of the procedure be created and the caller would be
linked to the appropriate one statically by the existing rules
of the language.

For the above, REAL, COMPLEX, INTEGER and any derived
types that the programmer wanted to permit could all be listed
or otherwise permitted by the constraints. For this purpose,
the same type name but different KINDs would be regarded as
separate types.

The inference syntax (the thing with the ^) is an optional part of
the idea, but I think that, once it's familiar, it would make programs
*lots* more legible.

--
J. Giles

"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare


Richard E Maine

2004-09-28, 9:28 pm

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

> Richard E Maine wrote:


[color=darkred]
> I was thinking of it as a compile time function, a little bit
> like C's sizeof() which isn't really a function even though it
> looks like one.


Selected_real_kind really is one. It is likely to be evaluated at
compile time in its most common applications, but that is an extra
feature instead of a restriction.

> How about KIND, though. Is that not a function?


KIND has a bit more "magic" to the extent that it could be misleading
to call it a function. (It is called one, but one could consider that
misleading). Some of its magic means that it will probably always be
evaluated at compile time. In any case, it is always possible to
evaluate it at compile time, so it probably always will be.

The "magic" part of KIND is that it doesn't depend on the value of
its argument. It depends on other properties other than the
value. Several inquiry functions are like that. (Well, that's
basically the definition of an inquiry function).

Selected_real_kind, on the other hand, acts like a pretty normal
function. It takes 2 optional integer arguments and gives an integer
result that depends on the 2 values. All pretty mundane as interfaces
go. A user could write it (easily) except for the one detail that it
can be used in initialization expressions (at compile time).
User-written functions can't be called at compile time.

--
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
Dick Hendrickson

2004-09-29, 8:07 pm



glen herrmannsfeldt wrote:
>
>
> Richard E Maine wrote:
>
> I wrote:
>
>
>
>
>
>
>
>
>
> I was thinking of it as a compile time function, a little bit
> like C's sizeof() which isn't really a function even though it
> looks like one.
>
> How about KIND, though. Is that not a function?
>
>
> Now that we are this far in, the question I was thinking about
> from another discussion, how to write programs that can be compiled
> for different precision (KINDs).
>
> Many library routines come in single and double precision, often
> with a D at the beginning (or end) of the double precision name.
> It is easier to maintain only one version of the source, and compile
> it for the different versions. Some compiler options have been
> suggested that will force all REAL variables to double precision,
> hopefully also changing constants, but that doesn't seem very portable.
>
> -- glen
>

A portable way is to put almost everything into an include
file and then include it into separate header lines.
Something like
subroutine real_version(a,b)
integer, parameter :: wp = kind(1.0)
include "the_guts"
end real_version
subroutine double_version(a,b)
integer, parameter :: wp = kind(1.0D0)
include "the_guts"
end double_version
....
Where the_guts declares everything interms of wp for
precision. You only need to maintain the_guts and
can get versions for as many precisions as the machine
has. If you're a little more clever, you can get it
to work automagically on machines with or without
Quad precision. The Quad would default to double, or
you could put a run-time or compile-time test in
the quad routine to give an error is quad wasn't
supported.

It's not the most elegant way to do things, but it works
and is standard conforming with existing compilers.

Dick Hendrickson

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com