93 lines
3 KiB
C++
93 lines
3 KiB
C++
#pragma once
|
|
#include <cassert>
|
|
#include <iomanip> // setw()
|
|
#include <iostream>
|
|
#include <omp.h>
|
|
#include <vector>
|
|
|
|
/** Inner product
|
|
@param[in] x vector
|
|
@param[in] y vector
|
|
@return resulting Euclidian inner product <x,y>
|
|
*/
|
|
double scalar(std::vector<double> const &x, std::vector<double> const &y);
|
|
double scalar_manual(std::vector<double> const &x, std::vector<double> const &y);
|
|
double scalar_trans(std::vector<double> const &x, std::vector<double> const &y);
|
|
|
|
|
|
/** l2-norm
|
|
@param[in] x vector
|
|
@return resulting Euclidian norm
|
|
*/
|
|
double norm(std::vector<double> const &x);
|
|
|
|
/** Vector @p b adds its elements to vector @p a .
|
|
@param[in] a vector
|
|
@param[in] b vector
|
|
@return a+=b componentwise
|
|
*/
|
|
template<class T>
|
|
std::vector<T> &operator+=(std::vector<T> &a, std::vector<T> const &b)
|
|
{
|
|
assert(a.size()==b.size());
|
|
for (size_t k = 0; k < a.size(); ++k) {
|
|
a[k] += b[k];
|
|
}
|
|
return a;
|
|
}
|
|
|
|
// Declare the reduction operation in OpenMP for an STL-vector
|
|
// omp_out += omp_in requires operator+=(vector<int> &, vector<int> const &) from above
|
|
// ------------------------------------------------------------
|
|
// https://scc.ustc.edu.cn/zlsc/tc4600/intel/2016.0.109/compiler_c/common/core/GUID-7312910C-D175-4544-99C5-29C12D980744.htm
|
|
// https://gist.github.com/eruffaldi/7180bdec4c8c9a11f019dd0ba9a2d68c
|
|
// https://stackoverflow.com/questions/29633531/user-defined-reduction-on-vector-of-varying-size
|
|
// see also p.74ff in https://www.fz-juelich.de/ias/jsc/EN/AboutUs/Staff/Hagemeier_A/docs-parallel-programming/OpenMP-Slides.pdf
|
|
#pragma omp declare reduction(VecAdd : std::vector<int> : omp_out += omp_in) \
|
|
initializer (omp_priv=omp_orig)
|
|
|
|
#pragma omp declare reduction (VecAppend : std::vector<int> : \
|
|
omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end())) \
|
|
initializer (omp_priv = omp_orig)
|
|
|
|
// Templates are n o t possible, i.e. the reduction has to be declared fore a specified type.
|
|
//template <class T>
|
|
//#pragma omp declare reduction(VecAdd : std::vector<T> : omp_out += omp_in) initializer (omp_priv(omp_orig))
|
|
// MS: template nach #pragma !?
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
|
|
/** Test for vector reduction.
|
|
*
|
|
* The thread-private vectors of size @p n are initialized via @f$v_k^{tID}=tID+k@f$.
|
|
* Afterwards these vectors are accumulated, i.e.,
|
|
* @f$v_k= \sum_{tID=0}^{numThreads} v_k^{tID}@f$.
|
|
*
|
|
* @param[in] n size of global/private vector
|
|
* @return resulting global vector.
|
|
*/
|
|
std::vector<int> reduction_vec(int n);
|
|
|
|
|
|
/** Test for vector reduction with appending the local vectors to a global
|
|
* size of global vector: n*#threads
|
|
*
|
|
* @param[in] n size of local/private vector
|
|
* @return resultign global vector
|
|
*/
|
|
std::vector<int> reduction_vec_append(int n);
|
|
|
|
|
|
/** Output of a vector.
|
|
@param[in,out] s output stream
|
|
@param[in] x vector
|
|
@return modified output stream
|
|
*/
|
|
template <class T>
|
|
std::ostream &operator<<(std::ostream &s, std::vector<T> const &x)
|
|
{
|
|
for (auto const &v : x) s << std::setw(4) << v << " ";
|
|
return s;
|
|
}
|
|
|