-#include <iostream>\r
-#include <assert.h>\r
-\r
#include "Fractal.h"\r
-#include "Device.h"\r
-\r
-using std::cout;\r
-using std::endl;\r
-\r
-/*----------------------------------------------------------------------*\\r
- |* Declaration *|\r
- \*---------------------------------------------------------------------*/\r
-\r
-/*--------------------------------------*\\r
- |* Imported *|\r
- \*-------------------------------------*/\r
-\r
-extern __global__ void fractal(uchar4* ptrDevPixels, int w, int h, DomaineMath domaineMath, int n, float t);\r
-\r
-/*--------------------------------------*\\r
- |* Public *|\r
- \*-------------------------------------*/\r
\r
-/*--------------------------------------*\\r
- |* Private *|\r
- \*-------------------------------------*/\r
-\r
-/*----------------------------------------------------------------------*\\r
- |* Implementation *|\r
- \*---------------------------------------------------------------------*/\r
+#include <iostream>\r
+#include <sstream>\r
+#include <assert.h>\r
+using namespace std;\r
\r
-/*--------------------------------------*\\r
- |* Public *|\r
- \*-------------------------------------*/\r
+#include <omp.h>\r
\r
-/*-------------------------*\\r
- |* Constructeur *|\r
- \*-------------------------*/\r
+#include "FractalDevice.h"\r
+#include "Device.h"\r
\r
-Fractal::Fractal(int w, int h, float dt, int n)\r
- : w(w), h(h), n(n),\r
- dg(8, 8, 1),\r
- db(16, 16, 1),\r
- t(0),\r
- variateurAnimation(IntervalF(0, 2 * PI), dt),\r
- ptrDomaineMathInit(new DomaineMath(-2, -1.3, 0.8, 1.3)),\r
- title("Fractal Cuda")\r
+Fractal::Fractal(int w, int h) :\r
+ w(w), h(h),\r
+ dg(8, 8, 1),\r
+ db(16, 16, 1)\r
{\r
- assert(w == h);\r
-\r
//print(dg, db);\r
Device::assertDim(dg, db);\r
}\r
delete this->ptrDomaineMathInit;\r
}\r
\r
-/*-------------------------*\\r
- |* Methode *|\r
- \*-------------------------*/\r
-\r
/**\r
* Override\r
*/\r
-void Fractal::runGPU(uchar4* ptrDevPixels, const DomaineMath& domaineMath)\r
+int Fractal::getW()\r
{\r
- fractal<<<dg,db>>>(ptrDevPixels, this->w, this->h, domaineMath, this->n, this->t);\r
+ return this->w;\r
}\r
\r
/**\r
* Override\r
*/\r
-void Fractal::animationStep()\r
+int Fractal::getH()\r
{\r
- this->t = this->variateurAnimation.varierAndGet();\r
+ return this->h;\r
}\r
\r
-/*--------------*\\r
- |* get *|\r
- \*--------------*/\r
+DomaineMath* Fractal::getDomaineMathInit()\r
+ {\r
+ return this->ptrDomaineMathInit;\r
+ }\r
\r
+/////\r
\r
-/**\r
- * Override\r
- */\r
-int Fractal::getW()\r
+FractalMandelbrot::FractalMandelbrot(int w, int h, int dn, bool multiGPU) :\r
+ Fractal(w, h),\r
+ variateurAnimationN(IntervalI(10, 100), dn),\r
+ n(0),\r
+ multiGPU(multiGPU)\r
{\r
- return this->w;\r
+ // Constuit le titre dynamiquement.\r
+ ostringstream titleStream;\r
+ titleStream << "Fractal Mandelbrot (multi-GPU " << (this->multiGPU ? "activated" : "not activated") << ")";\r
+ this->title = titleStream.str();\r
+\r
+ this->ptrDomaineMathInit = new DomaineMath(-2, -1.3, 0.8, 1.3);\r
+\r
+ if (this->multiGPU)\r
+ {\r
+ const int nbDevice = Device::getDeviceCount();\r
+\r
+ this->hDevices = h / nbDevice;\r
+ this->hFirstDevice = h - ((nbDevice - 1) * this->hDevices);\r
+\r
+ // Allocation de la mémoire sur chaque GPU (sauf le premier pour lequel 'ptrDevPixels' est automatiquement alloué à l'appel de 'runGPU(..)').\r
+ this->ptrDevPixelsMultGPU = new uchar4*[nbDevice - 1];\r
+ for (int i = 0; i < nbDevice - 1; ++i)\r
+ {\r
+ HANDLE_ERROR(cudaSetDevice(i + 1));\r
+ HANDLE_ERROR(cudaMalloc(&this->ptrDevPixelsMultGPU[i], sizeof(uchar4) * w * this->hDevices));\r
+ }\r
+\r
+ HANDLE_ERROR(cudaSetDevice(0));\r
+ }\r
}\r
\r
-/**\r
- * Override\r
- */\r
-int Fractal::getH()\r
+FractalMandelbrot::~FractalMandelbrot()\r
{\r
- return this->h;\r
+ if (this->multiGPU)\r
+ {\r
+ const int nbDevice = Device::getDeviceCount();\r
+\r
+ for (int i = 0; i < nbDevice - 1; ++i)\r
+ {\r
+ HANDLE_ERROR(cudaSetDevice(i + 1));\r
+ HANDLE_ERROR(cudaFree(this->ptrDevPixelsMultGPU[i]));\r
+ }\r
+\r
+ HANDLE_ERROR(cudaSetDevice(0));\r
+ delete[] this->ptrDevPixelsMultGPU;\r
+ }\r
+\r
+ cout << "OKOKOKOK" << endl;\r
}\r
\r
-DomaineMath* Fractal::getDomaineMathInit()\r
+void FractalMandelbrot::animationStep()\r
{\r
- return this->ptrDomaineMathInit;\r
+ this->n = this->variateurAnimationN.varierAndGet();\r
}\r
\r
-/**\r
- * Override\r
- */\r
-float Fractal::getT()\r
+vector<string> FractalMandelbrot::getNames()\r
{\r
- return this->t;\r
+ vector<string> name;\r
+ name.push_back("n = ");\r
+ return name;\r
}\r
\r
-/**\r
- * Override\r
- */\r
-string Fractal::getTitle()\r
+void FractalMandelbrot::getValues(float* values)\r
+ {\r
+ values[0] = float(this->n);\r
+ }\r
+\r
+string FractalMandelbrot::getTitle()\r
{\r
return this->title;\r
}\r
\r
-/*--------------------------------------*\\r
- |* Private *|\r
- \*-------------------------------------*/\r
+void FractalMandelbrot::runGPU(uchar4* ptrDevPixels, const DomaineMath& domaineMath)\r
+ {\r
+\r
+ if (this->multiGPU)\r
+ {\r
+ HANDLE_ERROR(cudaSetDevice(0));\r
+ fractalMandelbrot<<<dg,db>>>(ptrDevPixels, this->w, 0, this->hFirstDevice, domaineMath, this->n);\r
+\r
+ const int nbDevice = Device::getDeviceCount();\r
+\r
+ // Rend chaque tranche par un GPU différent puis copie chaque tranche dans la mémoire du premier GPU.\r
+ #pragma omp parallel for\r
+ for (int i = 0; i < nbDevice - 1; ++i)\r
+ {\r
+ HANDLE_ERROR(cudaSetDevice(i + 1));\r
+ fractalMandelbrot<<<dg,db>>>(this->ptrDevPixelsMultGPU[i], this->w, i * this->hDevices + this->hFirstDevice, (i + 1) * this->hDevices + this->hFirstDevice, domaineMath, this->n);\r
+ HANDLE_ERROR(cudaMemcpy(ptrDevPixels + this->w * this->hFirstDevice + i * this->w * this->hDevices, this->ptrDevPixelsMultGPU[i], sizeof(uchar4) * this->w * this->hDevices, cudaMemcpyDeviceToDevice));\r
+ }\r
+\r
+ HANDLE_ERROR(cudaSetDevice(0));\r
+ }\r
+ else\r
+ {\r
+ fractalMandelbrot<<<dg,db>>>(ptrDevPixels, this->w, 0, this->h, domaineMath, this->n);\r
+ }\r
+ }\r
+\r
+/////\r
\r
-/*----------------------------------------------------------------------*\\r
- |* End *|\r
- \*---------------------------------------------------------------------*/\r
+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
+ Fractal(w, h),\r
+ n(n),\r
+ z_r(z_r_min),\r
+ z_i(z_i_min),\r
+ variateurAnimationR(IntervalF(-0.8, -0.7), 0.0005),\r
+ variateurAnimationI(IntervalF(-0.3, 0.3), 0.0004)\r
+ {\r
+ this->ptrDomaineMathInit = new DomaineMath(-1.7, -1.4, 1.7, 1.4);\r
+ }\r
+\r
+void FractalJulia::animationStep()\r
+ {\r
+ this->z_r = this->variateurAnimationR.varierAndGet();\r
+ this->z_i = this->variateurAnimationI.varierAndGet();\r
+ }\r
+\r
+vector<string> FractalJulia::getNames()\r
+ {\r
+ vector<string> name;\r
+ name.push_back("z_r = ");\r
+ name.push_back("z_i = ");\r
+ return name;\r
+ }\r
+\r
+void FractalJulia::getValues(float* values)\r
+ {\r
+ values[0] = this->z_r;\r
+ values[1] = this->z_i;\r
+ }\r
+\r
+string FractalJulia::getTitle()\r
+ {\r
+ return "Fractal Julia";\r
+ }\r
+\r
+void FractalJulia::runGPU(uchar4* ptrDevPixels, const DomaineMath& domaineMath)\r
+ {\r
+ fractalJulia<<<dg,db>>>(ptrDevPixels, this->w, this->h, domaineMath, this->n, this->z_r, this->z_i);\r
+ }\r
\r