#include #include #include #include #include #include #include #include #include #include template struct RandomEnginePool { using EngineType = T; T get() { /* check if we have a free engine in unused */ { std::lock_guard lock(mutex); if (unused.size() > 0) { T rg = std::move(unused.front()); unused.pop_front(); return rg; } } /* prepare new random generator */ return T(r()); } void free(T&& engine) { std::lock_guard lock(mutex); unused.push_back(engine); } private: std::mutex mutex; std::random_device r; std::list unused; }; template struct RandomEngineGuard { using EngineType = T; RandomEngineGuard(RandomEnginePool& pool) : pool(pool), engine(pool.get()) { } ~RandomEngineGuard() { pool.free(std::move(engine)); } T& get() { return engine; } RandomEnginePool& pool; T engine; }; template typename std::enable_if::value, void>::type randomInit(MA& A, Pool& pool) { using ElementType = typename MA::ElementType; using Index = typename MA::Index; using EngineType = typename Pool::EngineType; std::uniform_real_distribution uniform(-100, 100); RandomEngineGuard guard(pool); auto& engine(guard.get()); hpc::matvec::apply(A, [&](ElementType& val, Index i, Index j) -> void { val = uniform(engine); }); } int main() { using namespace hpc::matvec; using namespace hpc::aux; RandomEnginePool pool; GeMatrix A(51, 7); unsigned int nof_threads = std::thread::hardware_concurrency(); std::vector threads(nof_threads); Slices::Index> slices(nof_threads, A.numRows); for (int index = 0; index < nof_threads; ++index) { auto firstRow = slices.offset(index); auto numRows = slices.size(index); auto A_ = A(firstRow, 0, numRows, A.numCols); threads[index] = std::thread([=,&pool]() mutable { randomInit(A_, pool); }); } for (int index = 0; index < nof_threads; ++index) { threads[index].join(); } print(A, "A"); }