Ajit Jadhav
Ajit Jadhav

Reputation: 11

Why every time getting different output in openmp code?

Every time I execute cal() function with the same parameter I get different output. Function g() always calculate the same result for same input. Are threads overwriting any variable?

void cal(uint_fast64_t n) {
    Bint num = N(n);
    Bint total = 0, i, max_size(__UINT64_MAX__);
    for(i = 1; i <= num; i+= max_size){
        #pragma omp parallel shared(i,num,total)  
        { 
            int id = omp_get_thread_num();
            int numthreads = omp_get_num_threads();
            Bint sum(0), k;
            for(uint64_t j = id; (j < __UINT64_MAX__); j+=numthreads){
                k = i+j;
                if(k > num){
                    i = k;
                    break;
                }
                sum = sum + g(k);
            }
            #pragma omp critical
                total += sum;
        }
    }
    std::cout << total << std::endl;
}

Upvotes: 0

Views: 297

Answers (2)

Max Langhof
Max Langhof

Reputation: 23711

if(k > num){
    i = k;
    break;
}

Here you modify the shared variable i (possibly multiple times in parallel) while other threads may be reading from it (for k = i+j), all without synchronization. This is a race condition and your code thus has Undefined Behavior.

Upvotes: 7

Alexis Wilke
Alexis Wilke

Reputation: 20818

The value of j depends on the value of id. If different threads are used to do the math, you'll get different results.

        int id = omp_get_thread_num();      // <---
        int numthreads = omp_get_num_threads();
        Bint sum(0), k;
        for(uint64_t j = id; (j < __UINT64_MAX__); j+=numthreads){  // <---
            k = i+j;
            if(k > num){
                i = k;      // <---
                break;
            }
            sum = sum + g(k);

Further, you change i to k when k > num. This can happen much sooner or much later depending on which thread is picked up first to run the inner loop.

You may want to look at this question and answer.

Does an OpenMP ordered for always assign parts of the loop to threads in order, too?

Upvotes: 3

Related Questions