https://mooseframework.inl.gov
Sampler.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 // STL includes
11 #include <iterator>
12 
13 // MOOSE includes
14 #include "Sampler.h"
15 
18 {
20  params += SetupInterface::validParams();
22  params.addClassDescription("A base class for distribution sampling.");
23 
24  ExecFlagEnum & exec_enum = params.set<ExecFlagEnum>("execute_on", true);
26  exec_enum = {EXEC_INITIAL};
27 
28  params.addParam<unsigned int>("seed", 0, "Random number generator initial seed");
29  params.registerBase("Sampler");
30  params.registerSystemAttributeName("Sampler");
31 
32  // Define the allowable limits for data returned by getSamples/getLocalSamples/getNextLocalRow
33  // to prevent system for going over allowable limits. The DenseMatrix object uses unsigned int
34  // for size definition, so as start the limits will be based the max of unsigned int. Note,
35  // the values here are the limits of the number of items in the complete container. dof_id_type
36  // is used just in case in the future we need more.
37  params.addParam<dof_id_type>("limit_get_global_samples",
39  "The maximum allowed number of items in the DenseMatrix returned by "
40  "getGlobalSamples method.");
41  params.addParam<dof_id_type>(
42  "limit_get_local_samples",
44  "The maximum allowed number of items in the DenseMatrix returned by getLocalSamples method.");
45  params.addParam<dof_id_type>(
46  "limit_get_next_local_row",
48  "The maximum allowed number of items in the std::vector returned by getNextLocalRow method.");
49 
50  params.addParam<unsigned int>(
51  "min_procs_per_row",
52  1,
53  "This will ensure that the sampler is partitioned properly when "
54  "'MultiApp/*/min_procs_per_app' is specified. It is not recommended to use otherwise.");
55  params.addParam<unsigned int>(
56  "max_procs_per_row",
58  "This will ensure that the sampler is partitioned properly when "
59  "'MultiApp/*/max_procs_per_app' is specified. It is not recommended to use otherwise.");
60  return params;
61 }
62 
63 Sampler::Sampler(const InputParameters & parameters)
64  : MooseObject(parameters),
65  SetupInterface(this),
67  PerfGraphInterface(this),
68  SamplerInterface(this),
70  ReporterInterface(this),
71  _min_procs_per_row(getParam<unsigned int>("min_procs_per_row") > n_processors()
72  ? n_processors()
73  : getParam<unsigned int>("min_procs_per_row")),
74  _max_procs_per_row(getParam<unsigned int>("max_procs_per_row")),
75  _n_rows(0),
76  _n_cols(0),
77  _n_seeds(1),
78  _next_local_row_requires_state_restore(true),
79  _initialized(false),
80  _needs_reinit(true),
81  _has_executed(false),
82  _limit_get_global_samples(getParam<dof_id_type>("limit_get_global_samples")),
83  _limit_get_local_samples(getParam<dof_id_type>("limit_get_local_samples")),
84  _limit_get_next_local_row(getParam<dof_id_type>("limit_get_next_local_row")),
85  _auto_advance_generators(true)
86 {
87 }
88 
89 void
91 {
92  // The init() method is private so it is un-likely to be called, but just in case the following
93  // was added to help avoid future mistakes.
94  if (_initialized)
95  mooseError("The Sampler::init() method is called automatically and should not be called.");
96 
97  // Initialize the parallel partition of sample to return
98  reinit();
99 
100  // Seed the "master" seed generator
101  const unsigned int seed = getParam<unsigned int>("seed");
102  MooseRandom seed_generator;
103  seed_generator.seed(0, seed);
104 
105  // See the "secondary" generator that will be used for the random number generation
106  _generators.resize(_n_seeds);
107  for (std::size_t i = 0; i < _n_seeds; ++i)
108  {
109  const auto gseed = seed_generator.randl(0);
110  _generators[i] = std::make_unique<MooseRandomStateless>(gseed);
111  }
112 
113  // Mark class as initialized, which locks out certain methods
114  _initialized = true;
115 }
116 
117 void
119 {
120  _rank_config.first = constructRankConfig(false);
121  _rank_config.second = constructRankConfig(true);
122  if (_rank_config.first.num_local_sims != _rank_config.second.num_local_sims ||
123  _rank_config.first.first_local_sim_index != _rank_config.second.first_local_sim_index ||
124  _rank_config.first.is_first_local_rank != _rank_config.second.is_first_local_rank)
125  mooseError("Sampler has inconsistent partitionings for normal and batch mode.");
126 
127  _n_local_rows = _rank_config.first.is_first_local_rank ? _rank_config.first.num_local_sims : 0;
128  _local_row_begin = _rank_config.first.first_local_sim_index;
130 
131  // Set the next row iterator index
133 
134  // Create communicator that only has processors with rows
135  _communicator.split(_n_local_rows > 0 ? 1 : MPI_UNDEFINED, processor_id(), _local_comm);
136 
137  // Update reinit() flag (see execute method)
138  _needs_reinit = false;
139 }
140 
142 Sampler::constructRankConfig(bool batch_mode) const
143 {
144  return rankConfig(
146 }
147 
148 void
150 {
151  if (n_rows == 0)
152  mooseError("The number of rows cannot be zero.");
153 
154  _needs_reinit = true;
155  _n_rows = n_rows;
156 }
157 
158 void
160 {
161  if (n_cols == 0)
162  mooseError("The number of columns cannot be zero.");
163 
164  _needs_reinit = true;
165  _n_cols = n_cols;
166 }
167 
168 void
170 {
171  if (_initialized)
172  mooseError("The 'setNumberOfRandomSeeds()' method can not be called after the Sampler has been "
173  "initialized; "
174  "this method should be called in the constructor of the Sampler object.");
175 
176  if (n_seeds == 0)
177  mooseError("The number of seeds must be larger than zero.");
178 
179  _n_seeds = n_seeds;
180 }
181 
182 void
184 {
185  executeSetUp();
186  if (_needs_reinit)
187  reinit();
188 
189  if (_has_executed)
191 
192  executeTearDown();
193  _has_executed = true;
194 }
195 
198 {
199  TIME_SECTION("getGlobalSamples", 1, "Retrieving Global Samples");
200 
202 
204  paramError("limit_get_global_samples",
205  "The number of entries in the DenseMatrix (",
206  _n_rows * _n_cols,
207  ") exceeds the allowed limit of ",
209  ".");
210 
213  computeSampleMatrix(output);
214  return output;
215 }
216 
219 {
220  TIME_SECTION("getLocalSamples", 1, "Retrieving Local Samples");
221 
223 
225  paramError("limit_get_local_samples",
226  "The number of entries in the DenseMatrix (",
228  ") exceeds the allowed limit of ",
230  ".");
231 
233  if (_n_local_rows == 0)
234  return output;
235 
237  computeLocalSampleMatrix(output);
238  return output;
239 }
240 
241 std::vector<Real>
243 {
245 
247  {
249 
251  paramError("limit_get_next_local_row",
252  "The number of entries in the std::vector (",
253  _n_cols,
254  ") exceeds the allowed limit of ",
256  ".");
257  }
258 
259  std::vector<Real> output(_n_cols);
261  mooseAssert(output.size() == _n_cols, "The row of sample data is not sized correctly.");
262  _next_local_row++;
263 
265  {
268  }
269 
270  return output;
271 }
272 
273 void
275 {
276  TIME_SECTION("computeSampleMatrix", 2, "Computing Sample Matrix");
277 
278  for (dof_id_type i = 0; i < _n_rows; ++i)
279  {
280  std::vector<Real> row(_n_cols, 0);
281  computeSampleRow(i, row);
282  mooseAssert(row.size() == _n_cols, "The row of sample data is not sized correctly.");
283  mooseAssert(!_needs_reinit,
284  "Changing the size of the sample must not occur during matrix access.");
285  std::copy(row.begin(), row.end(), matrix.get_values().begin() + i * _n_cols);
286  }
287 }
288 
289 void
291 {
292  TIME_SECTION("computeLocalSampleMatrix", 2, "Computing Local Sample Matrix");
293 
294  for (dof_id_type i = _local_row_begin; i < _local_row_end; ++i)
295  {
296  std::vector<Real> row(_n_cols, 0);
297  computeSampleRow(i, row);
298  mooseAssert(row.size() == _n_cols, "The row of sample data is not sized correctly.");
299  mooseAssert(!_needs_reinit,
300  "Changing the size of the sample must not occur during matrix access.");
301  std::copy(
302  row.begin(), row.end(), matrix.get_values().begin() + ((i - _local_row_begin) * _n_cols));
303  }
304 }
305 
306 void
307 Sampler::computeSampleRow(dof_id_type i, std::vector<Real> & data)
308 {
309  for (dof_id_type j = 0; j < _n_cols; ++j)
310  {
311  data[j] = computeSample(i, j);
312  mooseAssert(!_needs_reinit,
313  "Changing the size of the sample must not occur during matrix access.");
314  }
315 }
316 
317 void
319 {
320  TIME_SECTION("advanceGenerators", 2, "Advancing Generators");
321 
322  for (std::size_t j = 0; j < _generators.size(); ++j)
323  advanceGenerator(j, count);
324 }
325 void
326 Sampler::advanceGenerator(const unsigned int seed_index, const dof_id_type count)
327 {
328  mooseAssert(seed_index < _generators.size(), "The seed number index does not exists.");
329  _generators[seed_index]->advance(count);
330 }
331 
332 void
334 {
336  advanceGenerators(count);
337 }
338 
339 void
341 {
342  _auto_advance_generators = state;
343 }
344 
345 Real
346 Sampler::getRand(std::size_t n, unsigned int index) const
347 {
348  mooseAssert(index < _generators.size(), "The seed number index does not exists.");
349  return _generators[index]->rand(n);
350 }
351 
352 unsigned int
353 Sampler::getRandl(std::size_t n, unsigned int lower, unsigned int upper, unsigned int index) const
354 {
355  mooseAssert(index < _generators.size(), "The seed number index does not exists.");
356  return _generators[index]->randl(n, lower, upper);
357 }
358 
361 {
363  return _n_rows;
364 }
365 
368 {
370  return _n_cols;
371 }
372 
375 {
377  return _n_local_rows;
378 }
379 
382 {
384  return _local_row_begin;
385 }
386 
389 {
391  return _local_row_end;
392 }
393 
394 void
396 {
397  if (_needs_reinit)
398  mooseError("A call to 'setNumberOfRows()/Columns()' was made after initialization, as such the "
399  "expected Sampler output has changed and a new sample must be created. However, a "
400  "call to Sampler::reinit() was not performed. The renit() method is automatically "
401  "called during Sampler execution, which occurs according to the 'execute_on' "
402  "settings of the Sampler object. An adjustment to this parameter may be required. "
403  "It is recommended that calls to 'setNumberOfRows()/Columns() occur within the "
404  "Sampler::executeSetUp() method; this will ensure that the reinitialize is handled "
405  "correctly. Have a nice day.");
406 }
void setNumberOfRows(dof_id_type n_rows)
These methods must be called within the constructor of child classes to define the size of the matrix...
Definition: Sampler.C:149
void init()
Functions called by MOOSE to setup the Sampler for use.
Definition: Sampler.C:90
void advanceGeneratorsInternal(const dof_id_type count)
Advance method for internal use that considers the auto advance flag.
Definition: Sampler.C:333
DenseMatrix< Real > getLocalSamples()
Definition: Sampler.C:218
dof_id_type _local_row_begin
Global row index for start of data for this processor.
Definition: Sampler.h:293
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
virtual Real computeSample(dof_id_type row_index, dof_id_type col_index)=0
Base class must override this method to supply the sample distribution data.
static InputParameters validParams()
Definition: Sampler.C:17
virtual void advanceGenerators(const dof_id_type count)
Method for advancing the random number generator(s) by the supplied number or calls to rand()...
Definition: Sampler.C:318
void paramError(const std::string &param, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
Definition: MooseBase.h:467
dof_id_type _n_local_rows
Number of rows for this processor.
Definition: Sampler.h:290
virtual void executeSetUp()
Callbacks for before and after execute.
Definition: Sampler.h:234
LocalRankConfig rankConfig(processor_id_type rank, processor_id_type nprocs, dof_id_type napps, processor_id_type min_app_procs, processor_id_type max_app_procs, bool batch_mode=false)
Returns app partitioning information relevant to the given rank for a multiapp scenario with the give...
Definition: MultiApp.C:1352
unsigned int getRandl(std::size_t n, unsigned int lower, unsigned int upper, unsigned int index=0) const
Get nth random integer from the generator within the specified range [lower, upper) ...
Definition: Sampler.C:353
T & set(const std::string &name, bool quiet_mode=false)
Returns a writable reference to the named parameters.
DenseMatrix< Real > getGlobalSamples()
Return the sampled complete or distributed sample data.
Definition: Sampler.C:197
Interface for objects that need to use samplers.
virtual void advanceGenerator(const unsigned int seed_index, const dof_id_type count)
Definition: Sampler.C:326
std::vector< Real > getNextLocalRow()
Return the "next" local row.
Definition: Sampler.C:242
void registerSystemAttributeName(const std::string &value)
This method is used to define the MOOSE system name that is used by the TheWarehouse object for stori...
The main MOOSE class responsible for handling user-defined parameters in almost every MOOSE system...
dof_id_type getLocalRowBegin() const
Return the beginning/end local row index for this processor.
Definition: Sampler.C:381
void checkReinitStatus() const
Helper function for reinit() errors.
Definition: Sampler.C:395
void addAvailableFlags(const ExecFlagType &flag, Args... flags)
Add additional execute_on flags to the list of possible flags.
Definition: ExecFlagEnum.h:82
const Parallel::Communicator & _communicator
virtual void computeLocalSampleMatrix(DenseMatrix< Real > &matrix)
Definition: Sampler.C:290
const dof_id_type _max_procs_per_row
The maximum number of processors that are associated with a set of rows.
Definition: Sampler.h:247
virtual void computeSampleMatrix(DenseMatrix< Real > &matrix)
Methods to populate the global or local sample matrix.
Definition: Sampler.C:274
const dof_id_type _limit_get_next_local_row
Max number of entries for matrix returned by getNextLocalRow.
Definition: Sampler.h:329
dof_id_type getNumberOfLocalRows() const
Definition: Sampler.C:374
static InputParameters validParams()
Sampler(const InputParameters &parameters)
Definition: Sampler.C:63
auto max(const L &left, const R &right)
virtual void computeSampleRow(dof_id_type i, std::vector< Real > &data)
Method to populate a complete row of sample data.
Definition: Sampler.C:307
void registerBase(const std::string &value)
This method must be called from every base "Moose System" to create linkage with the Action System...
processor_id_type n_processors() const
Real getRand(std::size_t n, unsigned int index=0) const
Get nth random number from the generator.
Definition: Sampler.C:346
bool _needs_reinit
Flag to indicate if the reinit method should be called during execute.
Definition: Sampler.h:317
const dof_id_type _limit_get_global_samples
Max number of entries for matrix returned by getGlobalSamples.
Definition: Sampler.h:323
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:28
const dof_id_type _limit_get_local_samples
Max number of entries for matrix returned by getLocalSamples.
Definition: Sampler.h:326
const ExecFlagType EXEC_PRE_MULTIAPP_SETUP
Definition: Moose.C:54
Interface for objects that need to use distributions.
Interface to allow object to consume Reporter values.
void split(int color, int key, Communicator &target) const
std::pair< LocalRankConfig, LocalRankConfig > _rank_config
The partitioning of the sampler matrix, built in reinit() first is for normal mode and send is for ba...
Definition: Sampler.h:333
std::size_t _n_seeds
Number of seeds.
Definition: Sampler.h:305
void reinit()
Definition: Sampler.C:118
static InputParameters validParams()
std::vector< Real > & get_values()
bool _has_executed
Flag for initial execute to allow the first set of random numbers to be always be the same...
Definition: Sampler.h:320
Interface for objects interacting with the PerfGraph.
virtual LocalRankConfig constructRankConfig(bool batch_mode) const
This is where the sampler partitioning is defined.
Definition: Sampler.C:142
dof_id_type getLocalRowEnd() const
Definition: Sampler.C:388
const dof_id_type _min_procs_per_row
The minimum number of processors that are associated with a set of rows.
Definition: Sampler.h:245
libMesh::Parallel::Communicator _local_comm
Communicator that was split based on samples that have rows.
Definition: Sampler.h:250
dof_id_type _local_row_end
Global row index for end of data for this processor.
Definition: Sampler.h:296
dof_id_type getNumberOfRows() const
Return the number of samples.
Definition: Sampler.C:360
void setAutoAdvanceGenerators(const bool state)
Definition: Sampler.C:340
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void setNumberOfCols(dof_id_type n_cols)
Definition: Sampler.C:159
static void seed(unsigned int seed)
The method seeds the random number generator.
Definition: MooseRandom.h:44
virtual void executeTearDown()
Definition: Sampler.h:235
bool _initialized
Flag to indicate if the init method for this class was called.
Definition: Sampler.h:314
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
Definition: MooseBase.h:281
void addClassDescription(const std::string &doc_string)
This method adds a description of the class that will be displayed in the input file syntax dump...
bool _auto_advance_generators
Flag for disabling automatic generator advancing.
Definition: Sampler.h:336
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an optional parameter and a documentation string to the InputParameters object...
bool _next_local_row_requires_state_restore
Flag for restoring state during getNextLocalRow iteration.
Definition: Sampler.h:311
Holds app partitioning information relevant to the a particular rank for a multiapp scenario...
Definition: MultiApp.h:46
dof_id_type _n_rows
Total number of rows in the sample matrix.
Definition: Sampler.h:299
std::vector< std::unique_ptr< MooseRandomStateless > > _generators
Random number generators, don&#39;t give users access. Control it via the interface from this class...
Definition: Sampler.h:287
static InputParameters validParams()
Definition: MooseObject.C:25
void execute()
Advance MooseRandomStateless generators so that new calls to sample methods will create new numbers...
Definition: Sampler.C:183
dof_id_type _n_cols
Total number of columns in the sample matrix.
Definition: Sampler.h:302
processor_id_type processor_id() const
void ErrorVector unsigned int
dof_id_type getNumberOfCols() const
Definition: Sampler.C:367
This class encapsulates a useful, consistent, cross-platform random number generator with multiple ut...
Definition: MooseRandom.h:37
uint8_t dof_id_type
void setNumberOfRandomSeeds(std::size_t number)
Set the number of seeds required by the sampler.
Definition: Sampler.C:169
dof_id_type _next_local_row
Iterator index for getNextLocalRow method.
Definition: Sampler.h:308
const ExecFlagType EXEC_INITIAL
Definition: Moose.C:30