Doxygen 1.9.1
Toolkit for Adaptive Stochastic Modeling and Non-Intrusive ApproximatioN: Tasmanian v8.1
tsgMPISampleDream.hpp
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_MPISAMPLEDREAM_HPP
32 #define __TASMANIAN_ADDONS_MPISAMPLEDREAM_HPP
33 
45 #include "tsgMPIConstructGrid.hpp"
46 
54 #ifdef Tasmanian_ENABLE_MPI
55 
56 namespace TasDREAM{
57 
111 template<TypeSamplingForm form = regform>
113 public:
133  DistributedPosterior(DreamModel distributed_model,
134  DreamLikelihood likelihood,
135  DreamPrior prior,
136  int num_inputs, int num_chains, int mpi_root, MPI_Comm communicator)
137  : model(distributed_model), likely(likelihood), dist_prior(prior),
138  num_dimensions(num_inputs), num_batch(num_chains), root(mpi_root), me(TasGrid::getMPIRank(communicator)), comm(communicator),
139  x(Utils::size_mult(num_dimensions, num_batch) + 1), y((size_t) num_batch){
140 
141  if (me != root){ // enter work loop
142  int num_candidates = 1;
143  do{
144  MPI_Bcast(x.data(), num_dimensions*num_batch+1, MPI_DOUBLE, root, comm);
145  num_candidates = (int) x.back(); // the last entry holds the effective number of candidates
146  if (num_candidates > 0){ // if not the shutdown signal
147  x.resize(Utils::size_mult(num_dimensions, num_candidates)); // set x to the correct size
148  y.resize((size_t) num_candidates);
149 
150  std::vector<double> model_outs;
151  model(x, model_outs);
152  likelihood(form, model_outs, y);
153 
154  MPI_Reduce(y.data(), nullptr, num_candidates, MPI_DOUBLE, ((form == regform) ? MPI_PROD : MPI_SUM), root, comm);
155 
156  x.resize(Utils::size_mult(num_dimensions, num_batch) + 1);
157  }
158  }while(num_candidates > 0);
159  }
160  }
161 
164 
166  void clear(){
167  if ((me == root) && (!x.empty())){ // send out the shutdown signal
168  x.back() = 0.0;
169  MPI_Bcast(x.data(), num_dimensions*num_batch+1, MPI_DOUBLE, root, comm);
170  }
171  }
172 
174  operator DreamPDF(){
175  if (me == root){
176  return [&](const std::vector<double> &candidates, std::vector<double> &values)->void{
177  std::copy_n(candidates.begin(), candidates.size(), x.begin());
178  int num_candidates = (int) candidates.size() / num_dimensions;
179  x.back() = (double) num_candidates;
180  MPI_Bcast(x.data(), num_dimensions*num_batch+1, MPI_DOUBLE, root, comm);
181 
182  y.resize((size_t) num_candidates);
183  std::vector<double> model_outs;
184  model(candidates, model_outs);
185  likely(form, model_outs, y);
186 
187  MPI_Reduce(y.data(), values.data(), num_candidates, MPI_DOUBLE, ((form == regform) ? MPI_PROD : MPI_SUM), root, comm);
188 
189  std::vector<double> prior_vals(values.size());
190  dist_prior(form, candidates, prior_vals);
191 
192  auto iv = values.begin();
193  if (form == regform){
194  for(auto p : prior_vals) *iv++ *= p;
195  }else{
196  for(auto p : prior_vals) *iv++ += p;
197  }
198  };
199  }else{ // no-op distribution
200  return [](const std::vector<double> &, std::vector<double> &)->void{};
201  }
202  }
203 
204 private:
205  std::function<void(std::vector<double> const &x, std::vector<double> &y)> model;
206  std::function<void(TypeSamplingForm, const std::vector<double> &model_outputs, std::vector<double> &likely)> likely;
207  std::function<void(TypeSamplingForm, const std::vector<double> &candidates, std::vector<double> &values)> dist_prior;
208  int num_dimensions, num_batch, root, me;
209  MPI_Comm comm;
210  std::vector<double> x, y;
211 };
212 
213 }
214 
215 #endif // Tasmanian_ENABLE_MPI
216 
217 #endif
Class that enables distributed DREAM sampling with MPI.
Definition: tsgMPISampleDream.hpp:112
DistributedPosterior(DreamModel distributed_model, DreamLikelihood likelihood, DreamPrior prior, int num_inputs, int num_chains, int mpi_root, MPI_Comm communicator)
Constructor that sets the parameters for the distribued posterior.
Definition: tsgMPISampleDream.hpp:133
void clear()
Unblocks the non-root ranks, the object cannot be used after this calls (can be destroyed only).
Definition: tsgMPISampleDream.hpp:166
~DistributedPosterior()
Destructor, unblocks the non-root ranks (if still blocked).
Definition: tsgMPISampleDream.hpp:163
TypeSamplingForm
Describes whether sampling should be done with the regular or logarithm form of the probability densi...
Definition: tsgDreamEnumerates.hpp:90
@ regform
Use the standard form for the probability density.
Definition: tsgDreamEnumerates.hpp:92
std::function< void(const std::vector< double > &candidates, std::vector< double > &outputs)> DreamModel
Generic model signature used by Tasmanian.
Definition: tsgDreamSample.hpp:157
std::function< void(const std::vector< double > &candidates, std::vector< double > &values)> DreamPDF
Generic probability distribution used by Tasmanian.
Definition: tsgDreamSample.hpp:142
std::function< void(TypeSamplingForm form, const std::vector< double > &model_outputs, std::vector< double > &likely)> DreamLikelihood
Generic likelihood signature used by Tasmanian.
Definition: tsgDreamSample.hpp:175
std::function< void(TypeSamplingForm form, const std::vector< double > &candidates, std::vector< double > &values)> DreamPrior
Generic signature for the prior distributions used by Tasmanian.
Definition: tsgDreamSample.hpp:187
Encapsulates the Tasmanian DREAM module.
Definition: TasmanianDREAM.hpp:80
Encapsulates the Tasmanian Sparse Grid module.
Definition: TasmanianSparseGrid.hpp:68