In have this class:
template <typename C, typename R, typename D>
class myClass{
public:
R Query(const C &query);
...
private:
struct Compare{
D val;
size_t index;
};
#pragma omp declare reduction(minimum : Compare : omp_out = omp_in.val < omp_out.val ? omp_in : omp_out)
std::vector<C> values;
...
}
template <typename C, typename R, typename D>
R Cache<C,R,D>::Query(const C &query){
Compare min;
R result;
if(!values.empty()){
#pragma omp parallel for reduction(minimum:min)
for(size_t i=1; i<values.size(); i++){
D d = distance->compute(query, values[i]);
std::cout<<" distance("<<query<<" "<<values[i].code<<")= "<<d;
if(d < min.val){
std::cout<<" NEW MIN!";
min.val = d;
min.index = i;
}
std::cout<<std::endl;
}
std::cout<<"min.val="<<min.val<<std::endl;
}
...
D d = distance->compute(query, values[i]);
value is correct (and the following print too).
However, for some weird reason, everytime that the parallel for
is computed, min.val
is 0
(in few words the last cout
prints always min.val=0
).
Obviously this is not the whole code and I made it as simple as possible.
The initializer is not needed at all If you initialize the struct inside the parallel block
You are missing the initalizer for user declared reduction:
Alternatively, you can add a member initialization:
This is more general and will make sure the program works correctly even without
-fopenmp
.