From fbec5a3863135d0ac5b17257fff345cb3db39a27 Mon Sep 17 00:00:00 2001 From: Jonathan Rouzaud-Cornabas <jonathan.rouzaud-cornabas@inria.fr> Date: Tue, 3 Jul 2018 14:46:31 +0200 Subject: [PATCH] Verified version with OpenMP Task without dependency --- src/libaevol/JumpingMT.cpp | 3 +- src/libaevol/JumpingMT.h | 2 +- src/libaevol/SIMD_Individual.cpp | 72 ++++++++++++++++++++------------ src/libaevol/Selection.cpp | 20 +++++++-- 4 files changed, 64 insertions(+), 33 deletions(-) diff --git a/src/libaevol/JumpingMT.cpp b/src/libaevol/JumpingMT.cpp index 97c4f0277..8d5b61e2b 100644 --- a/src/libaevol/JumpingMT.cpp +++ b/src/libaevol/JumpingMT.cpp @@ -236,13 +236,14 @@ double JumpingMT::gaussian_random() return x1 * r; } -int32_t JumpingMT::roulette_random(double* probs, int32_t nb_elts) +int32_t JumpingMT::roulette_random(double* probs, int32_t nb_elts, bool verbose ) { double pick_one = 0.0; while (pick_one == 0.0) { pick_one = random(); + //if (verbose) printf("pick one : %f\n",pick_one); } int32_t found_org = 0; diff --git a/src/libaevol/JumpingMT.h b/src/libaevol/JumpingMT.h index 4b0e38253..85b3ef6f4 100644 --- a/src/libaevol/JumpingMT.h +++ b/src/libaevol/JumpingMT.h @@ -101,7 +101,7 @@ class JumpingMT inline int64_t random(int64_t max); // ~ int32_t binomial_random(int32_t nb, double prob); // Binomial drawing of parameters (nb, prob) double gaussian_random(); // Double following a Standard Normal distribution - int32_t roulette_random(double* probs, int32_t nb_elts); // Roulette selection + int32_t roulette_random(double* probs, int32_t nb_elts, bool verbose = false); // Roulette selection void multinomial_drawing (int32_t* destination, double* source, int32_t nb_drawings, int32_t colors); // Multinomial drawing of parameters (nb, {source[0], source[1], ... source[colors-1]}) diff --git a/src/libaevol/SIMD_Individual.cpp b/src/libaevol/SIMD_Individual.cpp index 4d9561aa0..a44d22ef7 100644 --- a/src/libaevol/SIMD_Individual.cpp +++ b/src/libaevol/SIMD_Individual.cpp @@ -246,26 +246,32 @@ void SIMD_Individual::selection() { local_fit_array[count] = prev_internal_simd_struct[cur_x*grid_height+cur_y]->fitness; -/* printf("Local fit %e %d %d %d -> %e\n",local_fit_array[count],cur_x,cur_y,cur_x*grid_height+cur_y, - prev_internal_simd_struct[cur_x*grid_height+cur_y]->fitness);*/ +// printf("Local fit %e %d %d %d -> %e\n",local_fit_array[count],cur_x,cur_y,cur_x*grid_height+cur_y, +// prev_internal_simd_struct[cur_x*grid_height+cur_y]->fitness); local_meta_array[count] = prev_internal_simd_struct[cur_x*grid_height+cur_y]->metaerror; sum_local_fit += local_fit_array[count]; -/* if (indiv_id == 268) - printf("SIMD Local SUM Fit %e -- Fitness %e\n",sum_local_fit,local_fit_array[count]);*/ + /*if (indiv_id == 0) + printf("SIMD Local SUM Fit %e -- Fitness %e (CPU %e)\n",sum_local_fit,local_fit_array[count],exp_m_->world()->grid(x,y)->local_fit_array[count]);*/ count++; } } for(int16_t i = 0 ; i < neighborhood_size ; i++) { probs[i] = local_fit_array[i]/sum_local_fit; - /*if (i == 0) - printf("Local fit X %e %d %d %d -> %e\n",local_fit_array[i],cur_x,cur_y,cur_x*grid_height+cur_y, + + /*printf("Local fit X %e %d %d %d -> %e\n",local_fit_array[i],cur_x,cur_y,cur_x*grid_height+cur_y, prev_internal_simd_struct[cur_x*grid_height+cur_y]->fitness);*/ //printf("%d -- prob[%d] : %e : fitness %e (%f) sum %e\n",indiv_id,i,probs[i], // local_fit_array[i],local_meta_array[i],sum_local_fit); } + //printf("SIMD PRNG\n"); + /* bool verbose = false; + if (indiv_id == 2) { + printf("SIMD PRNG\n"); + verbose = true; + }*/ int16_t found_org = exp_m_->world()->grid(x,y)->reprod_prng_simd_->roulette_random(probs, neighborhood_size); int16_t x_offset = (found_org / selection_scope_x) - 1; @@ -276,26 +282,27 @@ void SIMD_Individual::selection() { ((y+y_offset+grid_height) % grid_height); -/* for (int i = 0; i < neighborhood_size; i++) { + for (int i = 0; i < neighborhood_size; i++) { float i_fit_1 = roundf(exp_m_->world()->grid(x,y)->probs[i] * 10000); float i_fit_2 = roundf(probs[i] * 10000); - if (found_id != internal_simd_struct[indiv_id]->parent_id) { + if (found_id != next_generation_reproducer_[indiv_id]) { - printf("For individual %d : Selection is diff SIMD %d CPU %d (Meta error %f -- %f || Fitness %e -- %e (%e %e diff %e -- %e %e -- %e %e)\n", - indiv_id, found_id, internal_simd_struct[indiv_id]->parent_id, - prev_internal_simd_struct[internal_simd_struct[indiv_id]->parent_id]->metaerror, + printf("For individual %d : Selection is diff SIMD %d CPU %d (Meta error %f -- %f || Fitness %e -- %e)\n", + // (Probs %e %e diff %e -- Fit Array %e %e -- Sum Fit %e %e)\n", + indiv_id, found_id, next_generation_reproducer_[indiv_id], + prev_internal_simd_struct[next_generation_reproducer_[indiv_id]]->metaerror, prev_internal_simd_struct[found_id]->metaerror, - prev_internal_simd_struct[internal_simd_struct[indiv_id]->parent_id]->fitness, - prev_internal_simd_struct[found_id]->fitness,exp_m_->world()->grid(x,y)->probs[i],probs[i], + prev_internal_simd_struct[next_generation_reproducer_[indiv_id]]->fitness, + prev_internal_simd_struct[found_id]->fitness/*,exp_m_->world()->grid(x,y)->probs[i],probs[i], exp_m_->world()->grid(x,y)->probs[i]-probs[i], exp_m_->world()->grid(x,y)->local_fit_array[i],local_fit_array[i], - exp_m_->world()->grid(x,y)->sum_local_fit,sum_local_fit + exp_m_->world()->grid(x,y)->sum_local_fit,sum_local_fit*/ ); } - }*/ + } delete [] local_fit_array; @@ -4078,7 +4085,7 @@ void SIMD_Individual::run_a_step(double w_max, double selection_pressure,bool op for (int indiv_id = 0; indiv_id < exp_m_->nb_indivs(); indiv_id++) { #pragma omp task firstprivate(indiv_id) { - //if (optim_prom) check_selection(indiv_id); + // if (AeTime::time() > 0 && optim_prom) check_selection(indiv_id); if (standalone_ && optim_prom) { selection(indiv_id); @@ -4276,19 +4283,29 @@ void SIMD_Individual::run_a_step(double w_max, double selection_pressure,bool op //exit(-44); if (optim_prom) { // printf("OPT -- Copy to old generation struct\n"); - for (int indiv_id = 0; indiv_id < (int) exp_m_->nb_indivs(); indiv_id++) { - if (prev_internal_simd_struct[indiv_id]->usage_count_-1 == 0) - delete prev_internal_simd_struct[indiv_id]; - else - prev_internal_simd_struct[indiv_id]->usage_count_--; - - prev_internal_simd_struct[indiv_id] = internal_simd_struct[indiv_id]; - internal_simd_struct[indiv_id] = nullptr; - } +//#pragma omp parallel +//#pragma omp single +//#pragma omp taskloop + for (int indiv_id = 0; indiv_id < (int) exp_m_->nb_indivs(); indiv_id++) { + int usage_cpt = 0; + + //#pragma omp critical + { + usage_cpt = prev_internal_simd_struct[indiv_id]->usage_count_--; + + if (usage_cpt == 0) + delete prev_internal_simd_struct[indiv_id]; + } + + prev_internal_simd_struct[indiv_id] = internal_simd_struct[indiv_id]; + internal_simd_struct[indiv_id] = nullptr; + } } else { // printf("Copy to old generation struct\n"); - - for (int indiv_id = 0; indiv_id < (int) exp_m_->nb_indivs(); indiv_id++) { +#pragma omp parallel +#pragma omp single +#pragma omp taskloop + for (int indiv_id = 0; indiv_id < (int) exp_m_->nb_indivs(); indiv_id++) { prev_internal_simd_struct[indiv_id] = internal_simd_struct[indiv_id]; internal_simd_struct[indiv_id] = nullptr; @@ -4630,6 +4647,7 @@ Internal_SIMD_Struct::Internal_SIMD_Struct(ExpManager* exp_m, Internal_SIMD_Stru count_prom = 0; exp_m_ = exp_m; + usage_count_ = 1; dna_ = new Dna_SIMD(clone->dna_,this,copy_dna); //promoters.resize(clone->promoters.size()); diff --git a/src/libaevol/Selection.cpp b/src/libaevol/Selection.cpp index 246f0983b..105352323 100644 --- a/src/libaevol/Selection.cpp +++ b/src/libaevol/Selection.cpp @@ -1031,12 +1031,14 @@ Individual *Selection::do_local_competition (int16_t x, int16_t y) { for (int8_t j = -1 ; j < selection_scope_y_-1 ; j++) { cur_x = (x + i + grid_width) % grid_width; cur_y = (y + j + grid_height) % grid_height; - //printf("%d %d : %lf %d\n",cur_x,cur_y,world->indiv_at(cur_x, cur_y)->fitness(),count); local_fit_array[count] = world->indiv_at(cur_x, cur_y)->fitness(); sort_fit_array[count] = local_fit_array[count]; initial_location[count] = count; sum_local_fit += local_fit_array[count]; + + //if (0 == x*grid_height+y) printf("%d %d : %e %d\n",cur_x,cur_y,world->indiv_at(cur_x, cur_y)->fitness(),count); + /* if (268 == x*grid_height+y) printf("CPU Local SUM Fit %e -- Fitness %e\n",sum_local_fit,local_fit_array[count]);*/ count++; @@ -1093,6 +1095,7 @@ Individual *Selection::do_local_competition (int16_t x, int16_t y) { case FITNESS_PROPORTIONATE : { for(int16_t i = 0 ; i < neighborhood_size ; i++) { probs[i] = local_fit_array[i]/sum_local_fit; + // if (0 == x*grid_height+y) printf("%d : %e %e\n",i,local_fit_array[i],sum_local_fit); } break; @@ -1104,6 +1107,11 @@ Individual *Selection::do_local_competition (int16_t x, int16_t y) { } // pick one organism to reproduce, based on probs[] calculated above, using roulette selection + /*bool verbose = false; + if (2 == x*grid_height+y) { + printf("PRNG CPU\n"); + verbose = true; + }*/ int16_t found_org = world->grid(x,y)->reprod_prng_->roulette_random(probs, neighborhood_size); int16_t x_offset = (found_org / selection_scope_x_) - 1; @@ -1113,9 +1121,13 @@ Individual *Selection::do_local_competition (int16_t x, int16_t y) { delete [] sort_fit_array; delete [] initial_location; delete [] probs; -/* world->grid(x,y)->probs = probs; - world->grid(x,y)->local_fit_array = local_fit_array; - world->grid(x,y)->sum_local_fit = sum_local_fit;*/ + + //world->grid(x,y)->probs = probs; + //world->grid(x,y)->local_fit_array = local_fit_array; + //world->grid(x,y)->sum_local_fit = sum_local_fit; + + exp_m_->simd_individual->next_generation_reproducer_[x*grid_height+y] = ((x+x_offset+grid_width) % grid_width)*grid_height+ + ((y+y_offset+grid_height) % grid_height); return world->indiv_at((x+x_offset+grid_width) % grid_width, (y+y_offset+grid_height) % grid_height); -- GitLab