diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | README.md | 34 | ||||
| -rw-r--r-- | examples/burning_ship.png | bin | 0 -> 5830856 bytes | |||
| -rw-r--r-- | examples/julia.png | bin | 0 -> 5672122 bytes | |||
| -rw-r--r-- | examples/mandelbrot.png | bin | 0 -> 1554396 bytes | |||
| -rw-r--r-- | examples/multibrot.png | bin | 0 -> 2304127 bytes | |||
| -rw-r--r-- | examples/multicorn.gif | bin | 0 -> 155443 bytes | |||
| -rw-r--r-- | examples/multicorn_framelist | 4 | ||||
| -rw-r--r-- | examples/tricorn.png | bin | 0 -> 1448374 bytes | |||
| -rw-r--r-- | makefile | 20 | ||||
| -rw-r--r-- | presentation/presentation.html | 411 | ||||
| -rw-r--r-- | presentation/presentation.md | 15 | ||||
| -rw-r--r-- | src/fractal_render.c | 3 | ||||
| -rw-r--r-- | src/renderers.c | 5 |
14 files changed, 480 insertions, 13 deletions
@@ -8,6 +8,7 @@ analysis/data/* build/* *.html !analysis/analysis.html +!presentation/presentation.html # IDE stuff .vscode @@ -8,7 +8,7 @@ Each version of the complex fractal generator has its own dependencies. The serial version should compile on all systems that support complex arithmetic. The shared version requires a compiler with [OpenMP](https://www.openmp.org/) support. -The CUDA version requires the `nvcc` compiler and `thrust libraries`. +The CUDA version requires the `nvcc` compiler and `thrust` libraries. For better performance on your machine, change the flag `-arch=sm_86` in `NVCFLAGS` in the makefile to your gpu's compute capability. ### Building @@ -68,6 +68,38 @@ Generates a 500x500 julia fractal grid which has a maximum of 30 iterations for ## Visualizations +The program `fractal-render` renders `.grid` files into txt, png's, and animated gifs. + +``` +Usage: fractal-render -i input.grid [-r renderer] [-o output.ext] +Options: + -i, --input <input grid> the grid to be rendered, if the file name is '-' reads from stdin + -r, --renderer <renderer> the renderer to use, defaults to the text renderer + renderers: txt, png, gif (TODO, with additional features) + -d, --delay <delay> the delay between animation frames in 1/100 s + -o, --output <output file> the file to output the result of rendering, if not given defaults to fractal.out. + -v, --verbose verbose output + -h, --help prints this help and exits +``` + +### Building + +To build simply run + +```bash +make +``` + +### Examples + +Some example visualizations are provided in `examples`, they can be regenerated with + +```bash +make examples/julia.png +make examples/multicorn.gif +``` + + ## Presentation Building the presentation requires a [pandoc](https://pandoc.org/) installation. diff --git a/examples/burning_ship.png b/examples/burning_ship.png Binary files differnew file mode 100644 index 0000000..98ce9f1 --- /dev/null +++ b/examples/burning_ship.png diff --git a/examples/julia.png b/examples/julia.png Binary files differnew file mode 100644 index 0000000..1b8440c --- /dev/null +++ b/examples/julia.png diff --git a/examples/mandelbrot.png b/examples/mandelbrot.png Binary files differnew file mode 100644 index 0000000..4fbfb8a --- /dev/null +++ b/examples/mandelbrot.png diff --git a/examples/multibrot.png b/examples/multibrot.png Binary files differnew file mode 100644 index 0000000..6aae55d --- /dev/null +++ b/examples/multibrot.png diff --git a/examples/multicorn.gif b/examples/multicorn.gif Binary files differnew file mode 100644 index 0000000..115eb9b --- /dev/null +++ b/examples/multicorn.gif diff --git a/examples/multicorn_framelist b/examples/multicorn_framelist new file mode 100644 index 0000000..243dfd2 --- /dev/null +++ b/examples/multicorn_framelist @@ -0,0 +1,4 @@ +examples/multicorn_2.grid +examples/multicorn_3.grid +examples/multicorn_4.grid +examples/multicorn_5.grid diff --git a/examples/tricorn.png b/examples/tricorn.png Binary files differnew file mode 100644 index 0000000..8d02e24 --- /dev/null +++ b/examples/tricorn.png @@ -48,19 +48,31 @@ $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR) $(OBJ_DIR): mkdir -p $@ -########### -# Tests # -########### +#################### +# Tests/Examples # +################### examples/julia.png: examples/julia.grid $(BUILD_DIR)/fractal-render $(BUILD_DIR)/fractal-render -i $< -r png -o $@ +examples/multicorn.gif: examples/multicorn_framelist + $(BUILD_DIR)/fractal-render -i $< -d 80 -r gif -o $@ + +examples/multicorn_framelist: examples/multicorn_2.grid examples/multicorn_3.grid examples/multicorn_4.grid examples/multicorn_5.grid + @echo $< > $@ + @echo $(word 2, $^) >> $@ + @echo $(word 3, $^) >> $@ + @echo $(word 4, $^) >> $@ + examples/julia.grid: $(BUILD_DIR)/shared-fractals - $< -c 0.285+0.01i -i 255 -r 2 -x 8192 -y 8192 -o $@ -f julia + $< -c 0.285+0.01i -i 155 -r 2 -x 8192 -y 8192 -o $@ -f julia examples/mandelbrot_%.grid: $(BUILD_DIR)/%-fractals $< -x 100 -y 100 -o $@ +examples/multicorn_%.grid: $(BUILD_DIR)/shared-fractals + $< -x1000 -y1000 -i50 -d $* -o $@ -f multicorn + tests/mandelbrot: examples/mandelbrot_serial.grid examples/mandelbrot_shared.grid examples/mandelbrot_cuda.grid cmp -l $< $(word 2, $^) > $@ cmp -l $(word 2, $^) $(word 3, $^) >> $@ diff --git a/presentation/presentation.html b/presentation/presentation.html new file mode 100644 index 0000000..31c1443 --- /dev/null +++ b/presentation/presentation.html @@ -0,0 +1,411 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <meta name="generator" content="pandoc"> + <meta name="author" content="JP Appel"> + <meta name="author" content="David Marrero"> + <title>HPC Complex Fractal Generation</title> + <meta name="apple-mobile-web-app-capable" content="yes"> + <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> + <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui"> + <link rel="stylesheet" href="https://unpkg.com/reveal.js@^4//dist/reset.css"> + <link rel="stylesheet" href="https://unpkg.com/reveal.js@^4//dist/reveal.css"> + <style> + .reveal .sourceCode { /* see #7635 */ + overflow: visible; + } + code{white-space: pre-wrap;} + span.smallcaps{font-variant: small-caps;} + span.underline{text-decoration: underline;} + div.column{display: inline-block; vertical-align: top; width: 50%;} + div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;} + ul.task-list{list-style: none;} + .display.math{display: block; text-align: center; margin: 0.5rem auto;} + </style> + <link rel="stylesheet" href="https://unpkg.com/reveal.js@^4//dist/theme/black.css" id="theme"> +</head> +<body> + <div class="reveal"> + <div class="slides"> + +<section id="title-slide"> + <h1 class="title">HPC Complex Fractal Generation</h1> + <p class="author">JP Appel</p> + <p class="author">David Marrero</p> +</section> + +<section> +<section id="prerequisite-knowledge" class="title-slide slide level1"> +<h1>Prerequisite Knowledge</h1> + +</section> +<section id="complex-numbers" class="slide level2"> +<h2>Complex Numbers</h2> +<p><span class="math display"><em>i</em><sup>2</sup> = − 1</span> <span +class="math display"><em>z</em> = <em>x</em> + <em>i</em><em>y</em></span></p> +<aside class="notes"> +<ul> +<li>complex numbers are an extension of real numbers, stemming from the +square root of <span class="math inline"> − 1</span></li> +<li>a complex number is just a pair of two real numbers (x,y) with +different ways to add and multiply</li> +<li>in computer science we model real numbers with a single float or +double, so we will need 2 floats or doubles to model a complex +number</li> +</ul> +</aside> +<div class="fragment"> +<h3 id="addition">Addition</h3> +<p><span +class="math display"><em>z</em><sub>1</sub> + <em>z</em><sub>2</sub> = (<em>x</em><sub>1</sub>+<em>x</em><sub>2</sub>) + <em>i</em>(<em>y</em><sub>1</sub>+<em>y</em><sub>2</sub>)</span></p> +<aside class="notes"> +<ul> +<li>addition behaves as you expect</li> +<li>multiplication involves multiplying then distributing, and using the +fact that <span +class="math inline"><em>i</em><sup>2</sup> = − 1</span></li> +<li>so adding two complex numbers is 2 float additions</li> +<li>and multiplying them is 4 multiplications and 2 additions</li> +</ul> +</aside> +<h3 id="multiplication">Multiplication</h3> +<p><span +class="math display"><em>z</em><sub>1</sub><em>z</em><sub>2</sub> = (<em>x</em><sub>1</sub><em>x</em><sub>2</sub>−<em>y</em><sub>1</sub><em>y</em><sub>2</sub>) + <em>i</em>(<em>x</em><sub>1</sub><em>y</em><sub>2</sub>+<em>x</em><sub>2</sub><em>y</em><sub>1</sub>)</span></p> +</div> +</section> +<section id="what-is-the-mandelbrot-set" class="slide level2"> +<h2>What is the Mandelbrot Set</h2> +<div class="fragment"> +<p><span +class="math display"><em>z</em><sub><em>n</em></sub> = <em>z</em><sub><em>n</em> − 1</sub><sup>2</sup> + <em>z</em><sub>0</sub></span></p> +<aside class="notes"> +<ul> +<li>this sequence is used to generate the mandelbrot set</li> +<li>if for some complex number <span +class="math inline"><em>z</em><sub>0</sub></span> the sequence remains +bounded as it <span class="math inline"><em>n</em></span> approaches +infinity then <span class="math inline"><em>z</em><sub>0</sub></span> +lies within the mandelbrot set</li> +<li>there are many recursive sequences related to this, where you modify +that happens with the recursive term</li> +</ul> +</aside> +</div> +</section> +<section id="fractals" class="slide level2"> +<h2>Fractals</h2> +<div class="columns"> +<div class="column" style="width:40%;"> +<ul> +<li>infinite self-similar geometric shape</li> +<li>have “fractional dimension”</li> +</ul> +</div><div class="column" style="width:60%;"> +<figure> +<img +data-src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/45/Sierpinski_triangle.svg/1920px-Sierpinski_triangle.svg.png" +style="width:80.0%" alt="Sripenski Triangle" /> +<figcaption aria-hidden="true">Sripenski Triangle</figcaption> +</figure> +</div> +</div> +<div class="fragment"> +<p>The Mandelbrot set is a fractal in the complex plane</p> +<aside class="notes"> +<ul> +<li>fractals are a infinite self-similar geometric shape</li> +<li>so if you zoom in on any one part it will look like the entire +object</li> +<li>the Sripenski triangle is an example of a fractal</li> +<li>the mandelbrot set forms a fractal in the complex plane</li> +</ul> +</aside> +</div> +</section> +<section id="fractal-in-nature" class="slide level2"> +<h2>Fractal in Nature</h2> +<figure> +<img +data-src="https://www.rocketgardens.co.uk/wp-content/uploads/2016/02/Cauliflower20Romanesco.jpg" +style="width:50.0%" alt="Romanesco Cauliflower" /> +<figcaption aria-hidden="true">Romanesco Cauliflower</figcaption> +</figure> +<aside class="notes"> +<ul> +<li>fractals often show up in nature</li> +</ul> +</aside> +</section> +<section id="escape-time-algorithm" class="slide level2"> +<h2>Escape Time Algorithm</h2> +<div> +<ul> +<li class="fragment">Inputs +<ul> +<li class="fragment">Maximum Number of iterations</li> +<li class="fragment">Upper bound</li> +</ul></li> +</ul> +<ol type="1"> +<li class="fragment">Create a grid of points to sample</li> +<li class="fragment">For each point in the sample space +<ol type="1"> +<li class="fragment">Compute the next term in the sequence</li> +<li class="fragment">if greater than the upper bound return the number +of iterations</li> +<li class="fragment">else repeat until the maximum number of iterations +and return</li> +</ol></li> +</ol> +</div> +<aside class="notes"> +<ul> +<li>to compute the complex sets we used an escape time algorithm</li> +<li>in general it takes in a maximum number of iterations, an initial +value, and an upper bound</li> +<li>the escape time algorithm is as follows (read of the slides)</li> +<li>note that each sampled point is completely independent of any other +point +<ul> +<li>this hints to us that the problem will parallelize well</li> +</ul></li> +<li>for most of the sets we looked at, there is a proven bound +<ul> +<li>ie if the sequence is ever larger than a value we know it +diverges</li> +</ul></li> +</ul> +</aside> +</section></section> +<section> +<section id="implementation" class="title-slide slide level1"> +<h1>Implementation</h1> + +</section> +<section id="program-structure" class="slide level2"> +<h2>Program Structure</h2> +<p><img data-src="diagram.png" /></p> +<aside class="notes"> +<ul> +<li>the translation units are roughly as pictured here</li> +<li>black ellipses are for serial code, color is for parallel</li> +<li>each version of the program fills in an array with the number of +iterations it took the sequence to grow too large</li> +<li>that array along with some extra data is a grid object, which can be +serialized and deserialized</li> +<li>the main fractals unit handles cli argument parsing for the sampling +resolution, fractal type etc</li> +<li>a separate renderer program handles creating images from the +<code>.grid</code> file</li> +<li>the <code>.grid</code> file format is really simple, it’s a magic +number, the grid dimensions, the maximum number of iterations, the lower +left and upper right most points of the region, and then the data</li> +</ul> +</aside> +</section> +<section id="mandelbrot" class="slide level2"> +<h2>Mandelbrot</h2> +<p><a href="../examples/mandelbrot.png">Image</a></p> +<aside class="notes"> +<ul> +<li>when mandelbrot initially tried to have this printed, the printers +kept removing the “dust” thinking it was an error in their printing +process</li> +</ul> +</aside> +</section> +<section id="tricorn" class="slide level2"> +<h2>Tricorn</h2> +<p><a href="../examples/tricorn.png">Image</a></p> +</section> +<section id="burning-ship" class="slide level2"> +<h2>Burning Ship</h2> +<p><a href="../examples/burning_ship.png">Image</a></p> +</section> +<section id="multibrot" class="slide level2"> +<h2>Multibrot</h2> +<p><a href="../examples/multibrot.png">Image</a></p> +</section> +<section id="multicorn" class="slide level2"> +<h2>Multicorn</h2> +<p><a href="../examples/multicorn.gif">GIF</a></p> +</section> +<section id="julia" class="slide level2"> +<h2>Julia</h2> +<p><a href="../examples/julia.png">Image</a></p> +</section></section> +<section> +<section id="analysis" class="title-slide slide level1"> +<h1>Analysis</h1> + +</section> +<section id="section" class="slide level2"> +<h2></h2> +<p><a href="../analysis/analysis.html">Interactive Plots</a></p> +</section></section> + </div> + </div> + + <script src="https://unpkg.com/reveal.js@^4//dist/reveal.js"></script> + + <!-- reveal.js plugins --> + <script src="https://unpkg.com/reveal.js@^4//plugin/notes/notes.js"></script> + <script src="https://unpkg.com/reveal.js@^4//plugin/search/search.js"></script> + <script src="https://unpkg.com/reveal.js@^4//plugin/zoom/zoom.js"></script> + + <script> + + // Full list of configuration options available at: + // https://revealjs.com/config/ + Reveal.initialize({ + // Display controls in the bottom right corner + controls: true, + + // Help the user learn the controls by providing hints, for example by + // bouncing the down arrow when they first encounter a vertical slide + controlsTutorial: true, + + // Determines where controls appear, "edges" or "bottom-right" + controlsLayout: 'bottom-right', + + // Visibility rule for backwards navigation arrows; "faded", "hidden" + // or "visible" + controlsBackArrows: 'faded', + + // Display a presentation progress bar + progress: true, + + // Display the page number of the current slide + slideNumber: false, + + // 'all', 'print', or 'speaker' + showSlideNumber: 'all', + + // Add the current slide number to the URL hash so that reloading the + // page/copying the URL will return you to the same slide + hash: true, + + // Start with 1 for the hash rather than 0 + hashOneBasedIndex: false, + + // Flags if we should monitor the hash and change slides accordingly + respondToHashChanges: true, + + // Push each slide change to the browser history + history: false, + + // Enable keyboard shortcuts for navigation + keyboard: true, + + // Enable the slide overview mode + overview: true, + + // Disables the default reveal.js slide layout (scaling and centering) + // so that you can use custom CSS layout + disableLayout: false, + + // Vertical centering of slides + center: true, + + // Enables touch navigation on devices with touch input + touch: true, + + // Loop the presentation + loop: false, + + // Change the presentation direction to be RTL + rtl: false, + + // see https://revealjs.com/vertical-slides/#navigation-mode + navigationMode: 'default', + + // Randomizes the order of slides each time the presentation loads + shuffle: false, + + // Turns fragments on and off globally + fragments: true, + + // Flags whether to include the current fragment in the URL, + // so that reloading brings you to the same fragment position + fragmentInURL: true, + + // Flags if the presentation is running in an embedded mode, + // i.e. contained within a limited portion of the screen + embedded: false, + + // Flags if we should show a help overlay when the questionmark + // key is pressed + help: true, + + // Flags if it should be possible to pause the presentation (blackout) + pause: true, + + // Flags if speaker notes should be visible to all viewers + showNotes: false, + + // Global override for autoplaying embedded media (null/true/false) + autoPlayMedia: null, + + // Global override for preloading lazy-loaded iframes (null/true/false) + preloadIframes: null, + + // Number of milliseconds between automatically proceeding to the + // next slide, disabled when set to 0, this value can be overwritten + // by using a data-autoslide attribute on your slides + autoSlide: 0, + + // Stop auto-sliding after user input + autoSlideStoppable: true, + + // Use this method for navigation when auto-sliding + autoSlideMethod: null, + + // Specify the average time in seconds that you think you will spend + // presenting each slide. This is used to show a pacing timer in the + // speaker view + defaultTiming: null, + + // Enable slide navigation via mouse wheel + mouseWheel: false, + + // The display mode that will be used to show slides + display: 'block', + + // Hide cursor if inactive + hideInactiveCursor: true, + + // Time before the cursor is hidden (in ms) + hideCursorTime: 5000, + + // Opens links in an iframe preview overlay + previewLinks: false, + + // Transition style (none/fade/slide/convex/concave/zoom) + transition: 'slide', + + // Transition speed (default/fast/slow) + transitionSpeed: 'default', + + // Transition style for full page slide backgrounds + // (none/fade/slide/convex/concave/zoom) + backgroundTransition: 'fade', + + // Number of slides away from the current that are visible + viewDistance: 3, + + // Number of slides away from the current that are visible on mobile + // devices. It is advisable to set this to a lower number than + // viewDistance in order to save resources. + mobileViewDistance: 2, + + // reveal.js plugins + plugins: [ + RevealNotes, + RevealSearch, + RevealZoom + ] + }); + </script> + </body> +</html> diff --git a/presentation/presentation.md b/presentation/presentation.md index b3297c3..a4a1f4f 100644 --- a/presentation/presentation.md +++ b/presentation/presentation.md @@ -139,6 +139,8 @@ The Mandelbrot set is a fractal in the complex plane ## Mandelbrot +[Image](../examples/mandelbrot.png) + ::: notes * when mandelbrot initially tried to have this printed, the printers kept removing the "dust" thinking it was an error in their printing process @@ -147,19 +149,24 @@ The Mandelbrot set is a fractal in the complex plane ## Tricorn +[Image](../examples/tricorn.png) + ## Burning Ship +[Image](../examples/burning_ship.png) + ## Multibrot +[Image](../examples/multibrot.png) + ## Multicorn -## Julia +[GIF](../examples/multicorn.gif) -## Serial Animation -## Shared Animation +## Julia -## CUDA Animation +[Image](../examples/julia.png) # Analysis diff --git a/src/fractal_render.c b/src/fractal_render.c index 721d3f2..fe25f12 100644 --- a/src/fractal_render.c +++ b/src/fractal_render.c @@ -21,8 +21,7 @@ void print_help(){ " -r, --renderer <renderer> the renderer to use, defaults to the text renderer\n" " renderers: txt, png, gif (TODO, with additional features)\n" " -d, --delay <delay> the delay between animation frames in 1/100 s\n" - " -o, --output <output file> the file to output the result of rendering, if not given defaults to output.<EXT>\n" - " where <EXT> is the renderer used\n" + " -o, --output <output file> the file to output the result of rendering, if not given defaults to fractal.out\n" " -v, --verbose verbose output\n" " -h, --help prints this help and exits\n" ); diff --git a/src/renderers.c b/src/renderers.c index 2955fb2..372d7a2 100644 --- a/src/renderers.c +++ b/src/renderers.c @@ -51,10 +51,11 @@ gdImagePtr converter(const grid_t* grid){ gdImagePtr img = gdImageCreate(width, height); int colors[256]; for(size_t i = 0; i < 255; i++){ - colors[i] = gdImageColorAllocate(img, 0, i, i/2); + colors[i] = gdImageColorAllocate(img, 0, 255-i, (255-i)/2); } colors[255] = gdImageColorAllocate(img, 0, 0, 0); + for(size_t y = 0; y < height; y++){ for(size_t x = 0; x < width; x++){ byte iteration = data[y * width + x]; @@ -82,7 +83,7 @@ void render_gif(FILE* output, const renderer_params* params){ gdImagePtr imgs[size]; imgs[0] = converter(grids[0]); - gdImageGifAnimBegin(imgs[0], output, 1, -1); + gdImageGifAnimBegin(imgs[0], output, 1, 0); gdImageGifAnimAdd(imgs[0], output, 0, 0, 0, delay, 1, NULL); for(size_t i = 1; i < size; i++){ |
