10 #include "FractalDevice.h"
\r
13 Fractal::Fractal(int w, int h) :
\r
19 Device::assertDim(dg, db);
\r
24 delete this->ptrDomaineMathInit;
\r
43 DomaineMath* Fractal::getDomaineMathInit()
\r
45 return this->ptrDomaineMathInit;
\r
50 FractalMandelbrot::FractalMandelbrot(int w, int h, int dn, bool multiGPU) :
\r
52 variateurAnimationN(IntervalI(10, 100), dn),
\r
56 // Constuit le titre dynamiquement.
\r
57 ostringstream titleStream;
\r
58 titleStream << "Fractal Mandelbrot (multi-GPU " << (this->multiGPU ? "activated" : "not activated") << ")";
\r
59 this->title = titleStream.str();
\r
61 this->ptrDomaineMathInit = new DomaineMath(-2, -1.3, 0.8, 1.3);
\r
65 const int nbDevice = Device::getDeviceCount();
\r
67 this->hDevices = h / nbDevice;
\r
68 this->hFirstDevice = h - ((nbDevice - 1) * this->hDevices);
\r
70 // Allocation de la mémoire sur chaque GPU (sauf le premier pour lequel 'ptrDevPixels' est automatiquement alloué à l'appel de 'runGPU(..)').
\r
71 this->ptrDevPixelsMultGPU = new uchar4*[nbDevice - 1];
\r
72 for (int i = 0; i < nbDevice - 1; ++i)
\r
74 HANDLE_ERROR(cudaSetDevice(i + 1));
\r
75 HANDLE_ERROR(cudaMalloc(&this->ptrDevPixelsMultGPU[i], sizeof(uchar4) * w * this->hDevices));
\r
78 HANDLE_ERROR(cudaSetDevice(0));
\r
82 FractalMandelbrot::~FractalMandelbrot()
\r
86 const int nbDevice = Device::getDeviceCount();
\r
88 for (int i = 0; i < nbDevice - 1; ++i)
\r
90 HANDLE_ERROR(cudaSetDevice(i + 1));
\r
91 HANDLE_ERROR(cudaFree(this->ptrDevPixelsMultGPU[i]));
\r
94 HANDLE_ERROR(cudaSetDevice(0));
\r
95 delete[] this->ptrDevPixelsMultGPU;
\r
98 cout << "OKOKOKOK" << endl;
\r
101 void FractalMandelbrot::animationStep()
\r
103 this->n = this->variateurAnimationN.varierAndGet();
\r
106 vector<string> FractalMandelbrot::getNames()
\r
108 vector<string> name;
\r
109 name.push_back("n = ");
\r
113 void FractalMandelbrot::getValues(float* values)
\r
115 values[0] = float(this->n);
\r
118 string FractalMandelbrot::getTitle()
\r
120 return this->title;
\r
123 void FractalMandelbrot::runGPU(uchar4* ptrDevPixels, const DomaineMath& domaineMath)
\r
126 if (this->multiGPU)
\r
128 HANDLE_ERROR(cudaSetDevice(0));
\r
129 fractalMandelbrot<<<dg,db>>>(ptrDevPixels, this->w, 0, this->hFirstDevice, domaineMath, this->n);
\r
131 const int nbDevice = Device::getDeviceCount();
\r
133 // Rend chaque tranche par un GPU différent puis copie chaque tranche dans la mémoire du premier GPU.
\r
134 #pragma omp parallel for
\r
135 for (int i = 0; i < nbDevice - 1; ++i)
\r
137 HANDLE_ERROR(cudaSetDevice(i + 1));
\r
138 fractalMandelbrot<<<dg,db>>>(this->ptrDevPixelsMultGPU[i], this->w, i * this->hDevices + this->hFirstDevice, (i + 1) * this->hDevices + this->hFirstDevice, domaineMath, this->n);
\r
139 HANDLE_ERROR(cudaMemcpy(ptrDevPixels + this->w * this->hFirstDevice + i * this->w * this->hDevices, this->ptrDevPixelsMultGPU[i], sizeof(uchar4) * this->w * this->hDevices, cudaMemcpyDeviceToDevice));
\r
142 HANDLE_ERROR(cudaSetDevice(0));
\r
146 fractalMandelbrot<<<dg,db>>>(ptrDevPixels, this->w, 0, this->h, domaineMath, this->n);
\r
152 FractalJulia::FractalJulia(int w, int h, int n, float z_r_min, float z_r_max, float z_i_min, float z_i_max) :
\r
157 variateurAnimationR(IntervalF(-0.8, -0.7), 0.0005),
\r
158 variateurAnimationI(IntervalF(-0.3, 0.3), 0.0004)
\r
160 this->ptrDomaineMathInit = new DomaineMath(-1.7, -1.4, 1.7, 1.4);
\r
163 void FractalJulia::animationStep()
\r
165 this->z_r = this->variateurAnimationR.varierAndGet();
\r
166 this->z_i = this->variateurAnimationI.varierAndGet();
\r
169 vector<string> FractalJulia::getNames()
\r
171 vector<string> name;
\r
172 name.push_back("z_r = ");
\r
173 name.push_back("z_i = ");
\r
177 void FractalJulia::getValues(float* values)
\r
179 values[0] = this->z_r;
\r
180 values[1] = this->z_i;
\r
183 string FractalJulia::getTitle()
\r
185 return "Fractal Julia";
\r
188 void FractalJulia::runGPU(uchar4* ptrDevPixels, const DomaineMath& domaineMath)
\r
190 fractalJulia<<<dg,db>>>(ptrDevPixels, this->w, this->h, domaineMath, this->n, this->z_r, this->z_i);
\r