It is fairly straight forward to do a user declared reduction for C++ vectors of a specific type:
#include <algorithm>
#include <vector>
#pragma omp declare reduction(vec_float_plus : std::vector<float> :
std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<float>()))
initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
std::vector<float> res(n,0);
#pragma omp parallel for reduction(vec_float_plus : res)
for(size_t i=0; i<m; i++){
res[...] += ...;
}
1a) Not knowing m
at compile time is not a requirement.
1b) You cannot use the array section reduction on std::vector
s, because they are not arrays (and std::vector::data
is not an identifier). If it were possible, you'd have to use n
, as this is the number of elements in the array section.
2) As long as you are only reading indexes
and vals
, there is no issue.
Edit: The original initializer
caluse was simpler: initializer(omp_priv = omp_orig)
. However, if the original copy is then not full of zeroes, the result will be wrong. Therefore, I suggest the more complicated initializer which always creates zero-element vectors.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…