139 |
#include "ecosystem.h" |
#include "ecosystem.h" |
140 |
#include "global.h" |
#include "global.h" |
141 |
|
|
142 |
#ifndef NO_OPENMP |
#ifdef _OPENMP |
143 |
#include "omp.h" |
#include "omp.h" |
144 |
#endif |
#endif |
145 |
|
|
146 |
extern Ecosystem* EcoSystem; |
extern Ecosystem* EcoSystem; |
147 |
#ifndef NO_OPENMP |
#ifdef _OPENMP |
148 |
extern Ecosystem** EcoSystems; |
extern Ecosystem** EcoSystems; |
149 |
#endif |
#endif |
150 |
|
|
178 |
} |
} |
179 |
|
|
180 |
/* given a point, look for a better one nearby, one coord at a time */ |
/* given a point, look for a better one nearby, one coord at a time */ |
181 |
#ifndef NO_OPENMP |
#ifdef _OPENMP |
182 |
/* |
/* |
183 |
* function bestBeraby parallelized with OpenMP |
* function bestBeraby parallelized with OpenMP |
184 |
* · 2 threads per coord to parallelize the calculation of +delta/-delta |
* · 2 threads per coord to parallelize the calculation of +delta/-delta |
185 |
* · parallelize the calculation of the best nearby of the coord |
* · parallelize the calculation of the best nearby of the coord |
186 |
*/ |
*/ |
187 |
double OptInfoHooke::bestNearbyOMP(DoubleVector& delta, DoubleVector& point, double prevbest, IntVector& param) { |
double OptInfoHooke::bestNearbyRepro(DoubleVector& delta, DoubleVector& point, double prevbest, IntVector& param) { |
188 |
double minf;//, ftmp; |
double minf;//, ftmp; |
189 |
int i, j, k; |
int i, j, k; |
190 |
DoubleVector z(point); |
DoubleVector z(point); |
209 |
return -1; |
return -1; |
210 |
} |
} |
211 |
|
|
212 |
|
// omp_set_dynamic(0); |
213 |
|
// omp_set_nested(1); //permit the nested parallelization |
214 |
while ( i < nvars) { |
while ( i < nvars) { |
215 |
if ((i + paral_tokens -1) >= nvars) |
if ((i + paral_tokens -1) >= nvars) |
216 |
paral_tokens = nvars - i; |
paral_tokens = nvars - i; |
217 |
omp_set_dynamic(0); |
#pragma omp parallel for num_threads(paral_tokens*2) private(k) //parallelize the parameters (numThr) |
218 |
omp_set_nested(1); //permit the nested parallelization |
for (j = 0; j < (paral_tokens*2); ++j) { |
|
#pragma omp parallel for num_threads(paral_tokens) private(k) //parallelize the parameters (numThr/2) |
|
|
for (j = 0; j < paral_tokens; ++j) { |
|
219 |
storage[j].z = z; |
storage[j].z = z; |
220 |
storage[j].delta = delta; |
storage[j].delta = delta; |
221 |
DoubleVector v1(z); |
DoubleVector v(z); |
|
DoubleVector v2(z); |
|
|
k = param[i+j]; |
|
|
v1[k] += delta[k]; |
|
|
v2[k] -= delta[k]; |
|
222 |
|
|
223 |
#pragma omp parallel sections num_threads(2) //parrallelize the +/- delta simulation for each parameter |
if (j<paral_tokens) { |
224 |
{ |
k = param[i+j]; |
225 |
#pragma omp section |
v[k] += delta[k]; |
|
{ |
|
|
storage[j].ftmp = EcoSystems[j]->SimulateAndUpdate(v1); |
|
|
} |
|
|
#pragma omp section |
|
|
{ |
|
|
storage[j+paral_tokens].ftmp = EcoSystems[j+paral_tokens]->SimulateAndUpdate(v2); |
|
226 |
} |
} |
227 |
|
else { |
228 |
|
k = param[i+j-paral_tokens]; |
229 |
|
v[k] -= delta[k]; |
230 |
} |
} |
231 |
|
|
232 |
|
storage[j].ftmp = EcoSystems[j]->SimulateAndUpdate(v); |
233 |
|
storage[j].z[k] = v[k]; |
234 |
|
} |
235 |
|
for (j = 0; j < paral_tokens; ++j) { |
236 |
|
k = param[i+j]; |
237 |
if (storage[j].ftmp < minf) { |
if (storage[j].ftmp < minf) { |
238 |
storage[j].iters = 1; |
storage[j].iters = 1; |
239 |
storage[j].z[k] = v1[k]; |
// storage[j].z[k] = v1[k]; |
240 |
} else { |
} else { |
241 |
storage[j].iters = 2; |
storage[j].iters = 2; |
242 |
storage[j].delta[k] = 0.0 - delta[k]; |
storage[j].delta[k] = 0.0 - delta[k]; |
243 |
if (storage[j+paral_tokens].ftmp < minf) { |
if (storage[j+paral_tokens].ftmp < minf) { |
244 |
storage[j].ftmp = storage[j+paral_tokens].ftmp; |
storage[j].ftmp = storage[j+paral_tokens].ftmp; |
245 |
storage[j].z[k] = v2[k]; |
storage[j].z[k] = storage[j+paral_tokens].z[k];; |
246 |
} |
} |
247 |
} |
} |
248 |
} |
} |
258 |
} |
} |
259 |
} |
} |
260 |
} |
} |
261 |
|
delete[] storage; |
262 |
for (i = 0; i < nvars; ++i) |
for (i = 0; i < nvars; ++i) |
263 |
point[i] = z[i]; |
point[i] = z[i]; |
264 |
return minf; |
return minf; |
287 |
IntVector trapped(nvars, 0); |
IntVector trapped(nvars, 0); |
288 |
|
|
289 |
EcoSystem->scaleVariables(); |
EcoSystem->scaleVariables(); |
290 |
#ifndef NO_OPENMP |
#ifdef _OPENMP |
291 |
int numThr = omp_get_max_threads ( ); |
int numThr = omp_get_max_threads ( ); |
292 |
for (i = 0; i < numThr; i++) // scale the variables for the ecosystem of every thread |
for (i = 0; i < numThr; i++) // scale the variables for the ecosystem of every thread |
293 |
EcoSystems[i]->scaleVariables(); |
EcoSystems[i]->scaleVariables(); |
332 |
|
|
333 |
while (1) { |
while (1) { |
334 |
if (isZero(bestf)) { |
if (isZero(bestf)) { |
335 |
#ifdef NO_OPENMP |
#ifndef _OPENMP |
336 |
iters = EcoSystem->getFuncEval() - offset; |
iters = EcoSystem->getFuncEval() - offset; |
337 |
#endif |
#endif |
338 |
handle.logMessage(LOGINFO, "Error in Hooke & Jeeves optimisation after", iters, "function evaluations, f(x) = 0"); |
handle.logMessage(LOGINFO, "Error in Hooke & Jeeves optimisation after", iters, "function evaluations, f(x) = 0"); |
357 |
/* find best new point, one coord at a time */ |
/* find best new point, one coord at a time */ |
358 |
for (i = 0; i < nvars; i++) |
for (i = 0; i < nvars; i++) |
359 |
trialx[i] = x[i]; |
trialx[i] = x[i]; |
360 |
#ifndef NO_OPENMP |
#ifdef _OPENMP |
361 |
newf = this->bestNearbyOMP(delta, trialx, bestf, param); |
newf = this->bestNearbyRepro(delta, trialx, bestf, param); |
362 |
if (newf == -1) { |
if (newf == -1) { |
363 |
handle.logMessage(LOGINFO, "\nStopping Hooke & Jeeves optimisation algorithm\n"); |
handle.logMessage(LOGINFO, "\nStopping Hooke & Jeeves optimisation algorithm\n"); |
364 |
handle.logMessage(LOGINFO, "\nThe number of threads must be a multiple of 2\n"); |
handle.logMessage(LOGINFO, "\nThe number of threads must be a multiple of 2\n"); |
369 |
#endif |
#endif |
370 |
/* if too many function evaluations occur, terminate the algorithm */ |
/* if too many function evaluations occur, terminate the algorithm */ |
371 |
|
|
372 |
#ifdef NO_OPENMP |
#ifndef _OPENMP |
373 |
iters = EcoSystem->getFuncEval() - offset; |
iters = EcoSystem->getFuncEval() - offset; |
374 |
#endif |
#endif |
375 |
if (iters > hookeiter) { |
if (iters > hookeiter) { |
439 |
/* only move forward if this is really an improvement */ |
/* only move forward if this is really an improvement */ |
440 |
oldf = newf; |
oldf = newf; |
441 |
newf = EcoSystem->SimulateAndUpdate(trialx); |
newf = EcoSystem->SimulateAndUpdate(trialx); |
442 |
#ifndef NO_OPENMP |
#ifdef _OPENMP |
443 |
iters++; |
iters++; |
444 |
#endif |
#endif |
445 |
if ((isEqual(newf, oldf)) || (newf > oldf)) { |
if ((isEqual(newf, oldf)) || (newf > oldf)) { |
452 |
for (i = 0; i < nvars; i++) |
for (i = 0; i < nvars; i++) |
453 |
x[i] = trialx[i]; |
x[i] = trialx[i]; |
454 |
|
|
455 |
#ifndef NO_OPENMP |
#ifdef _OPENMP |
456 |
newf = this->bestNearbyOMP(delta, trialx, bestf, param); |
newf = this->bestNearbyRepro(delta, trialx, bestf, param); |
457 |
if (newf == -1) { |
if (newf == -1) { |
458 |
handle.logMessage(LOGINFO, "\nStopping Hooke & Jeeves optimisation algorithm\n"); |
handle.logMessage(LOGINFO, "\nStopping Hooke & Jeeves optimisation algorithm\n"); |
459 |
handle.logMessage(LOGINFO, "\nThe number of threads must be a multiple of 2\n"); |
handle.logMessage(LOGINFO, "\nThe number of threads must be a multiple of 2\n"); |
466 |
break; |
break; |
467 |
|
|
468 |
/* if too many function evaluations occur, terminate the algorithm */ |
/* if too many function evaluations occur, terminate the algorithm */ |
469 |
#ifdef NO_OPENMP |
#ifndef _OPENMP |
470 |
iters = EcoSystem->getFuncEval() - offset; |
iters = EcoSystem->getFuncEval() - offset; |
471 |
#endif |
#endif |
472 |
if (iters > hookeiter) { |
if (iters > hookeiter) { |
483 |
EcoSystem->storeVariables(score, bestx); |
EcoSystem->storeVariables(score, bestx); |
484 |
return; |
return; |
485 |
} |
} |
486 |
} |
} // while (newf < bestf) |
487 |
|
|
488 |
#ifdef NO_OPENMP |
#ifndef _OPENMP |
489 |
iters = EcoSystem->getFuncEval() - offset; |
iters = EcoSystem->getFuncEval() - offset; |
490 |
#endif |
#endif |
491 |
if (newf < bestf) { |
if (newf < bestf) { |
522 |
} |
} |
523 |
|
|
524 |
/* Functions to perform the parallelization of the algorithm of HJ with OpenMP*/ |
/* Functions to perform the parallelization of the algorithm of HJ with OpenMP*/ |
525 |
#ifdef GADGET_OPENMP |
#ifdef SPECULATIVE |
526 |
double OptInfoHooke::bestNearbyOMP2(DoubleVector& delta, DoubleVector& point, double prevbest, IntVector& param) { |
double OptInfoHooke::bestNearbySpec(DoubleVector& delta, DoubleVector& point, double prevbest, IntVector& param) { |
527 |
double minf; |
double minf; |
528 |
int i, j, k, ii; |
int i, j, k, ii; |
529 |
DoubleVector z(point); |
DoubleVector z(point); |
547 |
return -1; |
return -1; |
548 |
} |
} |
549 |
|
|
550 |
|
// omp_set_dynamic(0); |
551 |
|
// omp_set_nested(1); //permit the nested parallelization |
552 |
for (ii=0; ii< paral_tokens; ii++) { |
for (ii=0; ii< paral_tokens; ii++) { |
553 |
i = 0; |
i = 0; |
554 |
while ( i < nvars) { |
while ( i < nvars) { |
555 |
if ((i + paral_tokens -1) >= nvars) |
if ((i + paral_tokens -1) >= nvars) |
556 |
paral_tokens = nvars - i; |
paral_tokens = nvars - i; |
557 |
omp_set_dynamic(0); |
#pragma omp parallel for num_threads(paral_tokens*2) private(k) |
558 |
omp_set_nested(1); |
for (j = 0; j < (paral_tokens*2); ++j) { |
|
#pragma omp parallel for num_threads(paral_tokens) private(k) |
|
|
for (j = 0; j < paral_tokens; ++j) { |
|
559 |
storage[j].z = z; |
storage[j].z = z; |
560 |
storage[j].delta = delta; |
storage[j].delta = delta; |
561 |
DoubleVector v1(z); |
DoubleVector v(z); |
|
DoubleVector v2(z); |
|
|
k = param[i+j]; |
|
|
v1[k] += delta[k]; |
|
|
v2[k] -= delta[k]; |
|
562 |
|
|
563 |
#pragma omp parallel sections num_threads(2) |
if (j<paral_tokens) { |
564 |
{ |
k = param[i+j]; |
565 |
#pragma omp section |
v[k] += delta[k]; |
566 |
{ |
} |
567 |
storage[j].ftmp = EcoSystems[j]->SimulateAndUpdate(v1); |
else { |
568 |
} |
k = param[i+j-paral_tokens]; |
569 |
#pragma omp section |
v[k] -= delta[k]; |
|
{ |
|
|
storage[j+paral_tokens].ftmp = EcoSystems[j+paral_tokens]->SimulateAndUpdate(v2); |
|
570 |
} |
} |
571 |
|
|
572 |
|
storage[j].ftmp = EcoSystems[j]->SimulateAndUpdate(v); |
573 |
|
storage[j].z[k] = v[k]; |
574 |
} |
} |
575 |
|
|
576 |
|
for (j = 0; j < paral_tokens; ++j) { |
577 |
|
k = param[i+j]; |
578 |
if (storage[j].ftmp < minf) { |
if (storage[j].ftmp < minf) { |
579 |
storage[j].iters = 1; |
storage[j].iters = 1; |
580 |
storage[j].z[k] = v1[k]; |
// storage[j].z[k] = v1[k]; |
581 |
} else { |
} else { |
582 |
storage[j].iters = 2; |
storage[j].iters = 2; |
583 |
storage[j].delta[k] = 0.0 - delta[k]; |
storage[j].delta[k] = 0.0 - delta[k]; |
584 |
if (storage[j+paral_tokens].ftmp < minf) { |
if (storage[j+paral_tokens].ftmp < minf) { |
585 |
storage[j].ftmp = storage[j+paral_tokens].ftmp; |
storage[j].ftmp = storage[j+paral_tokens].ftmp; |
586 |
storage[j].z[k] = v2[k]; |
storage[j].z[k] = storage[j+paral_tokens].z[k]; |
587 |
} |
} |
588 |
else iters += 2; |
else iters += 2; |
589 |
} |
} |
603 |
|
|
604 |
i += paral_tokens; |
i += paral_tokens; |
605 |
} |
} |
606 |
|
paral_tokens = numThr / 2; |
607 |
} |
} |
608 |
|
|
609 |
delete[] storage; |
delete[] storage; |
677 |
|
|
678 |
while (1) { |
while (1) { |
679 |
if (isZero(bestf)) { |
if (isZero(bestf)) { |
680 |
#ifdef NO_OPENMP |
#ifndef _OPENMP |
681 |
iters = EcoSystem->getFuncEval() - offset; |
iters = EcoSystem->getFuncEval() - offset; |
682 |
#endif |
#endif |
683 |
handle.logMessage(LOGINFO, "Error in Hooke & Jeeves optimisation after", iters, "function evaluations, f(x) = 0"); |
handle.logMessage(LOGINFO, "Error in Hooke & Jeeves optimisation after", iters, "function evaluations, f(x) = 0"); |
702 |
/* find best new point, one coord at a time */ |
/* find best new point, one coord at a time */ |
703 |
for (i = 0; i < nvars; i++) |
for (i = 0; i < nvars; i++) |
704 |
trialx[i] = x[i]; |
trialx[i] = x[i]; |
705 |
#ifndef NO_OPENMP |
#ifdef _OPENMP |
706 |
newf = this->bestNearbyOMP2(delta, trialx, bestf, param); |
newf = this->bestNearbySpec(delta, trialx, bestf, param); |
707 |
if (newf == -1) { |
if (newf == -1) { |
708 |
handle.logMessage(LOGINFO, "\nStopping Hooke & Jeeves optimisation algorithm\n"); |
handle.logMessage(LOGINFO, "\nStopping Hooke & Jeeves optimisation algorithm\n"); |
709 |
handle.logMessage(LOGINFO, "\nThe number of threads must be a multiple of 2\n"); |
handle.logMessage(LOGINFO, "\nThe number of threads must be a multiple of 2\n"); |
714 |
#endif |
#endif |
715 |
/* if too many function evaluations occur, terminate the algorithm */ |
/* if too many function evaluations occur, terminate the algorithm */ |
716 |
|
|
717 |
#ifdef NO_OPENMP |
#ifndef _OPENMP |
718 |
iters = EcoSystem->getFuncEval() - offset; |
iters = EcoSystem->getFuncEval() - offset; |
719 |
#endif |
#endif |
720 |
if (iters > hookeiter) { |
if (iters > hookeiter) { |
784 |
/* only move forward if this is really an improvement */ |
/* only move forward if this is really an improvement */ |
785 |
oldf = newf; |
oldf = newf; |
786 |
newf = EcoSystem->SimulateAndUpdate(trialx); |
newf = EcoSystem->SimulateAndUpdate(trialx); |
787 |
#ifndef NO_OPENMP |
#ifdef _OPENMP |
788 |
iters++; |
iters++; |
789 |
#endif |
#endif |
790 |
if ((isEqual(newf, oldf)) || (newf > oldf)) { |
if ((isEqual(newf, oldf)) || (newf > oldf)) { |
797 |
for (i = 0; i < nvars; i++) |
for (i = 0; i < nvars; i++) |
798 |
x[i] = trialx[i]; |
x[i] = trialx[i]; |
799 |
|
|
800 |
#ifndef NO_OPENMP |
#ifdef _OPENMP |
801 |
newf = this->bestNearbyOMP2(delta, trialx, bestf, param); |
newf = this->bestNearbySpec(delta, trialx, bestf, param); |
802 |
if (newf == -1) { |
if (newf == -1) { |
803 |
handle.logMessage(LOGINFO, "\nStopping Hooke & Jeeves optimisation algorithm\n"); |
handle.logMessage(LOGINFO, "\nStopping Hooke & Jeeves optimisation algorithm\n"); |
804 |
handle.logMessage(LOGINFO, "\nThe number of threads must be a multiple of 2\n"); |
handle.logMessage(LOGINFO, "\nThe number of threads must be a multiple of 2\n"); |
811 |
break; |
break; |
812 |
|
|
813 |
/* if too many function evaluations occur, terminate the algorithm */ |
/* if too many function evaluations occur, terminate the algorithm */ |
814 |
#ifdef NO_OPENMP |
#ifndef _OPENMP |
815 |
iters = EcoSystem->getFuncEval() - offset; |
iters = EcoSystem->getFuncEval() - offset; |
816 |
#endif |
#endif |
817 |
if (iters > hookeiter) { |
if (iters > hookeiter) { |
830 |
} |
} |
831 |
} |
} |
832 |
|
|
833 |
#ifdef NO_OPENMP |
#ifndef _OPENMP |
834 |
iters = EcoSystem->getFuncEval() - offset; |
iters = EcoSystem->getFuncEval() - offset; |
835 |
#endif |
#endif |
836 |
if (newf < bestf) { |
if (newf < bestf) { |