Brad + Others,
On Thu, 19 Oct 2017, Brad Chamberlain wrote:
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.
I am not so sure I know enough either but at least I can kick-start the
conversation and sound like I know something.
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:
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?
Sadly, it is worse than that, I cannot read. Yes, INFINITY is a proc. I
had been reading the params above INFINITE in the web documentation to
which you referred, specifically sqrt_2 and recipr_sqrt_2 (for an earlier
post to the mailing list). The word param must have gotten stuck in my
brain which got translated to my typing fingers. Can I blame overwork
or fat fingers?
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?
Yes. But not this week. I am curious at what the discussion was on the
C/C++ standard when they were discussing this when they deliberated this
topic. I will see if I can find anything in their minutes. That might give
us some clues as to the technical/political issues.
A related question in my mind is whether there should be imag(*) equivalents
of these constants,
Yes is probably the answer. Sorry, lazy me. I have not done anything with
complex(*) and imag(*) in any language for nearly 20 years so those types
tend to slip my mind.
or whether the programmer should be required to cast between real and
imaginary in such cases?
That is really a question for the compiler gurus but convenience for the
user is always a good aim if it is not too much work.
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.
Assuming Chapel just passes it through to the underlying C compilers, and
without checking by running some Chapel, some C compilers would allow you
to define in the Chapel code
proc fpINFINITY(type t) param real(64) where param t == real(64)
return 0x1.0p1024;
proc fpINFINITY(type t) param real(32) where param t == real(32)
return 0x1.0p128f;
and produce the right results when called by Chapel. And we have had hex
floating constants in Chapel for a while now. Thanks Michael.
Note sure I have that code correct as far as Chapel code goes. I only just
got educated on that technique a few hours ago!!! Indeed the definitions
of those constants is what GCC used to do until it replaced them with a
compiler builtin. I assume that a 'proc param', if that works, means it
gets done at compile time. I cannot see how a param definition would let
you define a constant with the same name for multiple floating types, real
or imaginary.
ASIDE - Note that the above two numbers,
0x1.0p128f AND 0x1.0p1024
are illegal floating point constants. Their evaluation by a Chapel-called
underlying C/C++ compiler would generate an floating point exception. But
luckily, certainly GCC ignores that and just inserts whatever value pops
out of the calculation which should be the correct value for Infinity for
the word size. So I guess you would say we are relying on current compiler
behaviour. I hope no overly zealous compiler writer gets up and tells us
we are defining numbers which are out of range and flags errors!
[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).
Interesting.
This of course may improve in the future...].
Hopefully that applies to everything in life!
[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.]
A proc would normally be a safer bet.
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) ...
Looks clean. A review of my discussion about 50 lines earlier will tell
you whether I am a fast learner or a poor student or worse!
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.
That should be a discussion for everybody. Object oriented or procedure
oriented. It even gets down to whether you have
var x : real(64)
and you use
x.abs() INSTEAD OF abs(x)
And should x.abs() return the |x| or should it do
x <- |x|
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;
That would be illegal as they different, having bit-wise representations
0x7f800000 = 0x1.0p128f (if such a number exists)
and
0x7ff0000000000000 = 0x1.0p1024 (again if such a number exists)
respectively so. If (assuming) you have access to the C constants HUGE_VAL
and HUGE_VALF defined in
/usr/include/bits/huge_val.h
and
/usr/include/bits/huge_valf.h
then you can probably consider trying
proc type (real(32)).INFINITE return HUGE_VALF;
and
proc type (real(64)).INFINITE return HUGE_VAL;
Personally I hate that these huge values are actually infinite but I was
not on the C/C++ committee. But that is a discussion for another day.
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...
Again, beyond my knowledge. That I will leave to the compiler gurus.
If the 'type' keyword were dropped on the declarations above, they'd
apply to values of those types rather than the types themselves.
I do not fully understand but it's probably irrelevant to this discussion.
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.
I really only mentioned these types because careful consideration of the
implications of what to do with these word-sizes might resolve any thought
bubble issues that are not so clear if we are just looking at 32/64 bit.
There was a lot of momentum a few years ago on those types in publications
but that does seem to have translated to silicon. ARM still only handles
16-bit reals for storage, not for data processing. But I would think that
the prospect of 32 16-bit reals in Intel's 512bit AVX register would have
people drooling over the performance potential, even if error analyses of
the imprecision gave people nightmares. 'NVIDIA's Pascal GPU implements
IEEE 16bit arithmetic' but those 7 words are about all I know on the topic
except that I think it is targetted at deep learning. I am struggling with
normal learning! Only Sparc does 128 bit reals in assembler so far as I
know, admittedly in software. But I would bet money on 128 bit reals being
in Power11 CPUs sometime in the next decade.
Regards - Damian
Pacific Engineering Systems International, 277-279 Broadway, Glebe NSW 2037
Ph:+61-2-8571-0847 .. Fx:+61-2-9692-9623 | unsolicited email not wanted here
Views & opinions here are mine and not those of any past or present employer
------------------------------------------------------------------------------
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