Skip to content

Example: Mandelbrot set

Hüseyin Tuğrul BÜYÜKIŞIK edited this page Feb 17, 2021 · 3 revisions

Mandelbrot set generation from: https://medium.com/farouk-ounanes-home-on-the-internet/mandelbrot-set-in-c-from-scratch-c7ad6a1bf2d9

Multithreaded color computations & writing to array, single threaded reading from array and writing to file.

#include "GraphicsCardSupplyDepot.h"
#include "VirtualMultiArray.h"


// testing
#include <iostream>
#include <fstream>
#include <complex>
#include <omp.h>

#ifndef M_PI
#define M_PI (3.14159265359)
#endif

class Color
{
public:
	Color(){}
	Color(int v){val=v;}
	int val;
};

const int width  = 1024;
const int height = 1024;

int value ( int x, int y)  {std::complex<float> point((float)x/width-1.5, (float)y/height-0.5);std::complex<float> z(0, 0);
    unsigned int nb_iter = 0;
    while (abs (z) < 2 && nb_iter <= 34) {
           z = z * z + point;
           nb_iter++;
    }
    if (nb_iter < 34) return (255*nb_iter)/33;
    else return 0;
}

int main(int argC, char ** argV)
{
	GraphicsCardSupplyDepot depot;

	// n needs to be integer multiple of pageSize !!!!
	const size_t n = width*height;
	const size_t pageSize=width;
	const int maxActivePagesPerGpu = 10;

	VirtualMultiArray<Color> img(n,depot.requestGpus(),pageSize,maxActivePagesPerGpu);

	std::cout<<"Starting cpu-compute on gpu-array"<<std::endl;

        #pragma omp parallel for
	for (int i = 0; i < width; i++) {
	    for (int j = 0; j < height; j++)  {
		 img.set(j+i*width,Color(value(i, j)));
	    }
        }

	std::cout<<"mandelbrot compute finished"<<std::endl;

	std::ofstream my_Image ("mandelbrot.ppm");
	if (my_Image.is_open ()) {
	     my_Image << "P3\n" << width << " " << height << " 255\n";
	     for (int i = 0; i < width; i++) {
	          for (int j = 0; j < height; j++)  {
	               int val = img.get(j+i*width).val;
	               my_Image << val<< ' ' << 0 << ' ' << 0 << "\n";
	          }
	     }
	     my_Image.close();
	}
	else std::cout << "Could not open the file";
	std::cout<<"File saved"<<std::endl;
	return 0;
}