# mandelbrot - quasi double-precision

For learning CUDA and go deeper with single/double I played around a little bit with the mandelbrot SDK example.
For the original mandelbrot example see this link too:
https://devtalk.nvidia.com/default/topic/376990/?comment=2690153

https://www.gmeindl.net/urlg/Mandelbrot.zip

I have changed the code a little bit.
If someone is interested: here is an overview about the changes

main changes

calculation:
three new classe on GPU and CPU for quasi double-precision
Basic arithmetical operations are implemented as operators (+,-,*,/)

=> you can use them in template-functions like float or double
=> you have to write code only once if you want to switch from float to a quasi double-precision

implemented classes
dfloat: quasi double-precision methode
dfloat1: fast quasi double-precision methode 1
dfloat2: fast quasi double-precision methode 2

the implementation of the algorithms (+,-,*) are out of the paper:
“FAST QUASI DOUBLE-PRECISION METHOD WITH SINGLE-PRECISION HARDWARE TO ACCELERATE SCIENTIFIC APPLICATIONS” (Testu Narumi, Tsuyoshi Hamada, Keigo Nitadori)

implementation of division:
I used the Newton–Raphson division algorithm out of Wikipedia
it’s slow (double will be faster usually) but if GPU doesn’t support double…

drawback
dfloat (as class) is slower as the non-class implementation: slowdown from 46 to 42 fps

algorithm:
changed kernel-calculation lines y = x * y * T(2.0) + yC to
y = T(2.0) * x * y + yC;
so FMA (fused multiply-add) is used - at least on my GPU with float: fps rose from 375 to 390

new and changed functionality and there hot-keys:
Press [w] or [W] to set black and white colors or reset colors back
Press [z] to toggle between quick (at once) zoom or slow zoom
Press [CTRL]+[z] or [Z] and [1…9] to set speed of slow zoom
Press [7]/[1] to move left-up and left-down
Press [9]/[3] to move right-up and right-down
Press [5] to center image and reset the scale
Left mouse button = move window towards the mouse curser
Left mouse button + drag = rectangle zoom
Left mouse button + Press [CTRL] = Mandelbrot: switch to corresponding Julia
Left mouse button + Press [CTRL] + drag = Julia: animate Julia
Mouse wheel = Zoom in/out
Press [CTRL]+[p] and [1…9] = like [p] with index
Press [CTRL]+[o] and [1…9] = like [o] with index
Press [i] to write the current Mandelbrot- or Julia-Set as ppm image
Press [CTRL]+[i] and [1…9] = like [i] with index

for moving (numbers 2,4,6,8) the cursor keys can be used as well

CPU-code:

• change code so we can use template-functions (like the GPU-code)
• improving fps calculation
• add new possible start parameters (see ./txt/2_commands.txt)

changes in other files
added and changed some functions in
…\common\inc\helper_string.h
to get arguments from argv through its position and that we can read double-values. This should not have an influence on other SDK examples.

general
changes are made to the mandelbrot-SDK-sample from v5.0.
the mandelbrot.sln is already for VS2012 (and VS2010)
chanches to non mandelbrot files (only helper_string.h) are made to the original files from SDK v5.5
=> you can add/override the files directly to the file-structure from the sdk (perhaps you make a copy of mandelbrot folder and helper_string.h file before)
if you copy the bin-directory only, you can test the mandelbrot.exe right away (without any CUDA programming files installed - all dll needed are there; a CUDA graphic card is essential of course:)