the_naive
the_naive

Reputation: 3064

Is "final" clause of "task" directive correctly?

I'm trying to understand how to make final clause of the task actually work and I found the following example of code in this link.

#include <stdio.h>
#include <omp.h>

#define THRESHOLD 5

int fib(int n)
{
  int i, j;

  if (n<2)
  return n;

  #pragma omp task shared(i) firstprivate(n) final(n <= THRESHOLD)
  i=fib(n-1);

  #pragma omp task shared(j) firstprivate(n) final(n <= THRESHOLD)
  j=fib(n-2);

  #pragma omp taskwait
  return i+j;
}


int main()
{
  int n = 30;
  omp_set_dynamic(0);
  omp_set_num_threads(4);

  #pragma omp parallel shared(n)
  {
     #pragma omp single
     printf ("fib(%d) = %d\n", n, fib(n));
  }
}

But when I check the value of n by debugging, I notice that apparently the recursive functions are still being called even when the condition n <= THRESHOLD is true. So, my question is, am I misunderstanding something or the there's something wrong with the code?

Upvotes: 3

Views: 2039

Answers (1)

Henkersmann
Henkersmann

Reputation: 1220

What happens when you call final is that the tasks that are spawned out of this one do not make a new task out of it.

From Specification:

[§ 2.10.1 task Construct] When a final clause is present on a task construct and the final clause expression evaluates to true, the generated task will be a final task. All task constructs encountered during execution of a final task will generate final and included tasks. Note that the use of a variable in a final clause expression of a task construct causes an implicit reference to the variable in all enclosing constructs.

Where a final task is:

A task that forces all of its child tasks to become final and included tasks.

and included task is:

A task for which execution is sequentially included in the generating task region. That is, an included task is undeferred and executed immediately by the encountering thread.

In your case that means: if in this task the THREASHOLD is met there are new tasks genereated with n-1 and n-2 are spawned and those tasks do not generate new tasks when coming to the recursive call but do still call the functions in 'old fashioned' function call way.

Upvotes: 5

Related Questions