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 Double::set_epsilon ( default_eps );
236
237 Mads mads ( _p , NULL , NULL , &cache , NULL );
238 stop_reason = mads.run();
239 best_feasible = mads.get_best_feasible();
240 best_infeasible = mads.get_best_infeasible();
241
242 bool success = false;
243
244 if ( best_feasible ) {
245
246 success = (best_feasible->get_f() < old_f);
247
248 if ( _debug )
249 _p.out() << "POLLSTER: ELL="
250 << mesh_index << " BBE="
251 << mads.get_stats().get_bb_eval()
252 << " OLD_F=" << old_f << " NEW_F="
253 << best_feasible->get_f()
254 << " SUCCESS=" << success << endl;
255 }
256
257 // pollster mesh update:
258 if ( success )
259 ++mesh_index;
260 else
261 --mesh_index;
262
263 }
264 }
265
266 send_optimization_result ( mesh_index ,
267 stop_algo ,
268 best_feasible ,
269 best_infeasible ,
270 stop_reason );
271 }
272
273 /*------------------*/
274 /* regular slaves */
275 /*------------------*/
276 else {
277
278 int i , j , pollster_mesh_index;
279
280 receive_optimization_data ( stop_algo ,
281 x0 ,
282 old_f ,
283 pollster_mesh_index ,
284 free_vars );
285
286 if ( _debug ) {
287 _p.out() << "SLAVE #" << _rank
288 << ": OPTIM. DATA: [STOP=" << stop_algo
289 << "] [POLLSTER_MESH_INDEX=" << pollster_mesh_index
290 << "] [X0=" << x0 << " ] [f(X0)="
291 << old_f << "] [FREE VARS= ";
292 for ( i = 0 ; i < _ns ; ++i )
293 _p.out() << free_vars[i] << " ";
294 _p.out() << " ]" << endl;
295 }
296
297 if ( !stop_algo ) {
298
299 // starting point:
300 _p.reset_X0();
301 _p.set_X0 ( x0 );
302
303 // mesh of the regular slave:
304 int ell_0 = 0;
305 if ( pollster_mesh_index > ell_0 )
306 ell_0 = pollster_mesh_index;
307
308 _p.check(); // Must do check to access signature
309 _p.get_signature()->get_mesh()->set_mesh_indices( NOMAD::Point( n,ell_0 ) );
310 delta_0=_p.get_signature()->get_mesh()->get_delta();
311
312 _p.get_signature()->get_mesh()->set_mesh_indices( NOMAD::Point( n ,pollster_mesh_index ) );
313 delta_min=_p.get_signature()->get_mesh()->get_delta();
314
315
316
317 Double::set_epsilon ( 1e-16 );
318 if ( !check_delta ( delta_0 ) || !check_delta ( delta_min ) )
319 stop_algo = true;
320
321 else {
322
323
324
325 // free variables:
326 {
327 _p.reset_fixed_variables();
328 bool fix_var;
329 for ( i = 0 ; i < n ; ++i ) {
330 fix_var = true;
331 for ( j = 0 ; j < _ns ; ++j )
332 if ( free_vars[j] == i ) {
333 fix_var = false;
334 break;
335 }
336 if ( fix_var )
337 _p.set_FIXED_VARIABLE ( i );
338 }
339 }
340
341 // check the parameters:
342 _p.check();
343
344 // modify mesh termination criterions
345 _p.get_signature()->get_mesh()->set_mesh_indices( NOMAD::Point( n,ell_0 ) );
346
347 if ( pollster_mesh_index <=0 )
348 _p.get_signature()->get_mesh()->set_limit_mesh_index( pollster_mesh_index );
349 else
350 _p.get_signature()->get_mesh()->set_limit_mesh_index( 0 );
351
352 _p.get_signature()->get_mesh()->set_min_mesh_sizes( delta_min );
353 _p.get_signature()->get_mesh()->set_delta_0 ( delta_0 );
354
355
356
357 Double::set_epsilon ( default_eps );
358
359 // MADS run:
360 Mads mads ( _p , NULL , NULL , &cache , NULL );
361 mads.run();
362 best_feasible = mads.get_best_feasible();
363 best_infeasible = mads.get_best_infeasible();
364
365 if ( _debug && best_feasible ) {
366 _p.out() << "RANK #" << _rank << ": POLLSTER_ELL="
367 << pollster_mesh_index << " VARS = [";
368 for ( i = 0 ; i < _ns ; ++i )
369 _p.out() << free_vars[i] << " ";
370 _p.out() << " ] BBE=" << mads.get_stats().get_bb_eval()
371 << " OLD_F=" << old_f << " NEW_F="
372 << best_feasible->get_f()
373 << " SUCCESS="
374 << (best_feasible->get_f() < old_f)
375 << endl;
376 }
377 }
378 }
379
380 {
381 int tmp1 = -1;
382 bool tmp2 = false;
383 stop_type tmp3 = UNKNOWN_STOP_REASON;
384 send_optimization_result ( tmp1 ,
385 tmp2 ,
386 best_feasible ,
387 best_infeasible ,
388 tmp3 );
389 }
390 }
391
392 // loop increment:
393 ++run_index;
394 }
395
396 delete [] free_vars;
397 }
398
399 /*----------------------------------------------------*/
400 /* receive an optimization result from the pollster */
401 /* POLLSTER --> MASTER */
402 /*----------------------------------------------------*/
receive_optimization_result(int & pollster_mesh_index,bool & stop_algo,double * & best_feasible,double * & best_infeasible,int source) const403 void Master_Slaves::receive_optimization_result
404 ( int & pollster_mesh_index ,
405 bool & stop_algo ,
406 double *& best_feasible ,
407 double *& best_infeasible ,
408 int source ) const {
409
410 int itab[5];
411 MPI_Status status;
412
413 MPI_Recv ( itab , 5 , MPI_INT , source ,
414 Master_Slaves::TAG_I1 , MPI_COMM_WORLD , &status );
415
416 pollster_mesh_index = itab[0];
417
418 // stop the algorithm ?
419 stop_algo = ( itab[4] == 1 );
420
421 if ( !stop_algo ) {
422
423 stop_type stop_reason = static_cast<stop_type>(itab[1]);
424
425 switch ( stop_reason ) {
426 case ERROR:
427 case UNKNOWN_STOP_REASON:
428 case CTRL_C:
429 case MESH_PREC_REACHED:
430 case X0_FAIL:
431 case P1_FAIL:
432 case L_MAX_REACHED:
433 case L_LIMITS_REACHED:
434 case MAX_TIME_REACHED:
435 case MAX_BB_EVAL_REACHED:
436 case MAX_SGTE_EVAL_REACHED:
437 case MAX_EVAL_REACHED:
438 case MAX_SIM_BB_EVAL_REACHED:
439 case MAX_ITER_REACHED:
440 case FEAS_REACHED:
441 case F_TARGET_REACHED:
442 case STAT_SUM_TARGET_REACHED:
443 case L_CURVE_TARGET_REACHED:
444 case MULTI_MAX_BB_REACHED:
445 case MULTI_NB_MADS_RUNS_REACHED:
446 case MULTI_STAGNATION:
447 case MULTI_NO_PARETO_PTS:
448 case MAX_CACHE_MEMORY_REACHED:
449 stop_algo = true;
450 default:
451 stop_algo = false;
452 }
453 }
454
455 int i , nb_pts = 0;
456 if ( itab[2] == 1 )
457 ++nb_pts;
458 if ( itab[3] == 1 )
459 ++nb_pts;
460
461 // itab[2] == 1 --> bf != NULL
462 // itab[3] == 1 --> bi != NULL
463
464 if ( nb_pts > 0 ) {
465
466 int n = _p.get_dimension();
467 double * rtab = new double [(n+2)*nb_pts];
468
469 MPI_Recv ( rtab , (n+2)*nb_pts , MPI_DOUBLE , source ,
470 Master_Slaves::TAG_R1 , MPI_COMM_WORLD , &status );
471
472 if ( nb_pts == 2 ) {
473
474 // best feasible and infeasible updates:
475 bool update = false;
476
477 if ( best_feasible ) {
478 Double old_f = best_feasible[n+1];
479 Double new_f = rtab [n+1];
480 if ( new_f < old_f )
481 update = true;
482 }
483 else {
484 best_feasible = new double[n+2];
485 update = true;
486 }
487
488 if ( update ) {
489 for ( i = 0 ; i < n ; ++i )
490 best_feasible[i] = rtab[i];
491 best_feasible[n ] = rtab[n];
492 best_feasible[n+1] = rtab[n+1];
493 }
494
495 update = false;
496
497 if ( best_infeasible ) {
498
499 Double old_h = best_infeasible[n];
500 Double new_h = rtab [2*n+2];
501 if ( new_h < old_h )
502 update = true;
503 }
504 else {
505 best_infeasible = new double[n+2];
506 update = true;
507 }
508
509 if ( update ) {
510 int cur = n+2;
511 for ( i = 0 ; i < n ; ++i )
512 best_infeasible[i] = rtab[cur++];
513 best_infeasible[n ] = rtab[cur++];
514 best_infeasible[n+1] = rtab[cur];
515 }
516 delete [] rtab;
517 }
518 else {
519
520 // best feasible update:
521 if ( itab[2] == 1 ) {
522 if ( best_feasible ) {
523 Double old_f = best_feasible[n+1];
524 Double new_f = rtab [n+1];
525 if ( new_f < old_f ) {
526 delete [] best_feasible;
527 best_feasible = rtab;
528 }
529 else
530 delete [] rtab;
531 }
532 else
533 best_feasible = rtab;
534 }
535
536 // best infeasible update:
537 else {
538 if ( best_infeasible ) {
539 Double old_h = best_infeasible[n];
540 Double new_h = rtab [n];
541 if ( new_h < old_h ) {
542 delete [] best_infeasible;
543 best_infeasible = rtab;
544 }
545 else
546 delete [] rtab;
547 }
548 else
549 best_infeasible = rtab;
550 }
551 }
552 }
553 }
554
555 /*---------------------------------------------*/
556 /* send an optimization result to the master */
557 /* POLLSTER --> MASTER */
558 /*---------------------------------------------*/
send_optimization_result(int pollster_mesh_index,bool stop_algo,const Eval_Point * bf,const Eval_Point * bi,stop_type st) const559 void Master_Slaves::send_optimization_result
560 ( int pollster_mesh_index ,
561 bool stop_algo ,
562 const Eval_Point * bf ,
563 const Eval_Point * bi ,
564 stop_type st ) const {
565
566 // send a signal to the master:
567 MPI_Send ( &Master_Slaves::OPTI_RES_SIGNAL , 1 , MPI_CHAR ,
568 0 , Master_Slaves::TAG_SIGNAL , MPI_COMM_WORLD );
569
570 // send the data:
571 int itab[5];
572
573 itab[0] = pollster_mesh_index;
574 itab[1] = static_cast<int>(st);
575
576 int nb_pts = 0;
577 if ( bf ) {
578 ++nb_pts;
579 itab[2] = 1;
580 }
581 else
582 itab[2] = 0;
583
584 if ( bi ) {
585 ++nb_pts;
586 itab[3] = 1;
587 }
588 else
589 itab[3] = 0;
590
591 itab[4] = (stop_algo) ? 1 : 0;
592
593 MPI_Send ( itab , 5 , MPI_INT , 0 ,
594 Master_Slaves::TAG_I1 , MPI_COMM_WORLD );
595
596 if ( nb_pts > 0 ) {
597
598 int n = _p.get_dimension();
599 double * rtab = new double [(n+2)*nb_pts];
600
601 int i , cur = 0;
602 if ( bf ) {
603 for ( i = 0 ; i < n ; ++i )
604 rtab[cur++] = (*bf)[i].value();
605 rtab[cur++] = bf->get_h().value();
606 rtab[cur++] = bf->get_f().value();
607 }
608
609 if ( bi ) {
610 for ( i = 0 ; i < n ; ++i )
611 rtab[cur++] = (*bi)[i].value();
612 rtab[cur++] = bi->get_h().value();
613 rtab[cur ] = bi->get_f().value();
614 }
615
616 MPI_Send ( rtab , cur , MPI_DOUBLE , 0 ,
617 Master_Slaves::TAG_R1 , MPI_COMM_WORLD );
618
619 delete [] rtab;
620 }
621 }
622
623 /*---------------------------------------------*/
624 /* receive optimization data from the master */
625 /* MASTER --> REGULAR SLAVE */
626 /*---------------------------------------------*/
receive_optimization_data(bool & stop_algo,Point & x0,Double & fx0,int & pollster_mesh_index,int * free_vars) const627 void Master_Slaves::receive_optimization_data
628 ( bool & stop_algo ,
629 Point & x0 ,
630 Double & fx0 ,
631 int & pollster_mesh_index ,
632 int * free_vars ) const {
633
634 // step 1/2: receive common pollster data:
635 receive_optimization_data ( stop_algo , x0 , fx0 );
636
637 int i;
638
639 // step 2/2: receive additional data for regular slaves:
640 if ( !stop_algo ) {
641
642 int * itab = new int [_ns+1];
643 MPI_Status status;
644
645 MPI_Recv ( itab , _ns+1 , MPI_INT , 0 ,
646 Master_Slaves::TAG_I2 , MPI_COMM_WORLD , &status );
647
648 for ( i = 0 ; i < _ns ; ++i )
649 free_vars[i] = itab[i];
650
651 pollster_mesh_index = itab[_ns];
652
653 delete [] itab;
654 }
655 else {
656 pollster_mesh_index = 1;
657 for ( i = 0 ; i < _ns ; ++i )
658 free_vars[i] = -1;
659 }
660 }
661
662 /*---------------------------------------------*/
663 /* receive optimization data from the master */
664 /* MASTER --> POLLSTER */
665 /*---------------------------------------------*/
receive_optimization_data(bool & stop_algo,Point & x0,Double & fx0) const666 void Master_Slaves::receive_optimization_data ( bool & stop_algo ,
667 Point & x0 ,
668 Double & fx0 ) const {
669 char c_stop;
670 MPI_Status status;
671 MPI_Request req = MPI_REQUEST_NULL;
672 int i , n = _p.get_dimension();
673
674 // send a request for c_stop:
675 MPI_Irecv ( &c_stop , 1 , MPI_CHAR , 0 ,
676 Master_Slaves::TAG_CSTOP , MPI_COMM_WORLD , &req );
677
678 // send a signal to the master:
679 MPI_Send ( &Master_Slaves::OPTI_DATA_SIGNAL , 1 , MPI_CHAR ,
680 0 , Master_Slaves::TAG_SIGNAL , MPI_COMM_WORLD );
681
682 MPI_Wait ( &req , &status );
683
684 // stop:
685 if ( c_stop == '1' ) {
686 stop_algo = true;
687 x0.reset();
688 }
689
690 // continue:
691 else {
692
693 stop_algo = false;
694 double * rtab = new double [n+2];
695
696 MPI_Recv ( rtab , n+2 , MPI_DOUBLE , 0 ,
697 Master_Slaves::TAG_D1 , MPI_COMM_WORLD , &status );
698
699 for ( i = 0 ; i < n ; ++i )
700 x0[i] = rtab[i];
701
702 Double h = rtab[n];
703 fx0 = ( h <= _p.get_h_min() ) ? rtab[n+1] : INF;
704
705 // get the best feasible point from the cache server:
706 {
707 char pt_flag;
708 int npm1 = _np-1;
709 MPI_Irecv ( &pt_flag , 1 , MPI_CHAR , npm1 ,
710 Cache_Server::TAG_BF , MPI_COMM_WORLD , &req );
711
712 MPI_Send ( &Cache_Server::BF_SIGNAL , 1 , MPI_CHAR ,
713 npm1 , Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD );
714
715 MPI_Wait ( &req , &status );
716
717 if ( pt_flag == '1' ) {
718
719 MPI_Recv ( rtab , n+2 , MPI_DOUBLE , npm1 ,
720 Cache_Server::TAG_X7 , MPI_COMM_WORLD , &status );
721
722 for ( i = 0 ; i < n ; ++i )
723 x0[i] = rtab[i];
724
725 Double h = rtab[n];
726 fx0 = ( h <= _p.get_h_min() ) ? rtab[n+1] : INF;
727
728 }
729 }
730 delete [] rtab;
731
732 // check the bounds:
733 const Point & lb = _p.get_lb();
734 const Point & ub = _p.get_ub();
735
736 for ( i = 0 ; i < n ; ++i ) {
737 if ( lb[i].is_defined() && x0[i].value() < lb[i].value() )
738 x0[i] = lb[i];
739 if ( ub[i].is_defined() && x0[i].value() > ub[i].value() )
740 x0[i] = ub[i];
741 }
742 }
743 }
744
745 /*-----------------------------------------------------*/
746 /* send optimization data from the master to a slave */
747 /* MASTER --> POLLSTER or MASTER --> SLAVE */
748 /*-----------------------------------------------------*/
send_optimization_data(int pollster_mesh_index,bool stop_algo,const double * best_feasible,const double * best_infeasible,int source) const749 void Master_Slaves::send_optimization_data
750 ( int pollster_mesh_index ,
751 bool stop_algo ,
752 const double * best_feasible ,
753 const double * best_infeasible ,
754 int source ) const {
755
756 char c_stop = (stop_algo) ? '1' : '0';
757
758 MPI_Rsend ( &c_stop , 1 , MPI_CHAR , source ,
759 Master_Slaves::TAG_CSTOP , MPI_COMM_WORLD );
760
761 // continue:
762 if ( !stop_algo ) {
763
764 int n = _p.get_dimension();
765
766 // data for pollster and regular slaves:
767 if ( best_feasible )
768 MPI_Send ( const_cast<double*>(best_feasible) , n+2 , MPI_DOUBLE ,
769 source , Master_Slaves::TAG_D1 , MPI_COMM_WORLD );
770 else
771 MPI_Send ( const_cast<double*>(best_infeasible) , n+2 , MPI_DOUBLE ,
772 source , Master_Slaves::TAG_D1 , MPI_COMM_WORLD );
773
774 // additional data for regular slaves:
775 if ( source != 1 ) {
776
777 int * itab = new int [_ns+1];
778
779 // choose the free varables:
780 {
781 Random_Pickup rp ( n );
782
783 for ( int i = 0 ; i < _ns ; ++i )
784 itab[i] = rp.pickup(); // index of the ith free variable
785 }
786
787 itab[_ns] = pollster_mesh_index;
788
789 MPI_Send ( itab , _ns+1 , MPI_INT , source ,
790 Master_Slaves::TAG_I2 , MPI_COMM_WORLD );
791
792 delete [] itab;
793 }
794 }
795 }
796
797 /*-----------------------------------------------*/
798 /* check the initial mesh size values */
799 /*-----------------------------------------------*/
check_delta(const Point & delta)800 bool Master_Slaves::check_delta ( const Point & delta ) {
801 int n = delta.size();
802 for ( int i = 0 ; i < n ; ++i )
803 if ( delta[i].value() < Double::get_epsilon() ||
804 delta[i].value() <= 0.0 )
805 return false;
806 return true;
807 }
808
809