www.mooseframework.org
Sampler.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
27  params.addParam<unsigned int>("seed", 0, "Random number generator initial seed");
28  params.registerBase("Sampler");
29  params.registerSystemAttributeName("Sampler");
30 
31  // Define the allowable limits for data returned by getSamples/getLocalSamples/getNextLocalRow
32  // to prevent system for going over allowable limits. The DenseMatrix object uses unsigned int
33  // for size definition, so as start the limits will be based the max of unsigned int. Note,
34  // the values here are the limits of the number of items in the complete container. dof_id_type
35  // is used just in case in the future we need more.
36  params.addParam<dof_id_type>("limit_get_global_samples",
38  "The maximum allowed number of items in the DenseMatrix returned by "
39  "getGlobalSamples method.");
40  params.addParam<dof_id_type>(
41  "limit_get_local_samples",
43  "The maximum allowed number of items in the DenseMatrix returned by getLocalSamples method.");
44  params.addParam<dof_id_type>(
45  "limit_get_next_local_row",
47  "The maximum allowed number of items in the std::vector returned by getNextLocalRow method.");
48 
49  params.addParam<unsigned int>(
50  "min_procs_per_row",
51  1,
52  "This will ensure that the sampler is partitioned properly when "
53  "'MultiApp/*/min_procs_per_app' is specified. It is not recommended to use otherwise.");
54  params.addParam<unsigned int>(
55  "max_procs_per_row",
57  "This will ensure that the sampler is partitioned properly when "
58  "'MultiApp/*/max_procs_per_app' is specified. It is not recommended to use otherwise.");
59  return params;
60 }
61 
62 Sampler::Sampler(const InputParameters & parameters)
63  : MooseObject(parameters),
64  SetupInterface(this),
66  PerfGraphInterface(this),
67  SamplerInterface(this),
69  ReporterInterface(this),
70  _min_procs_per_row(getParam<unsigned int>("min_procs_per_row") > n_processors()
71  ? n_processors()
72  : getParam<unsigned int>("min_procs_per_row")),
73  _max_procs_per_row(getParam<unsigned int>("max_procs_per_row")),
74  _n_rows(0),
75  _n_cols(0),
76  _n_seeds(1),
77  _next_local_row_requires_state_restore(true),
78  _initialized(false),
79  _needs_reinit(true),
80  _has_executed(false),
81  _limit_get_global_samples(getParam<dof_id_type>("limit_get_global_samples")),
82  _limit_get_local_samples(getParam<dof_id_type>("limit_get_local_samples")),
83  _limit_get_next_local_row(getParam<dof_id_type>("limit_get_next_local_row")),
84  _auto_advance_generators(true)
85 {
86 }
87 
88 void
90 {
91  // The init() method is private so it is un-likely to be called, but just in case the following
92  // was added to help avoid future mistakes.
93  if (_initialized)
94  mooseError("The Sampler::init() method is called automatically and should not be called.");
95 
96  // Initialize the parallel partition of sample to return
97  reinit();
98 
99  // Seed the "master" seed generator
100  const unsigned int seed = getParam<unsigned int>("seed");
101  MooseRandom seed_generator;
102  seed_generator.seed(0, seed);
103 
104  // See the "secondary" generator that will be used for the random number generation
105  for (std::size_t i = 0; i < _n_seeds; ++i)
106  _generator.seed(i, seed_generator.randl(0));
107 
108  // Save the initial state
110 
111  // Mark class as initialized, which locks out certain methods
112  _initialized = true;
113 }
114 
115 void
117 {
118  _rank_config.first = constructRankConfig(false);
119  _rank_config.second = constructRankConfig(true);
120  if (_rank_config.first.num_local_sims != _rank_config.second.num_local_sims ||
121  _rank_config.first.first_local_sim_index != _rank_config.second.first_local_sim_index ||
122  _rank_config.first.is_first_local_rank != _rank_config.second.is_first_local_rank)
123  mooseError("Sampler has inconsistent partitionings for normal and batch mode.");
124 
125  _n_local_rows = _rank_config.first.is_first_local_rank ? _rank_config.first.num_local_sims : 0;
126  _local_row_begin = _rank_config.first.first_local_sim_index;
128 
129  // Set the next row iterator index
131 
132  // Create communicator that only has processors with rows
133  _communicator.split(_n_local_rows > 0 ? 1 : MPI_UNDEFINED, processor_id(), _local_comm);
134 
135  // Update reinit() flag (see execute method)
136  _needs_reinit = false;
137 }
138 
140 Sampler::constructRankConfig(bool batch_mode) const
141 {
142  return rankConfig(
144 }
145 
146 void
148 {
149  if (n_rows == 0)
150  mooseError("The number of rows cannot be zero.");
151 
152  _needs_reinit = true;
153  _n_rows = n_rows;
154 }
155 
156 void
158 {
159  if (n_cols == 0)
160  mooseError("The number of columns cannot be zero.");
161 
162  _needs_reinit = true;
163  _n_cols = n_cols;
164 }
165 
166 void
168 {
169  if (_initialized)
170  mooseError("The 'setNumberOfRandomSeeds()' method can not be called after the Sampler has been "
171  "initialized; "
172  "this method should be called in the constructor of the Sampler object.");
173 
174  if (n_seeds == 0)
175  mooseError("The number of seeds must be larger than zero.");
176 
177  _n_seeds = n_seeds;
178 }
179 
180 void
182 {
183  executeSetUp();
184  if (_needs_reinit)
185  reinit();
186 
187  if (_has_executed)
188  {
191  }
193  executeTearDown();
194  _has_executed = true;
195 }
196 
199 {
200  TIME_SECTION("getGlobalSamples", 1, "Retrieving Global Samples");
201 
203 
205  paramError("limit_get_global_samples",
206  "The number of entries in the DenseMatrix (",
207  _n_rows * _n_cols,
208  ") exceeds the allowed limit of ",
210  ".");
211 
216  computeSampleMatrix(output);
218  return output;
219 }
220 
223 {
224  TIME_SECTION("getLocalSamples", 1, "Retrieving Local Samples");
225 
227 
229  paramError("limit_get_local_samples",
230  "The number of entries in the DenseMatrix (",
232  ") exceeds the allowed limit of ",
234  ".");
235 
237  if (_n_local_rows == 0)
238  return output;
239 
243  computeLocalSampleMatrix(output);
245  return output;
246 }
247 
248 std::vector<Real>
250 {
252 
254  {
259 
261  paramError("limit_get_next_local_row",
262  "The number of entries in the std::vector (",
263  _n_cols,
264  ") exceeds the allowed limit of ",
266  ".");
267  }
268 
269  std::vector<Real> output(_n_cols);
271  mooseAssert(output.size() == _n_cols, "The row of sample data is not sized correctly.");
272  _next_local_row++;
273 
275  {
280  }
281 
282  return output;
283 }
284 
285 void
287 {
288  TIME_SECTION("computeSampleMatrix", 2, "Computing Sample Matrix");
289 
290  for (dof_id_type i = 0; i < _n_rows; ++i)
291  {
292  std::vector<Real> row(_n_cols, 0);
293  computeSampleRow(i, row);
294  mooseAssert(row.size() == _n_cols, "The row of sample data is not sized correctly.");
295  mooseAssert(!_needs_reinit,
296  "Changing the size of the sample must not occur during matrix access.");
297  std::copy(row.begin(), row.end(), matrix.get_values().begin() + i * _n_cols);
298  }
299 }
300 
301 void
303 {
304  TIME_SECTION("computeLocalSampleMatrix", 2, "Computing Local Sample Matrix");
305 
307  for (dof_id_type i = _local_row_begin; i < _local_row_end; ++i)
308  {
309  std::vector<Real> row(_n_cols, 0);
310  computeSampleRow(i, row);
311  mooseAssert(row.size() == _n_cols, "The row of sample data is not sized correctly.");
312  mooseAssert(!_needs_reinit,
313  "Changing the size of the sample must not occur during matrix access.");
314  std::copy(
315  row.begin(), row.end(), matrix.get_values().begin() + ((i - _local_row_begin) * _n_cols));
316  }
318 }
319 
320 void
321 Sampler::computeSampleRow(dof_id_type i, std::vector<Real> & data)
322 {
323  for (dof_id_type j = 0; j < _n_cols; ++j)
324  {
325  data[j] = computeSample(i, j);
326  mooseAssert(!_needs_reinit,
327  "Changing the size of the sample must not occur during matrix access.");
328  }
329 }
330 
331 void
333 {
334  TIME_SECTION("advanceGenerators", 2, "Advancing Generators");
335 
336  for (std::size_t j = 0; j < _generator.size(); ++j)
337  advanceGenerator(j, count);
338 }
339 void
340 Sampler::advanceGenerator(const unsigned int seed_index, const dof_id_type count)
341 {
342  for (std::size_t i = 0; i < count; ++i)
343  getRand(seed_index);
344 }
345 
346 void
348 {
350  advanceGenerators(count);
351 }
352 
353 void
355 {
356  _auto_advance_generators = state;
357 }
358 
359 double
360 Sampler::getRand(const unsigned int index)
361 {
362  mooseAssert(index < _generator.size(), "The seed number index does not exists.");
363  return _generator.rand(index);
364 }
365 
366 uint32_t
367 Sampler::getRandl(unsigned int index, uint32_t lower, uint32_t upper)
368 {
369  mooseAssert(index < _generator.size(), "The seed number index does not exists.");
370  return _generator.randl(index, lower, upper);
371 }
372 
375 {
377  return _n_rows;
378 }
379 
382 {
384  return _n_cols;
385 }
386 
389 {
391  return _n_local_rows;
392 }
393 
396 {
398  return _local_row_begin;
399 }
400 
403 {
405  return _local_row_end;
406 }
407 
408 void
410 {
411  if (_needs_reinit)
412  mooseError("A call to 'setNumberOfRows()/Columns()' was made after initialization, as such the "
413  "expected Sampler output has changed and a new sample must be created. However, a "
414  "call to Sampler::reinit() was not performed. The renit() method is automatically "
415  "called during Sampler execution, which occurs according to the 'execute_on' "
416  "settings of the Sampler object. An adjustment to this parameter may be required. "
417  "It is recommended that calls to 'setNumberOfRows()/Columns() occur within the "
418  "Sampler::executeSetUp() method; this will ensure that the reinitialize is handled "
419  "correctly. Have a nice day.");
420 }
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:147
void init()
Functions called by MOOSE to setup the Sampler for use.
Definition: Sampler.C:89
void advanceGeneratorsInternal(const dof_id_type count)
Advance method for internal use that considers the auto advance flag.
Definition: Sampler.C:347
DenseMatrix< Real > getLocalSamples()
Definition: Sampler.C:222
static uint32_t randl()
This method returns the next random number (long format) from the generator.
Definition: MooseRandom.h:70
dof_id_type _local_row_begin
Global row index for start of data for this processor.
Definition: Sampler.h:339
A MultiMooseEnum object to hold "execute_on" flags.
Definition: ExecFlagEnum.h:21
uint32_t getRandl(unsigned int index, uint32_t lower, uint32_t upper)
Get the next random integer from the generator within the specified range [lower, upper) ...
Definition: Sampler.C:367
MooseRandom _generator
Random number generator, don&#39;t give users access. Control it via the interface from this class...
Definition: Sampler.h:333
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:332
dof_id_type _n_local_rows
Number of rows for this processor.
Definition: Sampler.h:336
virtual void executeSetUp()
Callbacks for before and after execute.
Definition: Sampler.h:269
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:1210
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:198
Interface for objects that need to use samplers.
virtual void advanceGenerator(const unsigned int seed_index, const dof_id_type count)
Definition: Sampler.C:340
std::vector< Real > getNextLocalRow()
Return the "next" local row.
Definition: Sampler.C:249
virtual void sampleTearDown(const SampleMode)
Definition: Sampler.h:212
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:395
void checkReinitStatus() const
Helper function for reinit() errors.
Definition: Sampler.C:409
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:302
const dof_id_type _max_procs_per_row
The maximum number of processors that are associated with a set of rows.
Definition: Sampler.h:290
void restoreGeneratorState()
Definition: Sampler.h:278
virtual void computeSampleMatrix(DenseMatrix< Real > &matrix)
Methods to populate the global or local sample matrix.
Definition: Sampler.C:286
const dof_id_type _limit_get_next_local_row
Max number of entries for matrix returned by getNextLocalRow.
Definition: Sampler.h:375
dof_id_type getNumberOfLocalRows() const
Definition: Sampler.C:388
Real getRand(unsigned int index=0)
Get the next random number from the generator.
Definition: Sampler.C:360
static InputParameters validParams()
Sampler(const InputParameters &parameters)
Definition: Sampler.C:62
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:321
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
bool _needs_reinit
Flag to indicate if the reinit method should be called during execute.
Definition: Sampler.h:363
const dof_id_type _limit_get_global_samples
Max number of entries for matrix returned by getGlobalSamples.
Definition: Sampler.h:369
Every object that can be built by the factory should be derived from this class.
Definition: MooseObject.h:33
const dof_id_type _limit_get_local_samples
Max number of entries for matrix returned by getLocalSamples.
Definition: Sampler.h:372
const ExecFlagType EXEC_PRE_MULTIAPP_SETUP
Definition: Moose.C:46
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
void saveGeneratorState()
Here we save/restore generator states.
Definition: Sampler.h:277
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:379
std::size_t _n_seeds
Number of seeds.
Definition: Sampler.h:351
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 ...
void reinit()
Definition: Sampler.C:116
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:366
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:140
std::size_t size()
Return the number of states.
Definition: MooseRandom.h:164
dof_id_type getLocalRowEnd() const
Definition: Sampler.C:402
const dof_id_type _min_procs_per_row
The minimum number of processors that are associated with a set of rows.
Definition: Sampler.h:288
libMesh::Parallel::Communicator _local_comm
Communicator that was split based on samples that have rows.
Definition: Sampler.h:293
dof_id_type _local_row_end
Global row index for end of data for this processor.
Definition: Sampler.h:342
dof_id_type getNumberOfRows() const
Return the number of samples.
Definition: Sampler.C:374
virtual void sampleSetUp(const SampleMode)
Setup method called prior and after looping through distributions.
Definition: Sampler.h:211
void setAutoAdvanceGenerators(const bool state)
Definition: Sampler.C:354
void setNumberOfCols(dof_id_type n_cols)
Definition: Sampler.C:157
static void seed(unsigned int seed)
The method seeds the random number generator.
Definition: MooseRandom.h:43
virtual void executeTearDown()
Definition: Sampler.h:270
bool _initialized
Flag to indicate if the init method for this class was called.
Definition: Sampler.h:360
static Real rand()
This method returns the next random number (Real format) from the generator.
Definition: MooseRandom.h:49
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type.
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:382
void addParam(const std::string &name, const S &value, const std::string &doc_string)
These methods add an option 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:357
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:345
static InputParameters validParams()
Definition: MooseObject.C:24
void execute()
Store the state of the MooseRandom generator so that new calls to getGlobalSamples/getLocalSamples me...
Definition: Sampler.C:181
dof_id_type _n_cols
Total number of columns in the sample matrix.
Definition: Sampler.h:348
processor_id_type processor_id() const
void ErrorVector unsigned int
dof_id_type getNumberOfCols() const
Definition: Sampler.C:381
This class encapsulates a useful, consistent, cross-platform random number generator with multiple ut...
Definition: MooseRandom.h:36
uint8_t dof_id_type
void setNumberOfRandomSeeds(std::size_t number)
Set the number of seeds required by the sampler.
Definition: Sampler.C:167
dof_id_type _next_local_row
Iterator index for getNextLocalRow method.
Definition: Sampler.h:354