#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 = 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 typename std::enable_if::value, void>::type randomInit(MA& A, POOL& pool) { using ElementType = typename MA::ElementType; using Index = typename MA::Index; std::uniform_real_distribution uniform(-100, 100); auto engine = pool.get(); hpc::matvec::apply(A, [&](ElementType& val, Index i, Index j) -> void { val = uniform(engine); }); pool.free(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"); }