Coder Social home page Coder Social logo

allow double precision about manifold HOT 13 OPEN

pca006132 avatar pca006132 commented on July 1, 2024
allow double precision

from manifold.

Comments (13)

elalish avatar elalish commented on July 1, 2024 3

When I talked to the Rhino CAD guys years ago I remember they said float precision was a hard blocker for them because of the physical scale of the engineering projects they're used for, so yes, I think double precision is important, especially now that CUDA is gone. This will make the library useful far beyond e.g. 3D printing.

from manifold.

elalish avatar elalish commented on July 1, 2024 2

Considering the additional code complexity involved, I'd prefer to wait on this until it becomes a problem for at least one of our users. I would say switching to double precision is probably a higher priority (float was mostly due to CUDA originally), since we know this is necessary for large-scale engineering design, e.g. ships.

from manifold.

ramcdona avatar ramcdona commented on July 1, 2024 1

I would +1 for double precision as floats really fall on their face so much sooner.

You can always use a #define or a template to make these options compile-time decisions. That would be a lot more simple than some dynamic system that changes types on the fly.

from manifold.

elalish avatar elalish commented on July 1, 2024 1

@t-paul We've been struggling through getting binary Python wheels building on our CI for deployment, thanks to @pca006132. I'm less clear on a good approach for C++ binary distribution and I'm also not sure how it fits with NVIDIA/thrust#554. If anyone does know how to make a good automation process for binary distribution, I would welcome a PR.

My only concern about making precision a template is that it might make compilation crazy, but I bet the rest of you know more about that than I do, so please chime in. @ramcdona you hit the nail on the head with "Doubles may seem like sweeping the same thing under the rug" - we're taking a different approach to rounding error in this library than traditional computational geometry libraries, so the point is to guarantee robustness without robust arithmetic or extended precision. So for me, double precision is not at all about robustness, but just coordinate accuracy. Agreed that the precision should never surprise the user.

from manifold.

pca006132 avatar pca006132 commented on July 1, 2024 1

I think template should not cause much issue, we can do specialization which should make the compile time manageable. If there is interest on this, I can work on it.

from manifold.

t-paul avatar t-paul commented on July 1, 2024 1

This gets a bit off-topic, so I'll only add that OpenSUSE provides some nice means for building packages for a good range of distributions via their OpenSUSE Build Service (OBS, but not the streaming thing).
https://build.opensuse.org/package/show/home:t-paul/OpenSCAD

from manifold.

pca006132 avatar pca006132 commented on July 1, 2024

Indeed, we can use some macro for compile-time decisions. However, I think it would be nice in the long run if we can make it dynamic to avoid performance regression for regular users. We are limited by memory bandwidth for some operations, so changing to larger size will make things slower.

from manifold.

t-paul avatar t-paul commented on July 1, 2024

When looking at compile time decisions, please consider shipping the library as binary. If it's application / library-user compile time, that's cool. If it's library compilation time that can make things difficult. Of course if a dynamic solution is possible, that's awesome.

from manifold.

ramcdona avatar ramcdona commented on July 1, 2024

@pca006132 I guess I'm curious how you're defining 'regular users'.

I'm thinking of Manifold as a library -- where the 'user' is actually the developer of an end-user application. In this situation, the developer of the application is probably in a very good position to know the kinds of problems typically encountered by their end users (in size and required precision) and also what kind of performance tradeoff they are willing to make. Here a compile time decision (by the developer) will usually suffice.

For example, in any engineering application, I will avoid floats at all cost. They are basically a subtle bug waiting to happen. Doubles may seem like sweeping the same thing under the rug, but they suffice for most engineering purposes. When they don't, we go to exotic lengths like robust arithmetic and compensated summation to avoid floating point problems. When we do that, we are acutely aware of exactly where our precision is running out and we likely want to delay it as much as possible.

Perhaps you're thinking of Manifold as an end-user application (say ManifoldCAD.org). In that case, you could possibly argue that you have no idea the size and scope of problem that an end user will bring -- and that you will need to trade precision for speed dynamically.

However as an end user, that kind of behavior scares me. Imagine I start with a simple problem and add complexity as my project moves forward. When the problem is simple, your heuristic uses double precision because computation is cheap. At some point, your heuristic is going to decide that it needs to switch to floats to improve performance. As a user, I might not immediately notice the loss of precision (though I may appreciate the performance), but when that loss in precision comes to bite me, it will hurt. Making this kind of change invisible to a user is scary to me.

