Commit 1cde3ed4 authored by maitre's avatar maitre
Browse files

Cuda unstable, rc3 for std tpl

parent fa39069c
......@@ -67,7 +67,7 @@ Centre de Math
bool bDoubleQuotes,bWithinDisplayFunction,bWithinInitialiser,bWithinMutator,bWithinXover;
bool bWaitingForSemiColon,bFinishNB_GEN,bFinishMINIMISE,bFinishMINIMIZE,bGenerationFunction;
bool bCatchNextSemiColon,bWaitingToClosePopulation, bMethodsInGenome, bFinalizationFunction;
bool bWithinCUDA_Initializer, bWithinMAKEFILEOPTION;
bool bWithinCUDA_Initializer, bWithinMAKEFILEOPTION, bWithinCUDA_Evaluator;
CSymbol *pASymbol;
public:
......@@ -82,7 +82,7 @@ Centre de Math
bSymbolInserted=bDoubleQuotes=bWithinDisplayFunction=bWithinInitialiser=bWithinMutator=bWithinXover=0;
bWaitingForSemiColon=bFinishNB_GEN=bFinishMINIMISE=bFinishMINIMIZE=bGenerationFunction=0;
bCatchNextSemiColon,bWaitingToClosePopulation=bMethodsInGenome=0;
bWithinCUDA_Initializer=0, bWithinMAKEFILEOPTION;
bWithinCUDA_Initializer=bWithinMAKEFILEOPTION =bWithinCUDA_Evaluator=0;
}
// macros
......@@ -179,6 +179,68 @@ exponent ([Ee][+-]?[0-9]+)
}
}
<TEMPLATE_ANALYSIS>"\\GENOME_SIZE" {
CListItem<CSymbol*> *pSym;
if (bVERBOSE) printf ("Inserting default genome size calculator.\n");
pGENOME->pSymbolList->reset();
size_t size_of_genome=0;
while (pSym=pGENOME->pSymbolList->walkToNextItem()){
/* if (pSym->Object->ObjectQualifier==1) continue; // 1=Static */
/* if ((pSym->Object->ObjectType==oArray)&&(TARGET==DREAM)) */
/* fprintf(fpOutputFile," %s = new %s[%d];\n",pSym->Object->sName,pSym->Object->pType->sName,pSym->Object->nSize/pSym->Object->pType->nSize); */
/* if (pSym->Object->ObjectType==oPointer){ */
/* if (TARGET==DREAM) fprintf(fpOutputFile," %s=null;\n",pSym->Object->sName); */
/* else fprintf(fpOutputFile," %s=NULL;\n",pSym->Object->sName); */
/* } */
DEBUG_PRT("%s has size : %lu",pSym->Object->sName,pSym->Object->nSize);
size_of_genome+=pSym->Object->nSize;
}
fprintf(fpOutputFile,"%d",size_of_genome);
DEBUG_PRT("Total genome size is %lu",size_of_genome);
}
<TEMPLATE_ANALYSIS>"\\COPY_CUDA_BUFFER" {
CListItem<CSymbol*> *pSym;
if (bVERBOSE) printf ("Inserting default genome constructor.\n");
pGENOME->pSymbolList->reset();
fprintf(fpOutputFile,"\tmemcpy(GENOME_ACCESS(id,buffer),this,Individual::sizeOfGenome);");
while (pSym=pGENOME->pSymbolList->walkToNextItem()){
if (pSym->Object->ObjectQualifier==1) continue; // 1=Static
if ((pSym->Object->ObjectType==oArray)&&(TARGET==DREAM))
fprintf(fpOutputFile," %s = new %s[%d];\n",pSym->Object->sName,pSym->Object->pType->sName,pSym->Object->nSize/pSym->Object->pType->nSize);
if (pSym->Object->ObjectType==oPointer){
if (TARGET==DREAM) fprintf(fpOutputFile," %s=null;\n",pSym->Object->sName);
else fprintf(fpOutputFile," %s=NULL;\n",pSym->Object->sName);
}
}
}
/* <TEMPLATE_ANALYSIS>"\\GENOME_CUDA_MOTION" { */
/* if (bVERBOSE) printf ("Inserting default genome cuda motion function.\n"); */
/* CListItem<CSymbol*> *pSym; */
/* if (bVERBOSE) printf ("Creating default copy constructor.\n"); */
/* fprintf (fpOutputFile,"// Memberwise copy\n"); */
/* pGENOME->pSymbolList->reset(); */
/* while (pSym=pGENOME->pSymbolList->walkToNextItem()){ */
/* if (pSym->Object->ObjectQualifier==1) continue; // 1=Static */
/* if (pSym->Object->ObjectType==oObject) */
/* fprintf(fpOutputFile," %s=genome.%s;\n",pSym->Object->sName,pSym->Object->sName); */
/* if (pSym->Object->ObjectType==oPointer) */
/* fprintf(fpOutputFile," %s=(genome.%s ? new %s(*(genome.%s)) : NULL);\n",pSym->Object->sName,pSym->Object->sName,pSym->Object->pType->sName,pSym->Object->sName); */
/* if (pSym->Object->ObjectType==oArray){ */
/* /\* fprintf(fpOutputFile," {for(int EASEA_Ndx=0; EASEA_Ndx<%d; EASEA_Ndx++)\n",pSym->Object->nSize/pSym->Object->pType->nSize); *\/ */
/* /\* fprintf(fpOutputFile," %s[EASEA_Ndx]=genome.%s[EASEA_Ndx];}\n",pSym->Object->sName,pSym->Object->sName); *\/ */
/* } */
/* } */
/* } */
<TEMPLATE_ANALYSIS>"\\GENOME_SERIAL" {
CListItem<CSymbol*> *pSym;
......@@ -462,6 +524,14 @@ exponent ([Ee][+-]?[0-9]+)
yyin = fpGenomeFile; // switch to .ez file and analyser
BEGIN COPY_EVALUATOR;
}
<TEMPLATE_ANALYSIS>"\\INSERT_CUDA_EVALUATOR" {
yyreset();
yyin = fpGenomeFile; // switch to .ez file and analyser
bWithinCUDA_Evaluator = 1;
BEGIN COPY_EVALUATOR;
}
<TEMPLATE_ANALYSIS>"\\ANALYSE_PARAMETERS" {
yyreset();
yyin = fpGenomeFile; // switch to .ez file and analyser
......@@ -1421,7 +1491,10 @@ exponent ([Ee][+-]?[0-9]+)
if (bWithinDisplayFunction) fprintf(fpOutputFile,"(*this)");
else if ((TARGET==EO)&&(bWithinInitialiser)) fprintf(fpOutputFile, "(*genome)");
else if ((TARGET==CUDA || TARGET==STD) && ((bWithinEvaluator) || bWithinMutator)) fprintf(fpOutputFile, "(*this)");
else if ((TARGET==CUDA || TARGET==STD) && ((bWithinEvaluator) || bWithinMutator))
if( bWithinCUDA_Evaluator)
fprintf(fpOutputFile, "(*INDIVIDUAL_ACCESS(devBuffer,id))");
else fprintf(fpOutputFile, "(*this)");
else if ((TARGET==EO)&&(bWithinMutator)) fprintf(fpOutputFile, "_genotype");
else fprintf(fpOutputFile,"genome");} // local genome name
......@@ -1497,7 +1570,12 @@ exponent ([Ee][+-]?[0-9]+)
else if (TARGET==EO) {fprintf(fpOutputFile,"genome.fitness(");bCatchNextSemiColon=true;}// changes function type// changes function type
else if (TARGET==DREAM) {fprintf(fpOutputFile,"infoHabitant.setFitness(new Double(");bCatchNextSemiColon=true;}// changes function type
else if( TARGET==CUDA || TARGET==STD) {
fprintf(fpOutputFile,"return fitness = ");
if( bWithinCUDA_Evaluator ){
fprintf(fpOutputFile,"return ");
bWithinCUDA_Evaluator = 0;
}
else
fprintf(fpOutputFile,"return fitness = ");
bCatchNextSemiColon=false;
}
bWithinEvaluator=0;
......
......@@ -43,8 +43,7 @@ void cross(GenomeClass *pChild, GenomeClass *pParent, int locus){
\end
\Finalization function:
std::cout << "fonction de finalization svp" << std::endl;
// std::cout << population ;
std::cout << population ;
\end
\GenomeClass::initialiser:
......
......@@ -18,7 +18,8 @@ __________________________________________________________*/
float pMutPerGene=0.1;
int n = 10;
#define N_LIM 10
int n = N_LIM;
double (*Fitness)(double *, int); // pointeur sur la fonction de fitness designee dans argv[1]
double Sphere(double *, int);
......@@ -26,9 +27,9 @@ double AckleyPath(double *, int);
double Easom(double *, int);
double Griewangk(double *, int);
double Rastrigin(double *, int);
double Rosenbrock(double *, int);
double Schwefel(double *, int);
double Weierstrass(double *, int);
float Rosenbrock(float *, int);
float Schwefel(float *, int);
float Weierstrass(float *, int);
\end
......@@ -36,66 +37,66 @@ double Weierstrass(double *, int);
//fitness function
#include <math.h>
inline double Sphere(double x[SIZE], int n) // Ex-DeJong function 1
inline float Sphere(float x[SIZE], int n) // Ex-DeJong function 1
{
double ret = 0;
float ret = 0;
for (int i = 0;i<n; i++) ret += x[ i ] * x[ i ];
return ret;
}
inline double AckleyPath(double x[SIZE], int n)
inline float AckleyPath(float x[SIZE], int n)
{
//Parameters
double a = 20.;
double b = 0.2;
double c = 2*PI;
double Scale = 32.768; // pour matcher avec les limites [-1,1]
float a = 20.;
float b = 0.2;
float c = 2*PI;
float Scale = 32.768; // pour matcher avec les limites [-1,1]
//Function computation
double sum_x2 = 0.0;
double sum_cos_cx = 0.0;
float sum_x2 = 0.0;
float sum_cos_cx = 0.0;
for (int i=0; i<n; i++) {
sum_x2 += Scale*Scale*x[i]*x[i];
sum_cos_cx += cos(c*Scale*x[i]);
}
double res = -a * exp( -b * sqrt( 1/(double)n * sum_x2) ) - exp( 1/(double)n * sum_cos_cx ) + a + exp(1);
float res = -a * exp( -b * sqrt( 1/(float)n * sum_x2) ) - exp( 1/(float)n * sum_cos_cx ) + a + exp(1);
return res;
}
inline double Easom(double x[SIZE], int n)
inline float Easom(float x[SIZE], int n)
{
double res = 1.;
float res = 1.;
//function computation
for (int i=0; i<n; i++)
res *= cos(100.*x[i])*exp(-(100.*x[i]-PI)*(100.*x[i]-PI));
return (1.-res); // pour avoir un minimum a 0.
}
inline double Griewangk(double x[SIZE], int n)
inline float Griewangk(float x[SIZE], int n)
{
double res, sum = 0., prod =1.;
double Scale = 600.; // pour matcher avec les limites [-1,1]
float res, sum = 0., prod =1.;
float Scale = 600.; // pour matcher avec les limites [-1,1]
for (int i=1; i<=n; i++) {
prod *= cos( Scale*x[i]/sqrt( (double)i ) );
prod *= cos( Scale*x[i]/sqrt( (float)i ) );
sum += (Scale*Scale*x[i]*x[i]/4000.);
}
res = sum - prod + 1.;
return res;
}
inline double Rastrigin(double x[SIZE], int n)
inline float Rastrigin(float x[SIZE], int n)
{
double res = 0.;
double Scale = 5.12; // pour matcher avec les limites [-1,1]
float res = 0.;
float Scale = 5.12; // pour matcher avec les limites [-1,1]
for (int i = 0;i<n; i++)
res += ((Scale*Scale*x[i]*x[i])-10*cos( 2*PI*Scale*x[i]));
return (10.*n + res);
}
inline double Rosenbrock(double x[SIZE], int n)
inline float Rosenbrock(float x[SIZE], int n)
{
double res = 0.;
double Scale = 2.048; // pour matcher avec les limites [-1,1]
float res = 0.;
float Scale = 2.048; // pour matcher avec les limites [-1,1]
for (int i = 0;i<n; i++)
res += 100.*((Scale*x[i+1] - Scale*Scale*x[i]*x[i])*(Scale*x[i+1]
......@@ -103,40 +104,40 @@ inline double Rosenbrock(double x[SIZE], int n)
return (res);
}
inline double Schwefel(double x[SIZE], int n)
inline float Schwefel(float x[SIZE], int n)
{
double res = 0.;
double Scale = 500.; // pour matcher avec les limites [-1,1]
float res = 0.;
float Scale = 500.; // pour matcher avec les limites [-1,1]
for (int i = 0;i<n; i++)
res += (-Scale*x[i]*sin( sqrt(Abs(Scale*x[i]))));
return ((double)n*418.9829 + res);
return ((float)n*418.9829 + res);
}
inline double Weierstrass(double x[SIZE], int n) // Weierstrass multimidmensionnel h = 0.25
__device__ __host__ inline float Weierstrass(float x[SIZE], int n) // Weierstrass multimidmensionnel h = 0.25
{
double res = 0.;
double val[SIZE];
double b=2.;
double h = 0.25;
float res = 0.;
float val[SIZE];
float b=2.;
float h = 0.25;
for (int i = 0;i<n; i++) {
val[i] = 0.;
for (int k=0;k<ITER;k++)
val[i] += pow(b,-(double)k*h) * sin(pow(b,(double)k)*x[i]);
val[i] += pow(b,-(float)k*h) * sin(pow(b,(float)k)*x[i]);
res += Abs(val[i]);
}
return (res);
}
double gauss()
float gauss()
/* Generates a normally distributed random value with variance 1 and 0 mean.
Algorithm based on "gasdev" from Numerical recipes' pg. 203. */
{
int iset = 0;
double gset = 0.0;
double v1 = 0.0, v2 = 0.0, r = 0.0;
double factor = 0.0;
float gset = 0.0;
float v1 = 0.0, v2 = 0.0, r = 0.0;
float factor = 0.0;
if (iset) {
iset = 0;
......@@ -144,8 +145,8 @@ double gauss()
}
else {
do {
v1 = (double)globalRandomGenerator->randFloat(0.,1.) * 2.0 - 1.0;
v2 = (double)globalRandomGenerator->randFloat(0.,1.) * 2.0 - 1.0;
v1 = (float)globalRandomGenerator->randFloat(0.,1.) * 2.0 - 1.0;
v2 = (float)globalRandomGenerator->randFloat(0.,1.) * 2.0 - 1.0;
r = v1 * v1 + v2 * v2;
}
while (r > 1.0);
......@@ -183,7 +184,7 @@ double gauss()
std::cout<<"************* n: "<<n<<std::endl;
// pour l'impression dans le fichier de resultats
/* double MinTheo = 0.; */
/* float MinTheo = 0.; */
// printf("%s_T_ad n= %s MinTheo= %f ",argv[1],argv[2],MinTheo);
\end
......@@ -193,22 +194,22 @@ cout << "finalization function called" << endl;
\User classes :
GenomeClass {
double x[SIZE];
double sigma[SIZE]; // auto-adaptative mutation parameter
float x[SIZE];
float sigma[SIZE]; // auto-adaptative mutation parameter
}
\end
\GenomeClass::initialiser : // "initializer" is also accepted
for(int i=0; i<n; i++ ) {
Genome.x[i] = (double)random(X_MIN,X_MAX);
Genome.sigma[i]=(double)random(0.,0.5);
Genome.x[i] = (float)random(X_MIN,X_MAX);
Genome.sigma[i]=(float)random(0.,0.5);
}
\end
\GenomeClass::crossover :
for (int i=0; i<n; i++)
for (int i=0; i<n; i++)
{
double alpha = (double)globalRandomGenerator->getRandomIntMax(1.); // barycentric crossover
float alpha = (float)globalRandomGenerator->getRandomIntMax(1.); // barycentric crossover
child1.x[i] = alpha*parent1.x[i] + (1.-alpha)*parent2.x[i];
//if (&child2) child2.x[i] = alpha*parent2.x[i] + (1.-alpha)*parent1.x[i];
}
......@@ -216,15 +217,15 @@ GenomeClass {
\GenomeClass::mutator : // Must return the number of mutations
int NbMut=0;
double pond = 1./sqrt((double)n);
float pond = 1./sqrt((float)n);
for (int i=0; i<n; i++)
if (tossCoin(pMutPerGene)){
NbMut++;
Genome.sigma[i] = Genome.sigma[i] * exp(SIGMA*pond*(double)gauss());
Genome.sigma[i] = Genome.sigma[i] * exp(SIGMA*pond*(float)gauss());
Genome.sigma[i] = MIN(0.5,Genome.sigma[0]);
Genome.sigma[i] = MAX(0.,Genome.sigma[0]);
Genome.x[i] += Genome.sigma[i]*(double)gauss();
Genome.x[i] += Genome.sigma[i]*(float)gauss();
Genome.x[i] = MIN(X_MAX,Genome.x[i]); // pour eviter les depassements
Genome.x[i] = MAX(X_MIN,Genome.x[i]);
}
......@@ -232,10 +233,10 @@ return NbMut;
\end
\GenomeClass::evaluator : // Returns the score
double Score= 0.0;
double Point[SIZE];
for (int i=0; i<n; i++) Point[i] = Genome.x[i];
Score= Weierstrass(Point, n);
float Score= 0.0;
float Point[SIZE];
for (int i=0; i<N_LIM; i++) Point[i] = Genome.x[i];
Score= Weierstrass(Point, N_LIM);
return Score;
\end
......
EXEC = main.out
CPPFLAGS += -DUNIX_OS -Ialexyacc/include/ -g
CPPC = g++
CPPFLAGS += -DUNIX_OS -Ialexyacc/include/ -g -Wno-deprecated
CPPC = g++
LDFLAGS =
......
......@@ -7,38 +7,43 @@ using namespace std;
#include <iostream>
#include "EASEATools.hpp"
#include "EASEAIndividual.hpp"
#include <time.h>
RandomGenerator* globalRandomGenerator;
int main(int argc, char** argv){
size_t parentPopulationSize = \POP_SIZE;
size_t offspringPopulationSize = \OFF_SIZE;
parseArguments("EASEA.prm",argc,argv);
size_t parentPopulationSize = setVariable("popSize",\POP_SIZE);
size_t offspringPopulationSize = setVariable("nbOffspring",\OFF_SIZE);
float pCrossover = \XOVER_PROB;
float pMutation = \MUT_PROB;
float pMutationPerGene = 0.05;
globalRandomGenerator = new RandomGenerator(0);
time_t seed = setVariable("seed",time(0));
globalRandomGenerator = new RandomGenerator(seed);
std::cout << "Seed is : " << seed << std::endl;
SelectionOperator* selectionOperator = new \SELECTOR;
SelectionOperator* replacementOperator = new \RED_FINAL;
float selectionPressure = \SELECT_PRM;
float replacementPressure = \RED_FINAL_PRM;
string outputfile = setVariable("outputfile","");
string inputfile = setVariable("inputfile","");
\INSERT_INIT_FCT_CALL
EASEAInit(argc,argv);
EvolutionaryAlgorithm ea(parentPopulationSize,offspringPopulationSize,selectionPressure,replacementPressure,
selectionOperator,replacementOperator,pCrossover, pMutation, pMutationPerGene);
selectionOperator,replacementOperator,pCrossover, pMutation, pMutationPerGene,outputfile,inputfile);
StoppingCriterion* sc = new GenerationalCriterion(&ea,\NB_GEN);
StoppingCriterion* sc = new GenerationalCriterion(&ea,setVariable("nbGen",\NB_GEN));
ea.addStoppingCriterion(sc);
Population* pop = ea.getPopulation();
//pop->initializeParentPopulation();
//pop->evaluateParentPopulation();
//cout << *pop;
ea.runEvolutionaryLoop();
......@@ -46,6 +51,10 @@ int main(int argc, char** argv){
delete pop;
delete sc;
delete selectionOperator;
delete replacementOperator;
delete globalRandomGenerator;
return 0;
}
......@@ -54,6 +63,12 @@ int main(int argc, char** argv){
\START_CUDA_GENOME_CU_TPL
#include "EASEAIndividual.hpp"
#include "EASEAUserClasses.hpp"
#include <string.h>
#include <fstream>
#include <sys/time.h>
#include "EASEATools.hpp"
#define STD_TPL
extern RandomGenerator* globalRandomGenerator;
......@@ -64,12 +79,17 @@ extern RandomGenerator* globalRandomGenerator;
\INSERT_INITIALISATION_FUNCTION
\INSERT_FINALIZATION_FUNCTION
\INSERT_GENERATION_FUNCTION
void EASEAFinal(Population* pop){
\INSERT_FINALIZATION_FCT_CALL
}
void EASEAInit(int argc, char** argv){
\INSERT_INIT_FCT_CALL
}
using namespace std;
RandomGenerator* Individual::rg;
......@@ -95,6 +115,33 @@ float Individual::evaluate(){
}
}
/**
This function allows to acces to the Individual stored in cudaBuffer as a standard
individual.
*/
__device__ __host__ inline Individual* INDIVIDUAL_ACCESS(void* buffer,size_t id){
return ((Individual*)(((char*)buffer)+(\GENOME_SIZE+sizeof(void*))*id));
}
__device__ float cudaEvaluate(void* devBuffer, size_t id){
\INSERT_CUDA_EVALUATOR
}
void Individual::copyToCudaBuffer(void* buffer, size_t id){
DEBUG_PRT("%p\n",(char*)this+sizeof(Individual*));
DEBUG_PRT("%p\n",&this->sigma);
DEBUG_PRT("%lu\n",id);
memcpy(((char*)buffer)+(\GENOME_SIZE+sizeof(Individual*))*id,((char*)this),\GENOME_SIZE+sizeof(Individual*));
}
Individual::Individual(const Individual& genome){
// ********************
......@@ -115,7 +162,7 @@ Individual* Individual::crossover(Individual** ps){
Individual parent2(*ps[0]);
Individual child1(*this);
DEBUG_PRT("Xover");
//DEBUG_PRT("Xover");
/* cout << "p1 : " << parent1 << endl; */
/* cout << "p2 : " << parent2 << endl; */
......@@ -149,13 +196,14 @@ std::ostream& operator << (std::ostream& O, const Individual& B)
size_t Individual::mutate( float pMutationPerGene ){
this->valid=false;
// ********************
// Problem specific part
\INSERT_MUTATOR
}
size_t Individual::sizeOfGenome=\GENOME_SIZE;
/* ****************************************
EvolutionaryAlgorithm class
****************************************/
......@@ -194,7 +242,7 @@ EvolutionaryAlgorithm::EvolutionaryAlgorithm( size_t parentPopulationSize,
float selectionPressure, float replacementPressure,
SelectionOperator* selectionOperator, SelectionOperator* replacementOperator,
float pCrossover, float pMutation,
float pMutationPerGene){
float pMutationPerGene, string& outputfile, string& inputfile){
RandomGenerator* rg = globalRandomGenerator;
......@@ -212,7 +260,130 @@ EvolutionaryAlgorithm::EvolutionaryAlgorithm( size_t parentPopulationSize,
this->reduceParents = 0;
this->reduceOffsprings = 0;
if( outputfile.length() )
this->outputfile = new string(outputfile);
else
this->outputfile = NULL;
if( inputfile.length() )
this->inputfile = new std::string(inputfile);
else
this->inputfile = NULL;
}
// do the repartition of data accross threads
__global__ void
cudaEvaluatePopulation(void* d_population, size_t popSize, float* d_fitnesses){
size_t id = (blockDim.x*blockIdx.x)+threadIdx.x; // id of the individual computed by this thread
// escaping for the last block
if(blockIdx.x == (gridDim.x-1)) if( id >= popSize ) return;
void* indiv = ((char*)d_population)+id*(\GENOME_SIZE+sizeof(Individual*)); // compute the offset of the current individual
d_fitnesses[id] = cudaEvaluate(indiv,id);
}
#define NB_MP 16
inline size_t
partieEntiereSup(float E){
int fl = floor(E);
if( fl == E )
return E;
else
return floor(E)+1;
}
inline int
puissanceDeuxSup(float n){
int tmp = 2;
while(tmp<n)tmp*=2;
return tmp;
}
bool
repartition(size_t popSize, size_t* nbBlock, size_t* nbThreadPB, size_t* nbThreadLB,
size_t nbMP, size_t maxBlockSize){
(*nbThreadLB) = 0;
if( ((float)popSize / (float)nbMP) <= maxBlockSize ){
//la population repartie sur les MP tient dans une bloc par MP
(*nbThreadPB) = partieEntiereSup( (float)popSize/(float)nbMP);
(*nbBlock) = popSize/(*nbThreadPB);
if( popSize%nbMP != 0 ){
//on fait MP-1 block de equivalent et un plus petit
(*nbThreadLB) = popSize - (*nbThreadPB)*(*nbBlock);
}
}
else{
//la population est trop grande pour etre repartie sur les MP
//directement
//(*nbBlock) = partieEntiereSup( (float)popSize/((float)maxBlockSize*NB_MP));
(*nbBlock) = puissanceDeuxSup( (float)popSize/((float)maxBlockSize*NB_MP));
(*nbBlock) *= NB_MP;
(*nbThreadPB) = popSize/(*nbBlock);
if( popSize%maxBlockSize!=0){
(*nbThreadLB) = popSize - (*nbThreadPB)*(*nbBlock);
// Le rest est trop grand pour etre place dans un seul block (c'est possible uniquement qd
// le nombre de block depasse maxBlockSize
while( (*nbThreadLB) > maxBlockSize ){
//on augmente le nombre de blocs principaux jusqu'a ce que nbthreadLB retombe en dessous de maxBlockSize
//(*nbBlock) += nbMP;
(*nbBlock) *= 2;
(*nbThreadPB) = popSize/(*nbBlock);
(*nbThreadLB) = popSize - (*nbThreadPB)*(*nbBlock);
}
}
}