On Mittwoch, 22. Juni 2016 16:24:01 CEST Michael Levine wrote: > 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. 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.
The reason why actions can't take non-const references is because those don't make a lot of sense in a distributed context. const references are fine, but the parameters you pass to async will get decay-copied into the packaged task anyway. > > > > 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? One possibility would be to create a thread local random number generator as suggested here: http://stackoverflow.com/questions/21237905/how-do-i-generate-thread-safe-uniform-random-numbers The other is of course to really construct a fully parallel number generator. > > 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." Makes sense, as explained above. > 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_); Is there any reason to use an action here? async can just take any callable (including regular function pointers). You could express what you have like this: async(&generate_random_vector, std::ref(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 hpx-users@stellar.cct.lsu.edu https://mail.cct.lsu.edu/mailman/listinfo/hpx-users