chore: init
This commit is contained in:
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
96
Student_Cuda/src/core/01_student/03_Slice/02_Slice_GM/host/SliceGM.cu
Executable file
96
Student_Cuda/src/core/01_student/03_Slice/02_Slice_GM/host/SliceGM.cu
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
63
Student_Cuda/src/core/01_student/03_Slice/02_Slice_GM/host/SliceGM.h
Executable file
63
Student_Cuda/src/core/01_student/03_Slice/02_Slice_GM/host/SliceGM.h
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
95
Student_Cuda/src/core/01_student/03_Slice/03_Slice_SM/host/SliceSM.cu
Executable file
95
Student_Cuda/src/core/01_student/03_Slice/03_Slice_SM/host/SliceSM.cu
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
58
Student_Cuda/src/core/01_student/03_Slice/03_Slice_SM/host/SliceSM.h
Executable file
58
Student_Cuda/src/core/01_student/03_Slice/03_Slice_SM/host/SliceSM.h
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -0,0 +1 @@
|
||||
Aucune partie device specifique, on utilise la classe Montecarlo, qui , elle, fait le job cote device
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
82
Student_Cuda/src/core/01_student/04_Montecarlo/entier_montecarlo.h
Executable file
82
Student_Cuda/src/core/01_student/04_Montecarlo/entier_montecarlo.h
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
210
Student_Cuda/src/core/01_student/05_addvector_stream/00_tools/VectorTools.cpp
Executable file
210
Student_Cuda/src/core/01_student/05_addvector_stream/00_tools/VectorTools.cpp
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
62
Student_Cuda/src/core/01_student/05_addvector_stream/00_tools/VectorTools.h
Executable file
62
Student_Cuda/src/core/01_student/05_addvector_stream/00_tools/VectorTools.h
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
82
Student_Cuda/src/core/01_student/05_addvector_stream/01_device/losetime.cu.h
Executable file
82
Student_Cuda/src/core/01_student/05_addvector_stream/01_device/losetime.cu.h
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
@@ -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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
125
Student_Cuda/src/core/02_private/creator_bridge_montercalo.cpp
Executable file
125
Student_Cuda/src/core/02_private/creator_bridge_montercalo.cpp
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
80
Student_Cuda/src/core/02_private/creator_bridge_slice.cpp
Executable file
80
Student_Cuda/src/core/02_private/creator_bridge_slice.cpp
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
65
Student_Cuda/src/core/02_private/creator_bridge_vector_stream.cpp
Executable file
65
Student_Cuda/src/core/02_private/creator_bridge_vector_stream.cpp
Executable 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
52
Student_Cuda/src/main/main.cpp
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
185
Student_Cuda/src/main/mainBenchmark.cpp
Executable file
185
Student_Cuda/src/main/mainBenchmark.cpp
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
377
Student_Cuda/src/main/mainBruteforce.cpp
Executable file
377
Student_Cuda/src/main/mainBruteforce.cpp
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
99
Student_Cuda/src/main/mainTest.cpp
Executable file
99
Student_Cuda/src/main/mainTest.cpp
Executable 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
216
Student_Cuda/src/main/mainUse.cpp
Executable 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 *|
|
||||
\*---------------------------------------------------------------------*/
|
||||
|
||||
Reference in New Issue
Block a user