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

Reply via email to