Sample solution
Content |
#include <cstdlib> #include <list> #include <mutex> #include <random> #include <thread> #include <vector> #include <hpc/aux/slices.hpp> #include <hpc/matvec/gematrix.hpp> #include <hpc/matvec/iterators.hpp> #include <hpc/matvec/print.hpp> using namespace hpc; using namespace hpc::matvec; using namespace hpc::aux; template<typename T> struct RandomEnginePool { using EngineType = T; T get() { /* check if we have a free engine in the unused list */ { std::lock_guard<std::mutex> 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<std::mutex> lock(mutex); unused.push_back(engine); } private: std::mutex mutex; std::random_device r; std::list<T> unused; }; template<typename T> struct RandomEngineGuard { using EngineType = T; RandomEngineGuard(RandomEnginePool<T>& pool) : pool(pool), engine(pool.get()) { } ~RandomEngineGuard() { pool.free(std::move(engine)); } T& get() { return engine; } RandomEnginePool<T>& pool; T engine; }; template < template<typename> class MatrixA, typename T, typename POOL, Require< Ge<MatrixA<T>> > = true > void randomInit(MatrixA<T>& A, POOL& pool) { using EngineType = typename POOL::EngineType; RandomEngineGuard<EngineType> guard(pool); std::uniform_real_distribution<double> uniform(-100, 100); auto& engine = guard.get(); for (auto [i, j, Aij]: A) { Aij = uniform(engine); (void) i; (void) j; // suppress gcc warning } } int main() { RandomEnginePool<std::mt19937> pool; GeMatrix<double> A(51, 7); std::size_t nof_threads = std::thread::hardware_concurrency(); std::vector<std::thread> threads(nof_threads); UniformSlices<std::size_t> slices(nof_threads, A.numRows()); for (std::size_t index = 0; index < nof_threads; ++index) { auto firstRow = slices.offset(index); auto numRows = slices.size(index); threads[index] = std::thread([ A_ = A.view(firstRow, 0, numRows, A.numCols()), &pool ]() mutable { randomInit(A_, pool); }); } for (std::size_t index = 0; index < nof_threads; ++index) { threads[index].join(); } print(A, " %7.2f"); }
theon$ g++ -O3 -g -I/home/numerik/pub/hpc/ws18/session16 -std=c++17 -o random_init11 random_init11.cpp theon$ ./random_init11 52.05 -84.42 -70.41 82.71 42.99 -10.32 -26.67 18.42 -67.41 -98.07 -52.44 32.25 38.25 94.61 -96.13 -95.66 93.61 -14.67 -18.19 1.62 31.80 9.01 -54.77 -67.99 -36.52 25.79 4.47 -50.03 80.51 9.21 -45.58 -57.71 -93.08 -96.91 -64.45 -68.71 -76.98 -6.86 -4.40 -3.40 -42.95 81.60 -22.70 -35.60 -51.70 -75.60 -69.47 25.08 -94.80 -67.77 52.75 -2.80 16.00 -15.22 -71.08 -11.12 79.68 11.78 75.86 83.90 9.78 -86.12 23.36 52.41 65.12 -80.13 -18.31 -58.01 -66.47 -26.16 68.37 56.91 -42.28 -49.31 -87.41 29.05 80.23 73.17 -60.38 -34.49 -17.82 27.98 43.84 -14.49 22.11 -7.32 40.94 -31.15 -11.52 -95.68 75.82 -75.69 -36.68 -74.44 -11.45 -37.08 12.85 -67.06 -71.38 72.95 97.41 37.68 33.07 -86.24 -23.83 44.00 60.54 -86.69 -11.59 27.79 -12.76 -4.94 -5.48 -27.00 20.48 -4.65 -23.89 21.78 81.62 -53.42 -42.26 -63.81 14.61 62.05 -95.61 97.66 -18.66 -82.45 -35.22 83.93 -70.50 41.23 8.53 -76.29 -88.75 37.39 -26.61 -69.61 -81.37 -94.74 -15.67 -28.90 3.77 -89.33 42.83 -32.81 -3.57 60.41 -63.28 -95.06 53.32 -91.42 44.80 76.33 -46.25 24.22 -4.99 -16.86 16.55 40.34 99.24 53.14 12.15 -20.86 14.80 -42.90 -59.19 -84.50 -6.02 46.38 -15.88 95.35 63.49 -12.10 -84.82 96.46 -1.44 1.57 57.75 -89.38 -19.93 0.21 -19.42 73.92 -37.51 13.41 -51.27 13.01 13.74 -65.19 -48.52 80.76 55.04 49.35 -64.61 -56.82 -5.21 64.21 68.86 -53.74 -77.67 97.51 81.25 -23.70 -90.48 1.87 -37.97 -7.07 -53.05 96.32 -40.13 45.47 -38.37 -84.48 -38.19 -80.99 4.82 -71.17 -0.81 -93.29 31.08 26.49 -3.87 -33.61 -95.68 -32.96 8.76 68.92 -78.09 42.14 -38.04 2.82 59.05 -43.83 -95.74 23.91 -21.95 -54.79 -64.45 90.79 -49.29 -42.83 32.07 -46.61 -90.83 35.15 -63.41 43.35 99.42 -91.02 72.04 27.14 -8.49 -38.77 -86.11 79.22 77.04 40.39 75.72 62.94 -26.84 -89.79 -38.39 86.08 44.47 -49.29 -41.06 -97.89 -21.50 85.16 -96.68 64.89 24.91 -5.58 81.60 -12.94 59.97 -5.03 69.06 50.61 67.83 -57.11 46.39 -54.23 -9.37 -88.16 -19.27 -29.50 -2.96 68.65 83.50 53.72 -67.49 -32.26 69.38 -84.02 -10.05 -12.30 76.54 72.94 33.93 -77.29 68.07 -20.85 -76.94 -91.80 2.44 58.24 85.18 -35.56 69.53 -83.92 13.84 -25.58 -28.67 -60.53 -80.18 14.90 -7.27 88.86 81.02 -38.75 35.69 -67.53 13.23 30.54 13.55 -70.63 -89.98 -57.03 -69.84 -36.94 -5.20 44.46 -12.10 28.91 -56.69 77.09 48.39 -43.31 -27.18 27.01 -0.40 -31.97 -50.45 -55.41 -32.06 14.85 86.69 -29.84 -41.44 73.78 -47.88 94.31 32.61 -65.25 -38.40 theon$