1 #include "Master_Slaves.hpp"
2 using namespace std;
3 using namespace NOMAD;
4
5 /*--------------------------*/
6 /* tags and signal values */
7 /*--------------------------*/
8 const int Master_Slaves::TAG_SIGNAL = 100;
9 const int Master_Slaves::TAG_I1 = 101;
10 const int Master_Slaves::TAG_R1 = 102;
11 const int Master_Slaves::TAG_CSTOP = 103;
12 const int Master_Slaves::TAG_D1 = 105;
13 const int Master_Slaves::TAG_I2 = 106;
14 char Master_Slaves::STOP_SIGNAL = 'S';
15 char Master_Slaves::OPTI_RES_SIGNAL = 'O';
16 char Master_Slaves::OPTI_DATA_SIGNAL = 'D';
17
18 /*--------------------------------*/
19 /* start the master (process 0) */
20 /*--------------------------------*/
start(void) const21 void Master_Slaves::start ( void ) const {
22
23 if ( _rank != 0 )
24 return;
25
26 MPI_Status status;
27 int source;
28 char signal;
29 int n = _p.get_dimension();
30 int nb_stops = 0;
31 int pollster_mesh_index = 0;
32 bool stop_algo = false;
33 double * best_feasible = NULL;
34
35 // the first best infeasible point is initialized with x0:
36 double * best_infeasible = new double [n+2];
37 const Point * x0 = (_p.get_x0s())[0];
38 for ( int i = 0 ; i < n ; ++i )
39 best_infeasible[i] = (*x0)[i].value();
40 best_infeasible[n ] = INF;
41 best_infeasible[n+1] = INF;
42
43 /*-------------*/
44 /* main loop */
45 /*-------------*/
46 while ( nb_stops != _np-2 ) {
47
48 MPI_Recv ( &signal , 1 , MPI_CHAR , MPI_ANY_SOURCE ,
49 Master_Slaves::TAG_SIGNAL , MPI_COMM_WORLD , &status );
50
51 source = status.MPI_SOURCE;
52
53 // stop signal:
54 // ------------
55 if ( signal == Master_Slaves::STOP_SIGNAL ) {
56 if ( _debug ) {
57 _p.out() << "MASTER: STOP SIGNAL FROM RANK " << source;
58 if ( source == 1 )
59 _p.out() << " (POLLSTER)";
60 _p.out() << endl;
61 }
62 ++nb_stops;
63 }
64
65 // optimization data signal:
66 // -------------------------
67 else if ( signal == Master_Slaves::OPTI_DATA_SIGNAL ) {
68 if ( _debug ) {
69 _p.out() << "MASTER: receive optimization data request from slave "
70 << source;
71 if ( source == 1 )
72 _p.out() << " (POLLSTER)";
73 _p.out() << endl;
74 }
75
76 send_optimization_data ( pollster_mesh_index ,
77 stop_algo ,
78 best_feasible ,
79 best_infeasible ,
80 source );
81 }
82
83 // optimization result signal:
84 // ---------------------------
85 else if ( signal == Master_Slaves::OPTI_RES_SIGNAL ) {
86 if ( _debug ) {
87 _p.out() << "MASTER: receive optimization result from slave "
88 << source;
89 if ( source == 1 )
90 _p.out() << " (POLLSTER)";
91 _p.out() << endl;
92 }
93
94 // pollster:
95 if ( source == 1 )
96 receive_optimization_result ( pollster_mesh_index ,
97 stop_algo ,
98 best_feasible ,
99 best_infeasible ,
100 source );
101
102 // other slaves:
103 else {
104 int tmp1;
105 bool tmp2;
106 receive_optimization_result ( tmp1 ,
107 tmp2 ,
108 best_feasible ,
109 best_infeasible ,
110 source );
111 }
112 }
113 }
114
115 if ( best_feasible )
116 delete [] best_feasible;
117 if ( best_infeasible )
118 delete [] best_infeasible;
119 }
120
121 /*------------------------------------------*/
122 /* stop the master (processes 1 to _np-2) */
123 /*------------------------------------------*/
stop(void) const124 void Master_Slaves::stop ( void ) const {
125 if ( _rank == 0 || _rank == _np-1 )
126 return;
127
128 MPI_Send ( &Master_Slaves::STOP_SIGNAL , 1 , MPI_CHAR ,
129 0 , Master_Slaves::TAG_SIGNAL , MPI_COMM_WORLD );
130 }
131
132 /*----------------------------------------*/
133 /* MADS run */
134 /*----------------------------------------*/
mads_run(Cache & cache)135 void Master_Slaves::mads_run ( Cache & cache ) {
136
137 const Eval_Point * best_feasible = NULL;
138 const Eval_Point * best_infeasible = NULL;
139 Double old_f = INF;
140 bool stop_algo = false;
141 int run_index = 0;
142 int mesh_index = 0;
143 double default_eps = Double::get_epsilon();
144 int n = _p.get_dimension();
145 int * free_vars = new int [_ns];
146 Point x0 ( n ) , delta_0 , delta_min;
147
148 /*---------------------*/
149 /* main loop */
150 /*---------------------*/
151 while ( !stop_algo ) {
152
153 best_feasible = NULL;
154 best_infeasible = NULL;
155
156 // Seed:
157 _p.set_SEED ( 99 * _rank + 20 * run_index );
158
159 // first run:
160 if ( run_index == 0 ) {
161
162 // max number of evaluations for regular slaves:
163 if ( _rank != 1 )
164 _p.set_MAX_BB_EVAL ( _bbe );
165
166 // display:
167 // p.set_DISPLAY_STATS ( "process #" + itos(_rank) + " BBE OBJ" );
168 // p.set_DISPLAY_DEGREE ( FULL_DISPLAY );
169 _p.set_DISPLAY_DEGREE ( NO_DISPLAY );
170 }
171
172 // force the parameters check:
173 _p.force_check_flag();
174
175 /*------------------*/
176 /* pollster slave */
177 /*------------------*/
178 if ( _rank == 1 ) {
179
180 stop_type stop_reason = UNKNOWN_STOP_REASON;
181
182 _p.check(); // must do check to get a valid signature
183 _p.get_signature()->get_mesh()->set_mesh_indices( NOMAD::Point( n,mesh_index ) );
184 delta_0=_p.get_signature()->get_mesh()->get_delta ( );
185
186
187
188 // we set a very small epsilon in order to accept
189 // very small initial mesh sizes:
190 Double::set_epsilon ( 1e-16 );
191
192 if ( !check_delta ( delta_0 ) )
193 stop_algo = true;
194
195 else {
196
197 // first run:
198 if ( run_index == 0 ) {
199
200 // directions:
201 {
202 bool use_orthomads = _p.has_orthomads_directions();
203 _p.reset_directions ( );
204 _p.set_DIRECTION_TYPE ( (use_orthomads) ? ORTHO_1 : LT_1 );
205 }
206
207 // cache search:
208 _p.set_CACHE_SEARCH ( true );
209 _p.set_OPPORTUNISTIC_CACHE_SEARCH ( false );
210 }
211
212 // other runs:
213 else {
214
215 // stop_algo may be set to 'false' here:
216 receive_optimization_data ( stop_algo , x0 , old_f );
217
218 // starting point:
219 _p.reset_X0();
220 _p.set_X0 ( x0 );
221 }
222
223 if ( !stop_algo ) {
224
225 // check the parameters:
226 _p.check();
227
228 _p.get_signature()->get_mesh()->set_min_mesh_sizes( delta_0 );
229
230 if ( mesh_index <= 0 )
231 _p.get_signature()->get_mesh()->set_limit_mesh_index ( mesh_index );
232 else
233 _p.get_signature()->get_mesh()->set_limit_mesh_index ( 0 );
234
235
236 Double::set_epsilon ( default_eps );
237
238 Mads mads ( _p , &_ev , NULL , &cache , NULL );
239 stop_reason = mads.run();
240 best_feasible = mads.get_best_feasible();
241 best_infeasible = mads.get_best_infeasible();
242
243 bool success = false;
244
245 if ( best_feasible ) {
246
247 success = (best_feasible->get_f() < old_f);
248
249 if ( _debug )
250 _p.out() << "POLLSTER: ELL="
251 << mesh_index << " BBE="
252 << mads.get_stats().get_bb_eval()
253 << " OLD_F=" << old_f << " NEW_F="
254 << best_feasible->get_f()
255 << " SUCCESS=" << success << endl;
256 }
257
258 // pollster mesh update:
259 if ( success )
260 ++mesh_index;
261 else
262 --mesh_index;
263
264 }
265 }
266
267 send_optimization_result ( mesh_index ,
268 stop_algo ,
269 best_feasible ,
270 best_infeasible ,
271 stop_reason );
272 }
273
274 /*------------------*/
275 /* regular slaves */
276 /*------------------*/
277 else {
278
279 int i , j , pollster_mesh_index;
280
281 receive_optimization_data ( stop_algo ,
282 x0 ,
283 old_f ,
284 pollster_mesh_index ,
285 free_vars );
286
287 if ( _debug ) {
288 _p.out() << "SLAVE #" << _rank
289 << ": OPTIM. DATA: [STOP=" << stop_algo
290 << "] [POLLSTER_MESH_INDEX=" << pollster_mesh_index
291 << "] [X0=" << x0 << " ] [f(X0)="
292 << old_f << "] [FREE VARS= ";
293 for ( i = 0 ; i < _ns ; ++i )
294 _p.out() << free_vars[i] << " ";
295 _p.out() << " ]" << endl;
296 }
297
298 if ( !stop_algo ) {
299
300 // starting point:
301 _p.reset_X0();
302 _p.set_X0 ( x0 );
303
304 // mesh of the regular slave:
305 int ell_0 = 0;
306 if ( pollster_mesh_index > ell_0 )
307 ell_0 = pollster_mesh_index;
308
309 _p.check(); // Must do check to access signature
310 _p.get_signature()->get_mesh()->set_mesh_indices( NOMAD::Point( n,ell_0 ) );
311 delta_0=_p.get_signature()->get_mesh()->get_delta();
312
313 _p.get_signature()->get_mesh()->set_mesh_indices( NOMAD::Point( n ,pollster_mesh_index ) );
314 delta_min=_p.get_signature()->get_mesh()->get_delta();
315
316
317
318 Double::set_epsilon ( 1e-16 );
319 if ( !check_delta ( delta_0 ) || !check_delta ( delta_min ) )
320 stop_algo = true;
321
322 else {
323
324 // free variables:
325 {
326 _p.reset_fixed_variables();
327 bool fix_var;
328 for ( i = 0 ; i < n ; ++i ) {
329 fix_var = true;
330 for ( j = 0 ; j < _ns ; ++j )
331 if ( free_vars[j] == i ) {
332 fix_var = false;
333 break;
334 }
335 if ( fix_var )
336 _p.set_FIXED_VARIABLE ( i );
337 }
338 }
339
340 // check the parameters:
341 _p.check();
342
343 // modify mesh termination criterions
344 _p.get_signature()->get_mesh()->set_mesh_indices( NOMAD::Point( n,ell_0 ) );
345
346 if ( pollster_mesh_index <=0 )
347 _p.get_signature()->get_mesh()->set_limit_mesh_index( pollster_mesh_index );
348 else
349 _p.get_signature()->get_mesh()->set_limit_mesh_index( 0 );
350
351 _p.get_signature()->get_mesh()->set_min_mesh_sizes( delta_min );
352 _p.get_signature()->get_mesh()->set_delta_0 ( delta_0 );
353
354
355
356 Double::set_epsilon ( default_eps );
357
358 // MADS run:
359 Mads mads ( _p , &_ev , NULL , &cache , NULL );
360 mads.run();
361 best_feasible = mads.get_best_feasible();
362 best_infeasible = mads.get_best_infeasible();
363
364 if ( _debug && best_feasible ) {
365 _p.out() << "RANK #" << _rank << ": POLLSTER_ELL="
366 << pollster_mesh_index << " VARS = [";
367 for ( i = 0 ; i < _ns ; ++i )
368 _p.out() << free_vars[i] << " ";
369 _p.out() << " ] BBE=" << mads.get_stats().get_bb_eval()
370 << " OLD_F=" << old_f << " NEW_F="
371 << best_feasible->get_f()
372 << " SUCCESS="
373 << (best_feasible->get_f() < old_f)
374 << endl;
375 }
376 }
377 }
378
379 {
380 int tmp1 = -1;
381 bool tmp2 = false;
382 stop_type tmp3 = UNKNOWN_STOP_REASON;
383 send_optimization_result ( tmp1 ,
384 tmp2 ,
385 best_feasible ,
386 best_infeasible ,
387 tmp3 );
388 }
389 }
390
391 // loop increment:
392 ++run_index;
393 }
394
395 delete [] free_vars;
396 }
397
398 /*----------------------------------------------------*/
399 /* receive an optimization result from the pollster */
400 /* POLLSTER --> MASTER */
401 /*----------------------------------------------------*/
receive_optimization_result(int & pollster_mesh_index,bool & stop_algo,double * & best_feasible,double * & best_infeasible,int source) const402 void Master_Slaves::receive_optimization_result
403 ( int & pollster_mesh_index ,
404 bool & stop_algo ,
405 double *& best_feasible ,
406 double *& best_infeasible ,
407 int source ) const {
408
409 int itab[5];
410 MPI_Status status;
411
412 MPI_Recv ( itab , 5 , MPI_INT , source ,
413 Master_Slaves::TAG_I1 , MPI_COMM_WORLD , &status );
414
415 pollster_mesh_index = itab[0];
416
417 // stop the algorithm ?
418 stop_algo = ( itab[4] == 1 );
419
420 if ( !stop_algo ) {
421
422 stop_type stop_reason = static_cast<stop_type>(itab[1]);
423
424 switch ( stop_reason ) {
425 case ERROR:
426 case UNKNOWN_STOP_REASON:
427 case CTRL_C:
428 case MESH_PREC_REACHED:
429 case X0_FAIL:
430 case P1_FAIL:
431 case L_MAX_REACHED:
432 case L_LIMITS_REACHED:
433 case MAX_TIME_REACHED:
434 case MAX_BB_EVAL_REACHED:
435 case MAX_SGTE_EVAL_REACHED:
436 case MAX_EVAL_REACHED:
437 case MAX_SIM_BB_EVAL_REACHED:
438 case MAX_ITER_REACHED:
439 case FEAS_REACHED:
440 case F_TARGET_REACHED:
441 case STAT_SUM_TARGET_REACHED:
442 case L_CURVE_TARGET_REACHED:
443 case MULTI_MAX_BB_REACHED:
444 case MULTI_NB_MADS_RUNS_REACHED:
445 case MULTI_STAGNATION:
446 case MULTI_NO_PARETO_PTS:
447 case MAX_CACHE_MEMORY_REACHED:
448 stop_algo = true;
449 default:
450 stop_algo = false;
451 }
452 }
453
454 int i , nb_pts = 0;
455 if ( itab[2] == 1 )
456 ++nb_pts;
457 if ( itab[3] == 1 )
458 ++nb_pts;
459
460 // itab[2] == 1 --> bf != NULL
461 // itab[3] == 1 --> bi != NULL
462
463 if ( nb_pts > 0 ) {
464
465 int n = _p.get_dimension();
466 double * rtab = new double [(n+2)*nb_pts];
467
468 MPI_Recv ( rtab , (n+2)*nb_pts , MPI_DOUBLE , source ,
469 Master_Slaves::TAG_R1 , MPI_COMM_WORLD , &status );
470
471 if ( nb_pts == 2 ) {
472
473 // best feasible and infeasible updates:
474 bool update = false;
475
476 if ( best_feasible ) {
477 Double old_f = best_feasible[n+1];
478 Double new_f = rtab [n+1];
479 if ( new_f < old_f )
480 update = true;
481 }
482 else {
483 best_feasible = new double[n+2];
484 update = true;
485 }
486
487 if ( update ) {
488 for ( i = 0 ; i < n ; ++i )
489 best_feasible[i] = rtab[i];
490 best_feasible[n ] = rtab[n];
491 best_feasible[n+1] = rtab[n+1];
492 }
493
494 update = false;
495
496 if ( best_infeasible ) {
497
498 Double old_h = best_infeasible[n];
499 Double new_h = rtab [2*n+2];
500 if ( new_h < old_h )
501 update = true;
502 }
503 else {
504 best_infeasible = new double[n+2];
505 update = true;
506 }
507
508 if ( update ) {
509 int cur = n+2;
510 for ( i = 0 ; i < n ; ++i )
511 best_infeasible[i] = rtab[cur++];
512 best_infeasible[n ] = rtab[cur++];
513 best_infeasible[n+1] = rtab[cur];
514 }
515 delete [] rtab;
516 }
517 else {
518
519 // best feasible update:
520 if ( itab[2] == 1 ) {
521 if ( best_feasible ) {
522 Double old_f = best_feasible[n+1];
523 Double new_f = rtab [n+1];
524 if ( new_f < old_f ) {
525 delete [] best_feasible;
526 best_feasible = rtab;
527 }
528 else
529 delete [] rtab;
530 }
531 else
532 best_feasible = rtab;
533 }
534
535 // best infeasible update:
536 else {
537 if ( best_infeasible ) {
538 Double old_h = best_infeasible[n];
539 Double new_h = rtab [n];
540 if ( new_h < old_h ) {
541 delete [] best_infeasible;
542 best_infeasible = rtab;
543 }
544 else
545 delete [] rtab;
546 }
547 else
548 best_infeasible = rtab;
549 }
550 }
551 }
552 }
553
554 /*---------------------------------------------*/
555 /* send an optimization result to the master */
556 /* POLLSTER --> MASTER */
557 /*---------------------------------------------*/
send_optimization_result(int pollster_mesh_index,bool stop_algo,const Eval_Point * bf,const Eval_Point * bi,stop_type st) const558 void Master_Slaves::send_optimization_result
559 ( int pollster_mesh_index ,
560 bool stop_algo ,
561 const Eval_Point * bf ,
562 const Eval_Point * bi ,
563 stop_type st ) const {
564
565 // send a signal to the master:
566 MPI_Send ( &Master_Slaves::OPTI_RES_SIGNAL , 1 , MPI_CHAR ,
567 0 , Master_Slaves::TAG_SIGNAL , MPI_COMM_WORLD );
568
569 // send the data:
570 int itab[5];
571
572 itab[0] = pollster_mesh_index;
573 itab[1] = static_cast<int>(st);
574
575 int nb_pts = 0;
576 if ( bf ) {
577 ++nb_pts;
578 itab[2] = 1;
579 }
580 else
581 itab[2] = 0;
582
583 if ( bi ) {
584 ++nb_pts;
585 itab[3] = 1;
586 }
587 else
588 itab[3] = 0;
589
590 itab[4] = (stop_algo) ? 1 : 0;
591
592 MPI_Send ( itab , 5 , MPI_INT , 0 ,
593 Master_Slaves::TAG_I1 , MPI_COMM_WORLD );
594
595 if ( nb_pts > 0 ) {
596
597 int n = _p.get_dimension();
598 double * rtab = new double [(n+2)*nb_pts];
599
600 int i , cur = 0;
601 if ( bf ) {
602 for ( i = 0 ; i < n ; ++i )
603 rtab[cur++] = (*bf)[i].value();
604 rtab[cur++] = bf->get_h().value();
605 rtab[cur++] = bf->get_f().value();
606 }
607
608 if ( bi ) {
609 for ( i = 0 ; i < n ; ++i )
610 rtab[cur++] = (*bi)[i].value();
611 rtab[cur++] = bi->get_h().value();
612 rtab[cur ] = bi->get_f().value();
613 }
614
615 MPI_Send ( rtab , cur , MPI_DOUBLE , 0 ,
616 Master_Slaves::TAG_R1 , MPI_COMM_WORLD );
617
618 delete [] rtab;
619 }
620 }
621
622 /*---------------------------------------------*/
623 /* receive optimization data from the master */
624 /* MASTER --> REGULAR SLAVE */
625 /*---------------------------------------------*/
receive_optimization_data(bool & stop_algo,Point & x0,Double & fx0,int & pollster_mesh_index,int * free_vars) const626 void Master_Slaves::receive_optimization_data
627 ( bool & stop_algo ,
628 Point & x0 ,
629 Double & fx0 ,
630 int & pollster_mesh_index ,
631 int * free_vars ) const {
632
633 // step 1/2: receive common pollster data:
634 receive_optimization_data ( stop_algo , x0 , fx0 );
635
636 int i;
637
638 // step 2/2: receive additional data for regular slaves:
639 if ( !stop_algo ) {
640
641 int * itab = new int [_ns+1];
642 MPI_Status status;
643
644 MPI_Recv ( itab , _ns+1 , MPI_INT , 0 ,
645 Master_Slaves::TAG_I2 , MPI_COMM_WORLD , &status );
646
647 for ( i = 0 ; i < _ns ; ++i )
648 free_vars[i] = itab[i];
649
650 pollster_mesh_index = itab[_ns];
651
652 delete [] itab;
653 }
654 else {
655 pollster_mesh_index = 1;
656 for ( i = 0 ; i < _ns ; ++i )
657 free_vars[i] = -1;
658 }
659 }
660
661 /*---------------------------------------------*/
662 /* receive optimization data from the master */
663 /* MASTER --> POLLSTER */
664 /*---------------------------------------------*/
receive_optimization_data(bool & stop_algo,Point & x0,Double & fx0) const665 void Master_Slaves::receive_optimization_data ( bool & stop_algo ,
666 Point & x0 ,
667 Double & fx0 ) const {
668 char c_stop;
669 MPI_Status status;
670 MPI_Request req = MPI_REQUEST_NULL;
671 int i , n = _p.get_dimension();
672
673 // send a request for c_stop:
674 MPI_Irecv ( &c_stop , 1 , MPI_CHAR , 0 ,
675 Master_Slaves::TAG_CSTOP , MPI_COMM_WORLD , &req );
676
677 // send a signal to the master:
678 MPI_Send ( &Master_Slaves::OPTI_DATA_SIGNAL , 1 , MPI_CHAR ,
679 0 , Master_Slaves::TAG_SIGNAL , MPI_COMM_WORLD );
680
681 MPI_Wait ( &req , &status );
682
683 // stop:
684 if ( c_stop == '1' ) {
685 stop_algo = true;
686 x0.reset();
687 }
688
689 // continue:
690 else {
691
692 stop_algo = false;
693 double * rtab = new double [n+2];
694
695 MPI_Recv ( rtab , n+2 , MPI_DOUBLE , 0 ,
696 Master_Slaves::TAG_D1 , MPI_COMM_WORLD , &status );
697
698 for ( i = 0 ; i < n ; ++i )
699 x0[i] = rtab[i];
700
701 Double h = rtab[n];
702 fx0 = ( h <= _p.get_h_min() ) ? rtab[n+1] : INF;
703
704 // get the best feasible point from the cache server:
705 {
706 char pt_flag;
707 int npm1 = _np-1;
708 MPI_Irecv ( &pt_flag , 1 , MPI_CHAR , npm1 ,
709 Cache_Server::TAG_BF , MPI_COMM_WORLD , &req );
710
711 MPI_Send ( &Cache_Server::BF_SIGNAL , 1 , MPI_CHAR ,
712 npm1 , Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD );
713
714 MPI_Wait ( &req , &status );
715
716 if ( pt_flag == '1' ) {
717
718 MPI_Recv ( rtab , n+2 , MPI_DOUBLE , npm1 ,
719 Cache_Server::TAG_X7 , MPI_COMM_WORLD , &status );
720
721 for ( i = 0 ; i < n ; ++i )
722 x0[i] = rtab[i];
723
724 Double h = rtab[n];
725 fx0 = ( h <= _p.get_h_min() ) ? rtab[n+1] : INF;
726
727 }
728 }
729 delete [] rtab;
730
731 // check the bounds:
732 const Point & lb = _p.get_lb();
733 const Point & ub = _p.get_ub();
734
735 for ( i = 0 ; i < n ; ++i ) {
736 if ( lb[i].is_defined() && x0[i].value() < lb[i].value() )
737 x0[i] = lb[i];
738 if ( ub[i].is_defined() && x0[i].value() > ub[i].value() )
739 x0[i] = ub[i];
740 }
741 }
742 }
743
744 /*-----------------------------------------------------*/
745 /* send optimization data from the master to a slave */
746 /* MASTER --> POLLSTER or MASTER --> SLAVE */
747 /*-----------------------------------------------------*/
send_optimization_data(int pollster_mesh_index,bool stop_algo,const double * best_feasible,const double * best_infeasible,int source) const748 void Master_Slaves::send_optimization_data
749 ( int pollster_mesh_index ,
750 bool stop_algo ,
751 const double * best_feasible ,
752 const double * best_infeasible ,
753 int source ) const {
754
755 char c_stop = (stop_algo) ? '1' : '0';
756
757 MPI_Rsend ( &c_stop , 1 , MPI_CHAR , source ,
758 Master_Slaves::TAG_CSTOP , MPI_COMM_WORLD );
759
760 // continue:
761 if ( !stop_algo ) {
762
763 int n = _p.get_dimension();
764
765 // data for pollster and regular slaves:
766 if ( best_feasible )
767 MPI_Send ( const_cast<double*>(best_feasible) , n+2 , MPI_DOUBLE ,
768 source , Master_Slaves::TAG_D1 , MPI_COMM_WORLD );
769 else
770 MPI_Send ( const_cast<double*>(best_infeasible) , n+2 , MPI_DOUBLE ,
771 source , Master_Slaves::TAG_D1 , MPI_COMM_WORLD );
772
773 // additional data for regular slaves:
774 if ( source != 1 ) {
775
776 int * itab = new int [_ns+1];
777
778 // choose the free varables:
779 {
780 Random_Pickup rp ( n );
781
782 for ( int i = 0 ; i < _ns ; ++i )
783 itab[i] = rp.pickup(); // index of the ith free variable
784 }
785
786 itab[_ns] = pollster_mesh_index;
787
788 MPI_Send ( itab , _ns+1 , MPI_INT , source ,
789 Master_Slaves::TAG_I2 , MPI_COMM_WORLD );
790
791 delete [] itab;
792 }
793 }
794 }
795
796 /*-----------------------------------------------*/
797 /* check the initial mesh size values */
798 /*-----------------------------------------------*/
check_delta(const Point & delta)799 bool Master_Slaves::check_delta ( const Point & delta ) {
800 int n = delta.size();
801 for ( int i = 0 ; i < n ; ++i )
802 if ( delta[i].value() < Double::get_epsilon() ||
803 delta[i].value() <= 0.0 )
804 return false;
805 return true;
806 }
807
808