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 void FractalMandelbrot::animationStep()
\r
84 this->n = this->variateurAnimationN.varierAndGet();
\r
87 vector<string> FractalMandelbrot::getNames()
\r
89 vector<string> name;
\r
90 name.push_back("n = ");
\r
94 void FractalMandelbrot::getValues(float* values)
\r
96 values[0] = float(this->n);
\r
99 string FractalMandelbrot::getTitle()
\r
101 return this->title;
\r
104 void FractalMandelbrot::runGPU(uchar4* ptrDevPixels, const DomaineMath& domaineMath)
\r
107 if (this->multiGPU)
\r
109 HANDLE_ERROR(cudaSetDevice(0));
\r
110 fractalMandelbrot<<<dg,db>>>(ptrDevPixels, this->w, 0, this->hFirstDevice, domaineMath, this->n);
\r
112 const int nbDevice = Device::getDeviceCount();
\r
114 // Rend chaque tranche par un GPU différent puis copie chaque tranche dans la mémoire du premier GPU.
\r
115 #pragma omp parallel for
\r
116 for (int i = 0; i < nbDevice - 1; ++i)
\r
118 HANDLE_ERROR(cudaSetDevice(i + 1));
\r
119 fractalMandelbrot<<<dg,db>>>(this->ptrDevPixelsMultGPU[i], this->w, i * this->hDevices + this->hFirstDevice, (i + 1) * this->hDevices + this->hFirstDevice, domaineMath, this->n);
\r
120 HANDLE_ERROR(cudaMemcpy(ptrDevPixels + this->w * this->hFirstDevice + i * this->w * this->hDevices, this->ptrDevPixelsMultGPU[i], sizeof(uchar4) * this->w * this->hDevices, cudaMemcpyDeviceToDevice));
\r
123 HANDLE_ERROR(cudaSetDevice(0));
\r
127 fractalMandelbrot<<<dg,db>>>(ptrDevPixels, this->w, 0, this->h, domaineMath, this->n);
\r
133 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
138 variateurAnimationR(IntervalF(-0.8, -0.7), 0.0005),
\r
139 variateurAnimationI(IntervalF(-0.3, 0.3), 0.0004)
\r
141 this->ptrDomaineMathInit = new DomaineMath(-1.7, -1.4, 1.7, 1.4);
\r
144 void FractalJulia::animationStep()
\r
146 this->z_r = this->variateurAnimationR.varierAndGet();
\r
147 this->z_i = this->variateurAnimationI.varierAndGet();
\r
150 vector<string> FractalJulia::getNames()
\r
152 vector<string> name;
\r
153 name.push_back("z_r = ");
\r
154 name.push_back("z_i = ");
\r
158 void FractalJulia::getValues(float* values)
\r
160 values[0] = this->z_r;
\r
161 values[1] = this->z_i;
\r
164 string FractalJulia::getTitle()
\r
166 return "Fractal Julia";
\r
169 void FractalJulia::runGPU(uchar4* ptrDevPixels, const DomaineMath& domaineMath)
\r
171 fractalJulia<<<dg,db>>>(ptrDevPixels, this->w, this->h, domaineMath, this->n, this->z_r, this->z_i);
\r