X-Git-Url: http://git.euphorik.ch/index.cgi?a=blobdiff_plain;f=WCudaMSE%2FStudent_Cuda_Image%2Fsrc%2Fcpp%2Fcore%2F02_Mandelbrot_Julia%2Fmoo%2Fhost%2FFractal.cu;h=67c8b74734c00c35b7faf8b53b0ff1189a7cf442;hb=fd0031be0a39a5d902750affaff6322fcd5229b1;hp=bfaff4bd9f6fc9080e8266c349b8a4bfe7e59707;hpb=2fd5d915e8a9de4d957d6031d2d68088784eac3c;p=GPU.git diff --git a/WCudaMSE/Student_Cuda_Image/src/cpp/core/02_Mandelbrot_Julia/moo/host/Fractal.cu b/WCudaMSE/Student_Cuda_Image/src/cpp/core/02_Mandelbrot_Julia/moo/host/Fractal.cu index bfaff4b..67c8b74 100755 --- a/WCudaMSE/Student_Cuda_Image/src/cpp/core/02_Mandelbrot_Julia/moo/host/Fractal.cu +++ b/WCudaMSE/Student_Cuda_Image/src/cpp/core/02_Mandelbrot_Julia/moo/host/Fractal.cu @@ -1,17 +1,19 @@ #include "Fractal.h" #include +#include #include using namespace std; +#include + #include "FractalDevice.h" #include "Device.h" Fractal::Fractal(int w, int h) : w(w), h(h), dg(8, 8, 1), - db(16, 16, 1), - title("Fractal Cuda") + db(16, 16, 1) { //print(dg, db); Device::assertDim(dg, db); @@ -43,22 +45,38 @@ DomaineMath* Fractal::getDomaineMathInit() return this->ptrDomaineMathInit; } -/** - * Override - */ -string Fractal::getTitle() - { - return this->title; - } - ///// -FractalMandelbrot::FractalMandelbrot(int w, int h, int dn) : +FractalMandelbrot::FractalMandelbrot(int w, int h, int dn, bool multiGPU) : Fractal(w, h), variateurAnimationN(IntervalI(10, 100), dn), - n(0) + n(0), + multiGPU(multiGPU) { + // Constuit le titre dynamiquement. + ostringstream titleStream; + titleStream << "Fractal Mandelbrot (multi-GPU " << (this->multiGPU ? "activated" : "not activated") << ")"; + this->title = titleStream.str(); + this->ptrDomaineMathInit = new DomaineMath(-2, -1.3, 0.8, 1.3); + + if (this->multiGPU) + { + const int nbDevice = Device::getDeviceCount(); + + this->hDevices = h / nbDevice; + this->hFirstDevice = h - ((nbDevice - 1) * this->hDevices); + + // Allocation de la mémoire sur chaque GPU (sauf le premier pour lequel 'ptrDevPixels' est automatiquement alloué à l'appel de 'runGPU(..)'). + this->ptrDevPixelsMultGPU = new uchar4*[nbDevice - 1]; + for (int i = 0; i < nbDevice - 1; ++i) + { + HANDLE_ERROR(cudaSetDevice(i + 1)); + HANDLE_ERROR(cudaMalloc(&this->ptrDevPixelsMultGPU[i], sizeof(uchar4) * w * this->hDevices)); + } + + HANDLE_ERROR(cudaSetDevice(0)); + } } void FractalMandelbrot::animationStep() @@ -78,9 +96,36 @@ void FractalMandelbrot::getValues(float* values) values[0] = float(this->n); } +string FractalMandelbrot::getTitle() + { + return this->title; + } + void FractalMandelbrot::runGPU(uchar4* ptrDevPixels, const DomaineMath& domaineMath) { - fractalMandelbrot<<>>(ptrDevPixels, this->w, this->h, domaineMath, static_cast(this->n)); + + if (this->multiGPU) + { + HANDLE_ERROR(cudaSetDevice(0)); + fractalMandelbrot<<>>(ptrDevPixels, this->w, 0, this->hFirstDevice, domaineMath, this->n); + + const int nbDevice = Device::getDeviceCount(); + + // Rend chaque tranche par un GPU différent puis copie chaque tranche dans la mémoire du premier GPU. + #pragma omp parallel for + for (int i = 0; i < nbDevice - 1; ++i) + { + HANDLE_ERROR(cudaSetDevice(i + 1)); + fractalMandelbrot<<>>(this->ptrDevPixelsMultGPU[i], this->w, i * this->hDevices + this->hFirstDevice, (i + 1) * this->hDevices + this->hFirstDevice, domaineMath, this->n); + HANDLE_ERROR(cudaMemcpy(ptrDevPixels + this->w * this->hFirstDevice + i * this->w * this->hDevices, this->ptrDevPixelsMultGPU[i], sizeof(uchar4) * this->w * this->hDevices, cudaMemcpyDeviceToDevice)); + } + + HANDLE_ERROR(cudaSetDevice(0)); + } + else + { + fractalMandelbrot<<>>(ptrDevPixels, this->w, 0, this->h, domaineMath, this->n); + } } ///// @@ -116,6 +161,11 @@ void FractalJulia::getValues(float* values) values[1] = this->z_i; } +string FractalJulia::getTitle() + { + return "Fractal Julia"; + } + void FractalJulia::runGPU(uchar4* ptrDevPixels, const DomaineMath& domaineMath) { fractalJulia<<>>(ptrDevPixels, this->w, this->h, domaineMath, this->n, this->z_r, this->z_i);