I feel that much of the argument for Manifold extends to this conversation -- non-manifold results may be good enough for graphics and animation (the eye forgives what it does not see) -- and likewise floats are good enough to send to a graphics card to generate pixels. However, for serious work, I would only use floats if I had done a very detailed study of my particular application to know if I could get away with them. Using floats is a clear example of premature optimization to me.

The counter example is when you are trying to develop algorithms that are robust to truncation error -- in this situation, using floats (that cause the TE to occur earlier and more obviously) can make it easier (by introducing the bug you're trying to fix). However, when these algorithms are put to real use, one would switch back to doubles to provide a belt and suspenders approach to truncation error.

All this is to say that being able to switch the fundamental data type is handy. Whether float, double, double-double, quad-double, or whatever.... Or to use complex numbers, or automatic differentiation via operator overloading, or something I haven't thought of, flexibility in type is good for the developer.

If I were developing an end-user application where I had determined that I needed the ability to change precision dynamically, I would develop my code with either a #define or templated data type. I would then compile it multiple times -- each wrapped up in a different namespace.

That way, I could then have my application access the library using the namespaced versions of the code. The goal would be to keep all the complexity of dynamic precision out of the library and in the application that needs it.

from manifold.

pca006132 avatar pca006132 commented on July 1, 2024

I would consider regular users as users building small stuff (e.g. most users using OpenSCAD, or Nomad Sculpt) where the precision of float is sufficient for their use cases.

The way I think about dynamically switching precision is actually the opposite of what you think: we should switch to double when the magnitude of the coordinates are large, and never switch from double to float. In practice this is probably making already slow operations (using float) even slower (due to switching to double), though this is not very accurate because our slowness mainly come from the complexity of the mesh instead of the magnitude of the coordinates.

In fact, after thinking for a while, I think we should probably go with template and let the users choose which precision they want. The wasm and python bindings (end-user facing part) can decide whether to use float or double based on the magnitude of the coordinates, and users can override the decision using some kind of flags. Applications using manifold as a library can do their own decision and we will respect that.

from manifold.

t-paul avatar t-paul commented on July 1, 2024

If anyone does know how to make a good automation process for binary distribution, I would welcome a PR.

I'm not sure you need to release binary libs directly. What I wanted to point out is the different times a feature set can be decided.

Example where we hit that issue is GLEW which for Linux supports both GLX (like the classic OpenGL window on X11) interface and EGL (works even headless on Linux commandline) for GL context creation.

GLEW has the decision as compile time switch at library compilation time. So Debian ships the GLX library version and there's no trivial chance to use EGL. Just replacing the package with one that supports EGL would potentially break other apps that expect GLX.

I'd be ok if we could select GLX/EGL at application compile time if there would be a binary libglew-dev package that supports both and gives the decision to the application.

Now that's not a point for header-only libraries or when assuming to always rebuild libraries along with the application. But at least the current state on Linux it's mostly prefered to ship shared libs which can be security fixed once for everyone depending on the library code.

from manifold.

ramcdona avatar ramcdona commented on July 1, 2024

In my experience, the difficulty in distributing binaries is one of combinatorics.

For a long time, we built binaries for Mac and Windows -- and we assumed that Linux users were smart enough to compile for themselves. This turned out to be less true than we had hoped.

Taking on a Linux binary build means you have to choose one or more distribution -- Debian, Ubuntu, RedHat, whatever -- and also which version (Ubuntu 20.04, 22.04, etc.) While I'm sure it is possible, cross-building Linux packages is more complex -- i.e. GitHub's CI is based on Ubuntu, so that is easy, but using GitHub's CI to build RedHat packages is surely more complex. So now the more flavors of Unix you want to support (FreeBSD, NetBSD, Slackware, SUSE, RedHat, etc.) you need a large number of CI servers. Our CI is on GitHub, so we build Ubuntu packages and that is it. Our CMake is set up to build RedHat / Centos packages, so users on those platforms can make their own *.rpm's.

My program uses SWIG to generate Python bindings for our C++ API. Now you have to deliver a binary package that matches a targeted version of Python (3.6, 3.9, 3.10, 3.11, etc). At a minimum, the binding needs to match the architecture (x86, x86-64, Aarch64), and I've sometimes had issues requiring that I match the same Python as built and packaged with Anaconda vs. an independent download of Python.

From what I can tell, matplotlib provides about 40 pre-built binary packages. That is just the major desktop platforms -- it gets substantially worse if you want to include RasberryPy, Game Consoles, Phones, Tablets, etc.

from manifold.

elalish avatar elalish commented on July 1, 2024

I'm changing the title to match the discussion. I don't think we want to distribute pre-built C++ packages - that sounds like a lot of work.

from manifold.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.