OpenSmalltalk / opensmalltalk-vm

Cross-platform virtual machine for Squeak, Pharo, Cuis, and Newspeak.
http://opensmalltalk.org/
Other
562 stars 110 forks source link

We need a solution for cross-platform bit-identical floating point. #315

Open eliotmiranda opened 5 years ago

eliotmiranda commented 5 years ago

The FloatMathPlugin provided cross-platform bit-identical floating point, needed for applications such as OpenCroquet/Qwaq/terf. The plugin depends on Sun's fdlibm which is effectively obsolete. There are better solutions; see for an overview http://christian-seiler.de/projekte/fpmath/ and for a solution (provided this is lesser GPL, which a cursory reading suggests it is) https://www.mpfr.org

If taking this approach, instead of needing a FloatMathPlugin we could perhaps arrange that the VM provides cross-platform bit-identical floating point by default, or that the VM is compilable with some flags that result in a VM whose floating point primitives are cross-platform bit-identical. Then one wouldn't have to use an interface to the plugin, with all the headaches that providing support for SmallFloat64 now in introduces, along with the slowness of that plugin interface.

nicolas-cellier-aka-nice commented 5 years ago

mpfr is multiple precision (arbitrary precision if you prefer), and not specially optimized for IEEE 754 double precision. IMO it's too much for FloatMathPlugin.

CRLIBM (correctly rounded mathematical library) could be a good modern alternative to fdlibm. CRLIBM is also LGPL and also from INRIA For documentation, see: https://hal-ens-lyon.archives-ouvertes.fr/ensl-01529804/file/crlibm.pdf

nicolas-cellier-aka-nice commented 5 years ago

In the interim, we can modernize fdlibm, it's easier than creating a new plugin from scratch, and it will preserve bit-identical backward compatibility with OpenCobalt/Terf/... while changing the underlying libm would require a simultaneous change of all the VM participating.

After searching for similar work in github, I saw that I would be better served by myself and gave it a go: https://github.com/nicolas-cellier-aka-nice/fdlibm/

I've run some smoke tests, but did not commit the test yet... The reason is that I tried to add dependency to googletest via git subtree, and it was a bad idea: https://stackoverflow.com/questions/12858199/how-to-rebase-after-git-subtree-add.

I crafted the tests with ArbitraryPrecisionFloat package (from squeaksource), but generating the reference results is quite slow. If someone knows of existing test suite for libm, that might help.

If someone wants to try it, just overwrite the fdlibm files with my master branch. No special flags required (except -D_IEEE_LIBM). My smoke tests pass with -O2, so should the OpenSmalltalk VM.

nicolas-cellier-aka-nice commented 5 years ago

I've checked that FloatMathPluginTests does not segfault anymore with head Win64 squeak.cog.spur if I replace platforms/Cross/plugins/FloatMathPlugin/fdlibm with my master branch. All the tests are red because they depend on Random implementation, and implementation changed from a naive Park Milller to a Mersenne Twister... I will try to fix the VMMaker tests.

EDIT Hmm, I had broken modf, but is fixed now. I've also fixed the VMMaker tests.
All theFloatMathPluginTests are green now on 64bits VM with my fdlibm branch.

nicolas-cellier-aka-nice commented 5 years ago

Now that I'm fairly confident that my patches are OK, I suggest this:

Does it sound OK?

eliotmiranda commented 5 years ago

Hi Nicolas,

On Fri, Jan 4, 2019 at 7:39 AM Nicolas Cellier notifications@github.com wrote:

Now that I'm fairly confident that my patches are OK, I suggest this:

  • we keep fdlibm for backward compatibility;
  • we maintain our own patched version;
  • we don't add any new feature nor try to patch anything but correct compilation of existing source; this should generate very low level of activity (only if C standard change and break another thing);
  • for this we clone https://github.com/nicolas-cellier-aka-nice/fdlibm/ on opensmalltalk so as to not depend on an exotic repository, and replace the fdlibm files by using a git submodule;
  • we start an alternate FloatMathPlugin implementation based on another library (I suggest CRLibm but other suggestions are welcome).

Does it sound OK?

Sounds perfect to me. I would add that once we have an alternate FloatMathPlugin implementation based on another library we can do the performance analysis and if it is fast enough we should implement normal floating point arithmetic with the same support and get rid of FloatMathPlugin altogether, having bit-identical floating point provided by the normal primitives.

,,,^..^,,, best, Eliot