Sample solution

Content

#include <printf.hpp>
#include <hpc/matvec/gematrix.hpp>
#include <hpc/matvec/iterators.hpp>
#include <hpc/matvec/print.hpp>
#include <hpc/matvec/asum.hpp>
#include <hpc/matvec/traits.hpp>
#include <hpc/aux/slices.hpp>
#include <hpc/aux/repool.hpp>

using namespace hpc;
using namespace hpc::aux;
using namespace hpc::matvec;

template <
   template<typename> class MatrixA, typename T,
   typename RandomEnginePool,
   Require< Ge<MatrixA<T>> > = true
>
void randomInit(MatrixA<T>& A, RandomEnginePool& repool) {
   using EngineType = typename RandomEnginePool::EngineType;
   RandomEngineGuard<EngineType> guard(repool);
   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
   }
}

template <
   template<typename> class MatrixA, typename T,
   typename RandomEnginePool,
   Require< Ge<MatrixA<T>> > = true
>
void mt_randomInit(MatrixA<T>& A, RandomEnginePool& repool) {
   #pragma omp parallel for
   for (std::size_t row = 0; row < A.numRows(); ++row) {
      auto A_ = A.block(row, 0).dim(1, A.numCols());
      randomInit(A_, repool);
   }
}

template<typename MA>
auto mt_asum(MA& A) -> decltype(hpc::matvec::asum(A)) {
   using Sum = decltype(hpc::matvec::asum(A));

   Sum sum = 0;
   #pragma omp parallel for reduction(+:sum)
   for (std::size_t row = 0; row < A.numRows(); ++row) {
      auto A_ = A.block(row, 0).dim(1, A.numCols());
      sum += hpc::matvec::asum(A_);
   }
   return sum;
}

int main() {
   RandomEnginePool<std::mt19937> repool(4);

   GeMatrix<double> A(1051, 781);
   mt_randomInit(A, repool);
   fmt::printf("mt_asum: %lg\n", mt_asum(A));
   fmt::printf("asum: %lg\n", hpc::matvec::asum(A));
}
theon$ g++ -O3 -g -I/home/numerik/pub/hpc/ws18/session22 -std=c++17 -fopenmp -o random_init17 random_init17.cpp
theon$ time env OMP_NUM_THREADS=1 ./random_init17
mt_asum: 4.10441e+07
asum: 4.10441e+07

real	0m0.11s
user	0m0.09s
sys	0m0.00s
theon$ time env OMP_NUM_THREADS=4 ./random_init17
mt_asum: 4.10456e+07
asum: 4.10456e+07

real	0m0.08s
user	0m0.15s
sys	0m0.00s
theon$