Program Listing for File rng_utils.hpp

Return to documentation for file (/home/docs/checkouts/readthedocs.org/user_builds/intel-qs/checkouts/docs/include/rng_utils.hpp)

#ifndef RNG_UTILS_HPP
#define RNG_UTILS_HPP

#include <cassert>
#include <string>
#include <vector>

#ifdef USE_MKL
#include "mkl.h"
#include "mkl_vsl.h"
#else
#include <cmath>    // std::floor
#include <random>
#endif

#include "mpi_env.hpp"


// utility methods related to the generation of (pseudo-)random numbers.

namespace qhipster {



// Type = float, double
template <typename Type>
class  RandomNumberGenerator
{
  private:

    std::size_t _seed=0;
    std::size_t _num_generated_or_skipped_local_numbers=0;
    std::size_t _num_generated_or_skipped_state_numbers=0;
    std::size_t _num_generated_or_skipped_pool_numbers =0;

#ifdef USE_MKL
    // vsl streams for random numbers
    VSLStreamStatePtr  _pool_stream;
    VSLStreamStatePtr _state_stream;
    VSLStreamStatePtr _local_stream;
#else
//   std::default_random_engine generator;
   std::mt19937  _pool_generator;
   std::mt19937 _state_generator;
   std::mt19937 _local_generator;
   std::uniform_real_distribution<Type> u_distribution
       = std::uniform_real_distribution<Type>(0.0,1.0); // uniform in [0,1[
   std::normal_distribution<Type> n_distribution
       = std::normal_distribution<Type>(0.0,1.0);   // mean=0, std.dev.=1
#endif

  public:

    RandomNumberGenerator() {
#ifdef USE_MKL
        _pool_stream  = nullptr;
        _state_stream = nullptr;
        _local_stream = nullptr;
#endif
    }

    ~RandomNumberGenerator() {}

    RandomNumberGenerator(RandomNumberGenerator * source_rng);

    std::size_t GetSeed ( )
    { return _seed; }

    std::size_t GetNumGeneratedOrSkippedLocalNumbers ( )
    { return _num_generated_or_skipped_local_numbers; }

    std::size_t GetNumGeneratedOrSkippedStateNumbers ( )
    { return _num_generated_or_skipped_state_numbers; }

    std::size_t GetNumGeneratedOrSkippedPoolNumbers ( )
    { return _num_generated_or_skipped_pool_numbers; }

    void SetSeedStreamPtrs ( std::size_t RNG_seed );

    void SkipAhead ( std::size_t num_skip, std::string shared = "local" );

    void UniformRandomNumbers( Type *value, std::size_t size = 1UL, Type a=0., Type b=1.,
                               std::string shared = "local");

    void GaussianRandomNumbers( Type *value, std::size_t size = 1UL,
                                std::string shared = "local");

    void RandomIntegersInRange( int *value, std::size_t size = 1UL, int a=0, int b=2,
                               std::string shared = "local");

#ifdef USE_MKL
    void SetRndStreamPtrs( VSLStreamStatePtr pool , VSLStreamStatePtr state ,
                           VSLStreamStatePtr local );

    VSLStreamStatePtr GetPoolStreamPtr  () const {return  _pool_stream; }
    VSLStreamStatePtr GetStateStreamPtr () const {return _state_stream; }
    VSLStreamStatePtr GetLocalStreamPtr () const {return _local_stream; }
#endif

  private:

#ifdef USE_MKL
    VSLStreamStatePtr SelectGeneratorAndUpdateCounter( std::size_t size, std::string shared);
    VSLStreamStatePtr SelectGenerator(std::string shared);
#else
    std::mt19937 * SelectGeneratorAndUpdateCounter( std::size_t size, std::string shared );
    std::mt19937 * SelectGenerator(std::string shared);
#endif


};  // end of class RandomNumberGenerator


// Shuffle array using the Fisher and Yates shuffle algorithm.
template<typename Type, typename TypeFloat>
void ShuffleFisherYates( std::vector<Type> &array,
                         RandomNumberGenerator<TypeFloat> *rnd_generator_ptr,
                         std::string shared="local");


}   // close namespace qhipster

#endif  // close header guards RNG_UTILS_HPP