[racket] 80-bit precision in Racket

From: Dmitry Pavlov (dpavlov at ipa.nw.ru)
Date: Fri Nov 9 08:56:08 EST 2012

Hello,

First, congratulations with Racket 5.3.1 release.
We are using Racket for our research project in
astronomy and we are very satisfied with it.

However, now we have come to the point where we
need extended precision (80-bit) for floating-point
numbers. We have seen some work done by Neil Toronto
in his development branch on "bigfloat" numbers based
on GNU MPFR library. But MPFR has poor performance as
opposed to native 80-bit calculations, so we need
something that is translated to native code--something
like flonum-s and flvector-s, but for 80-bit numbers.
Let us call them extnum-s and extvector-s.

We need extnums and extvectors badly and we are
considering to implement them in Racket on our own,
i.e. fork Racket and hack it to support extended precision.

Some preliminary technical information:

* It is unlikely that we will be able to (or need to)
   change Racket's real-number primitives to extended
   precision, nor alter the behavior of arithmetic
   operations like +, and sin/cos/etc. We will rather
   add a new set of operations called ext+, extsin etc.,
   and their "unsafe-" counterparts, and also
   real<->extnum conversion.

* We plan to add the necessary functionality to Racket JIT
   to make it handle 80-bit numbers. Racket JIT relies
   on GNU Lightning, and currently it handles real numbers
   with jit_*** instructions. Lightning can translate
   these instructions into FPU or SSE instructions, depending
   of the flags Lightning itself was compiled with. Lightning
   currently can not do 80-bit instructions. We are going to
   implement 80-bit instructions in Lightning, and to avoid
   messing up the behavior of Racket's reals, we will do a
   new set of jit_fpu_*** instructions, separate from jit_***,
   and devoted to 80-bit numbers exclusively.

* Racket's runtime currently sets FPU to "standard" mode,
   which makes 64-bit floating-point operations
   IEEE-compliant (i.e. no internal 80-bit operations).
   Obviously we can not do 80-bit computations in standard
   mode, so we will have to set the FPU to "extended" mode
   instead. That can make existing Racket programs give
   /slightly/ different results with floating-point
   computations. In case that is an issue for users, it
   seems that we can work it around by forcing the 64-bit
   calculations to be done with SSE. That is, we can set
   MZ_USE_JIT_SSE *and* --mfpmath=sse when compiling Racket,
   and then all 64-bit fp operations will be done on SSE
   and not FPU, so they will be IEEE-compliant. 80-bit
   operations will be done on FPU anyway as SSE can not
   do them.

* Our primary platform is Linux on x86, but we want to
   make extnums available on Windows, too. It is known
   that MSVC does not support 80-bit "long double" type.
   So we can not use MSVC for our Racket build. The other
   options are:
   - cygwin: seems to be supported currently by Racket, but
     can not provide native Windows controls etc.
   - mingw: probably should compile Racket with its gcc
     (given that Racket compiles with cygwin's gcc), and
     *can* provide native Windows controls etc.
   - Intel C compiler: probably gives the best performance
     for floating-point computations, yet it does not miss
     Winapi, but it is not known whether it is able to
     build Racket.


We have a full-time person for the job, and we tend to
think that it will take a month or so.

Questions to you noble gentlemen:

1. Does the plan look realistic to you?
Are there any difficulties we have missed?

2. Maybe we are cutting blocks with a razor here?
If there is any simpler way to have native 80-bit
floating point in Racket (say Racket->ASM compilation,
Racket->C, LLVM, anything), please do tell me.

3. If the work is done, will you merge it into the
upstream Racket? We will be extremely pleased if
extnums become available in the official distribution.

4. Does anybody have any experience in building Racket
with mingw or Intel?


Best regards,

Dmitry

Posted on the users mailing list.