kaveh808 / kons-9

Common Lisp 3D Graphics Project
MIT License
556 stars 32 forks source link

add tests to make sure kons-9 can run in modes suitable for scientific and engineering computing #177

Open awolven opened 1 year ago

awolven commented 1 year ago

Get kons-9 running with read-default-float-format set to 'double-float.

The problems arise mostly in the dependencies.

Furthermore, test with (pushnew :3d-vectors-double-floats features) for plugins which require double float vectors and matrices.

foretspaisibles commented 1 year ago

I am just curious about the application scenario we are thinking of because it is not clear to me why we want to have more precise floats to render graphics. Do you have a high-level workflow in mind, describing the interaction between KONS-9 and an engineering program? Or any pointer to an ongoing conversation around here? Thanks!

lukego commented 1 year ago

Do you have a high-level workflow in mind, describing the interaction between KONS-9 and an engineering program?

I'm using Kons-9 to visualize the results of Monte Carlo simulations running in the same Lisp image. My code is hungry for floating-point precision because it needs to do long chains of calculations on very small (log-)probability values. I definitely don't want any single-floats in my application-level calculations.

I agree with @awolven that it would be great for Kons-9 to interoperate more easily with this kind of application e.g. be able to load and run in an image that uses double-floats by default. Currently Bad Things Happen when Kons-9 is exposed to double-floats.

foretspaisibles commented 1 year ago

I am not questioning at all why scientific computations need double precision but I would like to understand more why KONS-9 should also use double floats for graphic-related computations. So understanding better an example of a workflow would be useful to figure out how to make KONS-9 suitable for scientific and engineering computing while still using faster single floats when it comes to graphic computations.

lukego commented 1 year ago

@foretspaisibles I believe the requirement here is only for Kons-9 to co-exist with code in the same image that uses double-floats. It can still use single-floats internally.

Here's an example that I think represents mine and @awolven's workflows that doesn't work today:

