X-Git-Url: http://git.euphorik.ch/?a=blobdiff_plain;ds=sidebyside;f=WCudaMSE%2FStudent_Cuda_Image%2Fsrc%2Fcpp%2Fcore%2F02_Mandelbrot_Julia%2Fmoo%2Fhost%2FFractal.cu;h=92280002291cf66835fc1da41968959f794755ec;hb=4182eb3a07b7143afb8ebebfe77e8ef8e8abc266;hp=a92b86b6320a2ada62b11756d9a71b37437d38ae;hpb=7798b7c27cf13aaeada22faae8648df8cb339f1b;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 a92b86b..9228000 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,53 +1,20 @@ -#include -#include - #include "Fractal.h" -#include "Device.h" - -using std::cout; -using std::endl; - -/*----------------------------------------------------------------------*\ - |* Declaration *| - \*---------------------------------------------------------------------*/ - -/*--------------------------------------*\ - |* Imported *| - \*-------------------------------------*/ - -extern __global__ void fractal(uchar4* ptrDevPixels, int w, int h, DomaineMath domaineMath, int n, float t); - -/*--------------------------------------*\ - |* Public *| - \*-------------------------------------*/ -/*--------------------------------------*\ - |* Private *| - \*-------------------------------------*/ - -/*----------------------------------------------------------------------*\ - |* Implementation *| - \*---------------------------------------------------------------------*/ +#include +#include +#include +using namespace std; -/*--------------------------------------*\ - |* Public *| - \*-------------------------------------*/ +#include -/*-------------------------*\ - |* Constructeur *| - \*-------------------------*/ +#include "FractalDevice.h" +#include "Device.h" -Fractal::Fractal(int w, int h, float dt, int n) - : w(w), h(h), n(n), - dg(8, 8, 1), - db(16, 16, 1), - t(0), - variateurAnimation(IntervalF(0, 2 * PI), dt), - ptrDomaineMathInit(new DomaineMath(-2, -1.3, 0.8, 1.3)), - title("Fractal Cuda") +Fractal::Fractal(int w, int h) : + w(w), h(h), + dg(8, 8, 1), + db(16, 16, 1) { - assert(w == h); - //print(dg, db); Device::assertDim(dg, db); } @@ -57,73 +24,169 @@ Fractal::~Fractal() delete this->ptrDomaineMathInit; } -/*-------------------------*\ - |* Methode *| - \*-------------------------*/ - /** * Override */ -void Fractal::runGPU(uchar4* ptrDevPixels, const DomaineMath& domaineMath) +int Fractal::getW() { - fractal<<>>(ptrDevPixels, this->w, this->h, domaineMath, this->n, this->t); + return this->w; } /** * Override */ -void Fractal::animationStep() +int Fractal::getH() { - this->t = this->variateurAnimation.varierAndGet(); + return this->h; } -/*--------------*\ - |* get *| - \*--------------*/ +DomaineMath* Fractal::getDomaineMathInit() + { + return this->ptrDomaineMathInit; + } +///// -/** - * Override - */ -int Fractal::getW() +FractalMandelbrot::FractalMandelbrot(int w, int h, int dn, bool multiGPU) : + Fractal(w, h), + variateurAnimationN(IntervalI(10, 100), dn), + n(0), + multiGPU(multiGPU) { - return this->w; + // 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)); + } } -/** - * Override - */ -int Fractal::getH() +FractalMandelbrot::~FractalMandelbrot() { - return this->h; + if (this->multiGPU) + { + const int nbDevice = Device::getDeviceCount(); + + for (int i = 0; i < nbDevice - 1; ++i) + { + HANDLE_ERROR(cudaSetDevice(i + 1)); + HANDLE_ERROR(cudaFree(this->ptrDevPixelsMultGPU[i])); + } + + HANDLE_ERROR(cudaSetDevice(0)); + delete[] this->ptrDevPixelsMultGPU; + } + + cout << "OKOKOKOK" << endl; } -DomaineMath* Fractal::getDomaineMathInit() +void FractalMandelbrot::animationStep() { - return this->ptrDomaineMathInit; + this->n = this->variateurAnimationN.varierAndGet(); } -/** - * Override - */ -float Fractal::getT() +vector FractalMandelbrot::getNames() { - return this->t; + vector name; + name.push_back("n = "); + return name; } -/** - * Override - */ -string Fractal::getTitle() +void FractalMandelbrot::getValues(float* values) + { + values[0] = float(this->n); + } + +string FractalMandelbrot::getTitle() { return this->title; } -/*--------------------------------------*\ - |* Private *| - \*-------------------------------------*/ +void FractalMandelbrot::runGPU(uchar4* ptrDevPixels, const DomaineMath& domaineMath) + { + + 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); + } + } + +///// -/*----------------------------------------------------------------------*\ - |* End *| - \*---------------------------------------------------------------------*/ +FractalJulia::FractalJulia(int w, int h, int n, float z_r_min, float z_r_max, float z_i_min, float z_i_max) : + Fractal(w, h), + n(n), + z_r(z_r_min), + z_i(z_i_min), + variateurAnimationR(IntervalF(-0.8, -0.7), 0.0005), + variateurAnimationI(IntervalF(-0.3, 0.3), 0.0004) + { + this->ptrDomaineMathInit = new DomaineMath(-1.7, -1.4, 1.7, 1.4); + } + +void FractalJulia::animationStep() + { + this->z_r = this->variateurAnimationR.varierAndGet(); + this->z_i = this->variateurAnimationI.varierAndGet(); + } + +vector FractalJulia::getNames() + { + vector name; + name.push_back("z_r = "); + name.push_back("z_i = "); + return name; + } + +void FractalJulia::getValues(float* values) + { + values[0] = this->z_r; + 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); + }