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.