Hi Hartmut,
Thanks for the email and the tip regarding Boost's RNG.  If I understand
correctly, it still says that the engine itself is not thread-safe.  In my
mind, that makes sense since the engine does have state, and concurrent
access/changes to this state from multiple threads could result in an
invalid state. 

As such, a mutex is still required for generating the random number itself.
The below code uses std::random rather than Boost Random, for no reason
other than I had the code handy, but from the stackoverflow link you sent, I
understand it to be exactly the same.

static std::vector<float> Generate_Random_Vector(float min, float max, int
length){
        static std::mt19937 rng_;
        static std::mutex mut_;

        std::uniform_real_distribution<float> dist_ (min, max);
        std::vector<float> vec;
        vec.reserve(length);

        for (int idx = 0; idx < length; ++idx){
                std::lock_guard<std::mutex> lock_(mut_);
                vec.push_back( dist_(rng_) );
        }

        return vec;
}

This static function is called from multiple threads.  It uses a static
variable for the RNG engine.  I suppose I could always keep this non-static,
and just ensure that each thread uses a different seed, but I prefer this
approach.

The mutex / lock_guard ensures that the RNG engine is not used by multiple
threads simultaneously, as noted in the link.  There is probably a fair
amount of overhead involved in instantiating a new
std::lock_guard<std::mutex> each iteration of the loop, and I would likely
be better served by manually locking and unlocking the mutex; however, this
was supposed to be representative code, not production code... 
                
Thanks again for your input.
Shmuel



> -----Original Message-----
> From: [email protected] [mailto:hpx-users-
> [email protected]] On Behalf Of Hartmut Kaiser
> Sent: June-23-16 12:13 PM
> To: [email protected]
> Subject: Re: [hpx-users] HPX futures and random number generators
> 
> 
> > I’m looking for some advice regarding creating an
> > std::vector<hpx::future<std::vector <int> > > where the elements of
> > the innermost vector use a random number generator.
> >
> > Typically, if I were to use to generate this vector of random
> > integers, I’d use either boost or standard library random functions
> > (or possibly Intel MKL / VSL); however, all of these RNGs have a state.
> 
> None of Boost's RNG maintain shared state. All are explicitly thread-safe,
see
> for instance:
> http://stackoverflow.com/questions/2920497/thread-safty-of-boost-rng
> 
> HTH
> Regards Hartmut
> ---------------
> http://boost-spirit.com
> http://stellar.cct.lsu.edu
> 
> 
> > As I
> > understand, a naïve implementation, just passing a reference to the
> > RNG state would lead to race conditions and will result in the RNG
> > state ending up in some undefined-state.  If I understand correctly,
> > that would be the reason that an action cannot have a non-const
reference
> parameter.
> > In light of this, how could I use a future to represent this vector of
> > future integer-vectors?  Is there any way to make this code concurrent?
> >
> > As a rough reference:
> >
> > #include <random>
> > #include <vector>
> > #include <hpx/hpx.hpp>
> > #include <hpx/include/future.hpp>
> > #include <hpx/include/async.hpp>
> > #include <hpx/hpx_main.hpp>
> >
> > using random_vec_t = std::vector<int>;
> >
> > constexpr int random_vec_size = 8;
> > constexpr int vec_random_size = 30;
> >
> > //template <typename RNG>
> > std::vector<random_vec_t> Generate_Random_Vector(std::mt19937_64
> &rng)
> > {
> >
> >   std::vector<random_vec_t> random_vector_set;
> >
> >   static const int range_ = 100;
> >  std::uniform_int_distribution<int> dist_(0, range_);
> >
> >   random_vector_set.resize(vec_random_size);
> >   for (auto &vec : random_vector_set) {
> >     vec.reserve(random_vec_size);
> >     for (int i = 0; i < random_vec_size; ++i)
> >       vec.push_back(dist_(rng));
> >   }
> >   return random_vector_set;
> >
> > }
> >
> > HPX_PLAIN_ACTION(Generate_Random_Vector,
> > generate_random_vector_action); // <= this line fails with message:
> > static_assert failed "Using non-const references as arguments for
actions is
> not supported."
> >
> > int main(int argc, char *argv[]) {
> >
> >   std::mt19937_64 rng_;
> >
> >
> >   hpx::future<std::vector<random_vec_t>> future_vectors_ =
> > hpx::async(generate_random_vector_action, rng_);
> >
> >   auto vecs_ = future_vectors_.get();
> >
> >   for (auto outer_vec : vecs_) {
> >     for (auto inner_vec : outer_vec)
> >       std::cout << inner_vec << "\t";
> >     std::cout << std::endl;
> >   }
> >
> >   return 0;
> > }
> >
> >
> > Thanks and regards,
> > Shmuel
> 
> _______________________________________________
> hpx-users mailing list
> [email protected]
> https://mail.cct.lsu.edu/mailman/listinfo/hpx-users

_______________________________________________
hpx-users mailing list
[email protected]
https://mail.cct.lsu.edu/mailman/listinfo/hpx-users

Reply via email to