Doxygen 1.9.1
Toolkit for Adaptive Stochastic Modeling and Non-Intrusive ApproximatioN: Tasmanian v8.2 (development)
tsgLoadNeededValues.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, Miroslav Stoyanov
3  *
4  * This file is part of
5  * Toolkit for Adaptive Stochastic Modeling And Non-Intrusive ApproximatioN: TASMANIAN
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
12  * and the following disclaimer in the documentation and/or other materials provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
20  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
21  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * UT-BATTELLE, LLC AND THE UNITED STATES GOVERNMENT MAKE NO REPRESENTATIONS AND DISCLAIM ALL WARRANTIES, BOTH EXPRESSED AND IMPLIED.
25  * THERE ARE NO EXPRESS OR IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY PATENT,
26  * COPYRIGHT, TRADEMARK, OR OTHER PROPRIETARY RIGHTS, OR THAT THE SOFTWARE WILL ACCOMPLISH THE INTENDED RESULTS OR THAT THE SOFTWARE OR ITS USE WILL NOT RESULT IN INJURY OR DAMAGE.
27  * THE USER ASSUMES RESPONSIBILITY FOR ALL LIABILITIES, PENALTIES, FINES, CLAIMS, CAUSES OF ACTION, AND COSTS AND EXPENSES, CAUSED BY, RESULTING FROM OR ARISING OUT OF,
28  * IN WHOLE OR IN PART THE USE, STORAGE OR DISPOSAL OF THE SOFTWARE.
29  */
30 
31 #ifndef __TASMANIAN_ADDONS_LOADNEEDEDVALS_HPP
32 #define __TASMANIAN_ADDONS_LOADNEEDEDVALS_HPP
33 
46 #include "tsgAddonsCommon.hpp"
47 
56 namespace TasGrid{
57 
103 template<bool parallel_construction = true, bool overwrite_loaded = false>
104 void loadNeededValues(std::function<void(double const x[], double y[], size_t thread_id)> model, TasmanianSparseGrid &grid, size_t num_threads){
105  int num_points = (overwrite_loaded) ? grid.getNumLoaded() : grid.getNumNeeded();
106  int num_outputs = grid.getNumOutputs();
107  if (grid.isUsingConstruction()) throw std::runtime_error("ERROR: cannot call loadNeededPoints() addon when isUsingConstruction() is true");
108  if (num_outputs == 0) throw std::runtime_error("ERROR: cannot call loadNeededPoints() addon when the grid has no outputs");
109  if (num_points == 0) return; // nothing to do here
110  if (overwrite_loaded && (grid.getNumNeeded() != 0)) grid.clearRefinement(); // using loaded points only, clear the refinement
111 
112  // get the points and values
113  auto points = (overwrite_loaded) ? grid.getLoadedPoints() : grid.getNeededPoints();
114  std::vector<double> values(Utils::size_mult(num_points, num_outputs));
115 
116  // divide logically into strips
117  Utils::Wrapper2D<double> xwrap(grid.getNumDimensions(), points.data());
118  Utils::Wrapper2D<double> ywrap(num_outputs, values.data());
119 
120  if (parallel_construction && (num_threads > 0)){
121  std::vector<bool> checked_out(num_points, false);
122  std::mutex checked_out_lock;
123 
124  std::vector<std::thread> workers;
125  workers.reserve(num_threads);
126  for(size_t thread_id=0; thread_id<num_threads; thread_id++){
127  workers.emplace_back( // create a new worker thread
128  [&, thread_id](void)->void{
129  int sample = 0;
130  do{
131  { // find the next sample
132  std::lock_guard<std::mutex> lock(checked_out_lock);
133  while ((sample < num_points) && checked_out[sample]) sample++;
134  if (sample < num_points) checked_out[sample] = true;
135  }
136  if (sample < num_points) // if found, compute the next sample
137  model(xwrap.getStrip(sample), ywrap.getStrip(sample), thread_id);
138  }while(sample < num_points);
139  }
140  );
141  }
142 
143  for(auto &w : workers) w.join(); // wait till finished
144 
145  }else{
146  for(int i=0; i<num_points; i++)
147  model(xwrap.getStrip(i), ywrap.getStrip(i), 0);
148  }
149 
150  grid.loadNeededPoints(values);
151 }
152 
163 template<bool parallel_construction = true, bool overwrite_loaded = false>
164 void loadNeededValues(std::function<void(std::vector<double> const &x, std::vector<double> &y, size_t thread_id)> model,
165  TasmanianSparseGrid &grid, size_t num_threads){
166  int num_dimensions = grid.getNumDimensions();
167  int num_outputs = grid.getNumOutputs();
168  loadNeededValues<parallel_construction, overwrite_loaded>(
169  [&](double const x[], double y[], size_t thread_id)->void{
170  std::vector<double> vecy(num_outputs);
171  model(std::vector<double>(x, x + num_dimensions), vecy, thread_id);
172  std::copy(vecy.begin(), vecy.end(), y);
173  }, grid, num_threads);
174 }
179 template<bool parallel_construction = true, bool overwrite_loaded = false>
180 void loadNeededPoints(std::function<void(double const x[], double y[], size_t thread_id)> model, TasmanianSparseGrid &grid, size_t num_threads){
181  loadNeededValues<parallel_construction, overwrite_loaded>(model, grid, num_threads);
182 }
187 template<bool parallel_construction = true, bool overwrite_loaded = false>
188 void loadNeededPoints(std::function<void(std::vector<double> const &x, std::vector<double> &y, size_t thread_id)> model,
189  TasmanianSparseGrid &grid, size_t num_threads){
190  loadNeededValues<parallel_construction, overwrite_loaded>(model, grid, num_threads);
191 }
192 
193 }
194 
195 #endif
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
int getNumNeeded() const
Return the number of points that should be provided to the next call of loadNeededValues().
Definition: TasmanianSparseGrid.hpp:659
int getNumLoaded() const
Return the number of points already associated with model values via loadNeededValues().
Definition: TasmanianSparseGrid.hpp:657
std::vector< double > getLoadedPoints() const
Return the points already associated with model values.
Definition: TasmanianSparseGrid.hpp:671
std::vector< double > getNeededPoints() const
Return the points that require model values.
Definition: TasmanianSparseGrid.hpp:695
void clearRefinement()
Remove all needed points from the grid.
bool isUsingConstruction() const
Returns true if the dynamic construction procedure has been initialized, false otherwise.
Definition: TasmanianSparseGrid.hpp:1403
void loadNeededPoints(std::vector< double > const &vals)
Alias of loadNeededValues().
Definition: TasmanianSparseGrid.hpp:884
int getNumDimensions() const
Return the dimensions of the grid, i.e., number of model inputs.
Definition: TasmanianSparseGrid.hpp:642
Wraps around a C-style of an array and mimics 2D data-structure.
Definition: tsgUtils.hpp:127
T * getStrip(int i)
Return a pointer to the i-th strip.
Definition: tsgUtils.hpp:135
void loadNeededValues(std::function< void(double const x[], double y[], size_t thread_id)> model, TasmanianSparseGrid &grid, size_t num_threads)
Loads the current grid with model values, does not perform any refinement.
Definition: tsgLoadNeededValues.hpp:104
void loadNeededPoints(std::function< void(double const x[], double y[], size_t thread_id)> model, TasmanianSparseGrid &grid, size_t num_threads)
Alias to loadNeededValues(), array variant.
Definition: tsgLoadNeededValues.hpp:180
size_t size_mult(IntA a, IntB b)
Converts two integer-like variables to size_t and returns the product..
Definition: tsgUtils.hpp:82
Encapsulates the Tasmanian Sparse Grid module.
Definition: TasmanianSparseGrid.hpp:68
Common includes and methods for all addons.