* (setq *read-default-float-format* 'double-float)
* ;; ... write and run some engineering code ...
* (require :kons-9)

Since we will be writing a bunch of engineering code in random files and in the REPL we set *READ-DEFAULT-FLOAT-FORMAT* to DOUBLE-FLOAT so that literals we write like 0.5 will be read as double-float objects. This is simply a user-friendly convenience to avoid writing suffixes like 0.5d0 to get double-floats.

The trouble is that kons-9 compilation breaks when we later try to load it into the same image:

* (setq *read-default-float-format* 'double-float)
* (require :kons-9)
...
; compiling file "/home/luke/git/kons-9/src/kernel/point-origin.lisp" (written 14 NOV 2022 06:52:36 AM):

; file: /home/luke/git/kons-9/src/kernel/point-origin.lisp
; in: DEFUN P-SMOOTH-LERP
;     (ORIGIN.VEC3:LERP KONS-9::P1 KONS-9::P2 (KONS-9::CUBIC KONS-9::F))
; 
; caught WARNING:
;   Derived type of
;   (+ (* -2.0 (* KONS-9::X KONS-9::X KONS-9::X)) (* 3.0 (* KONS-9::X KONS-9::X)))
;   is
;     (VALUES (OR DOUBLE-FLOAT (COMPLEX DOUBLE-FLOAT)) &OPTIONAL),
;   conflicting with its asserted type
;     SINGLE-FLOAT.
;   See also:
;     The SBCL Manual, Node "Handling of Types"

; in: DEFUN P-MIDPOINT
;     (ORIGIN.VEC3:SCALE (ORIGIN.VEC3:+ KONS-9::P1 KONS-9::P2) 0.5d0)
; 
; note: deleting unreachable code
; 
; caught WARNING:
;   Constant 0.5 conflicts with its asserted type SINGLE-FLOAT.
;   See also:
;     The SBCL Manual, Node "Handling of Types"

The reason is that kons-9 source code (and/or its dependencies) includes literals like 0.5 that it assumes will be read into single-float values but in fact won't be due to the customization in this image.

So it seems like kons-9 would ideally either explicitly suffix such literals as 0.5f0 to be agnostic to *READ-DEFAULT-FLOAT-FORMAT* or otherwise somehow (ASDF hook?) ensure that this variable has the necessary value during kons-9 compilation.

Is that a more helpful answer?

(I was going to assert that kons-9 also has problems with being accidentally passed double-float numbers via the API but I couldn't immediately formulate an example so maybe I am imagining that.)

JMC-design commented 1 year ago

It's not just about reading. You would need to be able to switch between the two, because double floats are wasteful for the majority of things and most people don't care about them. Since points aren't generic you'll also need to switch between libraries.

lukego commented 1 year ago

I made a separate issue #180 about the specific issue that kons-9's requirement that *read-default-float-format* be single-float is not documented (and potentially unfortunate.)

If that issue captures everything that is actionable here then perhaps we could close this issue.

awolven commented 1 year ago

To whoever said most people don't care about double floats is in err.

In my industry, which is an enormous industry, mechanical engineering, and in all other engineering disciplines civil, electrical, chemical, default is double float and nothing else will do, except for possibly 80 bit floats.

Many of the computer applications in engineering are graphical applications and graphical applications use single float calculations. Every programmer who has ever written a graphical engineering application has no problem converting double floats to single floats to render. It's extremely fast to cast or coerce a double float to a single float on a modern processor. For the argument this is a waste of space:

  1. Why do we have 64 bit machines if 64 bit pointers are even more of a waste of space than double floats?
  2. Would you rather fly on a jumbo jet which was designed with single floats rather than double floats?

Lisp is a dynamic language and easy enough that aeronautical engineers should not have to type "d0" after every number, which is why we have read-default-float-format in the first place. All I'm asking is that we honor the wisdom of the common lisp language designers and make it possible for engineers to run in this mode. I understand that this is a religious preference among Lispers, but I don't care, because I'm trying to sell software.

On Mon, Nov 14, 2022 at 11:29 AM Marengo Zed @.***> wrote:

why we want to have more precise floats to render graphics

I think it depends on how you define "render graphics" and what the scope kons-9 graphics rendering is. The traditional OpenGL "pushing triangles" pipeline gets away with single floats, but even GPUs are doing raytracing methods--which benefits from extended precision. In implicit function rendering, there are alternate ways to do QEF construction with doubles or singles--and the single precision method actually is slower due to using Givens rotations. CGAL, which OpenSCAD is built on, uses exact arithmetic for robustness.

A more general issue is that the CL spec doesn't address IEEE 754, although SBCL does to some degree. What do you do with floating point exceptions? How do you manage the rounding mode? If you rely on external libraries, what are they doing behind the scenes? In octree rendering, interval arithmetic comes in handy, and interval arithmetic methods need on-the-fly rounding mode changes.

— Reply to this email directly, view it on GitHub https://github.com/kaveh808/kons-9/issues/177#issuecomment-1314124436, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABGMMPQIK2QXD44FCOCHNTWIJZI3ANCNFSM6AAAAAAR7DDAAQ . You are receiving this because you were mentioned.Message ID: @.***>

kaveh808 commented 1 year ago

It would be good to be able to have the user be able to specify if they want single or double floats when they are loading our system. There are definitely use cases for both.

Let''s figure out how in #180

kaveh808 commented 1 year ago

I'm using Kons-9 to visualize the results of Monte Carlo simulations running in the same Lisp image.

@lukego I'd love to hear more about your use of the system. Maybe post about it in discussion #78 ?

foretspaisibles commented 1 year ago

@foretspaisibles I believe the requirement here is only for Kons-9 to co-exist with code in the same image that uses double-floats. It can still use single-floats internally. […]

Thank you @lukego that's a very helpful description of what you would like to do. I do not have experience with automated testing for Slime/Emacs or Sly/Emacs but we could start with a plain lisp test.

Yet that could be interesting to learn about UX-testing in Emacs for the future.