<feed xmlns='http://www.w3.org/2005/Atom'>
<title>llvm-project.git/openmp/runtime/src/kmp_taskdeps.cpp, branch main</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/'/>
<entry>
<title>[OpenMP] Fix taskgraph dependency tracking, memory access, and initialization (#136837)</title>
<updated>2025-04-25T08:17:07+00:00</updated>
<author>
<name>Josep Pinot</name>
<email>jsp.pinot@gmail.com</email>
</author>
<published>2025-04-25T08:17:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=ada4ad9d1f5580476918d490cb51382714cb2973'/>
<id>ada4ad9d1f5580476918d490cb51382714cb2973</id>
<content type='text'>
This commit resolves multiple issues in the OpenMP taskgraph implementation:
- Fix a potential use of uninitialized is_taskgraph and tdg fields when a task is created outside of a taskgraph construct.
- Fix use of task ID field when accessing the taskgraph’s record_map.
- Fix resizing and copying of the successors array when its capacity is exceeded.

Fixes memory management flaws, invalid memory accesses, and uninitialized data risks in taskgraph operations.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This commit resolves multiple issues in the OpenMP taskgraph implementation:
- Fix a potential use of uninitialized is_taskgraph and tdg fields when a task is created outside of a taskgraph construct.
- Fix use of task ID field when accessing the taskgraph’s record_map.
- Fix resizing and copying of the successors array when its capacity is exceeded.

Fixes memory management flaws, invalid memory accesses, and uninitialized data risks in taskgraph operations.</pre>
</div>
</content>
</entry>
<entry>
<title>[OpenMP] [Taskgraph] Differentiating task ids from the taskgraph and from the debugger (#130660)</title>
<updated>2025-03-12T18:39:02+00:00</updated>
<author>
<name>Rémy Neveu</name>
<email>95233708+rneveu@users.noreply.github.com</email>
</author>
<published>2025-03-12T18:39:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=3aa96f52cff3dfedba428d70fb2c55798b39e1b3'/>
<id>3aa96f52cff3dfedba428d70fb2c55798b39e1b3</id>
<content type='text'>
This PR creates a new member for task data, which is used to identify
the task in its taskgraph (when ompx taskgraph is enabled).
It aims to remove the overloading of the td_task_id member, which was
used both by the debugger and the taskgraph. This resulted in the
identifier's non-unicity in the case of multiple taskgraphs.

Co-authored-by: Rémy Neveu &lt;rem2007@free.fr&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This PR creates a new member for task data, which is used to identify
the task in its taskgraph (when ompx taskgraph is enabled).
It aims to remove the overloading of the td_task_id member, which was
used both by the debugger and the taskgraph. This resulted in the
identifier's non-unicity in the case of multiple taskgraphs.

Co-authored-by: Rémy Neveu &lt;rem2007@free.fr&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>[OpenMP][runtime] Fix comparison of integer expressions of different signedness (#128204)</title>
<updated>2025-03-03T07:54:57+00:00</updated>
<author>
<name>foxtran</name>
<email>39676482+foxtran@users.noreply.github.com</email>
</author>
<published>2025-03-03T07:54:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=3f48d34dfffac81bc73db626438f531c5324f85b'/>
<id>3f48d34dfffac81bc73db626438f531c5324f85b</id>
<content type='text'>
This PR fixes warning which occurs if one compiles OpenMP runtime with
GCC:
```
warning: comparison of integer expressions of different signedness: 'kmp_intptr_t' {aka 'long int'} and 'long unsigned int' [-Wsign-compare]
```</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This PR fixes warning which occurs if one compiles OpenMP runtime with
GCC:
```
warning: comparison of integer expressions of different signedness: 'kmp_intptr_t' {aka 'long int'} and 'long unsigned int' [-Wsign-compare]
```</pre>
</div>
</content>
</entry>
<entry>
<title>[OpenMP] Fix crash with task stealing and task dependencies (#126049)</title>
<updated>2025-02-14T09:55:59+00:00</updated>
<author>
<name>Julian Brown</name>
<email>julian.brown@amd.com</email>
</author>
<published>2025-02-10T10:20:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=2fdf191e244b62409fd73fa9bb717466d6e683b5'/>
<id>2fdf191e244b62409fd73fa9bb717466d6e683b5</id>
<content type='text'>
This patch series demonstrates and fixes a bug that causes crashes with
OpenMP 'taskwait' directives in heavily multi-threaded scenarios.

TLDR: The early return from __kmpc_omp_taskwait_deps_51 missed the
synchronization mechanism in place for the late return.

Additional debug assertions check for the implied invariants of the code.

@jpeyton52 found the timing hole as this sequence of events:
&gt;
&gt; 1. THREAD 1: A regular task with dependences is created, call it T1
&gt; 2. THREAD 1: Call into `__kmpc_omp_taskwait_deps_51()` and create a stack
based depnode (`NULL` task), call it T2 (stack)
&gt; 3. THREAD 2: Steals task T1 and executes it getting to
`__kmp_release_deps()` region.
&gt; 4. THREAD 1: During processing of dependences for T2 (stack) (within
`__kmp_check_deps()` region),  a link is created T1 -&gt; T2. This increases
T2's (stack) `nrefs` count.
&gt; 5. THREAD 2: Iterates through the successors list: decrement the T2's
(stack) npredecessor count. BUT HASN'T YET `__kmp_node_deref()`-ed it.
&gt; 6. THREAD 1: Now when finished with `__kmp_check_deps()`, it returns false
because npredecessor count is 0, but T2's (stack) `nrefs`  count is 2 because
THREAD 2 still references it!
&gt; 7. THREAD 1: Because `__kmp_check_deps()` returns false, early exit.
&gt;    _Now the stack based depnode is invalid, but THREAD 2 still references it._
&gt;
&gt; We've reached improper stack referencing behavior. Varied results/crashes/
asserts can occur if THREAD 1 comes back and recreates the exact same depnode
in the exact same stack address during the same time THREAD 2 calls
`__kmp_node_deref()`.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch series demonstrates and fixes a bug that causes crashes with
OpenMP 'taskwait' directives in heavily multi-threaded scenarios.

TLDR: The early return from __kmpc_omp_taskwait_deps_51 missed the
synchronization mechanism in place for the late return.

Additional debug assertions check for the implied invariants of the code.

@jpeyton52 found the timing hole as this sequence of events:
&gt;
&gt; 1. THREAD 1: A regular task with dependences is created, call it T1
&gt; 2. THREAD 1: Call into `__kmpc_omp_taskwait_deps_51()` and create a stack
based depnode (`NULL` task), call it T2 (stack)
&gt; 3. THREAD 2: Steals task T1 and executes it getting to
`__kmp_release_deps()` region.
&gt; 4. THREAD 1: During processing of dependences for T2 (stack) (within
`__kmp_check_deps()` region),  a link is created T1 -&gt; T2. This increases
T2's (stack) `nrefs` count.
&gt; 5. THREAD 2: Iterates through the successors list: decrement the T2's
(stack) npredecessor count. BUT HASN'T YET `__kmp_node_deref()`-ed it.
&gt; 6. THREAD 1: Now when finished with `__kmp_check_deps()`, it returns false
because npredecessor count is 0, but T2's (stack) `nrefs`  count is 2 because
THREAD 2 still references it!
&gt; 7. THREAD 1: Because `__kmp_check_deps()` returns false, early exit.
&gt;    _Now the stack based depnode is invalid, but THREAD 2 still references it._
&gt;
&gt; We've reached improper stack referencing behavior. Varied results/crashes/
asserts can occur if THREAD 1 comes back and recreates the exact same depnode
in the exact same stack address during the same time THREAD 2 calls
`__kmp_node_deref()`.
</pre>
</div>
</content>
</entry>
<entry>
<title>[OpenMP][OMPT] Add missing callbacks for asynchronous target tasks (#93472)</title>
<updated>2024-06-04T15:07:15+00:00</updated>
<author>
<name>Joachim</name>
<email>jenke@itc.rwth-aachen.de</email>
</author>
<published>2024-06-04T15:07:15+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=2464f1cef3d28182da42debe6abf9bad8ab5a4d2'/>
<id>2464f1cef3d28182da42debe6abf9bad8ab5a4d2</id>
<content type='text'>
- The first hidden-helper-thread did not trigger thread-begin
- The "detaching" from a target-task when waiting for completion missed
to call task-switch
- Target tasks identified themself as explicit task

Co-authored-by: Kaloyan Ignatov &lt;kaloyan.ignatov@rwth-aachen.de&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- The first hidden-helper-thread did not trigger thread-begin
- The "detaching" from a target-task when waiting for completion missed
to call task-switch
- Target tasks identified themself as explicit task

Co-authored-by: Kaloyan Ignatov &lt;kaloyan.ignatov@rwth-aachen.de&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>[OpenMP] Fix node destruction race in __kmpc_omp_taskwait_deps_51 (#86130)</title>
<updated>2024-03-28T11:15:39+00:00</updated>
<author>
<name>Ulrich Weigand</name>
<email>ulrich.weigand@de.ibm.com</email>
</author>
<published>2024-03-28T11:15:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=b999e631c03640f7d1d93b5319da496ed4e0df55'/>
<id>b999e631c03640f7d1d93b5319da496ed4e0df55</id>
<content type='text'>
The __kmpc_omp_taskwait_deps_51 allocates a kmp_depnode_t node on its
stack, and there is currently a race condition where another thread
might still be accessing that node after the function has returned and
its stack frame was released.

While the function does wait until the node's npredecessors count has
reached zero before exiting, there is still a window where the function
that last decremented the npredecessors count assumes the node is still
accessible.

For heap-allocated kmp_depnode_t nodes, this normally works via a
separate ndeps count that only reaches zero at the point where no
accesses to the node are expected at all; in fact, at this point the
heap allocation will be freed.

For this case of a stack-allocated kmp_depnode_t node, it therefore
makes sense to similarly respect the ndeps count; we need to wait until
this reaches 1 (not 0, because it is not heap-allocated so there's
always one extra count to prevent it from being freed), before we can
safely deallocate our stack frame.

As this is expected to be a short race window of only a few
instructions, it should be fine to just use a busy wait loop checking
the ndeps count.

Fixes: https://github.com/llvm/llvm-project/issues/85963</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The __kmpc_omp_taskwait_deps_51 allocates a kmp_depnode_t node on its
stack, and there is currently a race condition where another thread
might still be accessing that node after the function has returned and
its stack frame was released.

While the function does wait until the node's npredecessors count has
reached zero before exiting, there is still a window where the function
that last decremented the npredecessors count assumes the node is still
accessible.

For heap-allocated kmp_depnode_t nodes, this normally works via a
separate ndeps count that only reaches zero at the point where no
accesses to the node are expected at all; in fact, at this point the
heap allocation will be freed.

For this case of a stack-allocated kmp_depnode_t node, it therefore
makes sense to similarly respect the ndeps count; we need to wait until
this reaches 1 (not 0, because it is not heap-allocated so there's
always one extra count to prevent it from being freed), before we can
safely deallocate our stack frame.

As this is expected to be a short race window of only a few
instructions, it should be fine to just use a busy wait loop checking
the ndeps count.

Fixes: https://github.com/llvm/llvm-project/issues/85963</pre>
</div>
</content>
</entry>
<entry>
<title>[OpenMP] Optimized trivial multiple edges from task dependency graph</title>
<updated>2023-11-21T17:36:12+00:00</updated>
<author>
<name>Joachim Jenke</name>
<email>jenke@itc.rwth-aachen.de</email>
</author>
<published>2023-11-21T17:36:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=f5e50b21da0cb543064b2d0b9304ce0b368cf2bb'/>
<id>f5e50b21da0cb543064b2d0b9304ce0b368cf2bb</id>
<content type='text'>
From "3.1 Reducing the number of edges" of this [[ https://hal.science/hal-04136674v1/ | paper ]] - Optimization (b)

Task (dependency) nodes have a `successors` list built upon passed dependency.
Given the following code, B will be added to A's successors list building the graph `A` -&gt; `B`
```
// A
 # pragma omp task depend(out: x)
{}

// B
 # pragma omp task depend(in: x)
{}
```

In the following code, B is currently added twice to A's successor list
```
// A
 # pragma omp task depend(out: x, y)
{}

// B
 # pragma omp task depend(in: x, y)
{}
```

This patch removes such dupplicates by checking lastly inserted task in `A` successor list.

Authored by: Romain Pereira (rpereira-dev)
Differential Revision: https://reviews.llvm.org/D158544
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
From "3.1 Reducing the number of edges" of this [[ https://hal.science/hal-04136674v1/ | paper ]] - Optimization (b)

Task (dependency) nodes have a `successors` list built upon passed dependency.
Given the following code, B will be added to A's successors list building the graph `A` -&gt; `B`
```
// A
 # pragma omp task depend(out: x)
{}

// B
 # pragma omp task depend(in: x)
{}
```

In the following code, B is currently added twice to A's successor list
```
// A
 # pragma omp task depend(out: x, y)
{}

// B
 # pragma omp task depend(in: x, y)
{}
```

This patch removes such dupplicates by checking lastly inserted task in `A` successor list.

Authored by: Romain Pereira (rpereira-dev)
Differential Revision: https://reviews.llvm.org/D158544
</pre>
</div>
</content>
</entry>
<entry>
<title>[OpenMP] Add OMPT support for omp_all_memory task dependence</title>
<updated>2023-07-07T11:44:53+00:00</updated>
<author>
<name>Joachim Jenke</name>
<email>jenke@itc.rwth-aachen.de</email>
</author>
<published>2023-07-07T11:19:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=6ef16f2618093e3f3def6e905437013de71785f5'/>
<id>6ef16f2618093e3f3def6e905437013de71785f5</id>
<content type='text'>
omp_all_memory currently has no representation in OMPT.

Adding new dependency flags as suggested by omp-lang issue #3007.

Differential Revision: https://reviews.llvm.org/D111788
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
omp_all_memory currently has no representation in OMPT.

Adding new dependency flags as suggested by omp-lang issue #3007.

Differential Revision: https://reviews.llvm.org/D111788
</pre>
</div>
</content>
</entry>
<entry>
<title>[OpenMP] Implement task record and replay mechanism</title>
<updated>2023-05-15T15:00:55+00:00</updated>
<author>
<name>Chenle Yu</name>
<email>chenle.yu@bsc.es</email>
</author>
<published>2023-05-15T14:56:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=36d4e4c9b5f6cd0577b6029055b825caaec2dd11'/>
<id>36d4e4c9b5f6cd0577b6029055b825caaec2dd11</id>
<content type='text'>
This patch implements the "task record and replay" mechanism.  The idea is to be able to store tasks and their dependencies in the runtime so that we do not pay the cost of task creation and dependency resolution for future executions. The objective is to improve fine-grained task performance, both for those from "omp task" and "taskloop".

The entry point of the recording phase is __kmpc_start_record_task, and the end of record is triggered by __kmpc_end_record_task.

Tasks encapsulated between a record start and a record end are saved, meaning that the runtime stores their dependencies and structures, referred to as TDG, in order to replay them in subsequent executions. In these TDG replays, we start the execution by scheduling all root tasks (tasks that do not have input dependencies), and there will be no involvement of a hash table to track the dependencies, yet tasks do not need to be created again.

At the beginning of __kmpc_start_record_task, we must check if a TDG has already been recorded. If yes, the function returns 0 and starts to replay the TDG by calling __kmp_exec_tdg; if not, we start to record, and the function returns 1.

An integer uniquely identifies TDGs. Currently, this identifier needs to be incremented manually in the source code. Still, depending on how this feature would eventually be used in the library, the caller function must do it; also, the caller function needs to implement a mechanism to skip the associated region, according to the return value of __kmpc_start_record_task.

Reviewed By: tianshilei1992

Differential Revision: https://reviews.llvm.org/D146642
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch implements the "task record and replay" mechanism.  The idea is to be able to store tasks and their dependencies in the runtime so that we do not pay the cost of task creation and dependency resolution for future executions. The objective is to improve fine-grained task performance, both for those from "omp task" and "taskloop".

The entry point of the recording phase is __kmpc_start_record_task, and the end of record is triggered by __kmpc_end_record_task.

Tasks encapsulated between a record start and a record end are saved, meaning that the runtime stores their dependencies and structures, referred to as TDG, in order to replay them in subsequent executions. In these TDG replays, we start the execution by scheduling all root tasks (tasks that do not have input dependencies), and there will be no involvement of a hash table to track the dependencies, yet tasks do not need to be created again.

At the beginning of __kmpc_start_record_task, we must check if a TDG has already been recorded. If yes, the function returns 0 and starts to replay the TDG by calling __kmp_exec_tdg; if not, we start to record, and the function returns 1.

An integer uniquely identifies TDGs. Currently, this identifier needs to be incremented manually in the source code. Still, depending on how this feature would eventually be used in the library, the caller function must do it; also, the caller function needs to implement a mechanism to skip the associated region, according to the return value of __kmpc_start_record_task.

Reviewed By: tianshilei1992

Differential Revision: https://reviews.llvm.org/D146642
</pre>
</div>
</content>
</entry>
<entry>
<title>[OpenMP] Remove uses of ATOMIC_VAR_INIT</title>
<updated>2023-02-24T22:47:55+00:00</updated>
<author>
<name>Fangrui Song</name>
<email>i@maskray.me</email>
</author>
<published>2023-02-24T22:47:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=46262cab24312c71717ca70a9d0700481aa59152'/>
<id>46262cab24312c71717ca70a9d0700481aa59152</id>
<content type='text'>
ATOMIC_VAR_INIT has a trivial definition
`#define ATOMIC_VAR_INIT(value) (value)`,
is deprecated in C17/C++20, and will be removed in newer standards in
newer GCC/Clang (e.g. https://reviews.llvm.org/D144196).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
ATOMIC_VAR_INIT has a trivial definition
`#define ATOMIC_VAR_INIT(value) (value)`,
is deprecated in C17/C++20, and will be removed in newer standards in
newer GCC/Clang (e.g. https://reviews.llvm.org/D144196).
</pre>
</div>
</content>
</entry>
</feed>
