/*-----------------------------------------------------*/
bool NOMAD::Cache::erase ( const NOMAD::Eval_Point & x )
{
    // check the eval types:
    if ( x.get_eval_type() != _eval_type )
        throw NOMAD::Cache::Cache_Error ( "Cache.cpp" , __LINE__ ,
                                         "NOMAD::Cache:erase(x): x.eval_type != cache.eval_type" );
    
    std::set<NOMAD::Cache_Point>::iterator it;
    NOMAD::cache_index_type       cache_index;
    
    // search in cache:
    const NOMAD::Eval_Point * cache_x = find ( x , it , cache_index );
    
    // the point has been found:
    if ( cache_x ) {
        
        // remove the point from the list of extern points:
        if ( cache_x->get_current_run() || x.get_current_run() ) {
            std::list<const NOMAD::Eval_Point*>::const_iterator end2 = _extern_pts.end();
            std::list<const NOMAD::Eval_Point*>::iterator       it2  = _extern_pts.begin();
            while ( it2 != end2 ) {
                if ( *it2 == cache_x || *it2 == &x ) {
                    _extern_pts.erase ( it2 );
                    break;
                }
                ++it2;
            }
        }
        
        // erase the point in cache if its address is different from &x:
        if ( cache_x != &x )
            delete cache_x;
        
        // remove the point from the cache:
        _sizeof -= x.size_of();
        
        switch ( cache_index ) {
            case NOMAD::CACHE_1:
                _cache1.erase ( it );
                break;
            case NOMAD::CACHE_2:
                _cache2.erase ( it );
                break;
            case NOMAD::CACHE_3:
                _cache3.erase ( it );
                break;
            case NOMAD::UNDEFINED_CACHE:
                break;
        }
        return true;
    }
    return false;
}
/*------------------------------------------------*/
void NOMAD::Cache::insert ( const NOMAD::Eval_Point & x )
{
    // check the eval types:
    if ( x.get_eval_type() != _eval_type )
        throw NOMAD::Cache::Cache_Error ( "Cache.cpp" , __LINE__ ,
                                         "NOMAD::Cache:insert(x): x.eval_type != cache.eval_type" );
    
    // insertion in _extern_pts:
    insert_extern_point ( x );
    
    // insertion in _cache2:
    NOMAD::Cache_Point cp  ( &x );
    _cache2.insert  (  cp  );
    x.set_in_cache ( true );
    _sizeof += x.size_of();
}
/*---------------------------------------------------------*/
void NOMAD::Barrier::insert ( const NOMAD::Eval_Point & x )
{
    // we compare the eval types (_SGTE_ or _TRUTH_) of x and *this:
    if ( x.get_eval_type() != _eval_type )
        throw Barrier::Insert_Error ( "Barrier.cpp" , __LINE__ ,
                                     "insertion of an Eval_Point into the bad Barrier object" );
    
    // basic check:
    if ( !x.is_eval_ok() )
    {
        _one_eval_succ = NOMAD::UNSUCCESSFUL;
        return;
    }
    
    // pre-filter: if tag(x) is already in the pre-filter,
    // then return _UNSUCCESSFUL_:
    size_t size_before = _prefilter.size();
    _prefilter.insert ( x.get_tag() );
    if ( _prefilter.size() == size_before )
    {
        _one_eval_succ = NOMAD::UNSUCCESSFUL;
        return;
    }
    
    // insertion in _all_inserted:
    _all_inserted.push_back ( &x );
    
    // other checks:
    const NOMAD::Double & h = x.get_h();
    if ( !x.is_EB_ok             () ||
        !x.get_f().is_defined   () ||
        !h.is_defined           () ||
        h.value() > _h_max.value()    )
    {
        _one_eval_succ = NOMAD::UNSUCCESSFUL;
        return;
    }
    
    // insert_feasible or insert_infeasible:
    _one_eval_succ = ( x.is_feasible ( _p.get_h_min() ) ) ?
    insert_feasible ( x ) : insert_infeasible(x);
    
    if ( _one_eval_succ > _success )
        _success = _one_eval_succ;
}
Beispiel #4
0
    //Function + Constraint Evaluation
    bool eval_x(NOMAD::Eval_Point &x, const NOMAD::Double &h_max, bool &count_eval)
    {
        char errstr[1024];
        bool stop = false;
        int i, j, n = x.size(), status;
        double *xm, *fvals;
        mxLogical *sur;
        count_eval = true; //mexErrMsgTxt will kill MEX

        //Check for Ctrl-C
        if (utIsInterruptPending()) {
            utSetInterruptPending(false); /* clear Ctrl-C status */
            mexPrintf("\nCtrl-C Detected. Exiting NOMAD...\n\n");
            count_eval = false;
            raise(SIGINT);
            return false;
        }

        //Blackbox / Objective Evaluation
        fun->plhs[0] = NULL;
        xm = mxGetPr(fun->prhs[fun->xrhs]);
        for(i=0;i<n;i++)
            xm[i] = x[i].value();
        //Add Surrogate if present and requested
        if(hasSur) {
            sur=mxGetLogicals(fun->prhs[fun->xrhs+1]);
			(x.get_eval_type()==NOMAD::SGTE)? *sur=true:*sur=false;
        }
        //Call MATLAB Objective
        try {
            status = mexCallMATLAB(1, fun->plhs, fun->nrhs, fun->prhs, fun->f);   
        }
        //Note if these errors occur it is due to errors in MATLAB code, no way to recover?
        catch(exception &e) {
            sprintf(errstr,"Unrecoverable Error from Objective / Blackbox Callback:\n%sExiting NOMAD...\n\n",e.what());
            mexWarnMsgTxt(errstr);
            //Force exit
            raise(SIGINT);
            return false;
        }  
        catch(...) {            
            mexWarnMsgTxt("Unrecoverable Error from Objective / Blackbox Callback, Exiting NOMAD...\n\n");
            //Force exit
            raise(SIGINT);
            return false;
        }
        if(status) {
            mexWarnMsgTxt("Unrecoverable Error from Objective / Blackbox Callback, Exiting NOMAD...\n\n");
            raise(SIGINT);
            return false;
        }
        
        #ifdef OPTI_VERSION  
            //Check we got the correct number back
            if(mxGetM(fun->plhs[0]) != nobj)
                mexErrMsgTxt("Incorrect number of elements returned from the objective function");
            //Set Objective (Or multi-objective)
            fvals = mxGetPr(fun->plhs[0]);
            for(i=0;i<nobj;i++)
                x.set_bb_output(i,fvals[i]);

            //Constraint Evaluation
            if(ncon) {
                //Add Surrogate if present and requested
                if(hasSur) {
                    sur=mxGetLogicals(con->prhs[con->xrhs+1]);
                    (x.get_eval_type()==NOMAD::SGTE)? *sur=true:*sur=false;
                }
                con->plhs[0] = NULL;
                xm = mxGetPr(con->prhs[con->xrhs]);
                for(i=0;i<n;i++)
                    xm[i] = x[i].value();
                //Call MATLAB Constraint
                try {
                    status = mexCallMATLAB(1, con->plhs, con->nrhs, con->prhs, con->f);
                }
                catch(...)
                {
                    mexWarnMsgTxt("Unrecoverable Error from Constraint Callback, Exiting NOMAD...\n\n");
                    //Force exit
                    raise(SIGINT);
                    return false;
                }
                if(status) {
                    mexWarnMsgTxt("Unrecoverable Error from Constraint Callback, Exiting NOMAD...\n\n");
                    raise(SIGINT);
                    return false;
                }
                //Check we got the correct number back
                if(mxGetM(con->plhs[0]) != ncon)
                    mexErrMsgTxt("Incorrect number of elements returned from nonlinear constraint function");
                //Set Constraints
                double *cons = mxGetPr(con->plhs[0]);            
                for(i=0,j=nobj;i<ncon;i++,j++)
                    x.set_bb_output(j,cons[i] - con->nlrhs[i]); //subtract nlrhs        
                // Clean up LHS Ptr
                mxDestroyArray(con->plhs[0]); 
            }     
        #else //GERAD VERSION
            //Check we got the correct number of elements back
            if(mxGetNumberOfElements(fun->plhs[0]) > nobj+ncon)
                mexWarnMsgTxt("Black box returns more elements than required. Please provide a BB_OUTPUT_TYPE consistent with your black box function");
            else if(mxGetNumberOfElements(fun->plhs[0]) < nobj+ncon) {
                mexErrMsgTxt("Insufficient outputs provided by the black box function. Exiting NOMAD...\n\n");
                raise(SIGINT);
                return false;
            }
            //Assign bb output
            fvals = mxGetPr(fun->plhs[0]);
            for(i=0;i<(nobj+ncon);i++)
                x.set_bb_output(i,fvals[i]);
             
        #endif
                    
        //Iteration Callback
        if(iterF->enabled)
        {
            iterF->plhs[0] = NULL;
            memcpy(mxGetData(iterF->prhs[1]), &citer, sizeof(int));
            memcpy(mxGetPr(iterF->prhs[2]), fvals, sizeof(double));
            memcpy(mxGetPr(iterF->prhs[3]), xm, n * sizeof(double));
            try {
                status = mexCallMATLAB(1, iterF->plhs, 4, iterF->prhs, iterF->f);
            }
            catch (...)
            {
                mexWarnMsgTxt("Unrecoverable Error from Iteration Callback, Exiting NOMAD...\n\n");
                //Force exit
                raise(SIGINT);
                return false;
            }  
            if(status) {
                mexWarnMsgTxt("Unrecoverable Error from Iteration Callback, Exiting NOMAD...\n\n");
                raise(SIGINT);
                return false;
            }
            
            //Collect return argument
            stop = *(bool*)mxGetData(iterF->plhs[0]);
            //Clean up Ptr
            mxDestroyArray(iterF->plhs[0]);
        }              
        
        //Add Function Eval Counter
        citer++;
        
        // Clean up LHS Fun Ptr
        mxDestroyArray(fun->plhs[0]);
        
        //Check for iterfun stop
        if(stop)
        {
            mexPrintf("\nIterFun Called Stop. Exiting NOMAD...\n\n");
            count_eval = false;
            raise(SIGINT);
            return false;
        }
        else        
            return true;
    }    
