Hi Damian --
As a blanket disclaimer on this response (and part of the reason I didn't
chime in on your last thread): I'm not at all a floating point expert and
rely upon learning from those who are moreso (like you) to help guide
Chapel's design in sensible and attractive ways.
Currently there is
param INFINITY : real(64)
and
proc NAN : real(64)
I'm not seeing that INFINITY is a param. It appears to me that both
symbols are proc's:
http://chapel.cray.com/docs/latest/modules/standard/Math.html?highlight=nan#Math.NAN
http://chapel.cray.com/docs/latest/modules/standard/Math.html?highlight=infinity#Math.INFINITY
I'm guessing this means you've found some other documentation that needs
updating. If so, can you tell me where you got your definitions?
i note that there are no 32 bit equivalents
I think this would be a great feature request (if not code contribution)
-- would you be willing to open a GitHub issue requesting it, and ideally
proposing symbol names / interfaces for accessing these values?
A related question in my mind is whether there should be imag(*)
equivalents of these constants, or whether the programmer should be
required to cast between real and imaginary in such cases?
Why is it not a 'proc param'?
The current implementations rely on evaluating the C definitions at
execution time, so aren't available at compile-time (a requirement to be a
param). I'm not enough of a floating point expert to be 100% confident,
but would imagine that these values are sufficiently well-defined that
they could be represented/computed in the Chapel source (e.g., via a hex
floating point literal?), in which case they could be written as 'proc
param's or simply 'param's.
[All that said, Chapel does not currently do much compile-time
optimization of floating point 'param' values, so making them 'param'
would likely not have a big impact at present (unless it helped the
back-end compiler with optimizations). This of course may improve in the
future...].
[Aside: I found myself curious why they are 'proc's rather than simply
'const's, and with a quick check, believe that the answer relates to the
supporting them in the LLVM back-end.]
To write truly templated code, something the C standard did not have to
consider, do we need something like
proc fpINFINITY(fudge : real(64)) param real(64) ......
proc fpINFINITY(fudge : real(32)) param real(32) ......
proc fpNAN(fudge : real(64)) param real(64) ......
proc fpNAN(fudge : real(32)) param real(32) ......
Rather than using 'fudge', if I were pursuing a procedure-based approach
like this, I'd simply make them functions that took a type argument:
proc fpINFINITY(type t): real(64) where t == real(64) ...
proc fpINFINITY(type t): real(32) where t == real(32) ...
in which case you could call:
fpINFINITY(real(32))
fpINFINITY(real(64))
fpINFINITY(real)
or are such constants an attribute of a real, e.g.
var x : real(64)
assert(isinf(x.INFINITY()) == true)
or
assert(isnan(x.NAN()) == true)
They're definitely standalone constants at present, though we could make
them into methods on a real value -- or better, the real type -- if that
was considered attractive. For example, the following declaration:
proc type real.INFINITY return INFINITY;
says to define a method named 'INFINITY' on the (64-bit) real type, and
supports calls like:
writeln(real.INFINITY);
writeln(real(64).INFINITY);
I believe we _ought_ to also be able to create overloads on 32- vs. 64-bit
real types like so:
proc type (real(32)).INFINITY return INFINITY;
proc type (real(64)).INFINITY return INFINITY;
but I'm having trouble getting them to compile today. I suspect this is
due to a bug in the compiler related to 'real's being treated as somewhat
more of a special type than typical generics...
If the 'type' keyword were dropped on the declarations above, they'd apply
to values of those types rather than the types themselves.
What about when Chapel rules the HPC/GPU space and Chapel has to support the
IEEE types
real(128)
or
real(16)
I certainly think we'd want to support such types and their related
constants as well.
Also how viable/smart is my use of 'fudge' because it is just a dummy
variable except for its number of bits?
See above for some counterproposals that avoid 'fudge'.
Assume that if I want a set of
templated functions to return say the limits of the exponents of a given
IEEE754 floating point number
proc fpEmax(x : real(32)) : param return 127:int(32);
proc fpEmax(x : real(64)) : param return 1023:int(64);
proc fpEmin(x : real(32)) : param return -126:int(32);
proc fpEmin(x : real(64)) : param return -1022:int(64);
Is there a better way to guarantee the correct templated instantiation?
Here also, I'd make the arguments 'type's rather than values, but other
than that, I think you're on the right track.
Thanks for your continued thoughts and feedback in this,
-Brad
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Chapel-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/chapel-developers