chore: init

This commit is contained in:
2025-09-19 15:36:37 +02:00
commit 9d707a253a
2190 changed files with 17598 additions and 0 deletions

View File

@@ -0,0 +1,55 @@
#include "Thread2D.cu.h"
#include "Thread1D.cu.h"
#include "cudas.h"
#include <stdio.h>
/*----------------------------------------------------------------------*\
|* Private *|
\*---------------------------------------------------------------------*/
static __device__ float f(float x);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/**
* <pre>
* Chaque thread effectue une reduction intrathread avec le patern d'entrelacement,
* puis stocke son resultat dans SA case dans tabGM
*
* tabGM est un tableau promu, qui a autant de case que de thread
* </pre>
*/
__global__ void reductionIntraThreadGMHOST(float* tabGM , int nbSlice)
{
const int NB_THREAD = Thread2D::nbThread();
const int TID = Thread2D::tid();
// TODO SliceGMHOST
// Conseils :
//
// (C1) Ne calculer pas en double cote device, mais tout en float.
// En particulier, on ecrira 4.0f et non 4 (meme si ici le compilateur va l'optimiser a notre place, mais c'est bien de la faire par principe)
//
// (C2) Effectuez plutot le fois DX de l'aire du slice une seule fois par Thread, que pour chaque slice,
// ou qu'une seule fois cote host (debordement de type float cote device, car on ne fait que sommer?)
}
/*--------------------------------------*\
|* Private *|
\*-------------------------------------*/
__device__ float f(float x)
{
// TODO SliceGMHOST
return -1;
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,95 @@
#include "SliceGMHOST.h"
#include <iostream>
#include <assert.h>
#include "GM.h"
#include "Maths.h"
#include "Hardware.h"
#include "Kernel.h"
using std::cout;
using std::endl;
using std::to_string;
/*--------------------------------------*\
|* Imported *|
\*-------------------------------------*/
extern __global__ void reductionIntraThreadGMHOST(float* tabGM,int nbSlice);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*--------------------------------------*\
|* Constructeur *|
\*-------------------------------------*/
SliceGMHOST::SliceGMHOST(Grid grid , int nbSlice , double* ptrPiHat , bool isVerbose) :
RunnableGPU(grid, "SliceGM_HOST_" + to_string(nbSlice), isVerbose), // classe parente
//
nbSlice(nbSlice), //
ptrPiHat(ptrPiHat) //
{
this->nTabGM = -1; // TODO SliceGMHOST // le nombre de case de tabGM. Indication : grid.threadCounts() donne le nombre de thread ed la grille
this->sizeTabGM = -1; // TODO SliceGMHOST // la taille en octet de tabGM [octet]
// TODO SliceGMHOST
}
SliceGMHOST::~SliceGMHOST(void)
{
// TODO SliceGMHOST
}
/*--------------------------------------*\
|* Methode *|
\*-------------------------------------*/
/**
* <pre>
* Idea globale
*
* Etape 0 : Promotion d'un tableau en GM (MemoryManagement MM) (Dans le constructeur)
* Etape 1 : Reduction intra-thread dans un tableau promu en GM
* Etape 2 : Copy du tableau coter host
* Etape 3 : Reduction du tableau coter host
* Etape 4 : Destruction GM (Dans le destructeur)
*
* </pre>
*/
void SliceGMHOST::run()
{
// TODO SliceGMHOST // call the kernel
// Indication:
// dg et db sont stokcer dans la classe parente
// vous pouvez les utiliser directement
// exemple : reductionIntraThreadGMHOST<<<dg,db>>>(...)
reductionHost();
}
/*--------------------------------------*\
|* Private *|
\*-------------------------------------*/
/**
* Reduction paralle sur cpu du tableau promu en GM, ramener coter host
*/
void SliceGMHOST::reductionHost()
{
// 1) Creer un tableau de bonne dimension (sur la pile, possible ssi petit, sinon sur la tas)
// 2) Transferer la tabGM dedans
// 3) Reduction sequentiel cote host
// 4) Finalisation du calcul de ptrPiHat
// TODO SliceGMHOST
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,71 @@
#pragma once
#include "cudas.h"
#include "Grid.h"
#include "RunnableGPU.h"
#include "SliceGMHost_BestGrid.h"
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
/**
* On passse la grille à SliceGM pour pouvoir facilement la faire varier de l'extérieur pour trouver l'optimum, ou faire des tests avec des grilles différentes
*/
class SliceGMHOST: public RunnableGPU
{
/*--------------------------------------*\
|* Constructor *|
\*-------------------------------------*/
public:
/**
* update piHat
* Hyp : nbThread est une puissance de 2
*/
SliceGMHOST(Grid grid, int nbSlice , double* ptrPiHat , bool isVerbose=true);
virtual ~SliceGMHOST();
/*--------------------------------------*\
|* Methodes *|
\*-------------------------------------*/
public:
/**
* override
*/
virtual void run();
private:
void reductionHost();
/*--------------------------------------*\
|* Attributs *|
\*-------------------------------------*/
private:
// Inputs
int nbSlice;
// Inputs/Outputs
double* ptrPiHat;
// Tools
float* tabGM; // promotion de tabeau en GM (GM = Global Memory du Device).
// On devrait presque l'appeler ptrDevTabGM, mais un tableau est deja un pointeur (sur la premiere case)
// et GM et est la global memory du device
// Terminologie: on enleve ptrDev, car redondant!
size_t sizeTabGM; // [octet]
int nTabGM;
};
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,40 @@
#pragma once
#include <iostream>
#include <assert.h>
#include "Grid.h"
#include "Hardware.h"
#include "Couts.h"
/*----------------------------------------------------------------------*\
|* Impelmentation *|
\*---------------------------------------------------------------------*/
namespace sliceGMHost
{
class BestGrid
{
public:
static Grid get()
{
const int MP = Hardware::getMPCount();
// TODO SliceGMHOST grid
// to remove once coded
{
Couts::redln("aie aie aie, your best grid won t build itself");
assert(false);
}
}
};
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,57 @@
#include "Thread2D.cu.h"
#include "Thread1D.cu.h"
#include "cudas.h"
#include <stdio.h>
/*----------------------------------------------------------------------*\
|* Private *|
\*---------------------------------------------------------------------*/
static __device__ float f(float x);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/**
* <pre>
* Chaque thread effecteur une reduction intrathread avec le patern d'entrelacement,
* puis stocke son résultat dans SA case dans tabGM
*
* tabGM est un tableau promu, qui a autant de case que de thread
* </pre>
*/
__global__ void reductionIntraThreadGM(float* tabGM , int nbSlice)
{
// TODO SliceGM (idem SliceGMHOST) pour cette partie
}
/**
* <pre>
* Effectue la reduction de tabGM cote device, par ecrasement 2 à 2 successif.
* Ce kernel d ecrasement est appeler depuis le host dans une boucle, avec le bon nombre de thread
*
* Hypothese : |tabGM| est une puissance de 2
*
* Output: le resultat de la reduction est tans tabGM[0]
* </pre>
*/
__global__ void ecrasementGM(float* tabGM , int moitier)
{
// TODO SliceGM
}
/*--------------------------------------*\
|* Private *|
\*-------------------------------------*/
__device__ float f(float x)
{
return 4.f / (1.f + x * x);
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,96 @@
#include "SliceGM.h"
#include <iostream>
#include <assert.h>
#include "GM.h"
#include "Maths.h"
#include "Hardware.h"
#include "Kernel.h"
using std::cout;
using std::endl;
using std::to_string;
/*----------------------------------------------------------------------*\
|* Imported *|
\*---------------------------------------------------------------------*/
extern __global__ void reductionIntraThreadGM(float* tabGM,int nbSlice);
extern __global__ void ecrasementGM(float* tabGM, int moitier);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*--------------------------------------*\
|* Constructeur *|
\*-------------------------------------*/
SliceGM::SliceGM(Grid grid , int nbSlice , double* ptrPiHat , bool isVerbose) :
RunnableGPU(grid, "SliceGM_" + to_string(nbSlice), isVerbose), // classe parente
//
nbSlice(nbSlice), //
ptrPiHat(ptrPiHat) //
{
this->nTabGM = -1; // TODO SliceGM
this->sizeTabGM = -1; // TODO SliceGM // [octet]
}
SliceGM::~SliceGM(void)
{
// TODO SliceGM
}
/*--------------------------------------*\
|* Methode *|
\*-------------------------------------*/
/**
* <pre>
* Idea globale
*
* Etape 0 : Promotion d'un tableau en GM (MemoryManagement MM)
* Etape 1 : Reduction intra-thread dans un tableau promu en GM
* Etape 2 : Reduction du tableau en GM par ecrasement hierarchique 2 à 2
* On lance les kernels d'ecrasement depuis le host (chef d'orchestre)
* Etape 4 : Copy du resultat coter host
* Etape 5 : Destruction GM
* </pre>
*/
void SliceGM::run()
{
//TODO SliceGM // call the kernel (asynchrone)
reductionGM();
}
/*--------------------------------------*\
|* Private *|
\*-------------------------------------*/
/**
* Etape 1 : Lancement des kernels d'ecrasement depuis le host, dans une boucle,
* Etape 2 : recuperer le resultat coter host
* Etape 3 : finaliser le calcule de PI
*/
void SliceGM::reductionGM()
{
int midle = nTabGM >> 1; // nTabGM/2;
// TODO SliceGM
// Warning: Utiliser une autre grille que celle heriter de la classe parente dg, db
// Votre grid ici doit avoir une taille speciale!
// N'utiliser donc pas les variables dg et db de la classe parentes
// Tip: Il y a une methode dedier pour ramener un float cote host
//
// float resultat;
// GM::memcpyDToH_float(&resultat,ptrResultGM);
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,63 @@
#pragma once
#include "cudas.h"
#include "Grid.h"
#include "RunnableGPU.h"
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
class SliceGM: public RunnableGPU
{
/*--------------------------------------*\
|* Constructor *|
\*-------------------------------------*/
public:
/**
* update piHat
* Hyp : nbThread est une puissance de 2
*/
SliceGM(Grid grid , int nbSlice , double* ptrPiHat , bool isVerbose);
virtual ~SliceGM();
/*--------------------------------------*\
|* Methodes *|
\*-------------------------------------*/
public:
/**
* override
*/
virtual void run();
private:
void reductionGM();
/*--------------------------------------*\
|* Attributs *|
\*-------------------------------------*/
private:
// Inputs
int nbSlice;
// Inputs/Outputs
double* ptrPiHat;
// Tools
float* tabGM;
size_t sizeTabGM; // [octet]
int nTabGM;
};
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,46 @@
#pragma once
#include <iostream>
#include <assert.h>
#include "Grid.h"
#include "Hardware.h"
#include "Couts.h"
/*----------------------------------------------------------------------*\
|* Impelmentation *|
\*---------------------------------------------------------------------*/
namespace sliceGM
{
class BestGrid
{
public:
static Grid get()
{
const bool IS_CHECK_HEURISTIC = false;
const int MP = Hardware::getMPCount();
dim3 dg(1, 1, 1); // power 2 // TODO SliceGM grid
dim3 db(1, 1, 1); // power 2 // TODO SliceGM grid
Grid grid(dg, db, IS_CHECK_HEURISTIC); // all power 2
// to remove once coded
{
Couts::redln("aie aie aie, your best grid won t build itself");
assert(false);
}
return grid;
}
};
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,53 @@
#include "Thread2D.cu.h"
#include "Thread1D.cu.h"
#include "ReductionAdd.cu.h"
#include "cudas.h"
#include <stdio.h>
/*----------------------------------------------------------------------*\
|* Private *|
\*---------------------------------------------------------------------*/
static __device__ void reductionIntraThread(float* tabSM,int nbSlice);
static __device__ float f(float x);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
__global__ void sliceSM(int nbSlice , float* ptrPiHatGM)
{
// TODO SliceSM
// Reception tabSM
// ReductionIntraThread
// Reduction de tabSM (use tools ReductionAdd)
// __syncthreads(); necessaire? ou? pas a la fin en tout cas
}
/*--------------------------------------*\
|* Private *|
\*-------------------------------------*/
/**
* remplit la sm
*/
void reductionIntraThread(float* tabSM , int nbSlice)
{
// TODO SliceSM
// Warning: Il faut employer TID et TID_LOCAL
}
__device__ float f(float x)
{
return 4.f / (1.f + x * x);
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,95 @@
#include "SliceSM.h"
#include <iostream>
#include <assert.h>
#include "GM.h"
#include "SM.h"
using std::cout;
using std::endl;
using std::to_string;
/*----------------------------------------------------------------------*\
|* Imported *|
\*---------------------------------------------------------------------*/
extern __global__ void sliceSM(int nbSlice,float* ptrPiHatGM);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*--------------------------------------*\
|* Constructeur *|
\*-------------------------------------*/
SliceSM::SliceSM(const Grid& grid , int nbSlice , double* ptrPiHat , bool isVerbose) :
RunnableGPU(grid, "SliceSM_" + to_string(nbSlice), isVerbose), // classe parente
//
ptrPiHat(ptrPiHat), //
nbSlice(nbSlice) //
{
this->sizeSM = -1; //TODO SliceSM
// MM
{
// TODO SliceSM (pas oublier de mettre a zero, avec mallocfloat0 par exemple)
// Tip: Il y a une methode dedier pour malloquer un float cote device et l'initialiser a zero
//
// GM::mallocfloat0(&ptrPiHatGM);
}
}
SliceSM::~SliceSM(void)
{
//TODO SliceSM
}
/*--------------------------------------*\
|* Methode *|
\*-------------------------------------*/
void SliceSM::run()
{
// Etape 1 : lancer le kernel
// Etape 2 : recuperer le resultat coter host (par exemple avec memcpyDToH_float)
// Etape 3 : finaliser le calcul de PI
// Warning : ptrPiHat est un double, ptrPiHatGM un double, et un float de peux pas aller dans un double
// Solution : double result; // et ramener dans result, transferer et finaliser ensuite dans ptrPiHat
// TODO SliceSM
}
/////////////////////////
// Rappel:
////////////////////////
//
// (O2)
// La taille des tableau promu en SM doit etre une puissance de 2, pour pouvoir lancer les ecrasements
// Or tabSM a autant de cases qu il y a de threads èar blocks
// Et on aimerait bien respecter l'heuristique
//
// (H2) nbThreadByBlock % nbCoreByMp = 0
//
// Question :
//
// Peut on respecter la contrainte "puissance de 2" et l'heuristique (H2)?
//
// Reponse:
// Tout depend du nombre de core par MP, mais c'est souvent 32 ou 64 ou 128
// ie dans les 3 cas une puissance de 2, youpie
//
// Comme il y a max 1024 threads par block, il n'y a pas beaucoup de possibilites
//
// 1024 512 256 128 64 32
//
// Lors du forcebrute, il faut donc adapter les grilles a cette contrainte.
// Regarde a cet effet la methode sliceSM dans mainBruteforce.cpp
// et plus particulierement la methode bruteforceReduction utilisee.
//
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,58 @@
#pragma once
#include "cudas.h"
#include "Grid.h"
#include "RunnableGPU.h"
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
class SliceSM: public RunnableGPU
{
/*--------------------------------------*\
|* Constructor *|
\*-------------------------------------*/
public:
/**
* update piHat
* Hyp : nbThread est une puissance de 2
*/
SliceSM(const Grid& grid , int nbSlice , double* ptrPiHat , bool isVerbose);
virtual ~SliceSM(void);
/*--------------------------------------*\
|* Methodes *|
\*-------------------------------------*/
public:
/**
* override
*/
virtual void run();
/*--------------------------------------*\
|* Attributs *|
\*-------------------------------------*/
private:
// Inputs
int nbSlice;
// Inputs/Outputs
double* ptrPiHat;
// Tools
size_t sizeSM; // [octet]
float* ptrPiHatGM;
};
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,40 @@
#pragma once
#include <iostream>
#include <assert.h>
#include "Grid.h"
#include "Hardware.h"
#include "Couts.h"
/*----------------------------------------------------------------------*\
|* Impelmentation *|
\*---------------------------------------------------------------------*/
namespace sliceSM
{
class BestGrid
{
public:
static Grid get()
{
const int MP = Hardware::getMPCount();
// TODO SliceGMHOST grid
// to remove once coded
{
Couts::redln("aie aie aie, your best grid won t build itself");
assert(false);
}
}
};
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,156 @@
#include <stdio.h>
#include <curand_kernel.h>
#include "Thread1D.cu.h"
#include "cudas.h"
#include "entier_montecarlo.h"
#include "Lock.cu.h"
#include "ReductionAdd.cu.h"
#include "Reduction.cu.h"
using montecarlo::entier;
/*----------------------------------------------------------------------*\
|* Private *|
\*---------------------------------------------------------------------*/
__device__ static void reductionIntraThread(curandState* tabGeneratorGM , entier* tabSM , entier nbDarByThread , float h);
__device__ static float f(float x);
__device__ static long add(long x , long y);
__device__ static void addAtomic(long* ptrX , long y);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*-------------------*\
|* generateur alea *|
\*------------------*/
/**
* Each thread gets same seed, a different sequence number, no offset
* host side : Device::getDeviceId();
*/
__global__ void createGenerator(curandState* tabGeneratorGM , int deviceId)
{
// Customisation du generator:
// Proposition, au lecteur de faire mieux !
// Contrainte : Doit etre différent d'un GPU à l'autre
// Contrainte : Doit etre différent d'un thread à l'autre
const int TID = Thread1D::tid();
int deltaSeed = deviceId * INT_MAX / 10000;
int deltaSequence = deviceId * 100;
int deltaOffset = deviceId * 100;
int seed = 1234 + deltaSeed;
int sequenceNumber = TID + deltaSequence;
int offset = deltaOffset;
curand_init(seed, sequenceNumber, offset, &tabGeneratorGM[TID]);
}
/*-------------------*\
|* reduce *|
\*------------------*/
/**
* Chaque thread doit
* 1) tirer nbDarByThread et compter le nombre de dar sous la courbe
* 2) Le ranger sans sa case en tabSM
* Puis on reduit les tabSM
*/
__global__ void kmontecarlo(curandState* tabGeneratorGM , entier nbDarByThread , entier* ptrNbDarUnderGM , float h)
{
// TODO Montecarlo
// Reception tabSM
// reductionIntraThread
// reduction des tabSM
#ifdef DAR_INT
// TODO Montecarlo Utiliser le tools ReductionAdd
#endif
#ifdef DAR_LONG
// TODO Montecarlo Utiliser le tools Reduction
#endif
}
/*--------------------------------------*\
|* Private *|
\*-------------------------------------*/
__device__
void reductionIntraThread(curandState* tabGeneratorGM , entier* tabSM , entier nbDarByThread , float h)
{
const int TID = Thread1D::tid();
const int TID_LOCAL = Thread1D::tidLocal();
// Global Memory -> Register (optimization)
curandState generatorThread = tabGeneratorGM[TID];
entier nbDarUnderCurveThread = 0;
float xAlea01;
float yAlea0h;
int nbDar = nbDarByThread / 2;
for (entier i = 1; i <= nbDarByThread; ++i)
{
xAlea01 = curand_uniform(&generatorThread); // in [0,1[
yAlea0h = curand_uniform(&generatorThread) * h; // in [0,h[
// TODO Montecarlo
// mettre flechette dans cible
// compter nbDarUnderCurveThread
}
// TODO Montecarlo
// stocker resultat du thread dans tabSM
//Register -> Global Memory
//Necessaire si on veut utiliser notre generator
// - dans d'autre kernel
// - avec d'autres nombres aleatoires !
tabGeneratorGM[TID] = generatorThread;
}
__device__
float f(float x)
{
return 4.f / (1.f + x * x);
}
/*-------------------*\
|* reduce operator *|
\*------------------*/
__device__
long add(long x , long y)
{
// TODO Montecarlo
}
/**
* Utiliser la methode system : atomicAdd(pointeurDestination, valeurSource)
* ou la technique du lock si atomicAdd existe pas pour les long
*/
__device__
int volatile mutex = 0; //variable global
__device__
void addAtomic(long* ptrX , long y)
{
Lock locker(&mutex);
locker.lock();
// TODO Montecarlo
locker.unlock();
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,168 @@
#include "Montecarlo.h"
#include <iostream>
#include <assert.h>
#include <typeinfo>
#include <math.h>
#include "GM.h"
#include "Hardware.h"
#include "Stream.h"
using std::cout;
using std::endl;
using std::string;
using std::to_string;
using montecarlo::entier;
using montecarlo::entierToString;
/*----------------------------------------------------------------------*\
|* Imported *|
\*---------------------------------------------------------------------*/
extern __global__ void createGenerator(curandState* tabGeneratorGM,int deviceId);
extern __global__ void kmontecarlo(curandState* tabGeneratorGM, entier nbDarByThread, entier* ptrNbDarUnderGM, float h);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*--------------------------------------*\
|* Constructeur *|
\*-------------------------------------*/
Montecarlo::Montecarlo(const Grid& grid , entier nbDarTotalAsk , double* ptrPiHat , float h , bool isVerbose) :
RunnableGPU(grid, title(nbDarTotalAsk, h), isVerbose), // classe parente
//
nbDarTotalAsk(nbDarTotalAsk), //
ptrPiHat(ptrPiHat), //
h(h) //
{
const entier NB_THREAD = grid.threadCounts(); //directement en entier pour éviter un cast
// Math : Calculer le nombre de flechette effectivment tirer!
{
this->nbDarByThread = (nbDarTotalAsk / NB_THREAD);
this->nbDarTotalEffective = NB_THREAD * nbDarByThread;
assert(nbDarTotalAsk >= grid.threadCounts());
assert(nbDarByThread > 0); // si =0, trop de threads et pas assez de dar!
}
// MM
{
this->sizeNbDarUnderGM = -1; // [octet]
// TODO Montecarlo NbDarUnderGM (pas oublier de mettre a zero, avec un malloc0 par exemple)
this->sizeSM = -1; // [octet]
}
// init : lancer le kernel de creation des generators
{
size_t sizeTabDevGeneratorGM = -1; // TODO Montecarlo
// TODO Montecarlo pou tabDevGeneratorGM
// TODO Montecarlo lancer le kernel createGenerator
int deviceId = Hardware::getDeviceId();
}
}
Montecarlo::~Montecarlo(void)
{
// TODO Montecarlo
}
/*--------------------------------------*\
|* Methode *|
\*-------------------------------------*/
/**
* Lancer kernel
* Recuperer resultat coter host
* Finaliser le calcul de pi
*/
void Montecarlo::run()
{
// Version : mono pure
{
// TODO Montecarlo
}
// Version : compatible with multiGPU, stream-version
{
// rien pour version mono pure
// puis des la version MontecarloMulti-stream
// commenter la version ci-dessus, et utiliser :
// - kernel_async
// - DtoH_async
// - Stream::synchronize(0);
// Valider cette npuvelle version, d'abord en reexecutamt une Montecarlo(Mono)
// TODO Montecarlo MontecarloMulti-stream
}
// calcule de Math
// TODO Montecarlo
}
/*----------------------*\
|* helper multiGPU *|
\*---------------------*/
/**
* usefull for multiGPU, stream version
* assynchrone
*/
void Montecarlo::kernel_async(cudaStream_t cudaStream)
{
kmontecarlo<<<dg, db, sizeSM,cudaStream>>>(tabDevGeneratorGM, nbDarByThread, ptrNbDarUnderGM, h);
}
/**
* usefull for multiGPU, stream version
* assynchrone
*/
void Montecarlo::DtoH_async(cudaStream_t cudaStream)
{
GM::memcpyAsyncDToH(&nbDarUnderCurve, ptrNbDarUnderGM, sizeNbDarUnderGM, cudaStream);
}
/*----------------*\
|* get *|
\*---------------*/
entier Montecarlo::getNbDarTotalEffective()
{
return nbDarTotalEffective;
}
entier Montecarlo::getNbDarUnderCurve()
{
return nbDarUnderCurve;
}
double Montecarlo::getInputGO()
{
return (nbDarTotalEffective / (double)1024 / (double)1024 / (double)1024) * sizeof(float) * 2;
}
/*----------------*\
|* private *|
\*---------------*/
/**
* static
*/
string Montecarlo::title(entier nbDarTotalAsk , float h)
{
return "Montecarlo_" + entierToString() + "_" + to_string(nbDarTotalAsk) + "_h" + to_string((int)h);
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,103 @@
#pragma once
#include <curand_kernel.h>
#include "cudas.h"
#include "Grid.h"
#include "RunnableGPU.h"
#include "entier_montecarlo.h"
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
class Montecarlo: public RunnableGPU
{
/*--------------------------------------*\
|* Constructor *|
\*-------------------------------------*/
public:
/**
* Hyp : db power 2
*/
Montecarlo(const Grid& grid , montecarlo::entier nbDarTotalAsk , double* ptrPiHat , float h , bool isVerbose);
virtual ~Montecarlo(void);
/*--------------------------------------*\
|* Methodes *|
\*-------------------------------------*/
public:
/**
* override
*/
virtual void run();
/**
* override
*/
virtual double getInputGO();
/**
* #dar effectivement tirer, !=nbDarTotalAsk car division entiere
*/
montecarlo::entier getNbDarTotalEffective();
montecarlo::entier getNbDarUnderCurve();
/*----------------------*\
|* helper multiGPU-stream*|
\*---------------------*/
/**
* usefull for multiGPU, stream version
* assynchrone
*/
void kernel_async(cudaStream_t cudaStream = 0);
/**
* usefull for multiGPU, stream version
* assynchrone
*/
void DtoH_async(cudaStream_t cudaStream = 0);
private:
static std::string title(montecarlo::entier nbDarTotalAsk , float h);
/*--------------------------------------*\
|* Attributs *|
\*-------------------------------------*/
private:
// Inputs
montecarlo::entier nbDarTotalAsk;
float h; // hauteur de la cible
// Inputs/Outputs
double* ptrPiHat;
// Outputs
montecarlo::entier nbDarTotalEffective;
montecarlo::entier nbDarUnderCurve;
// Tools
montecarlo::entier* ptrNbDarUnderGM;
size_t sizeNbDarUnderGM;
size_t sizeSM;
curandState* tabDevGeneratorGM;
montecarlo::entier nbDarByThread;
};
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,47 @@
#pragma once
#include <iostream>
#include <assert.h>
#include "Grid.h"
#include "Hardware.h"
#include "entier_montecarlo.h"
#include "Couts.h"
/*----------------------------------------------------------------------*\
|* Impelmentation *|
\*---------------------------------------------------------------------*/
namespace montecarlo
{
class BestGrid
{
public:
static Grid get()
{
const int MP = Hardware::getMPCount();
#ifdef DAR_INT
// TODO Montecarlo
#endif
#ifdef DAR_LONG
// TODO Montecarlo
#endif
// to remove once coded
{
Couts::redln("aie aie aie, your best grid won t build itself");
assert(false);
}
}
};
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1 @@
Aucune partie device specifique, on utilise la classe Montecarlo, qui , elle, fait le job cote device

View File

@@ -0,0 +1,162 @@
#include "MontecarloMulti_thread.h"
#include <iostream>
#include <assert.h>
#include "Montecarlo.h"
#include "Hardware.h"
using std::cerr;
using std::cout;
using std::endl;
using std::string;
using std::to_string;
using montecarlo::entier;
using montecarlo::entierToString;
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/**
* static
*/
int MontecarloMulti_thread::NB_DEVICE = Hardware::getDeviceCount();
/*--------------------------------------*\
|* Constructeur *|
\*-------------------------------------*/
MontecarloMulti_thread::MontecarloMulti_thread(const Grid& grid , entier nbDarTotalAsk , double* ptrPiHat , float h , bool isVerbose) :
RunnableGPU(grid, title(nbDarTotalAsk, h), isVerbose), // classe parente
//
nbDarTotalAsk(nbDarTotalAsk), //
ptrPiHat(ptrPiHat), //
h(h), //
grid(grid)
{
this->nbDarByDevice = -1; // TODO Montecarlo Multi-thread
assert(nbDarByDevice >= grid.threadCounts());
// warning
{
// TODO MontecarloMulti : Charger les drivers de tous les gpus avec:
//
// Hardware::loadCudaDriverAll();
//
// sinon votre code multi gpu sera sequentiel!
// Le mieux est de faire ca dans main.cpp avec la directive
//
// DeviceDriver::LOAD_ALL;
}
}
MontecarloMulti_thread::~MontecarloMulti_thread()
{
// rien
}
/*--------------------------------------*\
|* Methode *|
\*-------------------------------------*/
void MontecarloMulti_thread::run()
{
const int DEVICE_ID_ORIGINAL = Hardware::getDeviceId();
this->nbDarTotalEffective = 0;
entier nbDarUnderCurve = 0;
// paraleliser la boucle avec OpenMP (regarder le dernier exemple o8 OMP de slice,)
for (int deviceID = 0; deviceID < NB_DEVICE; ++deviceID)
{
// TODO MontecarloMulti-thread : utiliser Montecarlo
// Version parallel:
//
// (P1) Il y a deux reductions à faire:
// nbDarTotalEffective
// nbDarUnderCurve
//
// (P2) Utiliser une section critique! C'est pas cher, pas beaucoup de GPU, pas beaucoup de threads host-side!
//
// #pragma omp critical(blabla)
// {
// ...
// }
}
// TODO MontecarloMulti-thread
// calculer piHat avec nbDarTotalEffective et nbDarUnderCurve
*this->ptrPiHat = -1;
Hardware::setDevice(DEVICE_ID_ORIGINAL); // on restore le device d'origine
// Truc:
//
// Faite fonctionner ce code multiGPU d'abord "sequentiel", Device after Device, puis seulement ensuite tous les GPU en paralell
// Utiliser en ligne de commande
//
// nvidia-smi --loop=1
//
// pour voir le 100% d'utilisation du device, changer de device en device dans le cas sequentiel, puis voir un 100% simultaner sur tous les devices en meme temps
// Tirer assez de flechette (cas long) pour avoir le temps de monitorer (cf entier.h du to Montecarlo).
//
// Une fois l'observation terminer, kitter nvidia-smi (CTRL-C)
//
// Observation:
//
// (O1) En int, les performances ne sont pas a la hauteur des esperances
// Pire, c est meme parfois moins bon qu en mono gpu
//
// (O2) En long, les performances sont a la hauteur des espoirs.
// ie environ NB_DEVICE plus rapide que la version mono GPU
//
// Explication:
//
// En int, les kernels sont tres courts. La creation des threads cote host coute trop cher!
// En long, la creation des threads n est pas plus rapide, mais ce temps de creation devient negligeable par rapport a la durre des kernels
//
// Conseil:
//
// Realiser la version avec les streams au lieu des threads.
// En int, comme en long, les performances seront au top!
// C est a peine plus difficile que les threads!
}
/*----------------*\
|* get *|
\*---------------*/
entier MontecarloMulti_thread::getNbDarTotalEffective()
{
return nbDarTotalEffective;
}
double MontecarloMulti_thread::getInputGO()
{
return (nbDarTotalEffective / (double)1024 / (double)1024 / (double)1024) * sizeof(float) * 2;
}
/*----------------*\
|* set *|
\*---------------*/
void MontecarloMulti_thread::setH(float h)
{
this->h = h;
}
/*----------------*\
|* private *|
\*---------------*/
string MontecarloMulti_thread::title(entier nbDarTotalAsk , float h)
{
return "Montecarlo_" + entierToString() + "_thread_" + to_string(nbDarTotalAsk) + "_h" + to_string((int)h);
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,87 @@
#pragma once
#include <curand_kernel.h>
#include "cudas.h"
#include "Grid.h"
#include "RunnableGPU.h"
#include "Montecarlo.h"
#include "entier_montecarlo.h"
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
class MontecarloMulti_thread: public RunnableGPU
{
/*--------------------------------------*\
|* Constructor *|
\*-------------------------------------*/
public:
/**
* update piHat
* Hyp : nbThread est une puissance de 2
*/
MontecarloMulti_thread(const Grid& grid , montecarlo::entier nbDarTotalAsk , double* ptrPiHat , float h , bool isVerbose);
virtual ~MontecarloMulti_thread(void);
/*--------------------------------------*\
|* Methodes *|
\*-------------------------------------*/
public:
/**
* override
*/
virtual void run();
/**
* override
*/
virtual double getInputGO();
/**
* #dar effectivement tirer
*/
montecarlo::entier getNbDarTotalEffective();
void setH(float h);
private:
std::string title(montecarlo::entier nbDarTotalAsk , float h);
/*--------------------------------------*\
|* Attributs *|
\*-------------------------------------*/
private:
// Inputs
montecarlo::entier nbDarTotalAsk;
float h;
// Inputs/Outputs
double* ptrPiHat;
// Tools
montecarlo::entier nbDarTotalEffective;
montecarlo::entier nbDarByDevice;
Grid grid;
//Montecarlo** tabPtrMontecarlo;
static int NB_DEVICE;
};
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,173 @@
#include "MontecarloMulti_stream.h"
#include <iostream>
#include <assert.h>
#include "Montecarlo.h"
#include "Hardware.h"
#include "Stream.h"
using std::cerr;
using std::cout;
using std::endl;
using std::string;
using std::to_string;
using montecarlo::entier;
using montecarlo::entierToString;
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/**
* static
*/
int MontecarloMulti_stream::NB_DEVICE = Hardware::getDeviceCount();
/*--------------------------------------*\
|* Constructeur *|
\*-------------------------------------*/
MontecarloMulti_stream::MontecarloMulti_stream(const Grid& grid , entier nbDarTotalAsk , double* ptrPiHat , float h , bool isVerbose) :
RunnableGPU(grid, title(nbDarTotalAsk, h), isVerbose), // classe parente
//
nbDarTotalAsk(nbDarTotalAsk), //
ptrPiHat(ptrPiHat), //
h(h), //
grid(grid)
{
this->nbDarByDevice = nbDarTotalAsk / NB_DEVICE;
assert(nbDarByDevice >= grid.threadCounts());
this->tabStream = new cudaStream_t[NB_DEVICE];
this->tabMontecarlo = new Montecarlo*[NB_DEVICE];
const int DEVICE_ID_ORIGINAL = Hardware::getDeviceId();
for (int deviceID = 0; deviceID < NB_DEVICE; deviceID++)
{
// obligatoire de creer stream sur bon device
// obligatoire de crere Montecarlo sur bon device, car Montecarlo fait du MM
Hardware::setDevice(deviceID);
Stream::create(&tabStream[deviceID]);
tabMontecarlo[deviceID] = new Montecarlo(grid, nbDarByDevice, ptrPiHat, h, isVerbose);
}
Hardware::setDevice(DEVICE_ID_ORIGINAL); // restore deviceID
}
MontecarloMulti_stream::~MontecarloMulti_stream()
{
const int DEVICE_ID_ORIGINAL = Hardware::getDeviceId();
for (int deviceID = 0; deviceID < NB_DEVICE; deviceID++)
{
Hardware::setDevice(deviceID); // facultatif pour delele Montecarlo et destroy stream
delete tabMontecarlo[deviceID];
Stream::destroy(tabStream[deviceID]);
}
// tableaux
{
delete[] tabStream;
delete[] tabMontecarlo;
}
Hardware::setDevice(DEVICE_ID_ORIGINAL); // restore deviceID
}
/*--------------------------------------*\
|* Methode *|
\*-------------------------------------*/
void MontecarloMulti_stream::run()
{
const int DEVICE_ID_ORIGINAL = Hardware::getDeviceId();
for (int deviceID = 0; deviceID < NB_DEVICE; deviceID++)
{
// recuperation:
Montecarlo* ptrMontecarlo = tabMontecarlo[deviceID];
cudaStream_t stream = tabStream[deviceID];
// TODO MontecarloMulti-stream
// Appeler sur le bon device kernel_async de montecarlo mono
}
for (int deviceID = 0; deviceID < NB_DEVICE; deviceID++)
{
// recuperation:
Montecarlo* ptrMontecarlo = tabMontecarlo[deviceID];
cudaStream_t stream = tabStream[deviceID];
// TODO MontecarloMulti-stream
// Appeler sur le bon device DtoH_async de montecarlo mono
}
for (int deviceID = 0; deviceID < NB_DEVICE; deviceID++)
{
// TODO MontecarloMulti-stream
// synchroniser chacune des streams (Stream:: ...)
}
Hardware::setDevice(DEVICE_ID_ORIGINAL); // restore deviceID
// host consolidation
{
this->nbDarTotalEffective = 0;
entier nbDarUnderCurve = 0;
for (int deviceID = 0; deviceID < NB_DEVICE; deviceID++)
{
// TODO MontecarloMulti-stream
// update nbDarUnderCurve
// update nbDarTotalEffective
}
*this->ptrPiHat = this->h * nbDarUnderCurve / this->nbDarTotalEffective;
}
}
/*----------------*\
|* get *|
\*---------------*/
entier MontecarloMulti_stream::getNbDarTotalEffective()
{
return nbDarTotalEffective;
}
double MontecarloMulti_stream::getInputGO()
{
return (nbDarTotalEffective / (double)1024 / (double)1024 / (double)1024) * sizeof(float) * 2;
}
/*----------------*\
|* set *|
\*---------------*/
void MontecarloMulti_stream::setH(float h)
{
this->h = h;
}
/*----------------*\
|* private *|
\*---------------*/
string MontecarloMulti_stream::title(entier nbDarTotalAsk , float h)
{
return "Montecarlo_" + entierToString() + "_stream_" + to_string(nbDarTotalAsk) + "_h" + to_string((int)h);
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,89 @@
#pragma once
#include <curand_kernel.h>
#include "cudas.h"
#include "Grid.h"
#include "entier_montecarlo.h"
#include "RunnableGPU.h"
#include "Montecarlo.h"
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
class MontecarloMulti_stream: public RunnableGPU
{
/*--------------------------------------*\
|* Constructor *|
\*-------------------------------------*/
public:
/**
* update piHat
* Hyp : nbThread est une puissance de 2
*/
MontecarloMulti_stream(const Grid& grid , montecarlo::entier nbDarTotalAsk , double* ptrPiHat , float h , bool isVerbose);
virtual ~MontecarloMulti_stream(void);
/*--------------------------------------*\
|* Methodes *|
\*-------------------------------------*/
public:
/**
* override
*/
virtual void run();
/**
* override
*/
virtual double getInputGO();
/**
* #dar effectivement tirer
*/
montecarlo::entier getNbDarTotalEffective();
void setH(float h);
private:
std::string title(montecarlo::entier nbDarTotalAsk , float h);
/*--------------------------------------*\
|* Attributs *|
\*-------------------------------------*/
private:
// Inputs
montecarlo::entier nbDarTotalAsk;
float h;
// Inputs/Outputs
double* ptrPiHat;
// Tools
montecarlo::entier nbDarTotalEffective;
montecarlo::entier nbDarByDevice;
Grid grid;
// Toosl : multigpu
cudaStream_t* tabStream;
Montecarlo** tabMontecarlo;
static int NB_DEVICE;
};
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,47 @@
#pragma once
#include <iostream>
#include <assert.h>
#include "Grid.h"
#include "Hardware.h"
#include "entier_montecarlo.h"
#include "Couts.h"
/*----------------------------------------------------------------------*\
|* Impelmentation *|
\*---------------------------------------------------------------------*/
namespace montecarloMulti
{
class BestGrid
{
public:
static Grid get()
{
const int MP = Hardware::getMPCount();
#ifdef DAR_INT
// TODO MontecarloMulti
#endif
#ifdef DAR_LONG
// TODO MontecarloMulti
#endif
// to remove once coded
{
Couts::redln("aie aie aie, your best grid won t build itself");
assert(false);
}
}
};
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,82 @@
#pragma once
#include <iostream>
#include <assert.h>
using std::cout;
using std::endl;
using std::string;
using std::to_string;
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*----------------------*\
|* public *|
\*----------------------*/
// Choose one of the two (either/or):
//#define DAR_INT
#define DAR_LONG
/*----------------------*\
|* private *|
\*----------------------*/
namespace montecarlo
{
#ifdef DAR_INT
using entier=int;
#endif
#ifdef DAR_LONG
using entier=long;
#endif
static inline std::string entierToString()
{
#ifdef DAR_INT
return "int";
#endif
#ifdef DAR_LONG
return "long";
#endif
assert(false); // ne devrait jamais arriver
return ""; // pour éviter warning
}
static inline bool isInt()
{
#ifdef DAR_INT
return true;
#endif
#ifdef DAR_LONG
return false;
#endif
assert(false); // ne devrait jamais arriver
return false;
}
static inline bool isLong()
{
#ifdef DAR_INT
return false;
#endif
#ifdef DAR_LONG
return true;
#endif
assert(false); // ne devrait jamais arriver
return false;
}
} // namespace montecarlo
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,210 @@
#include <iostream>
#include <math.h>
#include <assert.h>
#include "VectorTools.h"
#include "HM.h"
#include "Limits.h"
using std::cout;
using std::endl;
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/**
* Contrainte n % nbSlice = 0
*/
int VectorTools::n()
{
// Pour le warmup, activer la ligne requise ci-dessous:
// return nWarmup_3_slices();
//return nWarmup_4_slices();
//return nWarmup_5_slices();
// pour le cas generique,activer une des deux lignes ci-dessous:
return nGenerique1();
//return nGenerique2();
}
/**
* Exemple de possiblity pour le nombre de slice possible avec ce n :
*
* Exemple 1: #slice in [2,15]
* Exemple 2: #slice in [5,75] par pas de 5
*/
int VectorTools::nGenerique1()
{
const int N = 2 * 3 * 4 * 5 * 7 * 9 * 11 * 13 * 5; // apres trop grand
// 8 remove car 2*4
// 10 remove car 2*5
// 12 remove car 3*4
// 15 remove car 3*5
//check_nGenerique1(N);
return N;
}
/**
* Exemple de possiblity pour le nombre de slice possible avec ce n :
*
* Exemple 1: #slice 10 20 30 40 50
* Exemple 2 : #slice 10 100 1000 10000 20000 30000 40000 50000
*/
int VectorTools::nGenerique2()
{
const int N = 2 * 3 * 4 * 5 * 10 * 10 * 10 * 10 * 2;
return N;
}
/**
* static
*/
void VectorTools::check_nGenerique1(int N)
{
//cout << N << endl;
assert(N >= 3);
assert(N <= Limits::MAX_INT);
for (int i = 2; i <= 15; i++)
{
//cout << i << endl;
assert(N % i == 0); // pour pouvoir faire varier le nombre de slice entre [3,nbSliceMax()]
}
for (int i = 5; i <= 75; i += 5)
{
//cout << i << endl;
assert(N % i == 0); // pour pouvoir faire varier le nombre de slice par pas de 5 dans [0,60]
}
}
/*--------------------------------------*\
|* warmup *|
\*-------------------------------------*/
int VectorTools::nWarmup_3_slices()
{
return 6; // doit etre divisible par 3
}
int VectorTools::nWarmup_4_slices()
{
return 8; // doit etre divisible par 4
}
int VectorTools::nWarmup_5_slices()
{
return 10; // doit etre divisible par 10
}
/*--------------------------------------*\
|* MM *|
\*-------------------------------------*/
static bool IS_MEMORY_DMA = true; // TODO changer a false pour voir la difference (bandepassante H2D et D2H afficher dans la console)
bool VectorTools::isDMA()
{
return IS_MEMORY_DMA;
}
int* VectorTools::create(int n)
{
if (!IS_MEMORY_DMA)
{
return new int[n];
}
else
{
int* ptr;
HM::malloc(&ptr, n * sizeof(int));
return ptr;
}
}
void VectorTools::free(int* ptrV)
{
if (!IS_MEMORY_DMA)
{
delete[] ptrV;
}
else
{
HM::free(ptrV);
}
}
/*--------------------------------------*\
|* Vector *|
\*-------------------------------------*/
int* VectorTools::createV1(int n)
{
int* ptrV = VectorTools::create(n);
for (int i = 0; i < n; i++)
{
ptrV[i] = i;
}
return ptrV;
}
int* VectorTools::createV2(int n)
{
int* ptrV = VectorTools::create(n);
for (int i = 0; i < n; i++)
{
ptrV[i] = i * 10;
}
return ptrV;
}
void VectorTools::print(int* ptrV , int n)
{
cout << endl;
for (int i = 0; i < n; i++)
{
cout << ptrV[i] << "\t";
}
cout << endl;
}
bool VectorTools::isAddVector_Ok(int* ptrV1 , int* ptrV2 , int* ptrW , int n)
{
for (int i = 0; i < n; i++)
{
int delta = ptrW[i] - ptrV1[i] - ptrV2[i];
if (delta != 0)
{
// // debug
// {
// print(ptrV1,n);
// print(ptrV2,n);
// print(ptrW,n);
//
// cout << "n = " << n << endl;
// cout << "i = " << i << endl;
// cout << "v1 + v2 = w : " << ptrV1[i] << " + " << ptrV2[i] << " = " << ptrW[i] << endl;
// }
return false;
}
}
return true;
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,62 @@
#pragma once
#include "cuda_fp16.h"
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
class VectorTools
{
/*--------------------------------------*\
|* Methodes *|
\*-------------------------------------*/
public:
/*--------------------------------------*\
|* Vector *|
\*-------------------------------------*/
static int n();
static int* createV1(int n);
static int* createV2(int n);
static void print(int* ptrV , int n);
static bool isAddVector_Ok(int* ptrV1 , int* ptrV2 , int* ptrW , int n);
/*--------------------------------------*\
|* MM *|
\*-------------------------------------*/
static int* create(int n);
static void free(int* ptrV);
static bool isDMA();
private:
/*--------------------------------------*\
|* n warmup *|
\*-------------------------------------*/
static int nWarmup_3_slices();
static int nWarmup_4_slices();
static int nWarmup_5_slices();
/*--------------------------------------*\
|* n generique *|
\*-------------------------------------*/
static int nGenerique1();
static int nGenerique2();
static void check_nGenerique1(int n);
};
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,91 @@
#include "Thread2D.cu.h"
#include "Thread1D.cu.h"
#include "cudas.h"
#include "Limits.h"
/*----------------------------------------------------------------------*\
|* private *|
\*---------------------------------------------------------------------*/
#include "losetime.cu.h"
static __device__ void processS(int* ptrGmSlice1 , int* ptrDevV2 , int* ptrGmSliceW , int sLocalSlice);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/**
* <pre>
* Inputs:
* - ptrGmSlice1 : pointeur sur la slice du vecteur1
* - ptrGmSlice2 : pointeur sur la slice du vecteur2
* - ptrGmSlicew : pointeur sur la slice du vecteur resultat w
*
* - n_by_slice : le nombre d'element dans une slice
* - sid : l'index de slice in [0,nbSlice[ (Pas used ici)
*
*
* Note:
* Ce meme kernel sera utiliser pour nos 3 versions:
* - baseline (sans stream, ou stream unique)
* - bistream (bislice)
* - tristram
*
* Version baseline (sans stream)
* - ptrGmSlice1 = ptrGMV1 pointeur sur le debut du vecteur complet v1
* - n_by_slice = n le nombre d'element total du vecteur
* - sid = 0 unique slice, la slice est le vecteur complet
*
* Version bistream (bislice)
* - ptrGmSlice1 = pointeur sur le debut d'une des slices du vecteur v1
* - n_by_slice = le nombre d'element d'une slice
* - sid = 0 ou 1 selon si on travailler la slice 0 ou la slice 1
*
* Version tristream
* - ptrGmSlice1 = ptrGMV1 pointeur sur le debut d'une des slices du vecteur v1
* - n_by_slice = n le nombre d'element d'une slice
* - sid le slice index
* </pre>
*/
__global__ void addVector(int* ptrGmSlice1 , int* ptrGmSlice2 , int* ptrGmSliceW , int n_by_slice , int sid = 0)
{
// Indications:
// (I1) Entrelacement sur le slice et uniquement sle slice
// (I2) Aidez vous ensuite de la fonction secondaire processS ci-dessous
// TODO vector stream
// int sGlobal = sLocalSlice + (sid * n_by_slice); // global au vecteur en partant du debut, pas used ici, car on a deja un pointeur sur le debut de la slice
}
/*--------------------------*\
|* private *|
\*-------------------------*/
/**
* calcul le resultat de la case sLocalSlice in [0,n_by_slice[ de la slice "courante"
*/
__device__ void processS(int* ptrGmSlice1 , int* ptrGmSlice2 , int* ptrGmSliceW , int sLocalSlice)
{
// Indications:
// (1) additioner la composante s: u=v1(s)+v2(s) (avec s= LocalSlice)
// (2) appeler loseTime sur u, loseTime ne modifie pas u,loseTime est un fonction identity
// (3) le resultat final est loseTime(u), ie la cases s additionner, mais avec une perte de temps
//
// resultatS=loseTime(u)
// TODO vector stream
// TIPS : pour debuguer, mettez au début:
//
// ptrGmSliceW[s]=sGlobal;
//
// Si vous avez un bug, ca permetra de savoir si ca vient du host ou du device
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,82 @@
#include "cudas.h"
#include "Limits.h"
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
static __device__ int loseTime(int u);
static __device__ int inc(int t);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/**
* Quoi:
*
* Fonction identity
* but :
*
* Ralentir pour le temps de kernel ne soit pas trop petit, et montrer l'interet des streams dans ce cas
*
* Piege:
*
* nvcc supprime les codes morts.
* Pour que losetime ne soit pas un code mort, on emploie la variable resultat que l'on doit renvoyer cote host.
* On modifie cette varaible, mais on s'arrange pour retomber sur nos pas a la fin
*
* Note1:
*
* loseTime et un Fonction identity
*
* u -> perdre du temps avec u -> u
* Note2:
* Le but du du TP est d'apprendre les streams, et non de devoir implementer un algorithme compliquer cote device.
* addVector est simple a coder cote device, mais on a pas besoin d'un gpu pour additionner deux vecteurs, un cpu
* fait ca tres bien et certainment en moins de temps que la copie des datas sur le device. On cree ici artificiellement
* un interet a l'activite avec la fonction losetime.
*/
__device__ int loseTime(int u)
{
// Plus le GPU est performant plus il faut prendre grand
const int N = 300; // chercher speed up de 2.1
long uu=u;
int t = 0;
while (t < N)
{
t++;
uu = uu +inc(t);
}
while(t>=1)
{
uu = uu - inc(t);
t--;
}
return (int)uu;
}
/*----------------------------------------------------------------------*\
|* Secondaire *|
\*---------------------------------------------------------------------*/
__device__ int inc(int t)
{
float a = t;
//int inc = round(cosf(a) * cosf(a) + sinf(a) * sinf(a)); // 1
int inc = __float2int_rn(cosf(a) * cosf(a) + sinf(a) * sinf(a)); // 1
return inc;
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,134 @@
#include "AddVector.h"
#include <iostream>
#include <assert.h>
#include "Kernel.h"
#include "GM.h"
#include "Bandwidth.h"
#include "VectorTools.h"
#include "Stream.h"
using std::cout;
using std::endl;
using std::to_string;
using std::string;
/*----------------------------------------------------------------------*\
|* Imported *|
\*---------------------------------------------------------------------*/
extern __global__ void addVector(int* ptrGmSlice1 , int* ptrGmSlice2 , int* ptrGmSliceW , int n_by_slice , int sid = 0);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*--------------------------------------*\
|* Constructeur *|
\*-------------------------------------*/
AddVector::AddVector(const Grid& grid , int* ptrV1 , int* ptrV2 , int* ptrW , int n , bool isVerbose) :
RunnableGPU(grid, title() + "-" + to_string(n), isVerbose), // classe parente
//
ptrV1(ptrV1), //
ptrV2(ptrV2), //
ptrW(ptrW), //
n(n)
{
this->sizeVector = n * sizeof(int); // octet
// MM (malloc Device)
{
GM::malloc(&ptrGMV1, sizeVector);
GM::malloc(&ptrGMV2, sizeVector);
GM::malloc(&ptrGMW, sizeVector);
}
}
AddVector::~AddVector(void)
{
//MM (device free)
{
GM::free(ptrGMV1);
GM::free(ptrGMV2);
GM::free(ptrGMW);
}
}
/*--------------------------------------*\
|* Methode *|
\*-------------------------------------*/
/**
* override
*/
void AddVector::run()
{
// MM (copy Host->Device)
{
Bandwidth bandwidth(sizeVector * 2, "[" + title() + "] : Host -> GM :");
GM::memcpyHToD(ptrGMV1, ptrV1, sizeVector);
GM::memcpyHToD(ptrGMV2, ptrV2, sizeVector);
if (isVerbose) // dans Runable ou RunnableGPU
{
cout << bandwidth << endl;
}
}
// call kernel
{
addVector<<<dg,db>>>(ptrGMV1, ptrGMV2, ptrGMW, n); // assynchrone
}
// MM (Device -> Host)
{
Bandwidth bandwidth(sizeVector, "[" + title() + "] : GM -> Host :");
GM::memcpyDToH(ptrW, ptrGMW, sizeVector);
if (isVerbose)
{
cout << bandwidth << endl;
}
}
}
/**
* override
*/
double AddVector::getInputGO()
{
return ((long)2 * (long)n * (long)sizeof(half)) / (double)((long)1024 * (long)1024 * (long)1024);
}
/**
* override
*/
double AddVector::getOutputGO()
{
return ((long)1 * (long)n * (long)sizeof(half)) / (double)((long)1024 * (long)1024 * (long)1024);
}
/*--------------------------------------*\
|* Private *|
\*-------------------------------------*/
string AddVector::title()
{
if (VectorTools::isDMA())
{
return "Addvector-DMA-int";
}
else
{
return "Addvector-int";
}
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,77 @@
#pragma once
#include "cudas.h"
#include "Grid.h"
#include "RunnableGPU.h"
#include "cuda_fp16.h"
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
class AddVector: public RunnableGPU
{
/*--------------------------------------*\
|* Constructor *|
\*-------------------------------------*/
public:
/**
* update w by v1+v2
*/
AddVector(const Grid& grid , int* ptrV1 , int* ptrV2 , int* ptrW , int n , bool isVerbose);
virtual ~AddVector(void);
/*--------------------------------------*\
|* Methodes *|
\*-------------------------------------*/
public:
/**
* override
*/
virtual void run();
/**
* override
*/
virtual double getOutputGO();
/**
* override
*/
virtual double getInputGO();
private:
std::string title();
/*--------------------------------------*\
|* Attributs *|
\*-------------------------------------*/
private:
// Inputs
int* ptrV1;
int* ptrV2;
int n;
// Inputs/Outputs
int* ptrW;
// Tools
int* ptrGMV1;
int* ptrGMV2;
int* ptrGMW;
size_t sizeVector; //[octet]
};
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,47 @@
#pragma once
#include <iostream>
#include <assert.h>
#include "Grid.h"
#include "Hardware.h"
#include "Couts.h"
/*----------------------------------------------------------------------*\
|* Impelmentation *|
\*---------------------------------------------------------------------*/
namespace addVector
{
class BestGrid
{
public:
static Grid get()
{
const int MP = Hardware::getMPCount();
const int CORE_MP = Hardware::getCoreCountMP();
dim3 dg(1 ,1, 1);
dim3 db(1, 1, 1); // contrainte : max(db.x*db.y*db.z)<=1024
Grid grid(dg, db);
// TODO addVector grid
// to remove once coded
{
Couts::redln("aie aie aie, your best grid won t build itself");
assert(false);
}
return grid;
}
};
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,178 @@
#include "AddVectorBistream.h"
#include <iostream>
#include <assert.h>
#include "Kernel.h"
#include "GM.h"
#include "Bandwidth.h"
#include "VectorTools.h"
#include "Stream.h"
using std::cout;
using std::endl;
using std::to_string;
using std::string;
/*----------------------------------------------------------------------*\
|* Imported *|
\*---------------------------------------------------------------------*/
extern __global__ void addVector(int* ptrGmSlice1 , int* ptrGmSlice2 , int* ptrGmSliceW , int n_by_slice , int sid = 0);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*--------------------------------------*\
|* Constructeur *|
\*-------------------------------------*/
AddVectorBistream::AddVectorBistream(const Grid& grid , int* ptrV1 , int* ptrV2 , int* ptrW , int n , bool isVerbose) :
RunnableGPU(grid, title() + "-" + to_string(n), isVerbose), // classe parente
//
ptrV1(ptrV1), //
ptrV2(ptrV2), //
ptrW(ptrW), //
n(n), //
isStreamDefaultUse(false)
{
assert(n % 2 == 0);
this->sizeVector = n * sizeof(int); // octet
// MM (malloc Device)
{
GM::malloc(&ptrGMV1, sizeVector);
GM::malloc(&ptrGMV2, sizeVector);
GM::malloc(&ptrGMW, sizeVector);
}
// Stream
{
// TODO stream, see attribute in .h
assert(false);
}
}
AddVectorBistream::~AddVectorBistream(void)
{
//MM (device free)
{
GM::free(ptrGMV1);
GM::free(ptrGMV2);
GM::free(ptrGMW);
}
// Stream
{
// TODO stream
}
}
/*--------------------------------------*\
|* Methode *|
\*-------------------------------------*/
/**
* override
*/
void AddVectorBistream::run()
{
const int MIDLE = n >> 1; // n/2
const size_t MIDLE_SIZE = sizeVector >> 1; // n/2
// Step 1:
{
// TODO stream see schema in pdf
// stream0 : copieHtoD slice0
Stream::synchronize(stream0);
}
// Step 2:
{
// TODO stream see schema in pdf
// stream1 : copieHtoD slice1
// stream0 : kernel slice0
// Warning : il faut lancer le kernel sur une slice!, pas sur tout le veteur!
// (W1) Attention a la dimension a donner
// (W2) Attention au sliceIndex, ie 0
}
// Step 3:
{
// TODO stream see schema in pdf
// stream0 : copieDtoH slice0
// stream1 : kernel slice1
// Warning : il faut lancer le kernel sur la slice1, pas sur tout le veteur!
// (W1) Attention a la dimension a donner, ie le nombre de case de la slice, ie MIDLE
// (W2) Attention au sliceIndex, ie 1
// (W3) Attention a l'arithmetic des pointeurs!
// on veut travailler non pas sur:
// ptrGMV1
// ptrGMV2
// ptrGMVW
// mais sur :
// ptrGMV1+MIDLE
// ptrGMV2+MIDLE
// ptrGMVW+MIDLE
}
// Step 4:
{
// TODO stream see schema in pdf
// stream1 : copieDtoH slice1
}
// Synchronize
{
// v1 : best
{
Stream::synchronize(stream0);
Stream::synchronize(stream1);
}
// v2 :bad (au cas ou d'autre TP sont lancer en meme temps
//Stream::synchronize();
}
}
/*--------------------------------------*\
|* secondaire *|
\*-------------------------------------*/
/**
* override
*/
double AddVectorBistream::getInputGO()
{
return ((long)2 * (long)n * (long)sizeof(half)) / (double)((long)1024 * (long)1024 * (long)1024);
}
/**
* override
*/
double AddVectorBistream::getOutputGO()
{
return ((long)1 * (long)n * (long)sizeof(half)) / (double)((long)1024 * (long)1024 * (long)1024);
}
/*--------------------------------------*\
|* Private *|
\*-------------------------------------*/
string AddVectorBistream::title()
{
if (VectorTools::isDMA())
{
return "Addvector-bistream-DMA-int";
}
else
{
return "Addvector-bistream-int";
}
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,79 @@
#pragma once
#include "cudas.h"
#include "Grid.h"
#include "RunnableGPU.h"
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
class AddVectorBistream: public RunnableGPU
{
/*--------------------------------------*\
|* Constructor *|
\*-------------------------------------*/
public:
/**
* update w by v1+v2
*/
AddVectorBistream(const Grid& grid , int* ptrV1 , int* ptrV2 , int* ptrW , int n , bool isVerbose);
virtual ~AddVectorBistream(void);
/*--------------------------------------*\
|* Methodes *|
\*-------------------------------------*/
public:
/**
* override
*/
virtual void run();
/**
* override
*/
virtual double getOutputGO();
/**
* override
*/
virtual double getInputGO();
private:
std::string title();
/*--------------------------------------*\
|* Attributs *|
\*-------------------------------------*/
private:
// Inputs
int* ptrV1;
int* ptrV2;
int n;
bool isStreamDefaultUse;
// Inputs/Outputs
int* ptrW;
// Tools
int* ptrGMV1;
int* ptrGMV2;
int* ptrGMW;
size_t sizeVector; //[octet]
cudaStream_t stream0;
cudaStream_t stream1;
};
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,44 @@
#pragma once
#include <iostream>
#include <assert.h>
#include "Grid.h"
#include "Hardware.h"
#include "Couts.h"
/*----------------------------------------------------------------------*\
|* Impelmentation *|
\*---------------------------------------------------------------------*/
namespace addVectorBistream
{
class BestGrid
{
public:
static Grid get()
{
const int MP = Hardware::getMPCount();
const int CORE_MP = Hardware::getCoreCountMP();
// TODO addVectorBistream
// to remove once coded
{
Couts::redln("aie aie aie, your best grid won t build itself");
assert(false);
}
}
};
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,225 @@
#include "AddVectorTristream.h"
#include <iostream>
#include <assert.h>
#include "Kernel.h"
#include "GM.h"
#include "Bandwidth.h"
#include "VectorTools.h"
#include "Stream.h"
using std::cout;
using std::endl;
using std::to_string;
using std::string;
/*----------------------------------------------------------------------*\
|* Imported *|
\*---------------------------------------------------------------------*/
extern __global__ void addVector(int* ptrGmSlice1 , int* ptrGmSlice2 , int* ptrGmSliceW , int n_by_slice , int sid = 0);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*--------------------------------------*\
|* Constructeur *|
\*-------------------------------------*/
AddVectorTristream::AddVectorTristream(const Grid& grid , int* ptrV1 , int* ptrV2 , int* ptrW , int n , int nbSlice , bool isVerbose) :
RunnableGPU(grid, title(nbSlice) + "-" + to_string(n), isVerbose), // classe parente
//
ptrV1(ptrV1), //
ptrV2(ptrV2), //
ptrW(ptrW), //
n(n), //
nbSlice(nbSlice)
{
assert(n % nbSlice == 0);
assert(nbSlice >= 3);
this->sizeVector = n * sizeof(int); // octet
this->SIZE_SLICE = sizeVector / nbSlice;
this->N_BY_SLICE = n / nbSlice;
// MM (malloc Device)
{
GM::malloc(&ptrGMV1, sizeVector);
GM::malloc(&ptrGMV2, sizeVector);
GM::malloc(&ptrGMW, sizeVector);
}
// Stream
{
// TODO stream, see attribute in .h
assert(false); // to remove once coded
}
}
AddVectorTristream::~AddVectorTristream(void)
{
//MM (device free)
{
GM::free(ptrGMV1);
GM::free(ptrGMV2);
GM::free(ptrGMW);
}
// Stream
{
// TODO stream, see attribute in .h
}
}
/*--------------------------------------*\
|* Methode *|
\*-------------------------------------*/
/**
* Conseils :
*
* (C1) Commencer par les warmup pour un nombre de slice petit et fixe, puis passer seulement ensuite a la generalisation.
*
* (C2) Pour les warmup, prenez une taille n de vecteur petit (pour pouvoir afficher le resultat)
* Aller dans:
*
* VectorTools::n(); // activez la ligne debug provisoirement, et dans nDebug() prenez une valeur petite et divisible par votre nombre se slice
*
* (C3) Travailler au début avec mainUse.cpp (utiliser le blog debug fournit avec flag de verbosite a false avec !)
*/
void AddVectorTristream::run()
{
// warmup
{
run3Slice();
//run4Slice();
//run5Slice();
}
//runGeneric(); // TODO stream a activer une fois le warmup valider
// Warning : le mode LaunchModeMOO::TEST dans main a besoin du code generic coder et activer
// synchronise
{
// TODO stream (attendre la fin de toutes les stream de ce tp)
}
}
/*--------------------------------------*\
|* Differentes Versions *|
\*-------------------------------------*/
// pour des raisons de clareter, le code se trouve dans les .h includer ci-dessous (il se trouve dans le folder helper)
#include "run3Slice.h"
#include "run4Slice.h"
#include "run5Slice.h"
#include "runGeneric.h"
/*--------------------------------------*\
|* Tools *|
\*-------------------------------------*/
/**
* sid=sliceIndex in [0,nbSlice[
* return decalage a effectuer pour pointer sur le premier element d'une slice.
*
* Exemple:
*
* Si les slices ont 4 cases, et qu'il a 3 slices:
*
* sid=0 offsetSlice(0) vaut 0 ptrGMV1+offsetSlice(0) pointe sur la premiere case du slice 0 (de v1)
* sid=1 offsetSlice(1) vaut 4 ptrGMV1+offsetSlice(1) pointe sur la premiere case du slice 1 (de v1)
* sid=2 offsetSlice(2) vaut 8 ptrGMV1+offsetSlice(2) pointe sur la premiere case du slice 2 (de v1)
*/
int AddVectorTristream::offsetSlice(int sid)
{
assert(false); // remove once coded
return 0; // TODO stream
}
/**
* copyHtoD: la slice sid pour
*
* v1
* v2
* ou
* sid=sliceIndex in [0,nbSlice[
*/
void AddVectorTristream::copyHtoD(int sid , cudaStream_t stream)
{
const int OFFSET_SLICE = offsetSlice(sid);
// Indication:
// pour le slice de v1
// pour le slice de v2
// TODO stream
assert(false); // remove once coded
}
/**
* copyDtoH: la slice sid pour
*
* w
* ou
* sid=liceIndex in [0,nbSlice[
*/
void AddVectorTristream::copyDtoH(int sid , cudaStream_t stream)
{
const int OFFSET_SLICE = offsetSlice(sid);
// TODO stream
assert(false); // remove once coded
}
/**
* lance le kernel de calcul pour la slice sid
* ou
* sid=sliceIndex in [0,nbSlice[
*/
void AddVectorTristream::kernelSlice(int sid , cudaStream_t stream)
{
const int OFFSET_SLICE = offsetSlice(sid);
// TODO stream
assert(false); // remove once coded
}
/*------------------------*\
|* secondaire *|
\*-----------------------*/
/**
* override
*/
double AddVectorTristream::getInputGO()
{
return ((long)2 * (long)n * (long)sizeof(half)) / (double)((long)1024 * (long)1024 * (long)1024);
}
/**
* override
*/
double AddVectorTristream::getOutputGO()
{
return ((long)1 * (long)n * (long)sizeof(half)) / (double)((long)1024 * (long)1024 * (long)1024);
}
string AddVectorTristream::title(int nbSlice)
{
if (VectorTools::isDMA())
{
return "Addvector-tristream-slice" + to_string(nbSlice) + "-DMA-int";
}
else
{
return "Addvector-tristream-slice" + to_string(nbSlice) + "-DMA-int";
}
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,120 @@
#pragma once
#include "cudas.h"
#include "Grid.h"
#include "RunnableGPU.h"
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
class AddVectorTristream: public RunnableGPU
{
/*--------------------------------------*\
|* Constructor *|
\*-------------------------------------*/
public:
/**
* update w by v1+v2
* 3 stream
* nbSlice >3 voir VectorTools::n()
*/
AddVectorTristream(const Grid& grid , int* ptrV1 , int* ptrV2 , int* ptrW , int n , int nbSlice , bool isVerbose);
virtual ~AddVectorTristream(void);
/*--------------------------------------*\
|* Methodes *|
\*-------------------------------------*/
public:
/**
* override
*/
virtual void run();
/**
* override
*/
virtual double getOutputGO();
/**
* override
*/
virtual double getInputGO();
private:
/*------------------------*\
|* differentes versions *|
\*-----------------------*/
void run3Slice(); // warmup
void run4Slice(); // warmup
void run5Slice(); // warmup
void runGeneric();
/*------------------------*\
|* Tools *|
\*-----------------------*/
/**
* sid=sliceIndex
*/
void copyHtoD(int sid , cudaStream_t stream);
/**
* sid=sliceIndex
*/
void copyDtoH(int sid , cudaStream_t stream);
/**
* sid=sliceIndex
*/
void kernelSlice(int sid , cudaStream_t stream);
/**
* sid=sliceIndex
* return decalage a effectuer pour pointer sur le premier element d'une slice
*/
int offsetSlice(int sid);
std::string title(int nbStream);
/*--------------------------------------*\
|* Attributs *|
\*-------------------------------------*/
private:
// Inputs
int* ptrV1;
int* ptrV2;
int n;
int nbSlice;
// Inputs/Outputs
int* ptrW;
// Tools
int* ptrGMV1;
int* ptrGMV2;
int* ptrGMW;
size_t sizeVector; //[octet]
cudaStream_t stream0;
cudaStream_t stream1;
cudaStream_t stream2;
size_t SIZE_SLICE;
int N_BY_SLICE;
};
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,42 @@
#pragma once
#include <iostream>
#include <assert.h>
#include "Grid.h"
#include "Hardware.h"
#include "Couts.h"
/*----------------------------------------------------------------------*\
|* Impelmentation *|
\*---------------------------------------------------------------------*/
namespace addVectorTristream
{
class BestGrid
{
public:
static Grid get()
{
const int MP = Hardware::getMPCount();
const int CORE_MP = Hardware::getCoreCountMP();
// TODO addVectorTristream
// to remove once coded
{
Couts::redln("aie aie aie, your best grid won t build itself");
assert(false);
}
}
};
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,64 @@
#pragma once
/*----------------------------------------------------------------------*\
|* implementation *|
\*---------------------------------------------------------------------*/
/**
* conseil : a coder que une fois tous les warmups reussis
*/
void AddVectorTristream::runGeneric()
{
// Warning : Aidez-vous de nouveau des 3 methodes:
//
// - void copyHtoD(int sid , cudaStream_t stream)
// - void copyDtoH(int sid , cudaStream_t stream)
// - kernelSlice (int sid , cudaStream_t stream)
// partie Init
{
// step1
{
// TODO stream see schema in pdf
}
// step2
{
// TODO stream see schema in pdf
}
}
// 6 variable utile pour les permutations
cudaStream_t streamA = stream0; // cudaStream_t est un int
cudaStream_t streamB = stream2;
cudaStream_t streamC = stream1;
cudaStream_t streamA_old = stream0;
cudaStream_t streamB_old = stream2;
cudaStream_t streamC_old = stream1;
// partie centrale 3 stream en parallel
{
// TODO stream see schema in pdf
}
// partie finale
{
const int INDEX_LAST = nbSlice - 1;
const int INDEX_BEFORE_LAST = INDEX_LAST - 1;
// before last
{
// TODO stream see schema in pdf
}
// last
{
// TODO stream see schema in pdf
}
}
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,51 @@
#pragma once
/*----------------------------------------------------------------------*\
|* implementation *|
\*---------------------------------------------------------------------*/
/**
* Warmup : 3 slice
*/
void AddVectorTristream::run3Slice()
{
// Warning : Aidez-vous des 3 methodes:
//
// - void copyHtoD(int sid , cudaStream_t stream)
// - void copyDtoH(int sid , cudaStream_t stream)
// - kernelSlice (int sid , cudaStream_t stream)
// Note:
// Ces 3 methodes sont a implementer dans le canvas tools de la classe AddVectorTristream
// step1 :
{
// TODO stream see schema in pdf
}
// step2 :
{
// TODO stream see schema in pdf
}
// partie centrale 3 stream en parallel
{
// step3 : (1 seul step pour 3 slice et 3 stream)
{
// TODO stream see schema in pdf
}
}
// step 4 :
{
// TODO stream see schema in pdf
}
// step 5 :
{
// TODO addVector see schema in pdf
}
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,61 @@
#pragma once
/*----------------------------------------------------------------------*\
|* implementation *|
\*---------------------------------------------------------------------*/
/**
* Warmup : 4 slice
*/
void AddVectorTristream::run4Slice()
{
// Warning : Aidez-vous de nouveau des 3 methodes
//
// - void copyHtoD(int sid , cudaStream_t stream)
// - void copyDtoH(int sid , cudaStream_t stream)
// - kernelSlice (int sid , cudaStream_t stream)
// partie Init
{
// step1
{
// TODO stream see schema in pdf
}
// step2
{
// TODO stream see schema in pdf
}
}
// partie centrale 3 stream en parallel
{
// step3
{
// TODO stream see schema in pdf
}
// step4
{
// TODO stream see schema in pdf
}
}
// partie Finale
{
// step 4
{
// TODO stream see schema in pdf
}
//step 5
{
// TODO stream see schema in pdf
}
}
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,69 @@
#pragma once
/*----------------------------------------------------------------------*\
|* implementation *|
\*---------------------------------------------------------------------*/
/**
* Warmup : 5 slice
*/
void AddVectorTristream::run5Slice()
{
// Warning : Aidez-vous de nouveau des 3 methodes:
//
// - void copyHtoD(int sid , cudaStream_t stream)
// - void copyDtoH(int sid , cudaStream_t stream)
// - kernelSlice (int sid , cudaStream_t stream)
// partie Init
{
// step1
{
// TODO stream see schema in pdf
}
// step2
{
// TODO stream see schema in pdf
}
}
// partie centrale 3 stream en parallel
{
// step3
{
// TODO stream see schema in pdf
}
// step4
{
// TODO stream see schema in pdf
}
// step 5
{
// TODO stream see schema in pdf
}
}
// partie finale
{
const int INDEX_LAST = -1; // TODO // un peu de genericiter
const int INDEX_BEFORE_LAST = INDEX_LAST - 1; // un peu de genericiter
// before last
{
// TODO stream see schema in pdf
}
// last
{
// TODO stream see schema in pdf
}
}
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,125 @@
#include <iostream>
using std::cout;
using std::cerr;
using std::endl;
#include "Montecarlo.h"
#include "Montecarlo_BestGrid.h"
#include "MontecarloMulti_thread.h"
#include "MontecarloMulti_BestGrid.h"
#include "MontecarloMulti_stream.h"
#include "MontecarloMulti_BestGrid.h"
#include "entier_montecarlo.h"
#include "entiertype_montecarlo.h"
#include "Limits.h"
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*----------------------*\
|* Mono *|
\*---------------------*/
extern montecarlo::EntierType entierTypeMontecarlo()
{
if (montecarlo::isInt())
{
return montecarlo::EntierType::INT;
}
else if (montecarlo::isLong())
{
return montecarlo::EntierType::LONG;
}
else
{
assert(false);
return montecarlo::EntierType::LONG;
}
}
extern RunnableGPU_I* createMontecarlo(const Grid& grid , long nbDarTotalAsk , double* ptrPiHat , float h , bool isVerbose)
{
if (montecarlo::isInt())
{
assert(nbDarTotalAsk <= Limits::MAX_INT);
return new Montecarlo(grid, (int)nbDarTotalAsk, ptrPiHat, h, isVerbose);
}
else if (montecarlo::isLong())
{
return new Montecarlo(grid, nbDarTotalAsk, ptrPiHat, h, isVerbose);
}
else
{
assert(false);
return NULL;
}
}
extern Grid bestGridMontecarlo()
{
return montecarlo::BestGrid::get();
}
/*----------------------*\
|* Thread *|
\*---------------------*/
extern RunnableGPU_I* createMontecarloMultiThread(const Grid& grid , long nbDarTotalAsk , double* ptrPiHat , float h , bool isVerbose)
{
if (montecarlo::isInt())
{
assert(nbDarTotalAsk <= Limits::MAX_INT);
return new MontecarloMulti_thread(grid, (int)nbDarTotalAsk, ptrPiHat, h, isVerbose);
}
else if (montecarlo::isLong())
{
return new MontecarloMulti_thread(grid, nbDarTotalAsk, ptrPiHat, h, isVerbose);
}
else
{
assert(false);
return NULL;
}
}
extern Grid bestGridMontecarloMultiThread()
{
return montecarloMulti::BestGrid::get();
}
/*----------------------*\
|* Stream *|
\*---------------------*/
extern RunnableGPU_I* createMontecarloMultiStream(const Grid& grid , long nbDarTotalAsk , double* ptrPiHat , float h , bool isVerbose)
{
if (montecarlo::isInt())
{
assert(nbDarTotalAsk <= Limits::MAX_INT);
return new MontecarloMulti_stream(grid, (int)nbDarTotalAsk, ptrPiHat, h, isVerbose);
}
else if (montecarlo::isLong())
{
return new MontecarloMulti_stream(grid, nbDarTotalAsk, ptrPiHat, h, isVerbose);
}
else
{
assert(false);
return NULL;
}
}
extern Grid bestGridMontecarloMultiStream()
{
return montecarloMulti::BestGrid::get();
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,80 @@
#include <iostream>
using std::cout;
using std::cerr;
using std::endl;
#include "SliceGMHOST.h"
#include "SliceGMHost_BestGrid.h"
#include "SliceGM.h"
#include "SliceGM_BestGrid.h"
#include "SliceSM.h"
#include "SliceSM_BestGrid.h"
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*----------------------*\
|* gm host *|
\*---------------------*/
extern RunnableGPU_I* createSliceGMHOST(Grid grid , int nbSlice , double* ptrPiHat , bool isVerbose)
{
return new SliceGMHOST(grid, nbSlice, ptrPiHat, isVerbose);
}
extern Grid bestGridliceGMHOST()
{
return sliceGMHost::BestGrid::get();
}
/*----------------------*\
|* gm *|
\*---------------------*/
extern RunnableGPU_I* createSliceGM(Grid grid , int nbSlice , double* ptrPiHat , bool isVerbose)
{
return new SliceGM(grid, nbSlice, ptrPiHat, isVerbose);
}
extern Grid bestGridliceGM()
{
return sliceGM::BestGrid::get();
}
/*----------------------*\
|* sm *|
\*---------------------*/
extern RunnableGPU_I* createSliceSM(const Grid& grid , int nbSlice , double* ptrPiHat , bool isVerbose)
{
return new SliceSM(grid, nbSlice, ptrPiHat, isVerbose);
}
extern Grid bestGridliceSM()
{
return sliceSM::BestGrid::get();
}
/*----------------------*\
|* multi *|
\*---------------------*/
extern RunnableGPU_I* createSliceMulti(Grid grid , int nbSlice , double* ptrPiHat , bool isVerbose)
{
// return new SliceMulti(grid, nbSlice, ptrPiHat, isVerbose);
}
extern Grid bestGridliceMulti()
{
// return sliceMulti::BestGrid::get();
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,65 @@
#include <iostream>
using std::cout;
using std::cerr;
using std::endl;
#include "AddVector.h"
#include "AddVector_BestGrid.h"
#include "AddVectorBistream.h"
#include "AddVectorBistream_BestGrid.h"
#include "AddVectorTristream.h"
#include "AddVectorTristream_BestGrid.h"
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*----------------------*\
|* base line *|
\*---------------------*/
RunnableGPU_I* createAddVector(const Grid& grid , int* ptrV1 , int* ptrV2 , int* ptrW , int n , bool isVerbose)
{
return new AddVector(grid, ptrV1, ptrV2, ptrW, n, isVerbose);
}
Grid bestGridAddVector()
{
return addVector::BestGrid::get();
}
/*----------------------*\
|* bi-stream *|
\*---------------------*/
RunnableGPU_I* createAddVectorBistream(const Grid& grid , int* ptrV1 , int* ptrV2 , int* ptrW , int n , bool isVerbose)
{
return new AddVectorBistream(grid, ptrV1, ptrV2, ptrW, n, isVerbose);
}
Grid bestGridAddVectorBistream()
{
return addVectorBistream::BestGrid::get();
}
/*----------------------*\
|* tri-stream *|
\*---------------------*/
RunnableGPU_I* createAddVectorTristream(const Grid& grid , int* ptrV1 , int* ptrV2 , int* ptrW , int n , int nbSlice , bool isVerbose)
{
return new AddVectorTristream(grid, ptrV1, ptrV2, ptrW, n, nbSlice,isVerbose);
}
Grid bestGridAddVectorTriStream()
{
return addVectorTristream::BestGrid::get();
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

52
Student_Cuda/src/main/main.cpp Executable file
View File

@@ -0,0 +1,52 @@
#include <iostream>
#include "CudaContext.h"
#include "Limits.h"
using std::cout;
using std::cerr;
using std::endl;
/*----------------------------------------------------------------------*\
|* Imported *|
\*---------------------------------------------------------------------*/
extern int mainUse();
extern int mainTest();
extern int mainBenchmark();
extern int mainBrutforce();
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
int main(int argc , char** argv)
{
// Limits::show();
CudaContext cudaContext;
// public
{
cudaContext.deviceId = 0; // in [0,2] width Server Cuda3
cudaContext.launchMode = LaunchModeMOO::USE; // USE TEST BENCHMARK FORCEBRUT
cudaContext.deviceDriver = DeviceDriver::LOAD_ALL; // LOAD_CURRENT LOAD_ALL
cudaContext.deviceInfo = DeviceInfo::ALL_SIMPLE; // NONE ALL ALL_SIMPLE CURRENT
}
// private
{
cudaContext.mainUse = mainUse;
cudaContext.mainTest = mainTest;
cudaContext.mainBenchmark = mainBenchmark;
cudaContext.mainBrutforce = mainBrutforce;
}
return cudaContext.process();
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,185 @@
#include <iostream>
#include <stdlib.h>
#include "Benchmark.h"
// Slice
#include "SliceGmHostUse.h"
#include "SliceGmUse.h"
#include "SliceSmUse.h"
#include "SliceMultiUse.h"
// Montecarlo
#include "entier_montecarlo.h"
#include "MontecarloUse.h"
#include "MontecarloMultiUse_thread.h"
#include "MontecarloMultiUse_stream.h"
// Vector
#include "AddVectorUse.h"
#include "AddVectorBistreamUse.h"
#include "AddVectorTristreamUse.h"
#include "VectorTools.h"
using std::cout;
using std::endl;
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
/*--------------------------------------*\
|* Private *|
\*-------------------------------------*/
static void sliceGMHOST();
static void sliceGM();
static void montecarloMono();
static void montecarloMulti_thread();
static void montecarloMulti_stream();
static void addvector();
static void addvectorBistream();
static void addvectorTristream();
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*--------------------------------------*\
|* Public *|
\*-------------------------------------*/
int mainBenchmark()
{
// one at a time!
// Slice
{
sliceGMHOST();
//sliceGM();
//sliceSM();
//sliceMulti();
}
// Montecarlo
{
// montecarloMono();
// montecarloMulti_thread();
// montecarloMulti_stream();
}
// Vector
{
// addvector();
// addvectorBistream();
// addvectorTristream();
}
return EXIT_SUCCESS;
}
/*--------------------------------------*\
|* Private *|
\*-------------------------------------*/
void sliceGMHOST()
{
const double DURATION_MAX_S = 10;
const bool IS_VERBOSE = false;
SliceGmHostUse sliceGmHostUse(IS_VERBOSE);
Benchmark::run(sliceGmHostUse.getRunnableGPU(), DURATION_MAX_S);
}
void sliceGM()
{
const double DURATION_MAX_S = 10;
const bool IS_VERBOSE = false;
SliceGmUse sliceGmUse(IS_VERBOSE);
Benchmark::run(sliceGmUse.getRunnableGPU(), DURATION_MAX_S);
}
void sliceSM()
{
const double DURATION_MAX_S = 10;
const bool IS_VERBOSE = false;
SliceSmUse sliceSmUse(IS_VERBOSE);
Benchmark::run(sliceSmUse.getRunnableGPU(), DURATION_MAX_S);
}
void montecarloMono()
{
const double DURATION_MAX_S = 10;
const bool IS_VERBOSE = false;
MontecarloUse montecarloUse(IS_VERBOSE);
Benchmark::run(montecarloUse.getRunnableGPU(), DURATION_MAX_S);
}
void montecarloMulti_thread()
{
const double DURATION_MAX_S = 10;
const bool IS_VERBOSE = false;
MontecarloMultiUse_thread montecarloMultiUse(IS_VERBOSE);
Benchmark::run(montecarloMultiUse.getRunnableGPU(), DURATION_MAX_S);
}
void montecarloMulti_stream()
{
const double DURATION_MAX_S = 10;
const bool IS_VERBOSE = false;
MontecarloMultiUse_stream montecarloMultiUse(IS_VERBOSE);
Benchmark::run(montecarloMultiUse.getRunnableGPU(), DURATION_MAX_S);
}
void addvector()
{
const double DURATION_MAX_S = 10;
const bool IS_VERBOSE = false;
AddVectorUse addVectorUse(IS_VERBOSE);
Benchmark::run(addVectorUse.getRunnableGPU(), DURATION_MAX_S);
}
void addvectorBistream()
{
const double DURATION_MAX_S = 10;
const bool IS_VERBOSE = false;
AddVectorBistreamUse addVectorBistreamUse(IS_VERBOSE);
Benchmark::run(addVectorBistreamUse.getRunnableGPU(), DURATION_MAX_S);
}
void addvectorTristream()
{
const double DURATION_MAX_S = 10;
const bool IS_VERBOSE = false;
int nbSlice = 20;
AddVectorTristreamUse addVectorTristreamUse(nbSlice, IS_VERBOSE);
Benchmark::run(addVectorTristreamUse.getRunnableGPU(), DURATION_MAX_S);
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,377 @@
#include <iostream>
#include <stdlib.h>
#include "Matlab.h"
#include "Hardware.h"
#include "BruteForce.h"
#include "ProviderUse_I.h"
//Slice
#include "SliceProviderGMHOST.h"
#include "SliceProviderGM.h"
#include "SliceProviderSM.h"
#include "SliceProviderMulti.h"
//Montecarlo
#include "entier_montecarlo.h"
#include "MontecarloProvider.h"
#include "MontecarloMultiProvider_thread.h"
#include "MontecarloMultiProvider_stream.h"
// Vector
#include "AddVectorProvider.h"
#include "AddVectorBistreamProvider.h"
#include "AddVectorTristreamProvider.h"
#include "VectorTools.h"
using std::cout;
using std::endl;
using std::string;
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
/*--------------------------------------*\
|* Private *|
\*-------------------------------------*/
static void sliceGMHOST(Matlab* ptrMatlab);
static void sliceGM(Matlab* ptrMatlab);
static void sliceSM(Matlab* ptrMatlab);
static void montecarloMono(Matlab* ptrMatlab);
static void montecarloMulti_thread(Matlab* ptrMatlab);
static void montecarloMulti_stream(Matlab* ptrMatlab);
static void addvector(Matlab* ptrMatlab);
static void addvectorBistream(Matlab* ptrMatlab);
static void addvectorTristream(Matlab* ptrMatlab);
static void addvectorTristream1a(Matlab* ptrMatlab);
static void addvectorTristream1b(Matlab* ptrMatlab);
static void addvectorTristream2a(Matlab* ptrMatlab);
static void addvectorTristream2b(Matlab* ptrMatlab);
static void addvectorTristreamDebug(Matlab* ptrMatlab);
// Tools
static void bruteforce(ProviderUse_I* ptrProviderUse , Matlab* ptrMatlab , const PlotType& plotType , double durationMaxS);
static void bruteforceReduction(ProviderUse_I* ptrProviderUse , Matlab* ptrMatlab , const PlotType& plotType , double durationMaxS);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
/*--------------------------------------*\
|* Public *|
\*-------------------------------------*/
int mainBrutforce()
{
Matlab matlab;
// one at a time!
// Slice
{
sliceGMHOST(&matlab);
// sliceGM(&matlab);
// sliceSM(&matlab);
}
// Montecarlo
{
//montecarloMono(&matlab); // long en long
// montecarloMulti_thread(&matlab);
// montecarloMulti_stream(&matlab);
}
// vector
{
// addvector(&matlab);
// addvectorBistream(&matlab);
// addvectorTristream(&matlab);
}
matlab.play();
return EXIT_SUCCESS;
}
/*--------------------------------------*\
|* Private *|
\*-------------------------------------*/
void sliceGMHOST(Matlab* ptrMatlab)
{
const double DURATION_MAX_S = 0.9;
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
SliceProviderGMHOST sliceProviderGMHOST;
bruteforce(&sliceProviderGMHOST, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
void sliceGM(Matlab* ptrMatlab)
{
const double DURATION_MAX_S = 0.9;
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
SliceProviderGM sliceProviderGM;
// brutefore: cas special dg et db power 2
{
const int WARP_SIZE = Hardware::getWarpSize();
// dg
Iterator iteratorDGx(WARP_SIZE, 1024, 2, Operator::MULTIPLY); // (min,max,step) // power 2
// db
Iterator iteratorDBx(WARP_SIZE, 1024, 2, Operator::MULTIPLY); // (min,max,step) // power 2
// gridMaillage
GridMaillage gridMaillage(iteratorDGx, iteratorDBx);
BruteForce::run(&sliceProviderGM, &gridMaillage, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
}
void sliceSM(Matlab* ptrMatlab)
{
const double DURATION_MAX_S = 0.9;
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
SliceProviderSM sliceProviderSM;
bruteforceReduction(&sliceProviderSM, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
void montecarloMono(Matlab* ptrMatlab)
{
#ifdef DAR_INT
const double DURATION_MAX_S = 0.9;
#endif
#ifdef DAR_LONG
const double DURATION_MAX_S = 0.0009;
#endif
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
MontecarloProvider montecarloProvider;
bruteforceReduction(&montecarloProvider, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
void montecarloMulti_thread(Matlab* ptrMatlab)
{
#ifdef DAR_INT
const double DURATION_MAX_S = 0.9;
#endif
#ifdef DAR_LONG
const double DURATION_MAX_S = 0.0009;
#endif
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
MontecarloMultiProvider_thread montecarloProviderMulti;
bruteforceReduction(&montecarloProviderMulti, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
void montecarloMulti_stream(Matlab* ptrMatlab)
{
#ifdef DAR_INT
const double DURATION_MAX_S = 0.9;
#endif
#ifdef DAR_LONG
const double DURATION_MAX_S = 0.0009;
#endif
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
MontecarloMultiProvider_stream montecarloProviderMulti;
bruteforceReduction(&montecarloProviderMulti, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
void addvector(Matlab* ptrMatlab)
{
const double DURATION_MAX_S = 0.9;
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
AddVectorProvider addVectorProvider;
bruteforce(&addVectorProvider, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
void addvectorBistream(Matlab* ptrMatlab)
{
const double DURATION_MAX_S = 0.9;
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
AddVectorBistreamProvider addVectorBistreamProvider;
bruteforce(&addVectorBistreamProvider, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
/*--------------------------------------*\
|* Tristream *|
\*-------------------------------------*/
/**
* Selon le cas il faut changer la taille du vecteur dans VectorTools.cpp, VectorTools::n()
* Why? On veut se simplifier la vie, et pourvoir avoir des slices de tranches égales
*/
void addvectorTristream(Matlab* ptrMatlab)
{
//addvectorTristream1a(ptrMatlab);
addvectorTristream1b(ptrMatlab);
//addvectorTristream2a(ptrMatlab);
//addvectorTristream2b(ptrMatlab);
// addvectorTristreamDebug(ptrMatlab);
}
/**
* cas 1.a : #slice : 3 4 5 6 7 8 9 10 11 12 13 14 15
*/
void addvectorTristream1a(Matlab* ptrMatlab)
{
const double DURATION_MAX_S = 0.9;
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
for (int nbSlice = 3; nbSlice <= 15; nbSlice++) // hyper long
{
AddVectorTristreamProvider addVectorTristreamProvider(nbSlice);
bruteforce(&addVectorTristreamProvider, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
}
/**
* cas 1.b : #slice in [5,75] par pas de 5
*/
void addvectorTristream1b(Matlab* ptrMatlab)
{
const double DURATION_MAX_S = 0.9;
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
for (int nbSlice = 5; nbSlice <= 75; nbSlice += 5) // hyper long
{
AddVectorTristreamProvider addVectorTristreamProvider(nbSlice);
bruteforce(&addVectorTristreamProvider, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
}
/**
* cas 2.a : #slice : 10 20 30 40 50
*/
void addvectorTristream2a(Matlab* ptrMatlab)
{
const double DURATION_MAX_S = 0.9;
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
for (int nbSlice = 10; nbSlice <= 50; nbSlice += 10) // hyper long
{
AddVectorTristreamProvider addVectorTristreamProvider(nbSlice);
bruteforce(&addVectorTristreamProvider, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
}
/**
* cas 2.b : #slice : 10 100 1000 10000 20000 30000 40000
*/
void addvectorTristream2b(Matlab* ptrMatlab)
{
const double DURATION_MAX_S = 0.9;
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
const int N = 6;
int tab[N];
tab[0] = 10;
tab[1] = 100;
tab[2] = 1000;
tab[3] = 10000;
tab[4] = 20000;
tab[5] = 30000;
tab[6] = 40000;
for (int i = 0; i < N; i++) // long
{
int nbSlice = tab[i];
AddVectorTristreamProvider addVectorTristreamProvider(nbSlice);
bruteforce(&addVectorTristreamProvider, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
}
void addvectorTristreamDebug(Matlab* ptrMatlab)
{
const double DURATION_MAX_S = 0.9;
const PlotType PLOT_TYPE = PlotType::ALL_GRAPHE;
int nbSlice = 25; // 15 20 30 75 cas 1.b
AddVectorTristreamProvider addVectorTristreamProvider(nbSlice);
bruteforce(&addVectorTristreamProvider, ptrMatlab, PLOT_TYPE, DURATION_MAX_S);
}
/*-----------------------------------*\
|* Tools *|
\*-----------------------------------*/
/**
* db power2
*/
void bruteforceReduction(ProviderUse_I* ptrProviderUse , Matlab* ptrMatlab , const PlotType& plotType , double durationMaxS)
{
// Hardware
const int MP = Hardware::getMPCount();
const int CORE_MP = Hardware::getCoreCountMP();
const int NB_THREAD_BLOCK_MAX = Hardware::getMaxThreadPerBlock();
const int WARP_SIZE = Hardware::getWarpSize();
// dg
Iterator iteratorDGx(MP, 10 * MP, MP, Operator::ADD); // (min,max,step)
// db
// Iterator iteratorDBx(WARP_SIZE, NB_THREAD_BLOCK_MAX, 2, Operator::MULTIPLY); // power2 (reduction)
Iterator iteratorDBx(CORE_MP, NB_THREAD_BLOCK_MAX, 2, Operator::MULTIPLY); // power2 (reduction)
// gridMaillage
GridMaillage gridMaillage(iteratorDGx, iteratorDBx);
BruteForce::run(ptrProviderUse, &gridMaillage, ptrMatlab, plotType, durationMaxS);
}
void bruteforce(ProviderUse_I* ptrProviderUse , Matlab* ptrMatlab , const PlotType& plotType , double durationMaxS)
{
// Hardware
const int MP = Hardware::getMPCount();
const int CORE_MP = Hardware::getCoreCountMP();
const int NB_THREAD_BLOCK_MAX = Hardware::getMaxThreadPerBlock();
const int WARP_SIZE = Hardware::getWarpSize();
// dg
Iterator iteratorDGx(MP, 10 * MP, MP, Operator::ADD); // (min,max,step)
// db
Iterator iteratorDBx(CORE_MP, NB_THREAD_BLOCK_MAX, CORE_MP, Operator::ADD); // (min,max,step)
// gridMaillage
GridMaillage gridMaillage(iteratorDGx, iteratorDBx);
BruteForce::run(ptrProviderUse, &gridMaillage, ptrMatlab, plotType, durationMaxS);
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

View File

@@ -0,0 +1,99 @@
#include <stdlib.h>
#include <iostream>
// Slice
#include "VTSliceSM.h"
#include "VTSliceGM.h"
#include "VTSliceGMHOST.h"
// Montecarlo
#include "entier_montecarlo.h"
#include "VTMontecarlo.h"
#include "VTMontecarloMulti_stream.h"
#include "VTMontecarloMulti_thread.h"
//vector
#include "VTVector.h"
#include "VTVectorBistream.h"
#include "VTVectorTristream.h"
using std::string;
using std::cout;
using std::endl;
/*----------------------------------------------------------------------*\
|* Declaration *|
\*---------------------------------------------------------------------*/
static void slice();
static void montercarlos();
static void vectorStream();
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
int mainTest()
{
// activer ci-dessous seulement le TP voulu (pas tous)
slice(); // voir code ci-dessous pour activer la version voulue
// montercarlos(); // voir code ci-dessous pour activer la version voulue
//vectorStream(); // voir code ci-dessous pour activer la version voulue
return EXIT_SUCCESS;
}
/*--------------------------------------*\
|* private *|
\*-------------------------------------*/
/**
* activer ci-dessous la version souhaiter
*/
void slice()
{
VTSliceGMHOST test1;
VTSliceGM test2;
VTSliceSM test3;
test1.run();
// test2.run();
// test3.run();
}
/**
* activer ci-dessous la version souhaiter
* Warning: a lancer une fois en int une fois en long (TODO cbi a checker
*/
void montercarlos()
{
VTMontecarlo test1;
VTMontecarloMulti_thread test2;
VTMontecarloMulti_stream test3;
test1.run();
// test2.run();
// test3.run();
}
/**
* activer ci-dessous la version souhaiter
*/
void vectorStream()
{
VTVector test1;
VTVectorBistream test2;
VTVectorTristream test3;
test1.run();
// test2.run();
// test3.run();
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/

216
Student_Cuda/src/main/mainUse.cpp Executable file
View File

@@ -0,0 +1,216 @@
#include <iostream>
#include <stdlib.h>
using std::cerr;
using std::cout;
using std::endl;
#include "Limits.h"
#include "Couts.h"
// Slice
#include "SliceGmHostUse.h"
#include "SliceGmUse.h"
#include "SliceSmUse.h"
#include "SliceMultiUse.h"
// Montecarlo
#include "entier_montecarlo.h"
#include "MontecarloUse.h"
#include "MontecarloMultiUse_thread.h"
#include "MontecarloMultiUse_stream.h"
// Vector
#include "AddVectorUse.h"
#include "AddVectorBistreamUse.h"
#include "AddVectorTristreamUse.h"
#include "VectorTools.h"
/*----------------------------------------------------------------------*\
|* declaration *|
\*---------------------------------------------------------------------*/
static void slice(bool& isOk);
static void montecarlo_use(bool& isOk);
static void vector(bool& isOk);
static void print(bool isSuccess);
/*----------------------------------------------------------------------*\
|* Implementation *|
\*---------------------------------------------------------------------*/
static const int IS_VERBOSE = true;
int mainUse()
{
// activer ci-dessous seulement le TP voulu (pas tous)
bool isOk = true;
slice(isOk); // voir code ci-dessous pour activer la version voulue
//montecarlo_use(isOk); // voir code ci-dessous pour activer la version voulue
//vector(isOk); // voir code ci-dessous pour activer la version voulue
print(isOk);
return isOk ? EXIT_SUCCESS : EXIT_FAILURE;
}
/*----------------------------------------------------------------------*\
|* TP *|
\*---------------------------------------------------------------------*/
/**
* activer ci-dessous la version souhaiter
*/
void slice(bool& isOk)
{
SliceGmHostUse sliceGmHostUse(IS_VERBOSE);
SliceGmUse sliceGmUse(IS_VERBOSE);
SliceSmUse sliceSmUse(IS_VERBOSE);
isOk &= sliceGmHostUse.isOk(IS_VERBOSE);
// isOk &= sliceGmUse.isOk(IS_VERBOSE);
// isOk &= sliceSmUse.isOk(IS_VERBOSE);
}
/**
* activer ci-dessous la version souhaiter
*/
void montecarlo_use(bool& isOk)
{
const float HMIN = 4;
const float HMAX = 10;
cout << endl;
// mono
{
for (float h = HMIN; h <= HMAX; h = h + 1)
{
MontecarloUse algo(IS_VERBOSE, h);
isOk &= algo.isOk(IS_VERBOSE);
}
}
cout << endl;
// thread
{
for (float h = HMIN; h <= HMAX; h = h + 1)
{
MontecarloMultiUse_thread algo(IS_VERBOSE, h);
isOk &= algo.isOk(IS_VERBOSE);
}
}
cout << endl;
// stream
{
for (float h = HMIN; h <= HMAX; h = h + 1)
{
MontecarloMultiUse_stream algo(IS_VERBOSE, h);
isOk &= algo.isOk(IS_VERBOSE);
}
}
cout << endl;
}
/**
* activer ci-dessous la version souhaiter
*/
void vector(bool& isOk)
{
// Base line
{
AddVectorUse algo(IS_VERBOSE);
isOk &= algo.isOk(false);
}
// Bi-stream
{
AddVectorBistreamUse algo(IS_VERBOSE);
isOk &= algo.isOk(false);
}
const bool IS_WARMUP = true;
// Warning :
// On ne peut pas en meme temps lancer en mode warmup et en mode generic.
// D'abord on valide completement le mode warmup (les 3) puis apres on attaque le mode generic.
// Une fois le mode generic fonctionel, le mode warmup n'est plus tres utile.
// Il nous a juste permis de contruire le mode generic
// Sauf erreur, les tests unitaires ne sont coder que pour le cas generique.
if (IS_WARMUP) // Tri-stream : warmup 3 4 5 slices
{
// Warning :
// (W0) Le code warump doit etre activer dans votre implementation soit pour 3 4 ou 5 slices
// (W1) Le true ci-dessous implique un affichage dans la console
// (W2) Dans ce cas il serait bien que VectorTools:n() soit petit
// (W3) Changer le provisoirement
// (W4) Ce n doit etre divisible par nbSlice
// (W5) Il faut donc changer le code a 4 endroits differents
// ICI : nbSlice
// ICI : IS_WARMUP
// VectorToos.n()
// void AddVectorTristream::run()
int nbSlice = 3;
// int nbSlice = 4;
// int nbSlice = 5;
AddVectorTristreamUse algo(nbSlice, IS_VERBOSE); // true implique un affichage dans la console
bool isOkSlice = algo.isOk(false);
//cout <<"Tri-stream : warmup : #slice = "<<nbSlice << " : success = "<<isOkSlice<<endl;
isOk &= isOkSlice;
}
else // Tri-stream (generic) : Warning : le code generic doit etre activer dans votre implementation
{
// Use1
{
for (int nbSlice = 3; nbSlice <= 15; nbSlice++)
{
AddVectorTristreamUse algo(nbSlice, IS_VERBOSE);
bool isOkSlice = algo.isOk(false);
//cout <<"Tri-stream : #slice = "<<nbSlice << " : success = "<<isOkSlice<<endl;
isOk &= isOkSlice;
}
}
// Use2
{
for (int nbSlice = 5; nbSlice <= 75; nbSlice += 5)
{
AddVectorTristreamUse algo(nbSlice, IS_VERBOSE);
bool isOkSlice = algo.isOk(false);
//cout <<"Tri-stream : #slice = "<<nbSlice << " : success = "<<isOkSlice<<endl;
isOk &= isOkSlice;
}
}
}
}
/*----------------------------------------------------------------------*\
|* Tools *|
\*---------------------------------------------------------------------*/
void print(bool isSuccess)
{
cout << endl << Couts::REVERSE;
Couts::status(isSuccess, "Success, Congratulations !", "Failed, sorry!");
cout << endl << Couts::RESET;
}
/*----------------------------------------------------------------------*\
|* End *|
\*---------------------------------------------------------------------*/