Skip to content
Snippets Groups Projects
Commit 65a3fb19 authored by Miroslav Shaltev's avatar Miroslav Shaltev
Browse files

Update to Nomad 3.7.2

parent fee81ae9
No related branches found
No related tags found
No related merge requests found
#include "Cache_Server.hpp"
using namespace std;
using namespace NOMAD;
/*--------------------------*/
/* tags and signal values */
/*--------------------------*/
const int Cache_Server::TAG_SIGNAL = 0;
const int Cache_Server::TAG_CACHE_HIT = 1;
const int Cache_Server::TAG_X1 = 2;
const int Cache_Server::TAG_X2 = 3;
const int Cache_Server::TAG_X3 = 4;
const int Cache_Server::TAG_X4 = 5;
const int Cache_Server::TAG_X5 = 6;
const int Cache_Server::TAG_X6 = 7;
const int Cache_Server::TAG_X7 = 8;
const int Cache_Server::TAG_BBOR = 9;
const int Cache_Server::TAG_BBOC = 10;
const int Cache_Server::TAG_NB_EP = 11;
const int Cache_Server::TAG_EP = 12;
const int Cache_Server::TAG_BF = 13;
char Cache_Server::STOP_SIGNAL = 'S';
char Cache_Server::FIND_SIGNAL = 'F';
char Cache_Server::INSERT_SIGNAL = 'I';
char Cache_Server::NB_EP_SIGNAL = 'N';
char Cache_Server::EP_SIGNAL = 'E';
char Cache_Server::BF_SIGNAL = 'B';
/*-----------------------------------*/
/* constructor */
/*-----------------------------------*/
Cache_Server::Cache_Server ( const Display & out ,
int rank ,
int np ,
const Double & h_min ,
int max_bbe ,
bool allow_multiple_evals ,
bool debug )
: Cache ( out , TRUTH ) ,
_rank ( rank ) ,
_np ( np ) ,
_debug ( debug ) ,
_h_min ( h_min ) ,
_max_bbe ( max_bbe ) ,
_bf ( NULL ) ,
_bi1 ( NULL ) ,
_bi2 ( NULL ) ,
_multiple_evals ( 0 ) ,
_cache_hits ( 0 ) ,
_cache_search_pts ( 0 ) ,
_waited_pts ( NULL ) ,
_clients_ext_pts ( NULL ) {
// cache server:
if ( _rank == _np - 1 ) {
_clients_ext_pts = new list<const Eval_Point*> [_np];
if ( !allow_multiple_evals ) {
_waited_pts = new Point * [_np];
for ( int i = 0 ; i < _np ; ++i )
_waited_pts[i] = NULL;
}
}
}
/*-----------------------------------*/
/* destructor */
/*-----------------------------------*/
Cache_Server::~Cache_Server ( void ) {
if ( _waited_pts ) {
for ( int i = 0 ; i < _np ; ++i )
if ( _waited_pts[i] )
delete _waited_pts;
delete [] _waited_pts;
}
if ( _clients_ext_pts )
delete [] _clients_ext_pts;
}
/*-----------------------------------*/
/* start the server (process np-1) */
/*-----------------------------------*/
void Cache_Server::start ( void ) {
int npm1 = _np-1;
if ( _rank != npm1 )
return;
MPI_Status status;
int nb_stops = 0;
int source;
char signal;
/*-------------*/
/* main loop */
/*-------------*/
while ( nb_stops != npm1 ) {
MPI_Recv ( &signal , 1 , MPI_CHAR , MPI_ANY_SOURCE ,
Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD , &status );
source = status.MPI_SOURCE;
// stop signal:
// ------------
if ( signal == Cache_Server::STOP_SIGNAL ) {
if ( _debug )
_out << "CACHE SERVER: STOP SIGNAL FROM RANK " << source << endl;
++nb_stops;
}
// find signal:
// ------------
else if ( signal == Cache_Server::FIND_SIGNAL ) {
if ( _debug )
_out << "CACHE SERVER: FIND SIGNAL FROM RANK " << source << endl;
process_find_signal ( source );
}
// insert signal:
// --------------
else if ( signal == Cache_Server::INSERT_SIGNAL ) {
if ( _debug ) {
_out << "CACHE SERVER: INSERT SIGNAL FROM RANK "
<< source;
if ( source == 1 )
_out << " (POLLSTER)";
_out << endl;
}
process_insert_signal ( source );
}
// number of extern points signal:
// -------------------------------
else if ( signal == Cache_Server::NB_EP_SIGNAL ) {
if ( _debug ) {
_out << "CACHE SERVER: NB EXTERN POINTS SIGNAL FROM RANK "
<< source;
if ( source == 1 )
_out << " (POLLSTER)";
_out << endl;
}
int nb_client_extern_pts = _clients_ext_pts[source].size();
MPI_Rsend ( &nb_client_extern_pts , 1 , MPI_INT , source ,
Cache_Server::TAG_NB_EP , MPI_COMM_WORLD );
}
// extern point signal:
// --------------------
else if ( signal == Cache_Server::EP_SIGNAL ) {
if ( _debug ) {
_out << "CACHE SERVER: EXTERN POINT SIGNAL FROM RANK "
<< source;
if ( source == 1 )
_out << " (POLLSTER)";
_out << endl;
}
process_ep_signal ( source );
}
// best feasible point signal:
else if ( signal == Cache_Server::BF_SIGNAL ) {
if ( _debug ) {
_out << "CACHE SERVER: BEST FEASIBLE POINT SIGNAL FROM RANK "
<< source;
if ( source == 1 )
_out << " (POLLSTER)";
}
process_bf_signal ( source );
}
}
}
/*---------------------------------*/
/* stop the server (clients) */
/*---------------------------------*/
void Cache_Server::stop ( void ) const {
int npm1 = _np-1;
if ( _rank == npm1 )
return;
MPI_Send ( &Cache_Server::STOP_SIGNAL , 1 , MPI_CHAR ,
npm1 , Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD );
}
/*----------------------------------------------*/
/* process the best feasible point signal */
/*----------------------------------------------*/
void Cache_Server::process_bf_signal ( int source ) const {
char pt_flag = (_bf) ? '1' : '0';
MPI_Rsend ( &pt_flag , 1 , MPI_CHAR , source ,
Cache_Server::TAG_BF , MPI_COMM_WORLD );
if ( _bf ) {
int n = _bf->size();
double * rtab = new double[n+2];
for ( int i = 0 ; i < n ; ++i )
rtab[i] = (*_bf)[i].value();
rtab[n] = _bf->get_h().value();
rtab[n+1] = _bf->get_f().value();
MPI_Send ( rtab , n+2 , MPI_DOUBLE , source ,
Cache_Server::TAG_X7 , MPI_COMM_WORLD );
delete [] rtab;
}
}
/*---------------------------------------*/
/* process the extern point signal */
/*---------------------------------------*/
void Cache_Server::process_ep_signal ( int source ) const {
int nb_pt = ( _clients_ext_pts[source].size() > 0 ) ? 1 : 0;
MPI_Rsend ( &nb_pt , 1 , MPI_INT , source ,
Cache_Server::TAG_EP , MPI_COMM_WORLD );
// send and remove the extern point:
if ( nb_pt > 0 ) {
const Eval_Point * x = *(_clients_ext_pts[source].begin());
++_cache_search_pts;
// send the point :
int i , n = x->size() , m = x->get_m();
int itab[5];
itab[0] = n;
itab[1] = m;
itab[2] = ( x->is_eval_ok() ) ? 1 : 0;
if ( x->get_signature() && (x->get_signature()->get_mesh()->get_mesh_indices())[0].is_defined() )
{
itab[3]=1;
itab[4]=static_cast<int>((x->get_signature()->get_mesh()->get_mesh_indices())[0].value());
}
else
itab[3] = itab[4] = 0;
double * rtab = new double[n+2*m];
for ( i = 0 ; i < n ; ++i )
rtab[i] = (*x)[i].value();
const Point & bbo = x->get_bb_outputs();
for ( i = 0 ; i < m ; ++i )
if ( bbo[i].is_defined() ) {
rtab[2*i+n ] = 1.0;
rtab[2*i+n+1] = bbo[i].value();
}
else
rtab[2*i+n] = rtab[2*i+n+1] = -1.0;
MPI_Send ( itab , 5 , MPI_INT , source ,
Cache_Server::TAG_X5 , MPI_COMM_WORLD );
MPI_Send ( rtab , n+2*m , MPI_DOUBLE , source ,
Cache_Server::TAG_X6 , MPI_COMM_WORLD );
// remove the point:
_clients_ext_pts[source].pop_front();
}
}
/*-------------------------------*/
/* process the find signal */
/*-------------------------------*/
void Cache_Server::process_find_signal ( int source ) const {
MPI_Status status;
int i;
// receive the point coordinates:
int itab[2];
MPI_Recv ( itab , 2 , MPI_INT , source ,
Cache_Server::TAG_X1 , MPI_COMM_WORLD , &status );
int n = itab[0];
int m = itab[1];
double * rtab = new double[n];
MPI_Recv ( rtab , n , MPI_DOUBLE , source ,
Cache_Server::TAG_X2 , MPI_COMM_WORLD , &status );
// create the Eval_Point to search:
Eval_Point * x = new Eval_Point ( n , m );
for ( i = 0 ; i < n ; ++i )
(*x)[i] = rtab[i];
delete [] rtab;
// search in cache, or stop the algorithm:
const Eval_Point * cache_x;
if ( _max_bbe > 0 && size() >= _max_bbe ) {
Eval_Point * stop_point = new Eval_Point ( n , m );
for ( i = 0 ; i < n ; ++i )
(*stop_point)[i] = (*x)[i];
stop_point->set_eval_status ( EVAL_FAIL );
cache_x = stop_point;
}
else
cache_x = Cache::find ( *x );
// cache hit signal :
int cache_hit;
// point in cache :
if ( cache_x ) {
delete x;
cache_hit = 1;
++_cache_hits;
MPI_Rsend ( &cache_hit , 1 , MPI_INT , source ,
Cache_Server::TAG_CACHE_HIT , MPI_COMM_WORLD );
// bb output values, defined values and eval_ok flag:
rtab = new double[m];
char * ctab = new char [m+1];
const Point & bbo = cache_x->get_bb_outputs();
for ( i = 0 ; i < m ; ++i ) {
if ( bbo[i].is_defined() ) {
rtab[i] = bbo[i].value();
ctab[i] = '1';
}
else {
rtab[i] = INF;
ctab[i] = '0';
}
}
ctab[m] = ( cache_x->is_eval_ok() ) ? '1' : '0';
MPI_Send ( rtab , m , MPI_DOUBLE , source ,
Cache_Server::TAG_BBOR , MPI_COMM_WORLD );
MPI_Send ( ctab , m+1 , MPI_CHAR , source ,
Cache_Server::TAG_BBOC , MPI_COMM_WORLD );
delete [] rtab;
delete [] ctab;
// remove this point from _clients_ext_pts:
{
list<const Eval_Point *>::iterator
it = _clients_ext_pts[source].begin() ,
end = _clients_ext_pts[source].end ();
while ( it != end ) {
if ( *it == cache_x ) {
_clients_ext_pts[source].erase(it);
break;
}
++it;
}
}
}
// point not in cache :
else {
cache_hit = 0;
// evaluation in progress ?
if ( _waited_pts ) {
for ( i = 0 ; i < _np ; ++i )
if ( _waited_pts[i] && *_waited_pts[i] == *x ) {
cache_hit = -1;
break;
}
if ( cache_hit == 0 )
_waited_pts[source] = x;
else
delete x;
}
else
delete x;
MPI_Rsend ( &cache_hit , 1 , MPI_INT , source ,
Cache_Server::TAG_CACHE_HIT , MPI_COMM_WORLD );
}
}
/*--------------------*/
/* find a point */
/*--------------------*/
const Eval_Point * Cache_Server::find ( const Eval_Point & x ) const {
int npm1 = _np-1;
// server:
if ( _rank == npm1 )
return Cache::find ( x );
// A. search in local cache:
const Eval_Point * cache_x = Cache::find ( x );
if ( cache_x )
return cache_x;
// B. ask the server.
int i , n = x.size() , m = x.get_m();
int itab[2];
itab[0] = n;
itab[1] = m;
double * rtab = new double[n];
for ( i = 0 ; i < n ; ++i )
rtab[i] = x[i].value();
int cache_hit = -1;
MPI_Request req = MPI_REQUEST_NULL;
MPI_Status status;
while ( cache_hit < 0 ) {
// B1. send a request for cache_hit:
MPI_Irecv ( &cache_hit , 1 , MPI_INT , npm1 ,
Cache_Server::TAG_CACHE_HIT , MPI_COMM_WORLD , &req );
// B2. send the find signal:
MPI_Send ( &Cache_Server::FIND_SIGNAL , 1 , MPI_CHAR ,
npm1 , Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD );
// B3. send the point coordinates:
MPI_Send ( itab , 2 , MPI_INT , npm1 ,
Cache_Server::TAG_X1 , MPI_COMM_WORLD );
MPI_Send ( rtab , n , MPI_DOUBLE , npm1 ,
Cache_Server::TAG_X2 , MPI_COMM_WORLD );
// B4. wait for the cache_hit request:
MPI_Wait ( &req , &status );
// cache hit possible values:
//
// -1: point is being evaluated by another process (wait)
// 0: point not in cache server
// 1: point in cache server
}
delete [] rtab;
// C. cache hit: receive the point outputs:
if ( cache_hit == 1 ) {
// C.1. bb output values and eval status:
rtab = new double[m];
MPI_Recv ( rtab , m , MPI_DOUBLE , npm1 ,
Cache_Server::TAG_BBOR , MPI_COMM_WORLD , &status );
char * ctab = new char[m+1];
MPI_Recv ( ctab , m+1 , MPI_CHAR , npm1 ,
Cache_Server::TAG_BBOC , MPI_COMM_WORLD , &status );
Point bbo(m);
for ( i = 0 ; i < m ; ++i )
if ( ctab[i]=='1' )
bbo[i] = rtab[i];
delete [] rtab;
// C.2. eval point construction:
Eval_Point * y = new Eval_Point ( n , m );
y->set_bb_output ( bbo );
for ( i = 0 ; i < n ; ++i )
(*y)[i] = x[i];
y->set_eval_status ( (ctab[m]=='1') ? EVAL_OK : EVAL_FAIL );
y->set_current_run ( x.get_current_run() );
delete [] ctab;
cache_x = y;
// C.3. insertion in local cache:
const_cast<Cache_Server*>(this)->Cache::insert ( *cache_x );
}
return cache_x;
}
/*------------------------------------*/
/* process the insertion signal */
/*------------------------------------*/
void Cache_Server::process_insert_signal ( int source ) {
if ( _waited_pts && _waited_pts[source] ) {
delete _waited_pts[source];
_waited_pts[source] = NULL;
}
MPI_Status status;
// receive the evaluation point:
int itab[7];
MPI_Recv ( itab , 7 , MPI_INT , source ,
Cache_Server::TAG_X3 , MPI_COMM_WORLD , &status );
int n = itab[0];
int m = itab[1];
double * rtab = new double[n+2*m+2];
MPI_Recv ( rtab , n+2*m+2 , MPI_DOUBLE , source ,
Cache_Server::TAG_X4 , MPI_COMM_WORLD , &status );
// create the Eval_Point to insert:
Eval_Point * x = new Eval_Point ( n , m );
int i;
for ( i = 0 ; i < n ; ++i )
(*x)[i] = rtab[i];
for ( i = 0 ; i < m ; ++i )
if ( rtab[2*i+n] > 0 )
x->set_bb_output ( i , rtab[2*i+n+1] );
if ( itab[5] == 1 )
x->set_f ( rtab[n+2*m ] );
if ( itab[6] == 1 )
x->set_h ( rtab[n+2*m+1] );
delete [] rtab;
x->set_eval_status ( ( itab[2] == 1 ) ? EVAL_OK : EVAL_FAIL );
// Eval_Point insertion in cache and multiple_evals detection:
const Eval_Point * cache_x = Cache::find ( *x );
if ( cache_x ) {
++_multiple_evals;
delete x;
x = const_cast<Eval_Point *>(cache_x);
}
else
Cache::insert ( *x );
// update the best points:
update_best_points ( *x , source );
}
/*--------------------*/
/* insert a point */
/*--------------------*/
void Cache_Server::insert ( const NOMAD::Eval_Point & x ) {
// insertion in local cache :
Cache::insert ( x );
int npm1 = _np-1;
if ( _rank == npm1 )
return;
// insert signal :
MPI_Send ( &Cache_Server::INSERT_SIGNAL , 1 , MPI_CHAR ,
npm1 , Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD );
// send the point :
int i , n = x.size() , m = x.get_m();
int itab[7];
itab[0] = n;
itab[1] = m;
itab[2] = ( x.is_eval_ok() ) ? 1 : 0;
if ( x.get_signature() && (x.get_signature()->get_mesh()->get_mesh_indices())[0].is_defined() )
{
itab[3]=1;
itab[4]=static_cast<int>((x.get_signature()->get_mesh()->get_mesh_indices())[0].value());
}
else
itab[3] = itab[4] = 0;
double * rtab = new double[n+2*m+2];
for ( i = 0 ; i < n ; ++i )
rtab[i] = x[i].value();
const Point & bbo = x.get_bb_outputs();
for ( i = 0 ; i < m ; ++i )
if ( bbo[i].is_defined() ) {
rtab[2*i+n ] = 1.0;
rtab[2*i+n+1] = bbo[i].value();
}
else
rtab[2*i+n] = rtab[2*i+n+1] = -1.0;
// f and h values:
if ( x.get_f().is_defined() ) {
itab[5 ] = 1;
rtab[n+2*m] = x.get_f().value();
}
else {
itab[5 ] = 0;
rtab[n+2*m] = INF;
}
if ( x.get_h().is_defined() ) {
itab[6 ] = 1;
rtab[n+2*m+1] = x.get_h().value();
}
else {
itab[6 ] = 0;
rtab[n+2*m+1] = INF;
}
MPI_Send ( itab , 7 , MPI_INT , npm1 ,
Cache_Server::TAG_X3 , MPI_COMM_WORLD );
MPI_Send ( rtab , n+2*m+2 , MPI_DOUBLE , npm1 ,
Cache_Server::TAG_X4 , MPI_COMM_WORLD );
delete [] rtab;
}
/*--------------------------------------*/
/* get and remove an extern point */
/*--------------------------------------*/
const Eval_Point * Cache_Server::get_and_remove_extern_point ( void ) const {
int npm1 = _np-1;
if ( _rank == npm1 )
return NULL;
// extern point from the client:
// -----------------------------
if ( Cache::get_nb_extern_points() > 0 )
return Cache::get_and_remove_extern_point();
// extern point from the server:
// -----------------------------
int nb_pt;
// send a request for an extern point:
MPI_Request req;
MPI_Irecv ( &nb_pt , 1 , MPI_INT , npm1 ,
Cache_Server::TAG_EP , MPI_COMM_WORLD , &req );
// extern points signal :
MPI_Send ( &Cache_Server::EP_SIGNAL , 1 , MPI_CHAR ,
npm1 , Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD );
// wait for the request:
MPI_Status status;
MPI_Wait ( &req , &status );
if ( nb_pt == 0 )
return NULL;
// receive the extern point:
int itab[5];
MPI_Recv ( itab , 5 , MPI_INT , npm1 ,
Cache_Server::TAG_X5 , MPI_COMM_WORLD , &status );
int n = itab[0];
int m = itab[1];
double * rtab = new double[n+2*m];
MPI_Recv ( rtab , n+2*m , MPI_DOUBLE , npm1 ,
Cache_Server::TAG_X6 , MPI_COMM_WORLD , &status );
// create the Eval_Point:
Eval_Point * x = new Eval_Point ( n , m );
int i;
for ( i = 0 ; i < n ; ++i )
(*x)[i] = rtab[i];
for ( i = 0 ; i < m ; ++i )
if ( rtab[2*i+n] > 0 )
x->set_bb_output ( i , rtab[2*i+n+1] );
delete [] rtab;
x->set_eval_status ( ( itab[2] == 1 ) ? EVAL_OK : EVAL_FAIL );
// insert the point in local cache:
const Eval_Point * cache_x = Cache::find ( *x );
if ( cache_x ) {
delete x;
return cache_x;
}
x->set_current_run ( true );
const_cast<Cache_Server*>(this)->Cache::insert ( *x );
x->set_current_run ( false );
return x;
}
/*---------------------------------------*/
/* get the number of extern points */
/*---------------------------------------*/
int Cache_Server::get_nb_extern_points ( void ) const {
int nb_client_extern_pts = Cache::get_nb_extern_points();
int nb_server_extern_pts = 0;
int npm1 = _np-1;
if ( _rank != npm1 ) {
// send a request for the number of extern points:
MPI_Request req;
MPI_Irecv ( &nb_server_extern_pts , 1 , MPI_INT , npm1 ,
Cache_Server::TAG_NB_EP , MPI_COMM_WORLD , &req );
// number of extern points signal :
MPI_Send ( &Cache_Server::NB_EP_SIGNAL , 1 , MPI_CHAR ,
npm1 , Cache_Server::TAG_SIGNAL , MPI_COMM_WORLD );
// wait for the request:
MPI_Status status;
MPI_Wait ( &req , &status );
}
return nb_client_extern_pts + nb_server_extern_pts;
}
/*---------------------------------*/
/* display the extern points */
/*---------------------------------*/
void Cache_Server::display_extern_pts ( const Display & out ) const {
int npm1 = _np-1;
// server:
// -------
if ( _rank == npm1 ) {
list<const Eval_Point*>::const_iterator it;
out << endl << open_block ("Clients extern points");
for ( int i = 0 ; i < npm1 ; ++i ) {
out.open_block ( "client #"+itos(i) );
for ( it = _clients_ext_pts[i].begin() ;
it != _clients_ext_pts[i].end () ;
++it ) {
out << "#" << (*it)->get_tag() << " ( ";
(*it)->Point::display ( out );
out << " ) " << " ["
<< (*it)->get_bb_outputs() << " ] f="
<< (*it)->get_f() << " h="
<< (*it)->get_h() << endl;
}
out.close_block();
}
}
// clients:
else {
out << endl
<< open_block ( "Process #" + itos(_rank) + ": extern points" );
out << "number of points = "
<< get_nb_extern_points() << endl;
const Eval_Point * extern_pt = get_and_remove_extern_point();
while ( extern_pt ) {
out << "#" << extern_pt->get_tag() << " ( ";
extern_pt->Point::display ( out );
out << " ) " << " ["
<< extern_pt->get_bb_outputs() << " ] f="
<< extern_pt->get_f() << " h="
<< extern_pt->get_h() << endl;
extern_pt = get_and_remove_extern_point();
}
}
out << close_block() << endl;
}
/*--------------------------------------*/
/* update and display the best points */
/*--------------------------------------*/
void Cache_Server::update_best_points ( const Eval_Point & x ,
int source ) {
const Double & f = x.get_f();
const Double & h = x.get_h();
if ( !f.is_defined() || !h.is_defined() )
return;
int i;
bool add_x = false;
// feasible:
if ( h <= _h_min ) {
// new best feasible point:
if ( !_bf || f < _bf->get_f() ) {
_bf = &x;
add_x = true;
display_current_solution();
}
}
// infeasible:
else {
if ( !_bi1 || h < _bi1->get_h() ) {
_bi1 = &x;
add_x = true;
}
if ( !_bi2 || f < _bi2->get_f() ) {
_bi2 = &x;
add_x = true;
}
}
if ( add_x )
for ( i = 0 ; i < _np-1 ; ++i )
if ( i != source )
_clients_ext_pts[i].push_front ( &x );
}
/*-----------------------------------------*/
/* display the current best solution */
/*-----------------------------------------*/
void Cache_Server::display_current_solution ( void ) const {
if ( _rank != _np-1 || !_bf )
return;
if ( _debug )
_out << "CACHE SERVER: CURRENT SOLUTION: \t";
_out << _clock.get_real_time() << "\t"
<< size() << "\t" << _bf->get_f() << endl;
}
/*-------------------------------*/
/* display the best points */
/*-------------------------------*/
void Cache_Server::display_best_points ( const Display & out ) const {
if ( _rank != _np-1 )
return;
// display the last solution:
display_current_solution();
// stats:
out << "evaluations: " << size() << endl
<< "cache hits : " << _cache_hits << endl;
// best feasible solution:
out << "best feasible solution: ";
if ( _bf ) {
out << "x=( ";
_bf->Point::display(out);
out << " )"
<< " F(x)=[ " << _bf->get_bb_outputs() << " ] h="
<< _bf->get_h() << " f=" << _bf->get_f() << endl;
}
else {
out << "NULL" << endl;
// best infeasible solutions:
if ( _bi1 ) {
out << "best infeas. sol. #1 : x=( ";
_bi1->Point::display(out);
out << " )"
<< " F(x)=[ " << _bi1->get_bb_outputs() << " ] h="
<< _bi1->get_h() << " f=" << _bi1->get_f() << endl;
}
if ( _bi2 && _bi2 != _bi1 ) {
out << "best infeas. sol. #2 : x=( ";
_bi2->Point::display(out);
out << " )"
<< " F(x)=[ " << _bi2->get_bb_outputs() << " ] h="
<< _bi2->get_h() << " f=" << _bi2->get_f() << endl;
}
}
}
#ifndef __CACHE_SERVER__
#define __CACHE_SERVER__
#include "mpi.h"
#include "nomad.hpp"
using namespace NOMAD;
using namespace std;
// Cache server:
class Cache_Server : public Cache {
private:
int _rank; // process rank
int _np; // number of processes
bool _debug; // debug display flag
Clock _clock; // clock
Double _h_min; // h_min (min feasibility)
int _max_bbe; // max number of bb evaluations
const Eval_Point * _bf; // best points
const Eval_Point * _bi1;
const Eval_Point * _bi2;
Eval_Point * _stop_point; // stopping point
mutable int _multiple_evals; // number of multiple evaluations
mutable int _cache_hits; // number of cache hits
mutable int _cache_search_pts; // number of cache search points
Point ** _waited_pts; // list of points beeing evaluated
list<const Eval_Point*> * _clients_ext_pts; // replaces _extern_pts
// process the best feasible point signal:
void process_bf_signal ( int source ) const;
// process the extern point signal:
void process_ep_signal ( int source ) const;
// process the find signal:
void process_find_signal ( int source ) const;
// process the insertion signal:
void process_insert_signal ( int source );
// update and display the best points:
void update_best_points ( const Eval_Point & x , int source );
public:
static const int TAG_SIGNAL;
static const int TAG_CACHE_HIT;
static const int TAG_X1;
static const int TAG_X2;
static const int TAG_X3;
static const int TAG_X4;
static const int TAG_X5;
static const int TAG_X6;
static const int TAG_X7;
static const int TAG_BBOR;
static const int TAG_BBOC;
static const int TAG_NB_EP;
static const int TAG_EP;
static const int TAG_BF;
static char STOP_SIGNAL;
static char FIND_SIGNAL;
static char INSERT_SIGNAL;
static char NB_EP_SIGNAL;
static char EP_SIGNAL;
static char BF_SIGNAL;
// Constructor:
Cache_Server ( const Display & out ,
int rank ,
int np ,
const Double & h_min ,
int max_bbe ,
bool allow_multiple_evals ,
bool debug );
// Destructor:
virtual ~Cache_Server ( void );
// Start the server:
void start ( void );
// Stop the server:
void stop ( void ) const;
// Display the clients extern points:
void display_extern_pts ( void ) const { display_extern_pts(_out); }
void display_extern_pts ( const Display & out ) const;
// Display the best points:
void display_best_points ( void ) const { display_best_points(_out); }
void display_best_points ( const Display & out ) const;
// Display the current best solution:
void display_current_solution ( void ) const;
// Find a point:
virtual const Eval_Point * find ( const Eval_Point & x ) const;
// Insert a point:
virtual void insert ( const NOMAD::Eval_Point & x );
// Get the number of extern points:
virtual int get_nb_extern_points ( void ) const;
// Get and remove an extern point:
virtual const Eval_Point * get_and_remove_extern_point ( void ) const;
};
#endif
This diff is collapsed.
#ifndef __MASTER_SLAVES__
#define __MASTER_SLAVES__
#include "Cache_Server.hpp"
using namespace NOMAD;
using namespace std;
// Cache server:
class Master_Slaves {
private:
int _rank; // process rank
int _np; // number of processes
int _bbe; // max number of evaluations for each process
int _ns; // number of free variables for each process
Parameters & _p; // parameters
bool _debug; // debug display flag
Evaluator & _ev; // Evaluator
static const int TAG_SIGNAL;
static const int TAG_I1;
static const int TAG_I2;
static const int TAG_R1;
static const int TAG_D1;
static const int TAG_CSTOP;
static char STOP_SIGNAL;
static char OPTI_RES_SIGNAL;
static char OPTI_DATA_SIGNAL;
// Receive an optimization result from the pollster:
void receive_optimization_result ( int & pollster_mesh_index ,
bool & stop_algo ,
double *& best_feasible ,
double *& best_infeasible ,
int source ) const;
// Send an optimization result to the master:
void send_optimization_result ( int pollster_mesh_index ,
bool stop_algo ,
const Eval_Point * bf ,
const Eval_Point * bi ,
stop_type st ) const;
// Send optimization data from the master to a slave:
void send_optimization_data ( int pollster_mesh_index ,
bool stop_algo ,
const double * best_feasible ,
const double * best_infeasible ,
int source ) const;
// Receive optimization data from the master:
void receive_optimization_data ( bool & stop_algo ,
Point & x0 ,
Double & fx0 ) const;
void receive_optimization_data ( bool & stop_algo ,
Point & x0 ,
Double & fx0 ,
int & pollster_mesh_index ,
int * free_vars ) const;
// Check the initial mesh size values:
static bool check_delta ( const Point & delta );
public:
// Constructor:
Master_Slaves ( int rank ,
int np ,
int bbe ,
int ns ,
Parameters & p ,
bool debug ,
Evaluator &ev )
: _rank ( rank ) ,
_np ( np ) ,
_bbe ( bbe ) ,
_ns ( ns ) ,
_p ( p ) ,
_debug ( debug ) ,
_ev ( ev ){}
// Destructor:
virtual ~Master_Slaves ( void ) {}
// Start the master:
void start ( void ) const;
// Stop the master:
void stop ( void ) const;
// MADS run:
void mads_run ( Cache & cache );
};
#endif
File added
/*-------------------------------------------------------------*/
/* PSD-MADS */
/*-------------------------------------------------------------*/
/* */
/* usage: */
/* */
/* "mpirun -np p psdmads param_file bbe ns" */
/* with p > 2, bbe > 0, and 1 <= ns <= number of variables */
/* . ns is the number of free variables for each process */
/* . bbe is the max number of evaluations for each process */
/* */
/*-------------------------------------------------------------*/
/* */
/* processes: */
/* */
/* 0: master */
/* 1: pollster slave (1 direction) */
/* 2 to p-2: regular slaves (2ns directions) */
/* p-1: cache server */
/* */
/*-------------------------------------------------------------*/
/* See the user guide for other details and the description */
/* of the algorithm */
/*-------------------------------------------------------------*/
/*-----------------------------------------------------------*/
#include "Master_Slaves.hpp"
using namespace std;
using namespace NOMAD;
const bool DEBUG = false;
/*---------------------------------------------------*/
/* The evaluator for G2_50 problem */
/*---------------------------------------------------*/
class My_Evaluator : public NOMAD::Evaluator {
public:
My_Evaluator ( const NOMAD::Parameters & p ) :
NOMAD::Evaluator ( p ) {}
~My_Evaluator ( void ) {}
bool eval_x ( NOMAD::Eval_Point & x ,
const NOMAD::Double & h_max ,
bool & count_eval ) const
{
int N=50;
long double sum1 = 0.0 , sum2 = 0.0 , sum3 = 0.0 , prod1 = 1.0 , prod2 = 1.0, g1=0, g2=0;
long double Xi;
for (int i = 0 ; i < N ; i++ )
{
Xi=x[i].value();
sum1 += pow ( cos(Xi) , 4 );
sum2 += Xi;
sum3 += (i+1)*Xi*Xi;
prod1 *= pow ( cos(Xi) , 2 );
prod2 *= Xi;
}
g1 = -prod2+0.75;
g2 = sum2 -7.5*N;
long double z = - fabs ( ( sum1 - 2 * prod1 ) / sqrt(sum3) );
x.set_bb_output ( 0 , g1 ); // constraint 1
x.set_bb_output ( 1 , g2 ); // constraint 2
x.set_bb_output ( 2 , z ); // objective value
count_eval = true; // count a black-box evaluation
return true; // the evaluation succeeded
}
};
/*-----------------------------------*/
/* main function */
/*-----------------------------------*/
int main ( int argc , char ** argv ) {
// MPI initialization:
MPI_Init ( &argc , &argv );
int rank , np;
MPI_Comm_rank ( MPI_COMM_WORLD, &rank );
MPI_Comm_size ( MPI_COMM_WORLD, &np );
// check the arguments and the number of processes:
if ( np <= 2 || argc != 4 ) {
if ( rank == 0 )
cerr << "usage: mpirun -np p " << argv[0]
<< " param_file bbe ns, with p>2,"
<< " bbe>1, and 1<=ns<=n."
<< endl;
MPI_Finalize();
return 1;
}
// display:
Display out ( cout );
out.precision ( 16 );
// parameters:
NOMAD::Parameters p ( out );
int bbe = atoi ( argv[2] );
int ns = atoi ( argv[3] );
try {
// read the parameters file:
p.read ( argv[1] );
// This option is needed to have the same mesh index for all variables
p.set_ANISOTROPIC_MESH ( false );
// check the parameters:
p.check();
if ( ns < 1 || ns > p.get_dimension() )
throw Exception ( __FILE__ , __LINE__ ,
"Bad value for ns the number of free variables for each process" );
if ( p.get_nb_obj() > 1 )
throw Exception ( __FILE__ , __LINE__ ,
"PSD-MADS is not designed for multi-objective optimization" );
}
catch ( exception & e ) {
if ( rank == 0 )
cerr << "error with parameters" << endl;
MPI_Finalize();
return 1;
}
// custom evaluator creation:
My_Evaluator ev ( p );
// start the master:
Master_Slaves master_slaves ( rank , np , bbe , ns , p , DEBUG ,ev);
master_slaves.start();
// cache server:
Cache_Server cache ( out ,
rank ,
np ,
p.get_h_min() ,
p.get_max_bb_eval() ,
false , // ALLOW_MULTIPLE_EVALS
DEBUG );
// start the cache server:
if ( rank == np-1 ) {
if ( !DEBUG )
out << endl << "TIME\tBBE\tOBJ" << endl << endl;
cache.start();
}
// slaves: algorithm creation and execution:
if ( rank != 0 && rank != np-1 ) {
// MADS run:
master_slaves.mads_run ( cache );
// stop the master:
master_slaves.stop();
}
// stop the cache server:
cache.stop();
// display the final solution:
if ( !DEBUG && rank == np-1 )
cache.display_best_points ( out );
// MPI finalization:
MPI_Finalize();
return 0;
}
EXE = psdmads.exe
COMPILATOR = mpic++
SUNAME = $(shell uname)
OSS=$(findstring MINGW32,$(SUNAME))
ifneq "$(strip $(OSS))" ""
COMPILATOR = g++
endif
COMPILATOR_OPTIONS = -ansi -O2
L1 = $(NOMAD_HOME)/lib/nomad.a
LIBS = $(L1) -lm -lmpi
INCLUDE = -I$(NOMAD_HOME)/src -I.
COMPILE = $(COMPILATOR) $(COMPILATOR_OPTIONS) $(INCLUDE) -c
OBJS = main.o Cache_Server.o Master_Slaves.o
ifndef NOMAD_HOME
define ECHO_NOMAD
@echo Please set NOMAD_HOME environment variable!
@false
endef
endif
$(EXE): $(OBJS) $(L1)
$(ECHO_NOMAD)
$(COMPILATOR) -o $(EXE) $(OBJS) $(LIBS) $(COMPILATOR_OPTIONS)
main.o: main.cpp Master_Slaves.o
$(COMPILE) main.cpp
Master_Slaves.o: Master_Slaves.cpp Master_Slaves.hpp Cache_Server.o
$(ECHO_NOMAD)
$(COMPILE) Master_Slaves.cpp
Cache_Server.o: Cache_Server.cpp Cache_Server.hpp
$(ECHO_NOMAD)
$(COMPILE) Cache_Server.cpp
$(L1): ;
$(ECHO_NOMAD)
clean:
@echo "cleaning obj files"
@rm -f $(OBJS)
del:
@echo "cleaning trash files"
@rm -f core *~
@echo "cleaning obj files"
@rm -f $(OBJS)
@echo "cleaning exe file"
@rm -f $(EXE)
\ No newline at end of file
DIMENSION 50
BB_OUTPUT_TYPE PB PB OBJ
x0 x0.txt
LOWER_BOUND * 0
UPPER_BOUND * 10
max_bb_eval 5000
DIRECTION_TYPE ORTHO 2N
display_stats time bbe obj
initial_mesh_size r0.2
snap_to_bounds no
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
5.0
6.4149169921875 6.2413330078125 6.3720703125 6.1068115234375 3.0206298828125 0.585693359375 0.435791015625 0.391357421875 3.0928955078125 3.171875 0.173583984375 3.1939697265625 2.92333984375 6.1531982421875 2.8271484375 0.27392578125 3.1434326171875 0.511474609375 0.1761474609375 2.9149169921875 0.27294921875 0.4522705078125 3.0953369140625 3.0416259765625 0.3453369140625 0.275390625 2.8414306640625 3.1175537109375 3.0628662109375 3.126953125 3.0113525390625 3.0687255859375 0.182861328125 2.9844970703125 0.2940673828125 0.161865234375 2.83740234375 2.681884765625 0.2615966796875 1.843994140625 0.2763671875 0.1839599609375 0.3106689453125 0.1778564453125 0.330810546875 0.3873291015625 0.313720703125 0.44140625 0.2330322265625 0.290283203125
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment