1 #include "Cache_Server.hpp"
2 using namespace std;
3 using namespace NOMAD;
4
5 /*--------------------------*/
6 /* tags and signal values */
7 /*--------------------------*/
8 const int Cache_Server::TAG_SIGNAL = 0;
9 const int Cache_Server::TAG_CACHE_HIT = 1;
10 const int Cache_Server::TAG_X1 = 2;
11 const int Cache_Server::TAG_X2 = 3;
12 const int Cache_Server::TAG_X3 = 4;
13 const int Cache_Server::TAG_X4 = 5;
14 const int Cache_Server::TAG_X5 = 6;
15 const int Cache_Server::TAG_X6 = 7;
16 const int Cache_Server::TAG_X7 = 8;
17 const int Cache_Server::TAG_BBOR = 9;
18 const int Cache_Server::TAG_BBOC = 10;
19 const int Cache_Server::TAG_NB_EP = 11;
20 const int Cache_Server::TAG_EP = 12;
21 const int Cache_Server::TAG_BF = 13;
22 char Cache_Server::STOP_SIGNAL = 'S';
23 char Cache_Server::FIND_SIGNAL = 'F';
24 char Cache_Server::INSERT_SIGNAL = 'I';
25 char Cache_Server::NB_EP_SIGNAL = 'N';
26 char Cache_Server::EP_SIGNAL = 'E';
27 char Cache_Server::BF_SIGNAL = 'B';
28
29 /*-----------------------------------*/
30 /* constructor */
31 /*-----------------------------------*/
Cache_Server(const Display & out,int rank,int np,const Double & h_min,int max_bbe,bool allow_multiple_evals,bool debug)32 Cache_Server::Cache_Server ( const Display & out ,
33 int rank ,
34 int np ,
35 const Double & h_min ,
36 int max_bbe ,
37 bool allow_multiple_evals ,
38 bool debug )
39 : Cache ( out , TRUTH ) ,
40 _rank ( rank ) ,
41 _np ( np ) ,
42 _debug ( debug ) ,
43 _h_min ( h_min ) ,
44 _max_bbe ( max_bbe ) ,
45 _bf ( NULL ) ,
46 _bi1 ( NULL ) ,
47 _bi2 ( NULL ) ,
48 _multiple_evals ( 0 ) ,
49 _cache_hits ( 0 ) ,
50 _cache_search_pts ( 0 ) ,
51 _waited_pts ( NULL ) ,
52 _clients_ext_pts ( NULL ) {
53
54 // cache server:
55 if ( _rank == _np - 1 ) {
56
57 _clients_ext_pts = new list<const Eval_Point*> [_np];
58
59 if ( !allow_multiple_evals ) {
60 _waited_pts = new Point * [_np];
61 for ( int i = 0 ; i < _np ; ++i )
62 _waited_pts[i] = NULL;
63 }
64 }
65 }
66
67 /*-----------------------------------*/
68 /* destructor */
69 /*-----------------------------------*/
~Cache_Server(void)70 Cache_Server::~Cache_Server ( void ) {
71 if ( _waited_pts ) {
72 for ( int i = 0 ; i < _np ; ++i )
73 if ( _waited_pts[i] )
74 delete _waited_pts;
75 delete [] _waited_pts;
76 }
77
78 if ( _clients_ext_pts )
79 delete [] _clients_ext_pts;
80 }
81
82 /*-----------------------------------*/
83 /* start the server (process np-1) */
84 /*-----------------------------------*/
start(void)85 void Cache_Server::start ( void ) {
86
87 int npm1 = _np-1;
88
89 if ( _rank != npm1 )
90 return;
91
92 MPI_Status status;
93 int nb_stops = 0;
94 int source;
95 char signal;
96
97 /*-------------*/
98 /* main loop */
99 /*-------------*/
100 while ( nb_stops != npm1 ) {
101
102 MPI_Recv ( &signal , 1 , MPI_CHAR , MPI_ANY_SOURCE ,
103 Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD , &status );
104
105 source = status.MPI_SOURCE;
106
107 // stop signal:
108 // ------------
109 if ( signal == Cache_Server::STOP_SIGNAL ) {
110 if ( _debug )
111 _out << "CACHE SERVER: STOP SIGNAL FROM RANK " << source << endl;
112 ++nb_stops;
113 }
114
115 // find signal:
116 // ------------
117 else if ( signal == Cache_Server::FIND_SIGNAL ) {
118 if ( _debug )
119 _out << "CACHE SERVER: FIND SIGNAL FROM RANK " << source << endl;
120 process_find_signal ( source );
121 }
122
123 // insert signal:
124 // --------------
125 else if ( signal == Cache_Server::INSERT_SIGNAL ) {
126 if ( _debug ) {
127 _out << "CACHE SERVER: INSERT SIGNAL FROM RANK "
128 << source;
129 if ( source == 1 )
130 _out << " (POLLSTER)";
131 _out << endl;
132 }
133 process_insert_signal ( source );
134 }
135
136 // number of extern points signal:
137 // -------------------------------
138 else if ( signal == Cache_Server::NB_EP_SIGNAL ) {
139 if ( _debug ) {
140 _out << "CACHE SERVER: NB EXTERN POINTS SIGNAL FROM RANK "
141 << source;
142 if ( source == 1 )
143 _out << " (POLLSTER)";
144 _out << endl;
145 }
146 int nb_client_extern_pts = _clients_ext_pts[source].size();
147 MPI_Rsend ( &nb_client_extern_pts , 1 , MPI_INT , source ,
148 Cache_Server::TAG_NB_EP , MPI_COMM_WORLD );
149 }
150
151 // extern point signal:
152 // --------------------
153 else if ( signal == Cache_Server::EP_SIGNAL ) {
154 if ( _debug ) {
155 _out << "CACHE SERVER: EXTERN POINT SIGNAL FROM RANK "
156 << source;
157 if ( source == 1 )
158 _out << " (POLLSTER)";
159 _out << endl;
160 }
161 process_ep_signal ( source );
162 }
163
164 // best feasible point signal:
165 else if ( signal == Cache_Server::BF_SIGNAL ) {
166 if ( _debug ) {
167 _out << "CACHE SERVER: BEST FEASIBLE POINT SIGNAL FROM RANK "
168 << source;
169 if ( source == 1 )
170 _out << " (POLLSTER)";
171 }
172 process_bf_signal ( source );
173 }
174 }
175 }
176
177 /*---------------------------------*/
178 /* stop the server (clients) */
179 /*---------------------------------*/
stop(void) const180 void Cache_Server::stop ( void ) const {
181
182 int npm1 = _np-1;
183
184 if ( _rank == npm1 )
185 return;
186
187 MPI_Send ( &Cache_Server::STOP_SIGNAL , 1 , MPI_CHAR ,
188 npm1 , Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD );
189 }
190
191 /*----------------------------------------------*/
192 /* process the best feasible point signal */
193 /*----------------------------------------------*/
process_bf_signal(int source) const194 void Cache_Server::process_bf_signal ( int source ) const {
195
196 char pt_flag = (_bf) ? '1' : '0';
197
198 MPI_Rsend ( &pt_flag , 1 , MPI_CHAR , source ,
199 Cache_Server::TAG_BF , MPI_COMM_WORLD );
200
201 if ( _bf ) {
202 int n = _bf->size();
203 double * rtab = new double[n+2];
204 for ( int i = 0 ; i < n ; ++i )
205 rtab[i] = (*_bf)[i].value();
206 rtab[n] = _bf->get_h().value();
207 rtab[n+1] = _bf->get_f().value();
208
209 MPI_Send ( rtab , n+2 , MPI_DOUBLE , source ,
210 Cache_Server::TAG_X7 , MPI_COMM_WORLD );
211
212 delete [] rtab;
213 }
214
215 }
216
217 /*---------------------------------------*/
218 /* process the extern point signal */
219 /*---------------------------------------*/
process_ep_signal(int source) const220 void Cache_Server::process_ep_signal ( int source ) const {
221
222 int nb_pt = ( _clients_ext_pts[source].size() > 0 ) ? 1 : 0;
223
224 MPI_Rsend ( &nb_pt , 1 , MPI_INT , source ,
225 Cache_Server::TAG_EP , MPI_COMM_WORLD );
226
227 // send and remove the extern point:
228 if ( nb_pt > 0 ) {
229
230 const Eval_Point * x = *(_clients_ext_pts[source].begin());
231
232 ++_cache_search_pts;
233
234 // send the point :
235 int i , n = x->size() , m = x->get_m();
236 int itab[5];
237 itab[0] = n;
238 itab[1] = m;
239 itab[2] = ( x->is_eval_ok() ) ? 1 : 0;
240
241 if ( x->get_signature() && (x->get_signature()->get_mesh()->get_mesh_indices())[0].is_defined() )
242 {
243 itab[3]=1;
244 itab[4]=static_cast<int>((x->get_signature()->get_mesh()->get_mesh_indices())[0].value());
245 }
246 else
247 itab[3] = itab[4] = 0;
248
249 double * rtab = new double[n+2*m];
250 for ( i = 0 ; i < n ; ++i )
251 rtab[i] = (*x)[i].value();
252
253 const Point & bbo = x->get_bb_outputs();
254
255 for ( i = 0 ; i < m ; ++i )
256 if ( bbo[i].is_defined() ) {
257 rtab[2*i+n ] = 1.0;
258 rtab[2*i+n+1] = bbo[i].value();
259 }
260 else
261 rtab[2*i+n] = rtab[2*i+n+1] = -1.0;
262
263 MPI_Send ( itab , 5 , MPI_INT , source ,
264 Cache_Server::TAG_X5 , MPI_COMM_WORLD );
265
266 MPI_Send ( rtab , n+2*m , MPI_DOUBLE , source ,
267 Cache_Server::TAG_X6 , MPI_COMM_WORLD );
268
269 // remove the point:
270 _clients_ext_pts[source].pop_front();
271 }
272 }
273
274 /*-------------------------------*/
275 /* process the find signal */
276 /*-------------------------------*/
process_find_signal(int source) const277 void Cache_Server::process_find_signal ( int source ) const {
278
279 MPI_Status status;
280 int i;
281
282 // receive the point coordinates:
283 int itab[2];
284 MPI_Recv ( itab , 2 , MPI_INT , source ,
285 Cache_Server::TAG_X1 , MPI_COMM_WORLD , &status );
286
287 int n = itab[0];
288 int m = itab[1];
289
290 double * rtab = new double[n];
291
292 MPI_Recv ( rtab , n , MPI_DOUBLE , source ,
293 Cache_Server::TAG_X2 , MPI_COMM_WORLD , &status );
294
295 // create the Eval_Point to search:
296 Eval_Point * x = new Eval_Point ( n , m );
297
298 for ( i = 0 ; i < n ; ++i )
299 (*x)[i] = rtab[i];
300
301 delete [] rtab;
302
303 // search in cache, or stop the algorithm:
304 const Eval_Point * cache_x;
305
306 if ( _max_bbe > 0 && size() >= _max_bbe ) {
307 Eval_Point * stop_point = new Eval_Point ( n , m );
308 for ( i = 0 ; i < n ; ++i )
309 (*stop_point)[i] = (*x)[i];
310 stop_point->set_eval_status ( EVAL_FAIL );
311 cache_x = stop_point;
312 }
313 else
314 cache_x = Cache::find ( *x );
315
316 // cache hit signal :
317 int cache_hit;
318
319 // point in cache :
320 if ( cache_x ) {
321
322 delete x;
323
324 cache_hit = 1;
325
326 ++_cache_hits;
327
328 MPI_Rsend ( &cache_hit , 1 , MPI_INT , source ,
329 Cache_Server::TAG_CACHE_HIT , MPI_COMM_WORLD );
330
331 // bb output values, defined values and eval_ok flag:
332 rtab = new double[m];
333 char * ctab = new char [m+1];
334 const Point & bbo = cache_x->get_bb_outputs();
335
336 for ( i = 0 ; i < m ; ++i ) {
337 if ( bbo[i].is_defined() ) {
338 rtab[i] = bbo[i].value();
339 ctab[i] = '1';
340 }
341 else {
342 rtab[i] = INF;
343 ctab[i] = '0';
344 }
345 }
346
347 ctab[m] = ( cache_x->is_eval_ok() ) ? '1' : '0';
348
349 MPI_Send ( rtab , m , MPI_DOUBLE , source ,
350 Cache_Server::TAG_BBOR , MPI_COMM_WORLD );
351
352 MPI_Send ( ctab , m+1 , MPI_CHAR , source ,
353 Cache_Server::TAG_BBOC , MPI_COMM_WORLD );
354
355 delete [] rtab;
356 delete [] ctab;
357
358 // remove this point from _clients_ext_pts:
359 {
360 list<const Eval_Point *>::iterator
361 it = _clients_ext_pts[source].begin() ,
362 end = _clients_ext_pts[source].end ();
363 while ( it != end ) {
364 if ( *it == cache_x ) {
365 _clients_ext_pts[source].erase(it);
366 break;
367 }
368 ++it;
369 }
370 }
371 }
372
373 // point not in cache :
374 else {
375
376 cache_hit = 0;
377
378 // evaluation in progress ?
379 if ( _waited_pts ) {
380
381 for ( i = 0 ; i < _np ; ++i )
382 if ( _waited_pts[i] && *_waited_pts[i] == *x ) {
383 cache_hit = -1;
384 break;
385 }
386
387 if ( cache_hit == 0 )
388 _waited_pts[source] = x;
389 else
390 delete x;
391 }
392 else
393 delete x;
394
395 MPI_Rsend ( &cache_hit , 1 , MPI_INT , source ,
396 Cache_Server::TAG_CACHE_HIT , MPI_COMM_WORLD );
397 }
398 }
399
400 /*--------------------*/
401 /* find a point */
402 /*--------------------*/
find(const Eval_Point & x) const403 const Eval_Point * Cache_Server::find ( const Eval_Point & x ) const {
404
405 int npm1 = _np-1;
406
407 // server:
408 if ( _rank == npm1 )
409 return Cache::find ( x );
410
411 // A. search in local cache:
412 const Eval_Point * cache_x = Cache::find ( x );
413 if ( cache_x )
414 return cache_x;
415
416 // B. ask the server.
417 int i , n = x.size() , m = x.get_m();
418 int itab[2];
419 itab[0] = n;
420 itab[1] = m;
421 double * rtab = new double[n];
422 for ( i = 0 ; i < n ; ++i )
423 rtab[i] = x[i].value();
424
425 int cache_hit = -1;
426 MPI_Request req = MPI_REQUEST_NULL;
427 MPI_Status status;
428
429 while ( cache_hit < 0 ) {
430
431 // B1. send a request for cache_hit:
432 MPI_Irecv ( &cache_hit , 1 , MPI_INT , npm1 ,
433 Cache_Server::TAG_CACHE_HIT , MPI_COMM_WORLD , &req );
434
435 // B2. send the find signal:
436 MPI_Send ( &Cache_Server::FIND_SIGNAL , 1 , MPI_CHAR ,
437 npm1 , Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD );
438
439 // B3. send the point coordinates:
440 MPI_Send ( itab , 2 , MPI_INT , npm1 ,
441 Cache_Server::TAG_X1 , MPI_COMM_WORLD );
442 MPI_Send ( rtab , n , MPI_DOUBLE , npm1 ,
443 Cache_Server::TAG_X2 , MPI_COMM_WORLD );
444
445 // B4. wait for the cache_hit request:
446 MPI_Wait ( &req , &status );
447
448 // cache hit possible values:
449 //
450 // -1: point is being evaluated by another process (wait)
451 // 0: point not in cache server
452 // 1: point in cache server
453 }
454
455 delete [] rtab;
456
457 // C. cache hit: receive the point outputs:
458 if ( cache_hit == 1 ) {
459
460 // C.1. bb output values and eval status:
461 rtab = new double[m];
462 MPI_Recv ( rtab , m , MPI_DOUBLE , npm1 ,
463 Cache_Server::TAG_BBOR , MPI_COMM_WORLD , &status );
464
465 char * ctab = new char[m+1];
466 MPI_Recv ( ctab , m+1 , MPI_CHAR , npm1 ,
467 Cache_Server::TAG_BBOC , MPI_COMM_WORLD , &status );
468
469 Point bbo(m);
470 for ( i = 0 ; i < m ; ++i )
471 if ( ctab[i]=='1' )
472 bbo[i] = rtab[i];
473
474 delete [] rtab;
475
476 // C.2. eval point construction:
477 Eval_Point * y = new Eval_Point ( n , m );
478 y->set_bb_output ( bbo );
479 for ( i = 0 ; i < n ; ++i )
480 (*y)[i] = x[i];
481
482 y->set_eval_status ( (ctab[m]=='1') ? EVAL_OK : EVAL_FAIL );
483
484 y->set_current_run ( x.get_current_run() );
485
486 delete [] ctab;
487
488 cache_x = y;
489
490
491 // C.3. insertion in local cache:
492 const_cast<Cache_Server*>(this)->Cache::insert ( *cache_x );
493 }
494
495 return cache_x;
496 }
497
498 /*------------------------------------*/
499 /* process the insertion signal */
500 /*------------------------------------*/
process_insert_signal(int source)501 void Cache_Server::process_insert_signal ( int source ) {
502
503 if ( _waited_pts && _waited_pts[source] ) {
504 delete _waited_pts[source];
505 _waited_pts[source] = NULL;
506 }
507
508 MPI_Status status;
509
510 // receive the evaluation point:
511 int itab[7];
512 MPI_Recv ( itab , 7 , MPI_INT , source ,
513 Cache_Server::TAG_X3 , MPI_COMM_WORLD , &status );
514
515 int n = itab[0];
516 int m = itab[1];
517
518 double * rtab = new double[n+2*m+2];
519
520 MPI_Recv ( rtab , n+2*m+2 , MPI_DOUBLE , source ,
521 Cache_Server::TAG_X4 , MPI_COMM_WORLD , &status );
522
523 // create the Eval_Point to insert:
524 Eval_Point * x = new Eval_Point ( n , m );
525
526 int i;
527 for ( i = 0 ; i < n ; ++i )
528 (*x)[i] = rtab[i];
529
530 for ( i = 0 ; i < m ; ++i )
531 if ( rtab[2*i+n] > 0 )
532 x->set_bb_output ( i , rtab[2*i+n+1] );
533
534 if ( itab[5] == 1 )
535 x->set_f ( rtab[n+2*m ] );
536
537 if ( itab[6] == 1 )
538 x->set_h ( rtab[n+2*m+1] );
539
540 delete [] rtab;
541
542 x->set_eval_status ( ( itab[2] == 1 ) ? EVAL_OK : EVAL_FAIL );
543
544 // Eval_Point insertion in cache and multiple_evals detection:
545 const Eval_Point * cache_x = Cache::find ( *x );
546 if ( cache_x ) {
547 ++_multiple_evals;
548 delete x;
549 x = const_cast<Eval_Point *>(cache_x);
550 }
551 else
552 Cache::insert ( *x );
553
554 // update the best points:
555 update_best_points ( *x , source );
556 }
557
558 /*--------------------*/
559 /* insert a point */
560 /*--------------------*/
insert(const NOMAD::Eval_Point & x)561 void Cache_Server::insert ( const NOMAD::Eval_Point & x ) {
562
563 // insertion in local cache :
564 Cache::insert ( x );
565
566 int npm1 = _np-1;
567 if ( _rank == npm1 )
568 return;
569
570 // insert signal :
571 MPI_Send ( &Cache_Server::INSERT_SIGNAL , 1 , MPI_CHAR ,
572 npm1 , Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD );
573
574 // send the point :
575 int i , n = x.size() , m = x.get_m();
576 int itab[7];
577 itab[0] = n;
578 itab[1] = m;
579 itab[2] = ( x.is_eval_ok() ) ? 1 : 0;
580
581 if ( x.get_signature() && (x.get_signature()->get_mesh()->get_mesh_indices())[0].is_defined() )
582 {
583 itab[3]=1;
584 itab[4]=static_cast<int>((x.get_signature()->get_mesh()->get_mesh_indices())[0].value());
585 }
586 else
587 itab[3] = itab[4] = 0;
588
589 double * rtab = new double[n+2*m+2];
590 for ( i = 0 ; i < n ; ++i )
591 rtab[i] = x[i].value();
592
593 const Point & bbo = x.get_bb_outputs();
594
595 for ( i = 0 ; i < m ; ++i )
596 if ( bbo[i].is_defined() ) {
597 rtab[2*i+n ] = 1.0;
598 rtab[2*i+n+1] = bbo[i].value();
599 }
600 else
601 rtab[2*i+n] = rtab[2*i+n+1] = -1.0;
602
603 // f and h values:
604 if ( x.get_f().is_defined() ) {
605 itab[5 ] = 1;
606 rtab[n+2*m] = x.get_f().value();
607 }
608 else {
609 itab[5 ] = 0;
610 rtab[n+2*m] = INF;
611 }
612 if ( x.get_h().is_defined() ) {
613 itab[6 ] = 1;
614 rtab[n+2*m+1] = x.get_h().value();
615 }
616 else {
617 itab[6 ] = 0;
618 rtab[n+2*m+1] = INF;
619 }
620
621 MPI_Send ( itab , 7 , MPI_INT , npm1 ,
622 Cache_Server::TAG_X3 , MPI_COMM_WORLD );
623
624 MPI_Send ( rtab , n+2*m+2 , MPI_DOUBLE , npm1 ,
625 Cache_Server::TAG_X4 , MPI_COMM_WORLD );
626
627 delete [] rtab;
628 }
629
630 /*--------------------------------------*/
631 /* get and remove an extern point */
632 /*--------------------------------------*/
get_and_remove_extern_point(void) const633 const Eval_Point * Cache_Server::get_and_remove_extern_point ( void ) const {
634
635 int npm1 = _np-1;
636
637 if ( _rank == npm1 )
638 return NULL;
639
640 // extern point from the client:
641 // -----------------------------
642 if ( Cache::get_nb_extern_points() > 0 )
643 return Cache::get_and_remove_extern_point();
644
645 // extern point from the server:
646 // -----------------------------
647
648 int nb_pt;
649
650 // send a request for an extern point:
651 MPI_Request req;
652 MPI_Irecv ( &nb_pt , 1 , MPI_INT , npm1 ,
653 Cache_Server::TAG_EP , MPI_COMM_WORLD , &req );
654
655 // extern points signal :
656 MPI_Send ( &Cache_Server::EP_SIGNAL , 1 , MPI_CHAR ,
657 npm1 , Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD );
658
659 // wait for the request:
660 MPI_Status status;
661 MPI_Wait ( &req , &status );
662
663 if ( nb_pt == 0 )
664 return NULL;
665
666 // receive the extern point:
667 int itab[5];
668 MPI_Recv ( itab , 5 , MPI_INT , npm1 ,
669 Cache_Server::TAG_X5 , MPI_COMM_WORLD , &status );
670
671 int n = itab[0];
672 int m = itab[1];
673
674 double * rtab = new double[n+2*m];
675
676 MPI_Recv ( rtab , n+2*m , MPI_DOUBLE , npm1 ,
677 Cache_Server::TAG_X6 , MPI_COMM_WORLD , &status );
678
679 // create the Eval_Point:
680 Eval_Point * x = new Eval_Point ( n , m );
681
682 int i;
683 for ( i = 0 ; i < n ; ++i )
684 (*x)[i] = rtab[i];
685
686 for ( i = 0 ; i < m ; ++i )
687 if ( rtab[2*i+n] > 0 )
688 x->set_bb_output ( i , rtab[2*i+n+1] );
689
690 delete [] rtab;
691
692 x->set_eval_status ( ( itab[2] == 1 ) ? EVAL_OK : EVAL_FAIL );
693
694
695 // insert the point in local cache:
696 const Eval_Point * cache_x = Cache::find ( *x );
697 if ( cache_x ) {
698 delete x;
699 return cache_x;
700 }
701
702 x->set_current_run ( true );
703 const_cast<Cache_Server*>(this)->Cache::insert ( *x );
704 x->set_current_run ( false );
705
706 return x;
707 }
708
709 /*---------------------------------------*/
710 /* get the number of extern points */
711 /*---------------------------------------*/
get_nb_extern_points(void) const712 int Cache_Server::get_nb_extern_points ( void ) const {
713
714 int nb_client_extern_pts = Cache::get_nb_extern_points();
715 int nb_server_extern_pts = 0;
716 int npm1 = _np-1;
717
718 if ( _rank != npm1 ) {
719
720 // send a request for the number of extern points:
721 MPI_Request req;
722 MPI_Irecv ( &nb_server_extern_pts , 1 , MPI_INT , npm1 ,
723 Cache_Server::TAG_NB_EP , MPI_COMM_WORLD , &req );
724
725 // number of extern points signal :
726 MPI_Send ( &Cache_Server::NB_EP_SIGNAL , 1 , MPI_CHAR ,
727 npm1 , Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD );
728
729 // wait for the request:
730 MPI_Status status;
731 MPI_Wait ( &req , &status );
732 }
733
734 return nb_client_extern_pts + nb_server_extern_pts;
735 }
736
737 /*---------------------------------*/
738 /* display the extern points */
739 /*---------------------------------*/
display_extern_pts(const Display & out) const740 void Cache_Server::display_extern_pts ( const Display & out ) const {
741
742 int npm1 = _np-1;
743
744 // server:
745 // -------
746 if ( _rank == npm1 ) {
747
748 list<const Eval_Point*>::const_iterator it;
749 out << endl << open_block ("Clients extern points");
750
751 for ( int i = 0 ; i < npm1 ; ++i ) {
752 out.open_block ( "client #"+itos(i) );
753 for ( it = _clients_ext_pts[i].begin() ;
754 it != _clients_ext_pts[i].end () ;
755 ++it ) {
756 out << "#" << (*it)->get_tag() << " ( ";
757 (*it)->Point::display ( out );
758 out << " ) " << " ["
759 << (*it)->get_bb_outputs() << " ] f="
760 << (*it)->get_f() << " h="
761 << (*it)->get_h() << endl;
762 }
763 out.close_block();
764 }
765 }
766
767 // clients:
768 else {
769
770 out << endl
771 << open_block ( "Process #" + itos(_rank) + ": extern points" );
772
773 out << "number of points = "
774 << get_nb_extern_points() << endl;
775
776 const Eval_Point * extern_pt = get_and_remove_extern_point();
777
778 while ( extern_pt ) {
779
780 out << "#" << extern_pt->get_tag() << " ( ";
781 extern_pt->Point::display ( out );
782 out << " ) " << " ["
783 << extern_pt->get_bb_outputs() << " ] f="
784 << extern_pt->get_f() << " h="
785 << extern_pt->get_h() << endl;
786
787 extern_pt = get_and_remove_extern_point();
788 }
789 }
790 out << close_block() << endl;
791 }
792
793 /*--------------------------------------*/
794 /* update and display the best points */
795 /*--------------------------------------*/
update_best_points(const Eval_Point & x,int source)796 void Cache_Server::update_best_points ( const Eval_Point & x ,
797 int source ) {
798 const Double & f = x.get_f();
799 const Double & h = x.get_h();
800
801 if ( !f.is_defined() || !h.is_defined() )
802 return;
803
804 int i;
805 bool add_x = false;
806
807 // feasible:
808 if ( h <= _h_min ) {
809
810 // new best feasible point:
811 if ( !_bf || f < _bf->get_f() ) {
812 _bf = &x;
813 add_x = true;
814 display_current_solution();
815 }
816 }
817
818 // infeasible:
819 else {
820 if ( !_bi1 || h < _bi1->get_h() ) {
821 _bi1 = &x;
822 add_x = true;
823 }
824 if ( !_bi2 || f < _bi2->get_f() ) {
825 _bi2 = &x;
826 add_x = true;
827 }
828 }
829
830 if ( add_x )
831 for ( i = 0 ; i < _np-1 ; ++i )
832 if ( i != source )
833 _clients_ext_pts[i].push_front ( &x );
834 }
835
836 /*-----------------------------------------*/
837 /* display the current best solution */
838 /*-----------------------------------------*/
display_current_solution(void) const839 void Cache_Server::display_current_solution ( void ) const {
840 if ( _rank != _np-1 || !_bf )
841 return;
842 if ( _debug )
843 _out << "CACHE SERVER: CURRENT SOLUTION: \t";
844 _out << _clock.get_real_time() << "\t"
845 << size() << "\t" << _bf->get_f() << endl;
846 }
847
848 /*-------------------------------*/
849 /* display the best points */
850 /*-------------------------------*/
display_best_points(const Display & out) const851 void Cache_Server::display_best_points ( const Display & out ) const {
852 if ( _rank != _np-1 )
853 return;
854
855 // display the last solution:
856 display_current_solution();
857
858 // stats:
859 out << "evaluations: " << size() << endl
860 << "cache hits : " << _cache_hits << endl;
861
862 // best feasible solution:
863 out << "best feasible solution: ";
864 if ( _bf ) {
865 out << "x=( ";
866 _bf->Point::display(out);
867 out << " )"
868 << " F(x)=[ " << _bf->get_bb_outputs() << " ] h="
869 << _bf->get_h() << " f=" << _bf->get_f() << endl;
870 }
871 else {
872
873 out << "NULL" << endl;
874
875 // best infeasible solutions:
876 if ( _bi1 ) {
877 out << "best infeas. sol. #1 : x=( ";
878 _bi1->Point::display(out);
879 out << " )"
880 << " F(x)=[ " << _bi1->get_bb_outputs() << " ] h="
881 << _bi1->get_h() << " f=" << _bi1->get_f() << endl;
882 }
883
884 if ( _bi2 && _bi2 != _bi1 ) {
885 out << "best infeas. sol. #2 : x=( ";
886 _bi2->Point::display(out);
887 out << " )"
888 << " F(x)=[ " << _bi2->get_bb_outputs() << " ] h="
889 << _bi2->get_h() << " f=" << _bi2->get_f() << endl;
890 }
891 }
892 }
893