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$