Michael,
> 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.
Alternatively you use one RNG per thread where you just need to protect the
initialization with a seed using some mutex (i.e. use a RNG to generate the
seed).
> 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...
All a lock_guard is doing is to lock and unlock the mutex. No additional
overheads should be created by using it.
HTH
Regards Hartmut
---------------
http://boost-spirit.com
http://stellar.cct.lsu.edu
>
> 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
> >
> >
> > > Im 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, Id 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
_______________________________________________
hpx-users mailing list
[email protected]
https://mail.cct.lsu.edu/mailman/listinfo/hpx-users