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