Sample solution
Content |
#include <condition_variable> #include <cstdlib> #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::aux; using namespace hpc::matvec; template<typename T> 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<std::mutex> lock(mutex); while (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); #pragma GCC diagnostic ignored "-Wreturn-type" } void free(T& engine) { { std::unique_lock<std::mutex> 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<bool> inuse; std::vector<T> engines; }; template<typename T> struct RandomEngineGuard { using EngineType = T; RandomEngineGuard(RandomEnginePool<T>& pool) : pool(pool), engine(pool.get()) { } ~RandomEngineGuard() { pool.free(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(2); 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/ws19/session16 -std=c++17 -o random_init12 random_init12.cpp theon$ ./random_init12 55.55 -24.56 -53.22 -36.93 -24.37 95.24 -85.57 99.69 80.71 90.21 23.76 28.01 -85.29 14.89 24.56 -2.35 79.40 -4.20 -4.62 -68.32 91.19 -17.51 81.92 39.06 57.78 -9.05 -68.66 94.46 95.26 82.23 -94.44 -26.16 -49.74 -93.82 27.99 30.67 -20.29 39.59 48.55 -65.42 70.88 -63.57 -18.62 1.75 -49.44 -72.32 -4.90 71.37 28.86 -31.85 70.55 -79.60 -88.74 -45.72 17.50 -33.11 93.60 -79.61 21.40 -48.87 -47.52 68.44 19.03 -1.20 -60.08 -8.59 -83.05 -4.79 21.24 93.49 -44.49 56.17 -59.99 -86.20 54.53 28.02 -16.12 -17.46 -46.28 -56.26 26.36 -16.70 56.47 91.33 -80.06 3.88 65.81 32.83 80.89 37.69 38.18 -66.94 47.48 89.78 -56.17 22.64 -77.18 54.91 -25.33 -82.47 -24.33 41.34 11.41 -48.41 11.52 -2.70 53.15 -2.86 -46.03 -53.47 -86.52 24.98 38.13 -41.45 79.71 71.13 -86.28 -61.74 93.02 -38.92 -92.38 -97.95 27.42 -15.91 -67.52 90.64 92.32 13.56 21.99 23.72 -73.62 -60.10 -49.68 -74.13 -87.93 -58.11 49.64 90.60 -75.37 -96.44 -48.12 90.80 -84.17 -10.92 -73.86 -69.37 15.54 40.78 -49.91 -8.44 -2.93 -77.48 76.11 88.15 56.88 9.13 -27.55 14.26 -72.24 93.32 -83.04 -33.57 84.42 -37.81 -38.97 -96.26 96.69 -52.90 54.84 19.00 -32.40 5.84 91.75 -4.19 29.12 -62.06 0.27 75.55 -45.01 88.35 29.60 40.84 -69.50 13.86 78.75 26.99 -84.21 27.68 -58.66 -17.12 -26.63 54.09 65.59 -63.95 -18.63 -53.92 10.29 -2.07 -57.78 -79.29 -86.53 8.72 -67.08 -43.27 11.38 96.02 -23.98 51.29 55.85 -37.95 -69.37 46.24 95.96 -99.66 35.33 46.21 -50.24 58.36 67.01 -93.13 80.80 -73.74 -33.26 -88.14 -66.20 -40.66 -1.18 45.46 -52.92 -52.21 -56.25 81.51 -2.58 -5.06 -3.29 60.51 5.91 -9.33 -26.04 69.11 -63.56 -7.77 -32.59 -70.13 -49.02 49.33 24.89 -30.54 2.40 -64.08 -72.10 -27.67 -87.95 -43.21 -38.05 -6.73 -65.84 77.63 -10.53 6.88 10.83 6.09 60.76 64.41 84.98 -96.02 74.86 32.40 -24.49 24.58 25.63 -85.85 -49.77 -75.04 95.04 -4.90 -2.45 -3.44 -86.59 -23.09 -21.07 -47.51 0.46 -40.76 47.19 2.24 -50.49 -57.06 -18.37 52.48 -3.56 -52.95 -37.09 -12.88 7.33 -76.64 -61.93 62.93 -69.24 41.91 19.60 -19.12 37.42 26.79 74.94 83.41 44.88 -6.02 -61.30 99.42 -22.57 -54.60 -6.27 -56.46 57.24 27.03 22.84 -1.78 28.89 -96.99 82.67 50.01 16.43 -84.37 -90.88 72.34 47.06 -62.42 1.83 -7.17 77.28 -11.34 45.84 74.46 80.67 26.10 81.04 -54.60 45.54 14.35 -91.69 -42.62 5.28 -37.98 1.89 2.70 7.84 3.69 27.98 88.62 26.93 75.21 -58.04 -41.25 38.34 -16.00 -16.63 theon$
heim$ g++-8.3 -O3 -g -I/home/numerik/pub/hpc/ws19/session16 -std=c++17 -o random_init12 random_init12.cpp -lpthread heim$ ./random_init12 83.66 -21.34 59.38 67.76 26.95 -97.11 -17.81 -78.66 -31.66 -92.73 -10.35 65.44 -84.74 -22.36 45.73 34.54 -21.90 52.54 -45.71 -43.01 71.66 94.88 96.28 -70.99 -55.68 -46.39 -16.78 -56.06 65.52 -75.20 1.38 -56.44 86.41 56.60 43.26 -22.49 -9.82 14.98 10.12 -4.93 -31.88 57.13 -76.22 78.90 -51.66 -37.26 -72.62 -36.54 -1.77 -90.37 -46.85 75.38 18.68 97.45 46.72 74.83 -34.74 -88.05 68.64 -11.84 4.14 -72.69 22.24 -77.86 -10.33 -64.31 -7.66 24.18 61.12 -29.95 72.38 -20.14 85.72 -50.77 -61.47 -12.23 31.17 35.86 -60.32 -78.97 -69.72 -35.16 -38.06 -4.75 12.31 77.88 4.77 -58.36 34.67 -95.00 -25.60 -27.69 90.88 -51.79 -48.00 -48.19 84.83 71.08 -4.89 57.86 -65.29 -77.99 60.46 1.68 -1.95 -57.43 35.26 -10.49 -28.55 -87.34 64.40 49.97 29.77 -36.97 69.84 -79.83 -40.66 -24.86 70.53 -60.03 -8.66 63.00 34.85 -81.81 43.92 -8.30 11.02 -7.98 -48.22 33.40 24.48 96.64 54.62 -34.71 24.61 -55.39 -70.76 -85.26 -63.05 79.64 92.45 -74.81 -71.40 51.98 -11.15 17.87 -95.83 79.50 -37.64 -44.36 -6.77 23.36 34.54 -14.41 52.18 -95.59 -81.10 -2.16 -62.06 58.53 -41.18 -25.23 2.44 73.66 34.18 88.99 38.40 -73.78 -31.58 95.13 -81.54 -5.72 89.73 -1.39 85.97 62.66 -73.92 13.37 81.88 9.62 -44.71 34.37 17.54 74.21 -12.23 42.57 -40.69 -31.65 7.07 -37.69 -53.61 37.81 -49.91 -27.88 -6.46 41.64 -21.92 -34.55 11.13 98.77 -96.76 -87.78 -6.89 53.58 45.36 -59.22 52.23 -54.31 47.97 -95.55 89.56 -29.48 11.94 -67.55 -56.76 13.98 -68.86 41.78 69.01 -11.59 -65.49 -62.95 36.00 -23.38 -74.97 -13.38 -18.05 92.21 -88.42 -5.68 -20.36 -18.35 -47.46 -35.70 74.14 60.39 86.25 -87.95 -69.56 -73.98 -30.39 -39.63 -18.41 42.16 67.14 -14.73 -90.89 -41.68 10.29 -38.96 -9.36 9.68 -88.25 -19.53 7.23 64.11 -74.72 -46.00 -39.69 -40.90 25.33 40.53 96.71 -85.46 -21.03 -6.77 -78.24 57.50 64.80 -77.77 -71.88 -41.70 20.92 -14.07 2.63 -97.95 10.12 64.20 -78.81 -73.31 45.36 99.02 41.73 78.91 -21.01 -63.71 55.27 -23.69 -44.54 71.65 -78.70 40.33 27.00 -81.92 74.20 -69.04 -9.94 -33.51 -50.35 -85.16 -77.61 92.68 94.41 -78.18 36.84 17.02 6.63 5.44 -58.46 70.77 42.08 37.84 -38.32 -21.65 -57.01 6.47 11.89 -32.25 16.42 71.64 -83.63 20.57 -90.94 72.96 36.64 -71.61 61.60 -29.14 -6.17 -25.83 -48.74 60.55 -59.70 58.57 -32.41 30.58 97.79 -10.68 -72.10 50.47 77.91 79.46 79.77 93.31 54.49 -29.19 -57.39 -23.22 45.67 -78.57 -6.83 -59.18 4.31 43.21 -10.32 51.38 -37.76 heim$