Openmp: check if parallesim is nested

Suppose I have a method that multiplies two std::vector:

double multiply(std::vector<double> const& a, std::vector<double> const& b){
    double tmp(0);
    /*here I could easily do a parallelization with*/
    /*#pragma omp parallel loop for*/
    for(unsigned int i=0;i<a.size();i++){
        tmp += a[i]*b[i];
    }
    return tmp;
}

If I set the pragma macro in this function, the call multiply(...)will be launched on all threads.

Now suppose that somewhere else I want to do a lot of vector multiplication:

void many_multiplication(std::vector<double>* a, std::vector<double>* b, unsigned int N){
    /*here I could easily do a parallelization with*/
    /*#pragma omp parallel loop for*/
    for(unsigned int i=0;i<N;i++){
        for(unsigned int j=0;j<N;j++){
            multiply(a[i],b[j]);
        }
    }
}

I could do parallelization too. But this will lead to unwanted nested parallelism.

How can I verify that if multiply(..)called in a parallel scope, then the macro is pragma multiply(...)disabled. And if it is called from a non-parallel area, then it "turns on".

+4
source share
2 answers

parallelism ​​ , , OMP_NESTED true omp_set_nested(1); (§2.3.2 OpenMP) , , . :

double multiply(std::vector<double> const& a, std::vector<double> const& b){
    double tmp(0);
    int active_levels = omp_get_active_level();
    #pragma omp parallel for reduction(+:tmp) if(active_level < 1)
    for(unsigned int i=0;i<a.size();i++){
        tmp += a[i]+b[i];
    }
    return tmp;
}

omp_get_active_level() , . 0, . if(active_level < 1) , , , .

OpenMP 3.0 (, MS Visual C/++ Compiler), omp_in_parallel():

double multiply(std::vector<double> const& a, std::vector<double> const& b){
    double tmp(0);
    int in_parallel = omp_in_parallel();
    #pragma omp parallel for reduction(+:tmp) if(in_parallel == 0)
    for(unsigned int i=0;i<a.size();i++){
        tmp += a[i]+b[i];
    }
    return tmp;
}

omp_in_parallel() , , , .

, . , , , parallelism .

+5

. parallelism omp_set_nested(int val) ( , ).

, , parallelism , many_multiplication, many_multiplication :

void many_multiplication(std::vector<double>* a, std::vector<double>* b, unsigned int N){
    omp_set_nested(0);
    #pragma omp parallel loop for
    for(unsigned int i=0;i<N;i++){
        for(unsigned int j=0;j<N;j++){
            multiply(a[i],b[j]);
        }
    }
    omp_set_nested(1);
}
+1

Source: https://habr.com/ru/post/1598722/


All Articles