/*-----------------------------------------------------------------*/
void NOMAD::Cache::update ( NOMAD::Eval_Point       & cache_x ,
                           const NOMAD::Eval_Point & x         ) const
{
    const NOMAD::Point & bbo_x = x.get_bb_outputs();
    
    if ( &cache_x == &x         ||
        !x.is_eval_ok()        ||
        !cache_x.is_in_cache() ||
        bbo_x.empty()          ||
        cache_x != x              )
        return;
    
    // check the eval types:
    if ( x.get_eval_type      () != _eval_type ||
        cache_x.get_eval_type() != _eval_type    )
        throw NOMAD::Cache::Cache_Error ( "Cache.cpp" , __LINE__ ,
                                         "NOMAD::Cache:update(): problem with the eval. types" );
    
    const NOMAD::Point & bbo_cache_x = cache_x.get_bb_outputs();
    int                  m           = bbo_cache_x.size();
    
    _sizeof -= cache_x.size_of();
    
    // if the current point could not evaluate and x did,
    // or if the number of bb outputs is different, we set cache_x = x:
    if ( !cache_x.is_eval_ok() || m != bbo_x.size() )
    {
        cache_x.set_eval_status ( NOMAD::EVAL_OK     );
        cache_x.set_bb_output   ( bbo_x              );
        cache_x.set_signature   ( x.get_signature () );
        cache_x.set_direction   ( x.get_direction () );
        
        _sizeof += cache_x.size_of();
        return;
    }
    
    // we complete _bb_outputs:
    int c1 = 0;
    int c2 = 0;
    
    for ( int i = 0 ; i < m ; ++i ) {
        
        if ( bbo_cache_x[i].is_defined() )
            ++c1;
        
        if ( bbo_x[i].is_defined() )
            ++c2;
        
        if ( !bbo_cache_x[i].is_defined() && bbo_x[i].is_defined() )
            cache_x.set_bb_output ( i , bbo_x[i] );
    }
    
    // the two points are 'eval_ok' and have comparable outputs:
    // we select the best as the one with the more defined bb_outputs:
    if ( c2 > c1 ) {
        cache_x.set_signature  ( x.get_signature () );
        cache_x.set_direction  ( x.get_direction () );
        
    }
    
    _sizeof += cache_x.size_of();
}
    /*-------------------------------------------------------------------*/
    bool NOMAD::Evaluator::eval_x ( NOMAD::Eval_Point	& x          ,
                                   const NOMAD::Double	& h_max      ,
                                   bool					& count_eval   ) const
    {
        count_eval = false;
        
        if ( _bb_exe.empty() || !x.is_complete() )
            throw NOMAD::Exception ( "Evaluator.cpp" , __LINE__ ,
                                    "Evaluator: no BB_EXE is defined (blackbox executable names)" );
        
        bool sgte = x.get_eval_type() == NOMAD::SGTE;
        if ( sgte && _sgte_exe.empty() )
            throw NOMAD::Exception ( "Evaluator.cpp" , __LINE__ ,
                                    "Evaluator: no SGTE_EXE is defined (surrogate executable names)" );
        
        int         pid     = NOMAD::get_pid();
        int         seed    = _p.get_seed();
        std::string tmp_dir = _p.get_tmp_dir();
        
        std::ostringstream oss;
        oss << "." << seed;
        if ( pid != seed )
            oss << "." << pid;
        oss << "." << x.get_tag() << ".";
        const std::string & sint = oss.str();
        
        // for the parallel version: no need to include the process rank in the names
        // as the point tags are unique for all the processes: each process creates
        // its own points and uses Eval_Point::set_tag()
        
        // blackbox input file writing:
        // ----------------------------
        std::string bb_input_file_name =
        tmp_dir + NOMAD::BLACKBOX_INPUT_FILE_PREFIX
        + sint + NOMAD::BLACKBOX_INPUT_FILE_EXT;
        
        std::string bb_output_file_name =
        tmp_dir + NOMAD::BLACKBOX_OUTPUT_FILE_PREFIX
        + sint + NOMAD::BLACKBOX_OUTPUT_FILE_EXT;
        
        std::ofstream fout ( bb_input_file_name.c_str() );
        if ( fout.fail() )
        {
            std::string err = "could not create file blackbox input file " + bb_input_file_name + ". \n \n #### Please check that write permission are granted for the working directory. #### ";
            throw NOMAD::Exception ( "Evaluator.cpp" , __LINE__ , err );
       }
        
        // include seed:
        if ( _p.get_bb_input_include_seed() )
            fout << seed << " ";
        
        // include tag:
        if ( _p.get_bb_input_include_tag() )
            fout << x.get_tag() << " ";
        
        fout.setf ( std::ios::fixed );
        fout.precision ( NOMAD::DISPLAY_PRECISION_BB );
        x.Point::display ( fout , " " , -1 , -1 );
        fout << std::endl;
        
        fout.close();
        
        if ( fout.fail() )
            return false;
        
        x.set_eval_status ( NOMAD::EVAL_IN_PROGRESS );
        
        std::string   cmd , bb_exe;
        std::ifstream fin;
        bool          failed;
        NOMAD::Double d;
        int           j , nbbok;
        int           ibbo = 0;
        
        // system call to evaluate the blackbox:
        // -------------------------------------
        size_t bn = _bb_exe.size();
        for ( size_t k = 0 ; k < bn ; ++k )
        {
            
            // executable name:
            bb_exe = ( sgte ) ? _sgte_exe[k] : _bb_exe[k];
            
            // system command:
            cmd = bb_exe + " " + bb_input_file_name;
            
            // redirection ? if no, the blackbox has to create
            // the output file 'bb_output_file_name':
            if ( _p.get_bb_redirection() )
                cmd += " > " + bb_output_file_name;
            
#ifdef DEBUG
#ifdef USE_MPI
            int rank;
            MPI_Comm_rank ( MPI_COMM_WORLD, &rank);
            _p.out() << "command(rank=" << rank
            << ") = \'" << cmd << "\'" << std::endl;
#else
            _p.out() << "command=\'" << cmd << "\'" << std::endl;
#endif
#endif
            
            // the evaluation:
            {
                int signal = system ( cmd.c_str() );
                
                // catch the ctrl-c signal:
                if ( signal == SIGINT )
                    raise ( SIGINT );
                
                // other evaluation error:
                failed = ( signal != 0 );
                count_eval = true;
            }
            
            // the evaluation failed (we stop the evaluations):
            if ( failed )
            {
                x.set_eval_status ( NOMAD::EVAL_FAIL );
                break;
            }
            
            // reading of the blackbox output file:
            // ------------------------------------
            else
            {
                
                // bb-output file reading:
                fin.open ( bb_output_file_name.c_str() );
                
                failed          = false;
                bool is_defined = true;
                bool is_inf     = false;
                
                // loop on the number of outputs for this blackbox:
                nbbok = _bb_nbo[k];
                for ( j = 0 ; j < nbbok ; ++j )
                {
                    
                    fin >> d;
                    
                    if ( !d.is_defined() )
                    {
                        is_defined = false;
                        break;
                    }
                    
                    if ( fin.fail() )
                    {
                        failed = true;
                        break;
                    }
                    
                    if ( d.value() >= NOMAD::INF )
                    {
                        is_inf = true;
                        break;
                    }
                    
                    x.set_bb_output ( ibbo++ , d );
                }
                
                fin.close();
                
                // the evaluation failed:
                if ( failed || !is_defined || is_inf )
                {
                    x.set_eval_status ( NOMAD::EVAL_FAIL );
                    break;
                }
                
                // stop the evaluations if h > h_max or if a 'EB' constraint is violated:
                if ( k < _bb_exe.size() - 1 && interrupt_evaluations ( x , h_max ) )
                    break;
            }
        }
        
        if ( x.get_eval_status() == NOMAD::EVAL_IN_PROGRESS )
            x.set_eval_status ( NOMAD::EVAL_OK );
        
        // delete the blackbox input and output files:
        // -------------------------------------------
        remove ( bb_input_file_name.c_str () );
        remove ( bb_output_file_name.c_str() );
        
        // check the CNT_EVAL output:
        // --------------------------
        int index_cnt_eval = _p.get_index_cnt_eval();
        if ( index_cnt_eval >= 0 && x.get_bb_outputs()[index_cnt_eval] == 0.0 )
            count_eval = false;
        
        return x.is_eval_ok();
    }