#include "mylib.h" #include // assert() #include #include #include // multiplies<>{} #include #include // iota() #ifdef _OPENMP #include #endif #include using namespace std; double scalar_parallel(vector const &x, vector const &y) { assert(x.size() == y.size()); // switch off via compile flag: -DNDEBUG size_t const N = x.size(); double sum = 0.0; #pragma omp parallel default(none) shared(x,y,N, cout) reduction(+:sum) { const size_t nthreads = omp_get_num_threads(); const size_t threadnum = omp_get_thread_num(); const size_t chunksize = N/nthreads; size_t start = threadnum*chunksize; size_t end = start + chunksize; if (threadnum == nthreads - 1) end = N; for (size_t i = start; i < end; ++i) { sum += x[i] * y[i]; } } return sum; } vector reduction_vec_append(int n) { vector vec(n); #pragma omp parallel default(none) shared(cout) reduction(VecAppend:vec) { #pragma omp barrier #pragma omp critical cout << omp_get_thread_num() << " : " << vec.size() << endl; #pragma omp barrier iota( vec.begin(),vec.end(), omp_get_thread_num() ); #pragma omp barrier } return vec; } double scalar(vector const &x, vector const &y) { assert(x.size() == y.size()); // switch off via compile flag: -DNDEBUG size_t const N = x.size(); double sum = 0.0; #pragma omp parallel for default(none) shared(x,y,N) reduction(+:sum) schedule(runtime) // added schedule(runtime) for (size_t i = 0; i < N; ++i) { sum += x[i] * y[i]; //sum += exp(x[i])*log(y[i]); } return sum; } double norm(vector const &x) { size_t const N = x.size(); double sum = 0.0; #pragma omp parallel for default(none) shared(x,N) reduction(+:sum) schedule(runtime) // added schedule(runtime) for (size_t i = 0; i < N; ++i) { sum += x[i]*x[i]; } return sum; } vector reduction_vec(int n) { vector vec(n); #pragma omp parallel default(none) shared(cout) reduction(VecAdd:vec) { #pragma omp barrier #pragma omp critical cout << omp_get_thread_num() << " : " << vec.size() << endl; #pragma omp barrier iota( vec.begin(),vec.end(), omp_get_thread_num() ); #pragma omp barrier } return vec; } double scalar_trans(vector const &x, vector const &y) { assert(x.size() == y.size()); // switch off via compile flag: -DNDEBUG vector z(x.size()); //list z(x.size()); // parallel for-loop on iterators not possible (missing 'operator-') // c++-20 CLANG_, ONEAPI_:condition of OpenMP for loop must be a relational comparison transform(cbegin(x),cend(x),cbegin(y),begin(z),std::multiplies<>{}); double sum = 0.0; #pragma omp parallel for default(none) shared(z) reduction(+:sum) schedule(runtime) // added schedule(runtime) for (auto pi = cbegin(z); pi!=cend(z); ++pi) { sum += *pi; } //for (auto val: z) //{ //sum += val; //} return sum; }