31 #ifndef __TASMANIAN_ADDONS_CONSTRUCT_SURROGATE_HPP 
   32 #define __TASMANIAN_ADDONS_CONSTRUCT_SURROGATE_HPP 
   66 using ModelSignature = std::function<void(std::vector<double> 
const &x, std::vector<double> &y, 
size_t thread_id)>;
 
  102 template<
bool parallel_construction, 
bool use_initial_guess>
 
  104                      size_t max_num_points, 
size_t num_parallel_jobs, 
size_t max_samples_per_job,
 
  107                      std::string 
const &checkpoint_filename){
 
  109     num_parallel_jobs   = std::max(
size_t(1), num_parallel_jobs);
 
  110     max_samples_per_job = std::max(
size_t(1), max_samples_per_job);
 
  116     std::string filename = checkpoint_filename;
 
  117     std::string filename_old = checkpoint_filename + 
"_old";
 
  119     if (!filename.empty()){ 
 
  120         std::ifstream infile(filename, std::ios::binary);
 
  122             if (!infile.good()) 
throw std::runtime_error(
"missing main checkpoint");
 
  124             complete.
read(infile);
 
  125         }
catch(std::runtime_error &){
 
  127             std::ifstream oldfile(filename_old, std::ios::binary);
 
  129                 if (!oldfile.good()) 
throw std::runtime_error(
"missing main checkpoint");
 
  131                 complete.
read(oldfile);
 
  132             }
catch(std::runtime_error &){
 
  138     if (!filename.empty()){ 
 
  139         std::ofstream ofs(filename, std::ios::binary);
 
  145     auto checkpoint = [&]()->
void{ 
 
  146         if (!filename.empty()){
 
  148                 std::ifstream current_state(filename, std::ios::binary);
 
  149                 std::ofstream previous_state(filename, std::ios::binary);
 
  150                 previous_state << current_state.rdbuf();
 
  152             std::ofstream ofs(filename, std::ios::binary);
 
  158     auto load_complete = [&]()->
void{ 
 
  163     auto refresh_candidates = [&]()->
void{ 
 
  165         manager = candidates(grid); 
 
  169     auto checkout_sample = [&]()->std::vector<double>{ 
 
  170         auto x = manager.
next(max_num_points - total_num_launched);
 
  172             refresh_candidates();
 
  173             x = manager.
next(max_num_points - total_num_launched); 
 
  179     auto set_initial_guess = [&](std::vector<double> 
const &x, std::vector<double> &y)->
void{
 
  180         if (use_initial_guess){
 
  184             y.resize(num_outputs * (x.size() / num_dimensions));
 
  191     refresh_candidates();
 
  195         std::vector<std::vector<double>> x(num_parallel_jobs),
 
  196                                          y(num_parallel_jobs, std::vector<double>(max_samples_per_job * num_outputs));
 
  198         std::vector<int> work_flag(num_parallel_jobs);
 
  199         constexpr 
int flag_done = 0;
 
  200         constexpr 
int flag_computing = 1;
 
  201         constexpr 
int flag_shutdown = 2;
 
  203         std::condition_variable until_someone_done;
 
  204         std::condition_variable until_new_job;
 
  205         std::mutex access_count_done;
 
  209         auto do_work = [&](
size_t thread_id)->
void{
 
  211             int my_flag = flag_computing;
 
  212             while(my_flag == flag_computing){
 
  213                 model(x[thread_id], y[thread_id], thread_id); 
 
  216                     std::lock_guard<std::mutex> lock(access_count_done);
 
  217                     work_flag[thread_id] = flag_done;
 
  220                 until_someone_done.notify_one(); 
 
  223                     std::unique_lock<std::mutex> lock(access_count_done);
 
  224                     until_new_job.wait(lock, [&]()->
bool{ 
return (work_flag[thread_id] != flag_done); });
 
  225                     my_flag = work_flag[thread_id];
 
  231         std::vector<std::thread> workers(num_parallel_jobs);
 
  232         for(
size_t id=0; 
id<num_parallel_jobs; 
id++){
 
  233             x[id] = manager.
next(max_num_points - total_num_launched);
 
  235                 total_num_launched += x[id].size() / num_dimensions;
 
  236                 set_initial_guess(x[
id], y[
id]);
 
  237                 work_flag[id] = flag_computing;
 
  238                 workers[id] = std::thread(do_work, 
id);
 
  240                 work_flag[id] = flag_shutdown; 
 
  244         auto collect_finished = [&]()->
bool{
 
  245             bool any_done = 
false;
 
  246             for(
size_t id=0; 
id<num_parallel_jobs; 
id++){
 
  247                 if (work_flag[
id] == flag_done){
 
  249                         complete.
add(x[
id], y[
id]);
 
  256                     if (total_num_launched < max_num_points){
 
  259                             refresh_candidates();
 
  261                         x[id] = checkout_sample(); 
 
  264                             total_num_launched += x[id].size() / num_dimensions;
 
  265                             set_initial_guess(x[
id], y[
id]);
 
  266                             work_flag[id] = flag_computing;
 
  268                             work_flag[id] = flag_shutdown; 
 
  271                         work_flag[id] = flag_shutdown; 
 
  280                 std::unique_lock<std::mutex> lock(access_count_done);
 
  282                 until_someone_done.wait(lock, [&]()->
bool{ 
return (count_done > 0); });
 
  285                 if (collect_finished()) checkpoint(); 
 
  288             until_new_job.notify_all();
 
  293         for(
auto &w : workers) 
if (w.joinable()) w.join(); 
 
  298         while((total_num_launched < max_num_points) && (manager.
getNumCandidates() > 0)){
 
  299             x = manager.
next(max_num_points - total_num_launched);
 
  301                 refresh_candidates();
 
  302                 x = manager.
next(max_num_points - total_num_launched); 
 
  305                 total_num_launched += x.size() / num_dimensions;
 
  306                 set_initial_guess(x, y);
 
  316                     refresh_candidates();
 
  463 template<
bool parallel_construction = TasGr
id::mode_parallel, 
bool initial_guess = no_initial_guess>
 
  465                         size_t max_num_points, 
size_t num_parallel_jobs, 
size_t max_samples_per_job,
 
  468                         std::vector<int> 
const &level_limits = std::vector<int>(),
 
  469                         std::string 
const &checkpoint_filename = std::string()){
 
  470     if (!grid.
isLocalPolynomial() && !grid.
isWavelet()) 
throw std::runtime_error(
"ERROR: construction (with tolerance and criteria) called for a grid that is not local polynomial or wavelet.");
 
  471     constructCommon<parallel_construction, initial_guess>
 
  472                                           (model, max_num_points, num_parallel_jobs, max_samples_per_job, grid,
 
  475                                            }, checkpoint_filename);
 
  490 template<
bool parallel_construction = TasGr
id::mode_parallel, 
bool initial_guess = no_initial_guess>
 
  492                         size_t max_num_points, 
size_t num_parallel_jobs, 
size_t max_samples_per_job,
 
  494                         TypeDepth type, std::vector<int> 
const &anisotropic_weights = std::vector<int>(),
 
  495                         std::vector<int> 
const &level_limits = std::vector<int>(),
 
  496                         std::string 
const &checkpoint_filename = std::string()){
 
  497     constructCommon<parallel_construction, initial_guess>
 
  498                                            (model, max_num_points, num_parallel_jobs, max_samples_per_job, grid,
 
  501                                            }, checkpoint_filename);
 
  517 template<
bool parallel_construction = TasGr
id::mode_parallel, 
bool initial_guess = no_initial_guess>
 
  519                         size_t max_num_points, 
size_t num_parallel_jobs, 
size_t max_samples_per_job,
 
  521                         TypeDepth type, 
int output, std::vector<int> 
const &level_limits = std::vector<int>(),
 
  522                         std::string 
const &checkpoint_filename = std::string()){
 
  523     constructCommon<parallel_construction, initial_guess>
 
  524                                            (model, max_num_points, num_parallel_jobs, max_samples_per_job, grid,
 
  527                                            }, checkpoint_filename);
 
Manages candidate points.
Definition: tsgCandidateManager.hpp:70
size_t getNumDone() const
Returns the number of complete jobs.
Definition: tsgCandidateManager.hpp:160
size_t getNumRunning() const
Returns the number of running jobs.
Definition: tsgCandidateManager.hpp:157
size_t getNumCandidates() const
Returns the number of all candidate jobs.
Definition: tsgCandidateManager.hpp:163
void complete(std::vector< double > const &p)
Mark a point as "complete".
Definition: tsgCandidateManager.hpp:105
std::vector< double > next(size_t remaining_budget)
Returns the next best point to compute, returns empty vector if no points are available.
Definition: tsgCandidateManager.hpp:132
Stores complete set of points before adding to the sparse grid.
Definition: tsgCandidateManager.hpp:227
void add(std::vector< double > const &x, std::vector< double > const &y)
Add a point to the stored list.
Definition: tsgCandidateManager.hpp:251
void read(std::istream &is)
Read the stored samples from the stream.
Definition: tsgCandidateManager.hpp:243
size_t getNumStored() const
Returns the number of stored points.
Definition: tsgCandidateManager.hpp:265
void write(std::ostream &os) const
Write the stored samples to a stream.
Definition: tsgCandidateManager.hpp:236
void load(TasmanianSparseGrid &grid)
Move the stored points into the grid.
Definition: tsgCandidateManager.hpp:257
The master-class that represents an instance of a Tasmanian sparse grid.
Definition: TasmanianSparseGrid.hpp:293
int getNumOutputs() const
Return the outputs of the grid, i.e., number of model outputs.
Definition: TasmanianSparseGrid.hpp:644
void write(const char *filename, bool binary=mode_binary) const
Write the grid to the given filename using either binary or ASCII format.
int getNumLoaded() const
Return the number of points already associated with model values via loadNeededValues().
Definition: TasmanianSparseGrid.hpp:657
void evaluateBatch(std::vector< FloatType > const &x, std::vector< FloatType > &y) const
Computes the value of the interpolant (or point-wise approximation) for a batch of points.
void beginConstruction()
Begin a dynamic construction procedure.
void read(const char *filename)
Read the grid from the given filename, automatically detect the format.
bool isUsingConstruction() const
Returns true if the dynamic construction procedure has been initialized, false otherwise.
Definition: TasmanianSparseGrid.hpp:1403
std::vector< double > getCandidateConstructionPoints(TypeDepth type, std::vector< int > const &anisotropic_weights=std::vector< int >(), std::vector< int > const &level_limits=std::vector< int >())
Generate a sorted list of points weighted by descending importance.
int getNumDimensions() const
Return the dimensions of the grid, i.e., number of model inputs.
Definition: TasmanianSparseGrid.hpp:642
bool isLocalPolynomial() const
Returns true if the grid is of type local polynomial, false otherwise.
Definition: TasmanianSparseGrid.hpp:1085
bool isWavelet() const
Returns true if the grid is of type wavelet, false otherwise.
Definition: TasmanianSparseGrid.hpp:1087
TypeDepth
Used by Global Sequence and Fourier grids, indicates the selection criteria.
Definition: tsgEnumerates.hpp:203
TypeRefinement
Refinement strategy for local polynomial and wavelet grids.
Definition: tsgEnumerates.hpp:425
std::function< void(std::vector< double > const &x, std::vector< double > &y, size_t thread_id)> ModelSignature
Signature of a model function to be used in the construction procedures.
Definition: tsgConstructSurrogate.hpp:66
constexpr bool mode_parallel
Allows for expressive calls to TasGrid::constructSurrogate().
Definition: tsgConstructSurrogate.hpp:72
constexpr bool with_initial_guess
Allows for expressive calls to TasGrid::constructSurrogate().
Definition: tsgConstructSurrogate.hpp:84
void constructCommon(ModelSignature model, size_t max_num_points, size_t num_parallel_jobs, size_t max_samples_per_job, TasmanianSparseGrid &grid, std::function< std::vector< double >(TasmanianSparseGrid &)> candidates, std::string const &checkpoint_filename)
Construction algorithm using generic candidates procedure.
Definition: tsgConstructSurrogate.hpp:103
void constructSurrogate(ModelSignature model, size_t max_num_points, size_t num_parallel_jobs, size_t max_samples_per_job, TasmanianSparseGrid &grid, double tolerance, TypeRefinement criteria, int output=-1, std::vector< int > const &level_limits=std::vector< int >(), std::string const &checkpoint_filename=std::string())
Construct a sparse grid surrogate to the model defined by the lambda.
Definition: tsgConstructSurrogate.hpp:464
constexpr bool mode_sequential
Allows for expressive calls to TasGrid::constructSurrogate().
Definition: tsgConstructSurrogate.hpp:78
constexpr bool no_initial_guess
Allows for expressive calls to TasGrid::constructSurrogate().
Definition: tsgConstructSurrogate.hpp:90
constexpr bool mode_binary
Constant allowing for more expressive selection of ascii and binary mode in IO methods.
Definition: tsgIOHelpers.hpp:68
Encapsulates the Tasmanian Sparse Grid module.
Definition: TasmanianSparseGrid.hpp:68
Manager for manipulations of candidate construction points.