BasePolicies.h
Go to the documentation of this file.
1 /**
2  * @file BasePolicies.h
3  * @brief Defines an interface for random seed assignment policies
4  * @author Gianluca Petrillo (petrillo@fnal.gov)
5  * @date 20150211
6  * @see SeedMaster.h
7  *
8  * No code in this files is directly serviceable.
9  * Documentation is up to date though.
10  */
11 
12 #ifndef NUTOOLS_RANDOMUTILS_PROVIDERS_BASEPOLICY_H
13 #define NUTOOLS_RANDOMUTILS_PROVIDERS_BASEPOLICY_H 1
14 
15 // C/C++ standard libraries
16 #include <vector>
17 #include <string>
18 #include <bitset>
19 #include <sstream>
20 #include <ostream> // std::endl
21 #include <memory> // std::unique_ptr<>
22 #include <random> // std::uniform_int_distribution, std::default_random_engine
23 #include <chrono> // std::system_clock
24 
25 // From art and its tool chain
27 #include "fhiclcpp/ParameterSet.h"
28 
29 // Art include files
31 
32 // Some helper classes
33 #include "nutools/RandomUtils/Providers/EngineId.h"
34 #include "nutools/RandomUtils/Providers/EventSeedInputData.h"
35 
36 
37 namespace rndm {
38 
39  namespace details {
40 
41  /// Interface for a policy implementation
42  template <typename SEED>
44  public:
45  using seed_t = SEED; ///< type of the random seed
46 
47  /// type of data used for event seeds
49 
50  /// An invalid seed
51  static constexpr seed_t InvalidSeed = 0;
52 
53  /// Constructor; requires the policy name
55  name(policy_name) {}
56 
57  // Virtual destructor
58  virtual ~RandomSeedPolicyBase() {}
59 
60  /// Configure this policy
61  virtual void configure(fhicl::ParameterSet const&) {}
62 
63  /// Returns the next random number
65  { return createSeed(id); }
66 
67  /// Returns a random number specific to an event
68  virtual seed_t getEventSeed
69  (SeedMasterHelper::EngineId const& id, EventData_t const& eventInfo)
70  { return createEventSeed(id, eventInfo); }
71 
72  /// Returns the given name of the policy
73  std::string getName() const { return name; }
74 
75  /// Prints information on the configuration of this policy
76  virtual void print(std::ostream& out) const
77  { out << "Random policy: '" << getName() << "'"; }
78 
79  /// Returns whether the returned seed should be unique
80  virtual bool yieldsUniqueSeeds() const override { return true; }
81 
82  protected:
83  std::string name; ///< name of the policy
84 
85  /// Extracts the next random number seed
86  virtual seed_t createSeed(SeedMasterHelper::EngineId const&) = 0;
87 
88  /// Extracts a seed for specified event information; returns InvalidSeed
89  virtual seed_t createEventSeed
91  { return InvalidSeed; }
92 
93  }; // class RandomSeedPolicyBase
94 
95 
96 
97  /// Helper class to support range checking
98  template <typename SEED>
100  public:
101  using seed_t = SEED;
102 
103  /// Constructor; specify configuration labels
105  std::string maxSeedsLabel = "maxUniqueEngines",
106  std::string baseSeedLabel = "baseSeed",
107  std::string checkRangeLabel = "checkRange"
108  )
109  { SetConfigLabels(maxSeedsLabel, baseSeedLabel, checkRangeLabel); }
110 
111 
112  void SetConfigLabels(
113  std::string maxSeedsLabel = "maxUniqueEngines",
114  std::string baseSeedLabel = "baseSeed",
115  std::string checkRangeLabel = "checkRange"
116  );
117 
118  /// Configures from a parameter set
119  /// @return if the configuration after the call is complete
120  bool configure(fhicl::ParameterSet const& pset);
121 
122 
123  /// Sets whether to perform the check or not
124  void SetCheck(bool doCheck = true)
125  { bCheck = doCheck; hasParameters.set(pmDoCheck); }
126 
127  /// Sets the base seed directly
128  void SetBaseSeed(seed_t base_seed)
129  { BaseSeed = base_seed; hasParameters.set(pmBaseSeed); }
130 
131  /// Sets the number of seeds directly
132  void SetNSeeds(seed_t nSeeds)
133  { MaxSeeds = nSeeds; hasParameters.set(pmMaxSeeds); }
134 
135  /// Performs the check on the specified seed
136  bool operator() (seed_t seed) const
137  {
138  return
139  !bCheck || ((seed >= BaseSeed) && (seed < BaseSeed + MaxSeeds));
140  } // operator()
141 
142  /// Throws an exception if the range check on seed fails
143  void EnsureRange
144  (std::string policy, SeedMasterHelper::EngineId const& id, seed_t seed)
145  const;
146 
147  /// Returns whether all the parameters are configured
148  bool isConfigured() const;
149 
150  /// Returns the items currently not configured
151  std::vector<std::string> missingConfig() const;
152 
153  /// Prints the configuration int the specified stream
154  template <typename STREAM>
155  void print(STREAM& out, std::string indent = std::string()) const;
156 
157  protected:
158  typedef enum {
162  pmNParams
163  } Params_t;
164  static constexpr unsigned int NParams = (unsigned int) pmNParams;
165 
166  std::array<std::string, NParams> paramLabels;
167  std::bitset<NParams> hasParameters;
168 
169  bool bCheck = true; ///< should we perform the check?
170  seed_t BaseSeed; ///< minimum valid seed
171  seed_t MaxSeeds; ///< number of valid seeds
172 
173  }; // class RangeCheckHelper
174 
175 
176  template <typename SEED>
178  std::string maxSeedsLabel /* = "maxUniqueEngines" */,
179  std::string baseSeedLabel /* = "baseSeed" */,
180  std::string checkRangeLabel /* = "checkRange" */
181  ) {
182  paramLabels[pmMaxSeeds] = maxSeedsLabel;
183  paramLabels[pmBaseSeed] = baseSeedLabel;
184  paramLabels[pmDoCheck] = checkRangeLabel;
185  } // RangeCheckHelper::SetConfigLabels()
186 
187 
188  template <typename SEED>
190  if (!paramLabels[pmMaxSeeds].empty()) {
191  seed_t seed;
192  if (pset.get_if_present(paramLabels[pmMaxSeeds], seed)) SetNSeeds(seed);
193  }
194  if (!paramLabels[pmBaseSeed].empty()) {
195  seed_t seed;
196  if (pset.get_if_present(paramLabels[pmBaseSeed], seed))
197  SetBaseSeed(seed);
198  }
199  if (!paramLabels[pmDoCheck].empty()) {
200  bool flag;
201  if (pset.get_if_present(paramLabels[pmDoCheck], flag)) SetCheck(flag);
202  }
203  return isConfigured();
204  } // RangeCheckHelper<SEED>::configure()
205 
206 
207  template <typename SEED>
209  return (hasParameters.test(pmDoCheck) && !bCheck) || hasParameters.all();
210  } // RangeCheckHelper<SEED>::isConfigured()
211 
212 
213  template <typename SEED>
215  std::string policy,
216  SeedMasterHelper::EngineId const& id, seed_t seed
217  ) const {
218  if (operator()(seed)) return;
219  seed_t offset = seed - BaseSeed;
221  << "NuRandomService (policy: " << policy << ") for engine: "
222  << id << " the offset of seed " << seed << " is: " << offset << "."
223  "\nAllowed seed offsets are in the range 0....(N-1) where N is: "
224  << MaxSeeds << " (as configured in maxUniqueEngines)";
225  } // RangeCheckHelper<SEED>::EnsureRange()
226 
227 
228  template <typename SEED> template <typename STREAM>
230  (STREAM& out, std::string indent /* = "" */) const
231  {
232  if (!isConfigured())
233  out << indent << "seed range checker not configured!";
234  else if (bCheck)
235  out << indent << "maximum number of seeds: " << MaxSeeds;
236  else
237  out << indent << "no limit on number of seeds.";
238  } // RangeCheckHelper<SEED>::print()
239 
240 
241  template <typename SEED>
242  std::vector<std::string> RangeCheckHelper<SEED>::missingConfig() const {
243  if (hasParameters.test(pmDoCheck) && !bCheck) return {};
244  std::vector<std::string> missing;
245  for (unsigned int i = 0; i < NParams; ++i)
246  if (!hasParameters.test(i)) missing.push_back(paramLabels[i]);
247  return missing;
248  } // RangeCheckHelper<SEED>::missingConfig()
249 
250 
251 
252  /// Range-checked policy (abstract)
253  template <typename SEED>
255  public:
258  using seed_t = typename base_t::seed_t;
259 
260  /// Constructor; requires the policy name
262  (std::string policy_name, fhicl::ParameterSet const& pset):
263  base_t(policy_name)
264  { this_t::configure(pset); }
265 
266  /**
267  * @brief Configure this policy
268  * @param pset the parameter set for the configuration
269  *
270  * Parameters:
271  * - *baseSeed* (unsigned integer): the first seed to be delivered
272  * - *checkRange* (boolean, default: true): whether to verify that each
273  * seed is within the expected range
274  * - *maxUniqueEngines* (unsigned integer, mandatory if /checkRange/ is
275  * true) the maximum number on seeds we expect to create
276  */
277  virtual void configure(fhicl::ParameterSet const& pset) override
278  { base_t::configure(pset); static_configure(pset); }
279 
280  /// Returns the next random number
282  {
283  seed_t seed = this->createSeed(id);
284  ensureRange(id, seed);
285  return seed;
286  } // getSeed()
287 
288  /// Prints information on the configuration of this policy
289  virtual void print(std::ostream& out) const override
290  {
291  base_t::print(out);
292  range_check.print(out << "\n", " ");
293  } // print()
294 
295  protected:
297 
298  /// Lets the derived class to start configuration
299  CheckedRangePolicy(std::string policy_name): base_t(policy_name) {}
300 
301  /// Performs the range checks and complains if needed
302  virtual void ensureRange
303  (SeedMasterHelper::EngineId const& id, seed_t seed) const
304  { range_check.EnsureRange(this->getName(), id, seed); }
305 
306  /// Check that the configuration is complete
307  void CheckRangeConfiguration() const;
308 
309  /// Local configuration; does not require the range config to be complete
310  void static_configure(fhicl::ParameterSet const& pset);
311 
312  }; // class CheckedRangePolicy
313 
314 
315  template <typename SEED>
317  (fhicl::ParameterSet const& pset)
318  {
319  range_check.configure(pset);
320  } // CheckedRangePolicy<SEED>::static_configure()
321 
322  template <typename SEED>
324  if (!range_check.isConfigured()) {
325  std::ostringstream sstr;
326  sstr << "configuration of policy '" << this->getName()
327  << "' incomplete:";
328  for (std::string const& name: range_check.missingConfig())
329  sstr << " " << name;
330  throw art::Exception(art::errors::Configuration) << sstr.str();
331  }
332  } // CheckedRangePolicy<SEED>::CheckRangeConfiguration()
333 
334 
335 
336  /** ************************************************************************
337  * @brief Implementation of the "autoIncrement" policy
338  * @see CheckedRangePolicy
339  *
340  * This is heavily based on CheckedRangePolicy.
341  */
342  template <typename SEED>
344  public:
347  using seed_t = typename base_t::seed_t;
348 
349  /// Configures from a parameter set
350  /// @see configure()
352  base_t("autoIncrement")
353  { this_t::configure(pset); }
354 
355 
356  /**
357  * @brief Configure this policy
358  * @param pset the parameter set for the configuration
359  *
360  * Parameters:
361  * - *baseSeed* (unsigned integer): the first seed to be delivered
362  * - *checkRange* (boolean, default: true): whether to verify that each
363  * seed is within the expected range
364  * - *maxUniqueEngines* (unsigned integer, mandatory if /checkRange/ is
365  * true) the maximum number on seeds we expect to create
366  */
367  virtual void configure(fhicl::ParameterSet const& pset) override
368  {
369  base_t::range_check.SetConfigLabels
370  ("maxUniqueEngines", "", "checkRange");
371  base_t::configure(pset);
372  static_configure(pset);
373  } // configure()
374 
375  /// Prints the configuration of this policy
376  virtual void print(std::ostream& out) const override;
377 
378  protected:
380  seed_t next_seed; ///< next seed delivered
381 
382  /// Returns the next random number
384  { return next_seed++; }
385 
386  void static_configure(fhicl::ParameterSet const&);
387  }; // class AutoIncrementPolicy<>
388 
389 
390  template <typename SEED>
392  (fhicl::ParameterSet const& pset)
393  {
394  first_seed = pset.get<seed_t>("baseSeed");
395  base_t::range_check.SetBaseSeed(first_seed);
396  base_t::CheckRangeConfiguration();
397  next_seed = first_seed;
398  } // AutoIncrementPolicy<SEED>::configure()
399 
400 
401  template <typename SEED>
402  void AutoIncrementPolicy<SEED>::print(std::ostream& out) const {
403  base_t::print(out);
404  out << "\n first seed: " << first_seed;
405  } // AutoIncrementPolicy<SEED>::print()
406 
407 
408  /** ************************************************************************
409  * @brief Implementation of the "linearMapping" policy
410  * @see CheckedRangePolicy
411  *
412  * This is heavily based on CheckedRangePolicy.
413  */
414  template <typename SEED>
416  public:
419  using seed_t = typename base_t::seed_t;
420 
421  /// Configures from a parameter set
422  /// @see configure()
424  base_t("linearMapping")
425  { this_t::configure(pset); }
426 
427 
428  /**
429  * @brief Configure this policy
430  * @param pset the parameter set for the configuration
431  *
432  * Parameters:
433  * - *nJob* (unsigned integer): the number of this job; the first seed
434  * - *checkRange* (boolean, default: true): whether to verify that each
435  * seed is within the expected range
436  * - *maxUniqueEngines* (unsigned integer, mandatory) the maximum number
437  * on seeds we expect to create
438  */
439  virtual void configure(fhicl::ParameterSet const& pset) override
440  {
441  base_t::range_check.SetConfigLabels("", "", "checkRange");
442  base_t::configure(pset);
443  static_configure(pset);
444  }
445 
446  /// Prints the configuration of this policy
447  virtual void print(std::ostream& out) const override;
448 
449  protected:
450  seed_t first_seed; ///< base seed
451  seed_t next_seed; ///< next seed delivered
452  unsigned int nSeedsPerJob;
453 
454  /// Returns the next random number
456  { return next_seed++; }
457 
458  void static_configure(fhicl::ParameterSet const& pset);
459 
460  }; // class LinearMappingPolicy<>
461 
462 
463  template <typename SEED>
465  (fhicl::ParameterSet const& pset)
466  {
467  // this code is for legacy support, and it could disappear in the future
468  if (!pset.get_if_present<seed_t>("nJob", first_seed)) {
469  if (!pset.get_if_present<seed_t>("baseSeed", first_seed)) {
470  // this is going to fail; I am doing this just to get
471  // the more appropriate error message possible
472  first_seed = pset.get<seed_t>("nJob");
473  }
474  else {
475  mf::LogWarning("SeedMaster") <<
476  std::string(80, '*') <<
477  "\nDEPRECATION WARNING: 'baseSeed' parameter has been deprecated"
478  " for linearMapping policy, in favour of 'nJob'."
479  "\nPlease update your configuration accordingly."
480  << "\n" << std::string(80, '*');
481  }
482  }
483  // first_seed = pset.get<seed_t>("nJob");
484  nSeedsPerJob = pset.get<seed_t>("maxUniqueEngines");
485  first_seed *= nSeedsPerJob;
486  ++first_seed; // we don't want 0 as a seed
487  next_seed = first_seed;
488  base_t::range_check.SetBaseSeed(next_seed);
489  base_t::range_check.SetNSeeds(nSeedsPerJob);
490  base_t::CheckRangeConfiguration();
491  } // LinearMappingPolicy<SEED>::configure()
492 
493 
494  template <typename SEED>
495  void LinearMappingPolicy<SEED>::print(std::ostream& out) const {
496  base_t::print(out);
497  out
498  << "\n first seed: " << first_seed
499  << "\n seeds per job: " << nSeedsPerJob;
500  } // LinearMappingPolicy<SEED>::print()
501 
502 
503 
504  /** ************************************************************************
505  * @brief Base class for policies reacting at engine instance level
506  * @see CheckedRangePolicy
507  *
508  */
509  template <typename SEED>
510  class PerInstancePolicy: public CheckedRangePolicy<SEED> {
511  public:
514  using seed_t = typename base_t::seed_t;
515 
516  /// Configures from a parameter set
517  /// @see configure()
519  base_t(name)
520  { this_t::configure(pset); }
521 
522  /**
523  * @brief Configure this policy
524  * @param pset the parameter set for the configuration
525  *
526  */
527  virtual void configure(fhicl::ParameterSet const& pset) override
528  { base_t::configure(pset); static_configure(pset); }
529 
530  protected:
531  fhicl::ParameterSet parameters; ///< configuration parameters
532 
533  /// Internal constructor: does not configure. For use in derived classes
535 
536  /// Retrieves the parameter (seed) for the specified engine ID
538  { return getInstanceParameter<seed_t>(parameters, id); }
539 
540 
541  /// Retrieves the parameter (seed) for the specified engine ID
542  template <typename T>
543  static T getInstanceParameter
544  (fhicl::ParameterSet const& pset, SeedMasterHelper::EngineId const& id);
545 
546 
547  void static_configure(fhicl::ParameterSet const& pset);
548 
549  }; // class PerInstancePolicy<>
550 
551 
552  template <typename SEED>
554  (fhicl::ParameterSet const& pset)
555  {
556  parameters = pset; // copy the parameters locally
557  } // PerInstancePolicy<SEED>::configure()
558 
559 
560  // This method reads a element of type T from the instance configuration
561  template <typename SEED> template <typename T>
563  fhicl::ParameterSet const& pset, SeedMasterHelper::EngineId const& id
564  ) {
565  // there must be /some/ configuration for the module
566  // FIXME: use ParameterSet::has_key() as soon as it's available
567  const auto cfgKeys = pset.get_names();
568  if (std::find(cfgKeys.begin(), cfgKeys.end(), id.moduleLabel) == cfgKeys.end()) {
570  << "A seed for the nameless instance '" << id
571  << "' was requested, but there is no configuration for '"
572  << id.moduleLabel << "' module label.";
573  }
574 
575  T param;
576  if (!id.hasInstanceName()) { // Case 1: no instance name.
577  // We expect the element to be just an item.
578  if (pset.is_key_to_table(id.moduleLabel)) {
579  // this is mostly a limitation of the FHiCL syntax,
580  // that we can overcome with some cumbersomeness if we need to.
582  << "A seed for the nameless instance '" << id
583  << "' was requested, but the configuration sets named instances ("
584  << pset.get<fhicl::ParameterSet>(id.moduleLabel).to_compact_string()
585  << ").\nNameless and named engine instances can't coexist.";
586  }
587  if (!pset.get_if_present(id.moduleLabel, param)) {
589  << "NuRandomService: unable to find the parameter for '" << id << "'";
590  }
591  } // if no instance name
592  else { // Case 2: instance name is given.
593 
594  if (pset.is_key_to_atom(id.moduleLabel)) {
595  // see above
597  << "A seed for '" << std::string(id) << "' was requested,"
598  " but the configuration sets a nameless instance of '"
599  << id.moduleLabel << "'.\n"
600  << "Nameless and named engine instances can't coexist.";
601  }
602  fhicl::ParameterSet subSet;
603  if (!pset.get_if_present(id.moduleLabel, subSet)) {
605  << "NuRandomService: unable to find the parameter block for: '"
606  << id << "'";
607  }
608 
609  if (!subSet.get_if_present(id.instanceName, param)) {
611  << "NuRandomService: unable to find the parameter value for: '"
612  << id << "'";
613  }
614  } // if instance name
615 
616  return param;
617  } // PerInstancePolicy<SEED>::getInstanceParameter<>()
618 
619 
620  /** ************************************************************************
621  * @brief Implementation of the "preDefinedSeed" policy
622  *
623  */
624  template <typename SEED>
626  public:
629  using seed_t = typename base_t::seed_t;
630 
631  /// Configures from a parameter set
632  /// @see configure()
634  base_t("preDefinedSeed")
635  { this_t::configure(pset); }
636 
637 
638  /**
639  * @brief Configure this policy
640  * @param pset the parameter set for the configuration
641  *
642  * Parameters: one entry per engine.
643  * The FHiCL grammar to specify the seeds takes two forms.
644  * If no instance name is given, the seed is given by:
645  *
646  * moduleLabel : seed
647  *
648  * When a module has multiple instances, the seeds are given by:
649  *
650  * moduleLabel : {
651  * instanceName1 : seed1
652  * instanceName2 : seed2
653  * }
654  *
655  */
656  virtual void configure(fhicl::ParameterSet const& pset) override
657  { base_t::configure(pset); static_configure(pset); }
658 
659  /// Prints the configuration of this policy
660  virtual void print(std::ostream& out) const override;
661 
662 
663  /// Returns whether the returned seed should be unique: for us it "no".
664  virtual bool yieldsUniqueSeeds() const override { return false; }
665 
666  protected:
667 
668  /// Returns the seed stored in the parameter set
669  virtual seed_t createSeed(SeedMasterHelper::EngineId const& id) override
670  { return base_t::getInstanceSeed(id); }
671 
673  { base_t::range_check.SetCheck(false); }
674 
675  }; // class PredefinedSeedPolicy<>
676 
677 
678  template <typename SEED>
679  void PredefinedSeedPolicy<SEED>::print(std::ostream& out) const {
680  base_t::print(out);
681  out << "\n seeds directly from the configuration";
682  } // PredefinedSeedPolicy<SEED>::print()
683 
684 
685 
686  /** ************************************************************************
687  * @brief Implementation of the "preDefinedOffset" policy
688  * @see CheckedRangePolicy
689  *
690  * This is heavily based on CheckedRangePolicy.
691  */
692  template <typename SEED>
694  public:
697  using seed_t = typename base_t::seed_t;
698 
699  /// Configures from a parameter set
700  /// @see configure()
702  base_t("preDefinedOffset")
703  { this_t::configure(pset); }
704 
705 
706  /**
707  * @brief Configure this policy
708  * @param pset the parameter set for the configuration
709  *
710  * Parameters:
711  * - *baseSeed* (unsigned integer): the base seed
712  * - *checkRange* (boolean, default: true): whether to verify that each
713  * seed is within the expected range
714  * - *maxUniqueEngines* (unsigned integer, mandatory if /checkRange/ is
715  * true) the maximum number on seeds we expect to create
716  * - in addition, one entry per engine (see below)
717  *
718  * The FHiCL grammar to specify the offsets takes two forms.
719  * If no instance name is given, the offset is given by:
720  *
721  * moduleLabel : offset
722  *
723  * When a module has multiple instances, the offsets are given by:
724  *
725  * moduleLabel : {
726  * instanceName1 : offset1
727  * instanceName2 : offset2
728  * }
729  */
730  virtual void configure(fhicl::ParameterSet const& pset) override
731  {
732  base_t::range_check.SetConfigLabels
733  ("maxUniqueEngines", "", "checkRange");
734  base_t::configure(pset);
735  static_configure(pset);
736  }
737 
738  /// Prints the configuration of this policy
739  virtual void print(std::ostream& out) const override;
740 
741  protected:
743 
744  /// Returns the seed stored in the parameter set
745  virtual seed_t createSeed(SeedMasterHelper::EngineId const& id) override
746  { return base_seed + base_t::getInstanceSeed(id); }
747 
748  void static_configure(fhicl::ParameterSet const&);
749 
750  }; // class PredefinedOffsetPolicy<>
751 
752 
753  template <typename SEED>
755  (fhicl::ParameterSet const& pset)
756  {
757  base_seed = pset.get<seed_t>("baseSeed");
758  base_t::range_check.SetBaseSeed(base_seed);
759  base_t::CheckRangeConfiguration();
760  } // PredefinedOffsetPolicy<SEED>::configure()
761 
762 
763  template <typename SEED>
764  void PredefinedOffsetPolicy<SEED>::print(std::ostream& out) const {
765  base_t::print(out);
766  out << "\n base seed: " << base_seed;
767  } // PredefinedOffsetPolicy<SEED>::print()
768 
769 
770 
771  /** ************************************************************************
772  * @brief Implementation of the "random" policy
773  *
774  * This policy extracts seeds randomly. Each seed is between 1 and the
775  * maximum seed value specified at construction, both extremes included.
776  * The sequence of these seeds is initialized by a random seed.
777  * The random generator used is potentially low quality -- it does not
778  * matter for this application.
779  */
780  template <typename SEED>
781  class RandomPolicy: public RandomSeedPolicyBase<SEED> {
782  public:
785  using seed_t = typename base_t::seed_t;
786 
787  /// Configures from a parameter set
788  /// @see configure()
789  RandomPolicy(fhicl::ParameterSet const& pset): base_t("random")
790  { this_t::configure(pset); }
791 
792 
793  /**
794  * @brief Configure this policy
795  * @param pset the parameter set for the configuration
796  *
797  * Parameters:
798  * - *masterSeed* (unsigned integer, optional): the seed of the seed
799  * generator; by default, it's taken from the system clock
800  */
801  virtual void configure(fhicl::ParameterSet const& pset) override;
802 
803  /// Prints the details of the configuration of the random generator
804  virtual void print(std::ostream& out) const override;
805 
806 
807  private:
808  class RandomImpl {
809  public:
810  RandomImpl(seed_t master_seed, seed_t min_seed, seed_t max_seed):
811  seed(master_seed),
812  generator(master_seed), distribution(min_seed, max_seed)
813  {}
814 
815  seed_t master_seed() const { return seed; }
816  seed_t min() const { return distribution.min(); }
817  seed_t max() const { return distribution.max(); }
818  seed_t operator() () { return distribution(generator); }
819 
820  private:
821  seed_t seed; ///< seed given at construction, for the record
822  std::default_random_engine generator; ///< random engine
823  std::uniform_int_distribution<seed_t> distribution; ///< flat
824  }; // RandomImpl
825 
826  std::unique_ptr<RandomImpl> random_seed;
827 
828  /// Extracts a random seed
830  { return (*random_seed)(); }
831 
832  }; // class RandomPolicy<>
833 
834 
835  template <typename SEED>
837  constexpr seed_t MagicMaxSeed = 900000000;
838  seed_t master_seed = 0;
839  if (!pset.get_if_present("masterSeed", master_seed)) {
840  // get the base seed randomly too, from the clock,
841  // and within [1; MagicMaxSeed]
842  master_seed = 1 +
843  std::chrono::system_clock::now().time_since_epoch().count()
844  % MagicMaxSeed;
845  }
846  random_seed.reset(new RandomImpl(master_seed, 1, MagicMaxSeed));
847  } // RandomPolicy<SEED>::configure()
848 
849 
850  /// Prints the details of the configuration of the random generator
851  template <typename SEED>
852  void RandomPolicy<SEED>::print(std::ostream& out) const {
853  base_t::print(out);
854  out
855  << "\n master seed: " << random_seed->master_seed()
856  << "\n seed within: [ " << random_seed->min()
857  << " ; " << random_seed->max() << " ]"
858  ;
859  } // RandomPolicy<SEED>::print()
860 
861 
862  } // namespace details
863 
864 } // namespace rndm
865 
866 
867 #endif // NUTOOLS_RANDOMUTILS_PROVIDERS_BASEPOLICY_H
virtual seed_t createEventSeed(SeedMasterHelper::EngineId const &, EventData_t const &)
Extracts a seed for specified event information; returns InvalidSeed.
Definition: BasePolicies.h:90
Base class for policies reacting at engine instance level.
Definition: BasePolicies.h:510
seed_t getInstanceSeed(SeedMasterHelper::EngineId const &id) const
Retrieves the parameter (seed) for the specified engine ID.
Definition: BasePolicies.h:537
seed_t next_seed
next seed delivered
Definition: BasePolicies.h:451
virtual void configure(fhicl::ParameterSet const &pset) override
Configure this policy.
Definition: BasePolicies.h:656
PerInstancePolicy(std::string name)
Internal constructor: does not configure. For use in derived classes.
Definition: BasePolicies.h:534
virtual seed_t createSeed(SeedMasterHelper::EngineId const &) override
Returns the next random number.
Definition: BasePolicies.h:383
SEED seed_t
type of the random seed
Definition: BasePolicies.h:45
virtual bool yieldsUniqueSeeds() const override
Returns whether the returned seed should be unique: for us it "no".
Definition: BasePolicies.h:664
std::bitset< NParams > hasParameters
Definition: BasePolicies.h:167
virtual seed_t createSeed(SeedMasterHelper::EngineId const &id) override
Returns the seed stored in the parameter set.
Definition: BasePolicies.h:745
std::unique_ptr< RandomImpl > random_seed
Definition: BasePolicies.h:826
std::string string
Definition: nybbler.cc:12
seed_t seed
seed given at construction, for the record
Definition: BasePolicies.h:821
virtual seed_t createSeed(SeedMasterHelper::EngineId const &) override
Extracts a random seed.
Definition: BasePolicies.h:829
virtual void print(std::ostream &out) const override
Prints the configuration of this policy.
Definition: BasePolicies.h:679
virtual void print(std::ostream &out) const override
Prints the configuration of this policy.
Definition: BasePolicies.h:764
std::vector< std::string > missingConfig() const
Returns the items currently not configured.
Definition: BasePolicies.h:242
bool isConfigured() const
Returns whether all the parameters are configured.
Definition: BasePolicies.h:208
unsigned long seed_t
virtual void configure(fhicl::ParameterSet const &pset) override
Configure this policy.
Definition: BasePolicies.h:730
virtual void configure(fhicl::ParameterSet const &pset) override
Configure this policy.
Definition: BasePolicies.h:439
seed_t MaxSeeds
number of valid seeds
Definition: BasePolicies.h:171
Simple data structure with data needed to extract a seed from a event.
void static_configure(fhicl::ParameterSet const &pset)
Definition: BasePolicies.h:465
Implementation of the "preDefinedOffset" policy.
Definition: BasePolicies.h:693
virtual void print(std::ostream &out) const
Prints information on the configuration of this policy.
Definition: BasePolicies.h:76
virtual bool yieldsUniqueSeeds() const override
Returns whether the returned seed should be unique.
Definition: BasePolicies.h:80
void static_configure(fhicl::ParameterSet const &)
Definition: BasePolicies.h:672
virtual seed_t getSeed(SeedMasterHelper::EngineId const &id)
Returns the next random number.
Definition: BasePolicies.h:64
Implementation of the "random" policy.
Definition: BasePolicies.h:781
void SetCheck(bool doCheck=true)
Sets whether to perform the check or not.
Definition: BasePolicies.h:124
virtual void print(std::ostream &out) const override
Prints information on the configuration of this policy.
Definition: BasePolicies.h:289
CheckedRangePolicy(std::string policy_name)
Lets the derived class to start configuration.
Definition: BasePolicies.h:299
virtual seed_t createSeed(SeedMasterHelper::EngineId const &)=0
Extracts the next random number seed.
bool is_key_to_table(std::string const &key) const
Definition: ParameterSet.h:149
RandomImpl(seed_t master_seed, seed_t min_seed, seed_t max_seed)
Definition: BasePolicies.h:810
bool configure(fhicl::ParameterSet const &pset)
Definition: BasePolicies.h:189
void SetNSeeds(seed_t nSeeds)
Sets the number of seeds directly.
Definition: BasePolicies.h:132
Interface for a policy implementation.
Definition: BasePolicies.h:43
virtual void configure(fhicl::ParameterSet const &pset) override
Configure this policy.
Definition: BasePolicies.h:367
virtual seed_t getEventSeed(SeedMasterHelper::EngineId const &id, EventData_t const &eventInfo)
Returns a random number specific to an event.
Definition: BasePolicies.h:69
Implementation of the "autoIncrement" policy.
Definition: BasePolicies.h:343
Helper class to support range checking.
Definition: BasePolicies.h:99
std::array< std::string, NParams > paramLabels
Definition: BasePolicies.h:166
std::string name
name of the policy
Definition: BasePolicies.h:83
T get(std::string const &key) const
Definition: ParameterSet.h:231
PredefinedOffsetPolicy(fhicl::ParameterSet const &pset)
Definition: BasePolicies.h:701
RangeCheckHelper(std::string maxSeedsLabel="maxUniqueEngines", std::string baseSeedLabel="baseSeed", std::string checkRangeLabel="checkRange")
Constructor; specify configuration labels.
Definition: BasePolicies.h:104
Implementation of the "preDefinedSeed" policy.
Definition: BasePolicies.h:625
virtual void configure(fhicl::ParameterSet const &pset) override
Configure this policy.
Definition: BasePolicies.h:277
RangeCheckHelper< seed_t > range_check
Definition: BasePolicies.h:296
RandomSeedPolicyBase(std::string policy_name)
Constructor; requires the policy name.
Definition: BasePolicies.h:54
Identifier for a engine, made of module name and optional instance name.
Definition: EngineId.h:22
bool get_if_present(std::string const &key, T &value) const
Definition: ParameterSet.h:208
void print(STREAM &out, std::string indent=std::string()) const
Prints the configuration int the specified stream.
Definition: BasePolicies.h:230
virtual void configure(fhicl::ParameterSet const &pset) override
Configure this policy.
Definition: BasePolicies.h:527
generator
Definition: train.py:468
virtual void configure(fhicl::ParameterSet const &pset) override
Configure this policy.
Definition: BasePolicies.h:836
seed_t next_seed
next seed delivered
Definition: BasePolicies.h:380
std::uniform_int_distribution< seed_t > distribution
flat
Definition: BasePolicies.h:823
seed_t BaseSeed
minimum valid seed
Definition: BasePolicies.h:170
virtual seed_t getSeed(SeedMasterHelper::EngineId const &id)
Returns the next random number.
Definition: BasePolicies.h:281
Implementation of the "linearMapping" policy.
Definition: BasePolicies.h:415
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
fhicl::ParameterSet parameters
configuration parameters
Definition: BasePolicies.h:531
virtual void configure(fhicl::ParameterSet const &)
Configure this policy.
Definition: BasePolicies.h:61
void static_configure(fhicl::ParameterSet const &pset)
Local configuration; does not require the range config to be complete.
Definition: BasePolicies.h:317
virtual seed_t createSeed(SeedMasterHelper::EngineId const &) override
Returns the next random number.
Definition: BasePolicies.h:455
std::default_random_engine generator
random engine
Definition: BasePolicies.h:822
PerInstancePolicy(std::string name, fhicl::ParameterSet const &pset)
Definition: BasePolicies.h:518
std::vector< std::string > get_names() const
PredefinedSeedPolicy(fhicl::ParameterSet const &pset)
Definition: BasePolicies.h:633
Range-checked policy (abstract)
Definition: BasePolicies.h:254
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
bool is_key_to_atom(std::string const &key) const
Definition: ParameterSet.h:161
LinearMappingPolicy(fhicl::ParameterSet const &pset)
Definition: BasePolicies.h:423
static constexpr seed_t InvalidSeed
An invalid seed.
Definition: BasePolicies.h:51
virtual seed_t createSeed(SeedMasterHelper::EngineId const &id) override
Returns the seed stored in the parameter set.
Definition: BasePolicies.h:669
virtual void print(std::ostream &out) const override
Prints the details of the configuration of the random generator.
Definition: BasePolicies.h:852
virtual void print(std::ostream &out) const override
Prints the configuration of this policy.
Definition: BasePolicies.h:495
void static_configure(fhicl::ParameterSet const &)
Definition: BasePolicies.h:392
RandomPolicy(fhicl::ParameterSet const &pset)
Definition: BasePolicies.h:789
void EnsureRange(std::string policy, SeedMasterHelper::EngineId const &id, seed_t seed) const
Throws an exception if the range check on seed fails.
Definition: BasePolicies.h:214
void SetConfigLabels(std::string maxSeedsLabel="maxUniqueEngines", std::string baseSeedLabel="baseSeed", std::string checkRangeLabel="checkRange")
Definition: BasePolicies.h:177
void SetBaseSeed(seed_t base_seed)
Sets the base seed directly.
Definition: BasePolicies.h:128
virtual void print(std::ostream &out) const override
Prints the configuration of this policy.
Definition: BasePolicies.h:402
std::string getName() const
Returns the given name of the policy.
Definition: BasePolicies.h:73
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
void CheckRangeConfiguration() const
Check that the configuration is complete.
Definition: BasePolicies.h:323
AutoIncrementPolicy(fhicl::ParameterSet const &pset)
Definition: BasePolicies.h:351
void static_configure(fhicl::ParameterSet const &pset)
Definition: BasePolicies.h:554
static T getInstanceParameter(fhicl::ParameterSet const &pset, SeedMasterHelper::EngineId const &id)
Retrieves the parameter (seed) for the specified engine ID.
Definition: BasePolicies.h:562
void static_configure(fhicl::ParameterSet const &)
Definition: BasePolicies.h:755