#include #include #include #include #include #include #include #include #include #include #include template struct RandomEnginePool { using EngineType = T; RandomEnginePool(std::size_t size) : size(size), nof_free_engines(size), inuse(size), engines(size) { std::random_device r; for (std::size_t i = 0; i < size; ++i) { engines[i].seed(r()); inuse[i] = false; } } T& get() { std::unique_lock lock(mutex); if (nof_free_engines == 0) { cv.wait(lock); } for (std::size_t i = 0; i < size; ++i) { if (!inuse[i]) { inuse[i] = true; --nof_free_engines; return engines[i]; } } assert(false); } void free(T& engine) { { std::unique_lock lock(mutex); bool found = false; for (std::size_t i = 0; i < size; ++i) { if (&engine == &engines[i]) { inuse[i] = false; ++nof_free_engines; found = true; break; } } assert(found); } cv.notify_one(); } private: std::mutex mutex; std::condition_variable cv; std::size_t size; std::size_t nof_free_engines; std::vector inuse; std::vector engines; }; template struct RandomEngineGuard { using EngineType = T; RandomEngineGuard(RandomEnginePool& pool) : pool(pool), engine(pool.get()) { } ~RandomEngineGuard() { pool.free(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(2); 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"); }