8.1.3 : Le main.cpp

On commence avec les includes standards :
1
2
3
4
#include <iostream>

#include <numeric>
#include <execution>


Puis, CURAND :
1
#include <curand.h>


Les includes de Thrust pour manipuler des vecteurs sur le CPU et le GPU
1
2
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>


On commence la fonction principale avec le nombre d'éléments à traiter :
1
2
int main(void){
	size_t nbElement(100000000lu);


Pour une raison obscure, thrust ne veut pas m'allouer mon vecteur directemenr sur le GPU, donc, on l'alloue vite fait sur le CPU et on le copie :
1
2
	thrust::host_vector<float> hValue(nbElement);
	thrust::device_vector<float> dValue = hValue;


On initialise the générateur de nombre aléatoire (juste par défaut) :
1
2
3
	//Create the generator
	curandGenerator_t generator;
	curandCreateGenerator(&generator, CURAND_RNG_PSEUDO_DEFAULT);


On donne un graine, c'est très important car cela permet d'avoir des résultats reproductibles :
1
2
	//Set the random seed
	curandSetPseudoRandomGeneratorSeed(generator, 42);


On génére une distribution gaussienne. Je dois dire que le dValue.data().get() ressemble à une grosse bidouille, mais c'est l'API thrust qui est comme ça :
1
2
	//Generate a normal distribution (generator, data, size, mean, std)
	curandGenerateNormal(generator, (float*)dValue.data().get(), nbElement, 2.0f, 1.0f);


On détruit le générateur de nombres aléatoires :
1
2
	//Destroy the generator
	curandDestroyGenerator(generator);


On appelle un std::reduce comme des gros bourins, car on a activé -stdpar=gpu lors de la compialtion
1
2
3
4
	float res = std::reduce(std::execution::par_unseq,  dValue.begin(), dValue.end());
	std::cout << "mean = " << (res/((float)nbElement)) << std::endl;
	return 0;
}


Le main.cpp complet :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/***************************************
	Auteur : Pierre Aubert
	Mail : pierre.aubert@lapp.in2p3.fr
	Licence : CeCILL-C
****************************************/
#include <iostream>

#include <numeric>
#include <execution>
#include <curand.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>

int main(void){
	size_t nbElement(100000000lu);
	thrust::host_vector<float> hValue(nbElement);
	thrust::device_vector<float> dValue = hValue;
	//Create the generator
	curandGenerator_t generator;
	curandCreateGenerator(&generator, CURAND_RNG_PSEUDO_DEFAULT);
	//Set the random seed
	curandSetPseudoRandomGeneratorSeed(generator, 42);
	//Generate a normal distribution (generator, data, size, mean, std)
	curandGenerateNormal(generator, (float*)dValue.data().get(), nbElement, 2.0f, 1.0f);
	//Destroy the generator
	curandDestroyGenerator(generator);
	float res = std::reduce(std::execution::par_unseq,  dValue.begin(), dValue.end());
	std::cout << "mean = " << (res/((float)nbElement)) << std::endl;
	return 0;
}


Le fichier main.cpp est disponible ici.