[llvm-branch-commits] [openmp] release/22.x: [OpenMP][OMPT] Fix `omp_control_tool` before any directive (#191429) (PR #192062)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Apr 14 06:56:30 PDT 2026
https://github.com/llvmbot created https://github.com/llvm/llvm-project/pull/192062
Backport c6bcd19
Requested by: @jprotze
>From 1f06cd11e311e9296272c391dca4c86708812d02 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Andr=C3=A9=20Reuter?= <j.reuter at fz-juelich.de>
Date: Fri, 10 Apr 2026 17:07:07 +0200
Subject: [PATCH] [OpenMP][OMPT] Fix `omp_control_tool` before any directive
(#191429)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When a user calls `omp_control_tool`, a tool is attached and it
registered the `ompt_control_tool` callback, the tool should receive a
callback with the users arguments.
However, in #112924, it was discovered that this only happens after at
least one host side directive or runtime call calling into
`__kmp_do_middle_initialize` has been executed.
The check for `__kmp_init_middle` in `FTN_CONTROL_TOOL` did not try to
do the middle initialization and instead always returned `-2` (no tool).
A tool therefore received no callback. The user program did not get the
info that there is a tool attached. To fix this, change the explicit
return to a call of `__kmp_middle_initialize()`, as done in several
other places of `libomp`.
Further handling is then done in `__kmp_control_tool`, where the values
`-2` (no tool), `-1` (no callback), or the tools return value are
returned.
Also expand the tests to introduce checks where no callaback is
registered, or `omp_control_tool` is called before any OpenMP directive.
Fixes #112924
CC @jprotze, @hansangbae
Signed-off-by: Jan André Reuter <j.reuter at fz-juelich.de>
(cherry picked from commit c6bcd194259e276aacadae8ac0d25680afc9489d)
---
openmp/runtime/src/kmp_ftn_entry.h | 2 +-
openmp/runtime/test/ompt/callback.h | 2 +
openmp/runtime/test/ompt/misc/control_tool.c | 5 ++-
.../ompt/misc/control_tool_before_directive.c | 43 +++++++++++++++++++
.../test/ompt/misc/control_tool_no_callback.c | 29 +++++++++++++
.../ompt/misc/control_tool_no_ompt_support.c | 10 ++++-
6 files changed, 88 insertions(+), 3 deletions(-)
create mode 100644 openmp/runtime/test/ompt/misc/control_tool_before_directive.c
create mode 100644 openmp/runtime/test/ompt/misc/control_tool_no_callback.c
diff --git a/openmp/runtime/src/kmp_ftn_entry.h b/openmp/runtime/src/kmp_ftn_entry.h
index 6adf60e7ad210..dc57a6a74668e 100644
--- a/openmp/runtime/src/kmp_ftn_entry.h
+++ b/openmp/runtime/src/kmp_ftn_entry.h
@@ -387,7 +387,7 @@ int FTN_STDCALL FTN_CONTROL_TOOL(int command, int modifier, void *arg) {
#else
OMPT_STORE_RETURN_ADDRESS(__kmp_entry_gtid());
if (!TCR_4(__kmp_init_middle)) {
- return -2;
+ __kmp_middle_initialize();
}
kmp_info_t *this_thr = __kmp_threads[__kmp_entry_gtid()];
ompt_task_info_t *parent_task_info = OMPT_CUR_TASK_INFO(this_thr);
diff --git a/openmp/runtime/test/ompt/callback.h b/openmp/runtime/test/ompt/callback.h
index cd8acb57ee2f7..bc4ce8b2c72df 100644
--- a/openmp/runtime/test/ompt/callback.h
+++ b/openmp/runtime/test/ompt/callback.h
@@ -1055,7 +1055,9 @@ int ompt_initialize(ompt_function_lookup_t lookup, int initial_device_num,
ompt_callback_sync_region_t);
register_ompt_callback_t(ompt_callback_reduction,
ompt_callback_sync_region_t);
+#ifndef _OMPT_DISABLE_CONTROL_TOOL
register_ompt_callback(ompt_callback_control_tool);
+#endif
register_ompt_callback(ompt_callback_flush);
register_ompt_callback(ompt_callback_cancel);
register_ompt_callback(ompt_callback_implicit_task);
diff --git a/openmp/runtime/test/ompt/misc/control_tool.c b/openmp/runtime/test/ompt/misc/control_tool.c
index 4b671e9eeab4d..e4b0c82f83cbd 100644
--- a/openmp/runtime/test/ompt/misc/control_tool.c
+++ b/openmp/runtime/test/ompt/misc/control_tool.c
@@ -6,14 +6,16 @@
#define TEST_NEED_PRINT_FRAME_FROM_OUTLINED_FN
#include "callback.h"
#include <omp.h>
+#include <stdio.h>
int main() {
#pragma omp parallel num_threads(1)
{
print_frame_from_outlined_fn(1);
print_frame(0);
- omp_control_tool(omp_control_tool_flush, 1, NULL);
+ int result = omp_control_tool(omp_control_tool_flush, 1, NULL);
print_current_address(0);
+ printf("control_tool result = %d\n", result);
}
// clang-format off
@@ -26,6 +28,7 @@ int main() {
// CHECK: {{^}}[[MASTER_ID]]: __builtin_frame_address(0)=[[REENTER_FRAME:(0x)?[0-f]*]]
// CHECK: {{^}}[[MASTER_ID]]: ompt_event_control_tool: command=3, modifier=1, arg=[[NULL]], codeptr_ra=[[RETURN_ADDRESS:(0x)?[0-f]*]], current_task_frame.exit=[[EXIT_FRAME]], current_task_frame.reenter={{(0x)?[0-f]*}}
// CHECK-NEXT: {{^}}[[MASTER_ID]]: current_address={{.*}}[[RETURN_ADDRESS]]
+ // CHECK-NEXT: control_tool result = 0
// clang-format on
return 0;
diff --git a/openmp/runtime/test/ompt/misc/control_tool_before_directive.c b/openmp/runtime/test/ompt/misc/control_tool_before_directive.c
new file mode 100644
index 0000000000000..52c3a21bbebcb
--- /dev/null
+++ b/openmp/runtime/test/ompt/misc/control_tool_before_directive.c
@@ -0,0 +1,43 @@
+// clang-format off
+// RUN: %libomp-compile-and-run | FileCheck %s
+// REQUIRES: ompt
+// UNSUPPORTED: gcc-4, gcc-5, gcc-6, gcc-7
+// clang-format on
+#define TEST_NEED_PRINT_FRAME_FROM_OUTLINED_FN
+#include "callback.h"
+#include <omp.h>
+#include <stdio.h>
+
+int main() {
+ int result = omp_control_tool(omp_control_tool_flush, 1, NULL);
+ printf("control_tool result = %d\n", result);
+
+#pragma omp parallel num_threads(1)
+ {
+ print_frame_from_outlined_fn(1);
+ print_frame(0);
+ print_current_address(0);
+ }
+
+ result = omp_control_tool(omp_control_tool_flush, 1, NULL);
+ printf("control_tool result = %d\n", result);
+
+ // clang-format off
+
+ // Check if libomp allows interacting with an attached tool both before and after the first
+ // directive is being used.
+
+ // CHECK-NOT: {{^}}0: Could not register callback 'ompt_callback_control_tool'
+
+ // CHECK: 0: NULL_POINTER=[[NULL:.*$]]
+
+ // CHECK: {{^}}[[MASTER_ID:[0-9]+]]: ompt_event_control_tool: command=3, modifier=1, arg=[[NULL]], codeptr_ra={{(0x)?[0-f]*}}, current_task_frame.exit={{.*}}, current_task_frame.reenter={{(0x)?[0-f]*}}
+ // CHECK-NEXT: control_tool result = 0
+
+ // CHECK: {{^}}[[MASTER_ID]]: ompt_event_control_tool: command=3, modifier=1, arg=[[NULL]], codeptr_ra={{(0x)?[0-f]*}}, current_task_frame.exit={{.*}}, current_task_frame.reenter={{(0x)?[0-f]*}}
+ // CHECK-NEXT: control_tool result = 0
+
+ // clang-format on
+
+ return 0;
+}
diff --git a/openmp/runtime/test/ompt/misc/control_tool_no_callback.c b/openmp/runtime/test/ompt/misc/control_tool_no_callback.c
new file mode 100644
index 0000000000000..c1cff24cfa43a
--- /dev/null
+++ b/openmp/runtime/test/ompt/misc/control_tool_no_callback.c
@@ -0,0 +1,29 @@
+// clang-format off
+// RUN: %libomp-compile-and-run | FileCheck %s
+// REQUIRES: ompt
+// UNSUPPORTED: gcc-4, gcc-5, gcc-6, gcc-7
+// clang-format on
+#define TEST_NEED_PRINT_FRAME_FROM_OUTLINED_FN
+#define _OMPT_DISABLE_CONTROL_TOOL
+#include "callback.h"
+#include <omp.h>
+#include <stdio.h>
+
+int main() {
+#pragma omp parallel num_threads(1)
+ {
+ int result = omp_control_tool(omp_control_tool_flush, 1, NULL);
+ printf("control_tool result = %d\n", result);
+ }
+
+ // clang-format off
+ // Check if libomp returns -1 (no callback) when a tool is attached,
+ // but ompt_callback_control_tool is not registered
+
+ // CHECK: 0: NULL_POINTER=[[NULL:.*$]]
+ // CHECK: control_tool result = -1
+
+ // clang-format on
+
+ return 0;
+}
diff --git a/openmp/runtime/test/ompt/misc/control_tool_no_ompt_support.c b/openmp/runtime/test/ompt/misc/control_tool_no_ompt_support.c
index 276d7c4c77f1a..86602ff2ffaca 100644
--- a/openmp/runtime/test/ompt/misc/control_tool_no_ompt_support.c
+++ b/openmp/runtime/test/ompt/misc/control_tool_no_ompt_support.c
@@ -3,12 +3,20 @@
// clang-format on
#include <omp.h>
+#include <stdio.h>
int main() {
#pragma omp parallel num_threads(1)
{
- omp_control_tool(omp_control_tool_flush, 1, NULL);
+ int result = omp_control_tool(omp_control_tool_flush, 1, NULL);
+ printf("control_tool result = %d\n", result);
}
+ // clang-format off
+ // Check if libomp correctly reports -2 (no tool) if no tool is attached.
+
+ // CHECK: control_tool result = -2
+ // clang-format on
+
return 0;
}
More information about the llvm-branch-commits
mailing list