Task Dependency in OpenMP 4

∥☆過路亽.° 提交于 2019-12-18 13:37:52

问题


The following code works based on the OpenMP 4.0 specification:

The out and inout dependence-types. The generated task will be a dependent task of all previously generated sibling tasks that reference at least one of the list items in an in, out, or inout dependence-type list.

This means that task3 becomes dependent of task2. Right? but it does not make sense! Why should an input-output dependency task be a dependent of an input dependency task?

What do I need to do in order to make them independent? p.s: code tested with g++ 4.9 on Linux.

#include <stdio.h>
#include <omp.h>
#include <unistd.h>
int main() {
int x,y;
#pragma omp parallel num_threads(10)
{
#pragma omp single nowait
 {
#pragma omp task depend (out:x)  //task1
  {
        x=1;
  }
#pragma omp task depend(in:x) depend(out:y)  //task2
  {
        sleep(2); //Does task3 wait for us? Yes!
        y=x+1;
  }
#pragma omp task depend (inout:x)  //task3
  {
        x++;
        printf("task3(x): %d\n" , x);
  }
#pragma omp task depend (in:x,y)  //task4
 {
        printf("task4 (x+y): %d\n" , x+y);
 }
 }
}
return 0;
}

回答1:


Question 1 : This means that task3 becomes dependent of task2. Right?

According to the OpenMP 4.0 standard on the depend clause (emphasis mine):

Task dependences are derived from the dependence-type of a depend clause and its list items, where dependence-type is one of the following:

The in dependence-type. The generated task will be a dependent task of all previously generated sibling tasks that reference at least one of the list items in an out or inout dependence-type list.

The out and inout dependence-types. The generated task will be a dependent task of all previously generated sibling tasks that reference at least one of the list items in an in, out, or inout dependence-type list.

From this description follows that:

  • the clause depend(in:x) will generate a task dependent on all the previously generated tasks with depend(out:x) or depend(inout:x)
  • the clause depend(out:x) or the clause depend(inoout:x) will generate a task dependent on all the previously generated tasks mentioning x in a depend clause

Applying this to your specific case gives a chain of dependencies of this kind:

       task1 (out:x) -> task2 (in:x,out:y) -> task4 (in:x,y)
                                   |            ^
                                   |            |
                                   > task3 (inout:x)   

Therefore task3 depends on the completion of task2.


Question 2 : Why should an input-output dependency task be a dependent of an input dependency task?

I would just let you notice that with this rule you will have a deterministic value of your variables x and y at the end of the run (assuming you take care of synchronizing accesses to memory). If task3 was dependent on task1 instead of task2, this determinism wouldn't hold (and an inout dependency would have been equivalent to an in dependency).


Question 3 : What do I need to do in order to make them independent?

Turn the inout:x dependency into an in:x dependency and synchronize accesses to x via atomic clauses. That way you will have runs in which either:

  • x == 2 and y == 2
  • x == 2 and y == 3

depending on whether task2 executes before task3 or not.



来源:https://stackoverflow.com/questions/27475174/task-dependency-in-openmp-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!