147
edits
Changes
→Code
The program can then be executed by running the compiled binary and it will display the time it took to generate the Mandelbrot set and save the pictures.
{| class="wikitable mw-collapsible mw-collapsed"
! Mandelbrot CPU( ... )
|-
|
<syntaxhighlight lang="cpp">
#include <iostream>
#include <complex>
#include <vector>
#include <chrono>
#include <functional>
#include "window.h"
#include "save_image.h"
#include "utils.h"
// clang++ -std=c++11 -stdlib=libc++ -O3 save_image.cpp utils.cpp mandel.cpp -lfreeimage
// Use an alias to simplify the use of complex type
using Complex = std::complex<float>;
// Convert a pixel coordinate to the complex domain
Complex scale(window<int> &scr, window<float> &fr, Complex c) {
Complex aux(c.real() / (float)scr.width() * fr.width() + fr.x_min(),
c.imag() / (float)scr.height() * fr.height() + fr.y_min());
return aux;
}
// Check if a point is in the set or escapes to infinity, return the number if iterations
int escape(Complex c, int iter_max, const std::function<Complex( Complex, Complex)> &func) {
Complex z(0);
int iter = 0;
while (abs(z) < 2.0 && iter < iter_max) {
z = func(z, c);
iter++;
}
return iter;
}
// Loop over each pixel from our image and check if the points associated with this pixel escape to infinity
void get_number_iterations(window<int> &scr, window<float> &fract, int iter_max, std::vector<int> &colors,
const std::function<Complex( Complex, Complex)> &func) {
int k = 0, progress = -1;
for(int i = scr.y_min(); i < scr.y_max(); ++i) {
for(int j = scr.x_min(); j < scr.x_max(); ++j) {
Complex c((float)j, (float)i);
c = scale(scr, fract, c);
colors[k] = escape(c, iter_max, func);
k++;
}
if(progress < (int)(i*100.0/scr.y_max())){
progress = (int)(i*100.0/scr.y_max());
std::cout << progress << "%\n";
}
}
}
void fractal(window<int> &scr, window<float> &fract, int iter_max, std::vector<int> &colors,
const std::function<Complex( Complex, Complex)> &func, const char *fname, bool smooth_color) {
auto start = std::chrono::steady_clock::now();
get_number_iterations(scr, fract, iter_max, colors, func);
auto end = std::chrono::steady_clock::now();
std::cout << "Time to generate " << fname << " = " << std::chrono::duration <float, std::milli> (end - start).count() << " [ms]" << std::endl;
// Save (show) the result as an image
plot(scr, colors, iter_max, fname, smooth_color);
}
void mandelbrot() {
// Define the size of the image
window<int> scr(0, 1000, 0, 1000);
// The domain in which we test for points
window<float> fract(-2.2, 1.2, -1.7, 1.7);
// The function used to calculate the fractal
auto func = [] (Complex z, Complex c) -> Complex {return z * z + c; };
int iter_max = 500;
const char *fname = "mandelbrot.png";
bool smooth_color = true;
std::vector<int> colors(scr.size());
// Experimental zoom (bugs ?). This will modify the fract window (the domain in which we calculate the fractal function)
//zoom(1.0, -1.225, -1.22, 0.15, 0.16, fract); //Z2
fractal(scr, fract, iter_max, colors, func, fname, smooth_color);
}
void triple_mandelbrot() {
// Define the size of the image
window<int> scr(0, 2000, 0, 2000);
// The domain in which we test for points
window<float> fract(-1.5, 1.5, -1.5, 1.5);
// The function used to calculate the fractal
auto func = [] (Complex z, Complex c) -> Complex {return z * z * z + c; };
int iter_max = 500;
const char *fname = "triple_mandelbrot.png";
bool smooth_color = true;
std::vector<int> colors(scr.size());
fractal(scr, fract, iter_max, colors, func, fname, smooth_color);
}
int main() {
mandelbrot();
// triple_mandelbrot();
return 0;
}
</syntaxhighlight>
|}
=== Observations ===
char *destFileName = argv[2];
#endif /* RUN_GROF RUN_GPROF */
if (showUsage)
To compile and run the program:
# Navigate to the directory you want to run the program in.
# Save [http://matrix.senecac.on.ca/~cpaul12/cinque_terre.bmp this] image and place it into the directory you will be running the program from.
# Copy the Linux version of the main source code above and paste it into a [your chosen file name].cpp file.
# Copy the Linux version of the header source code above and paste it into a file named windows.h.
To compile and run the program:
# Navigate to the directory you want to run the program in.
# Save [http://matrix.senecac.on.ca/~cpaul12/cinque_terre.bmp this] image and place it into the directory you will be running the program from.
# Copy the Linux version of the main source code above and paste it into a [your chosen file name].cpp file.
# Copy the Linux version of the header source code above and paste it into a file named windows.h.
= Assignment 2/3 - Parallelize & Optimize =
* For gaussian blur we say it's unoptimized because we feel that there is more that can be done to reduce the execution times.<br/> The code displayed in the code snippets does use CUDA parallel constructs and fine tuning techniques such as streaming - async.
== Gaussian Blur ==
{| class="wikitable mw-collapsible mw-collapsed"
! Unoptimized * - BlurImage( ... )
|-
|
{| class="wikitable mw-collapsible mw-collapsed"
! Unoptimized * - BlurImage -- Exert( ... )
|-
|