[llvm-branch-commits] [llvm] users/jplehr/feat/03 ompt upstream device tracing (PR #229410)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Oct 6 05:52:42 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-offload
Author: Jan Patrick Lehr (jplehr)
<details>
<summary>Changes</summary>
Adds the OMPT profiler implementation without wiring it up into the
whole plugins infrastructure yet.
The individual commits do a bit of cleanup from the original port and
to keep up with the changes to `main` in the meantime.
---
<sub>Stack created with <a href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
---
Patch is 29.98 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/229410.diff
7 Files Affected:
- (added) offload/include/OpenMP/OMPT/OmptCommonDefs.h (+128)
- (added) offload/include/OpenMP/OMPT/OmptEventInfoTy.h (+39)
- (modified) offload/plugins-nextgen/common/CMakeLists.txt (+5)
- (added) offload/plugins-nextgen/common/OMPT/OmptDeviceTracing.h (+100)
- (added) offload/plugins-nextgen/common/OMPT/OmptProfiler.cpp (+110)
- (added) offload/plugins-nextgen/common/OMPT/OmptProfiler.h (+122)
- (added) offload/plugins-nextgen/common/OMPT/OmptTracing.cpp (+256)
``````````diff
diff --git a/offload/include/OpenMP/OMPT/OmptCommonDefs.h b/offload/include/OpenMP/OMPT/OmptCommonDefs.h
new file mode 100644
index 000000000000000..8ab2ba10a869337
--- /dev/null
+++ b/offload/include/OpenMP/OMPT/OmptCommonDefs.h
@@ -0,0 +1,128 @@
+//===------ OmptCommonDefs.h - Common definitions for OMPT --*- C++ -*-----===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Common defines and typedefs for OMPT callback and tracing functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef OFFLOAD_INCLUDE_OMPTCOMMONDEFS_H
+#define OFFLOAD_INCLUDE_OMPTCOMMONDEFS_H
+
+#ifdef OMPT_SUPPORT
+
+#include "omp-tools.h"
+
+#pragma push_macro("DEBUG_PREFIX")
+#undef DEBUG_PREFIX
+#define DEBUG_PREFIX "OMPT"
+
+#define FUNCPTR_TO_PTR(x) ((void *)(uint64_t)x)
+
+#define FOREACH_OMPT_TARGET_CALLBACK(macro) \
+ FOREACH_OMPT_DEVICE_EVENT(macro) \
+ FOREACH_OMPT_NOEMI_EVENT(macro) \
+ FOREACH_OMPT_EMI_EVENT(macro)
+
+// Common device tracing functions
+#define FOREACH_OMPT_DEVICE_TRACING_FN_COMMON(macro) \
+ macro(ompt_set_trace_ompt) macro(ompt_start_trace) macro(ompt_flush_trace) \
+ macro(ompt_stop_trace) macro(ompt_advance_buffer_cursor) \
+ macro(ompt_get_record_type)
+
+// Supported device tracing entry points
+#define FOREACH_OMPT_DEVICE_TRACING_FN(macro) \
+ FOREACH_OMPT_DEVICE_TRACING_FN_COMMON(macro) \
+ macro(ompt_get_record_ompt) macro(ompt_get_device_time) \
+ macro(ompt_translate_time)
+
+// Device tracing functionalities, which are also e.g. coupled to mutexes
+#define FOREACH_OMPT_DEVICE_TRACING_FN_IMPLEMENTAIONS(macro) \
+ FOREACH_OMPT_DEVICE_TRACING_FN_COMMON(macro) \
+ macro(ompt_set_timestamp) macro(ompt_set_granted_teams)
+
+#define OMPT_API_ROUTINE static
+
+#define OMPT_CALLBACK_AVAILABLE(fn) (llvm::omp::target::ompt::Initialized && fn)
+
+#define OMPT_IF_BUILT(stmt) stmt
+
+#define OMPT_IF_ENABLED(stmts) \
+ do { \
+ if (llvm::omp::target::ompt::Initialized) { \
+ stmts \
+ } \
+ } while (0)
+
+#define OMPT_IF_TRACING_ENABLED(stmts) \
+ do { \
+ if (llvm::omp::target::ompt::TracingActive) { \
+ stmts \
+ } \
+ } while (0)
+
+#define OMPT_FRAME_FLAGS (ompt_frame_runtime | OMPT_FRAME_POSITION_DEFAULT)
+
+#if (__PPC64__ | __arm__)
+#define OMPT_GET_FRAME_ADDRESS(level) __builtin_frame_address(level)
+#define OMPT_FRAME_POSITION_DEFAULT ompt_frame_cfa
+#else
+#define OMPT_GET_FRAME_ADDRESS(level) __builtin_frame_address(level)
+#define OMPT_FRAME_POSITION_DEFAULT ompt_frame_framepointer
+#endif
+
+#define OMPT_PTR_UNKNOWN ((void *)0)
+
+#define performIfOmptInitialized(stmt) \
+ do { \
+ if (llvm::omp::target::ompt::Initialized) { \
+ stmt; \
+ } \
+ } while (0)
+
+#define performOmptCallback(CallbackName, ...) \
+ do { \
+ if (ompt_callback_##CallbackName##_fn) \
+ ompt_callback_##CallbackName##_fn(__VA_ARGS__); \
+ } while (0)
+
+/// Device-independent OMPT tracing entry points, implemented by libomptarget
+/// and linked into the same library as their plugin-side callers.
+extern "C" {
+ompt_set_result_t libomptarget_ompt_set_trace_ompt(int DeviceId,
+ unsigned int Enable,
+ unsigned int EventTy);
+int libomptarget_ompt_start_trace(int DeviceId,
+ ompt_callback_buffer_request_t Request,
+ ompt_callback_buffer_complete_t Complete);
+int libomptarget_ompt_flush_trace(int DeviceId);
+int libomptarget_ompt_stop_trace(int DeviceId);
+int libomptarget_ompt_advance_buffer_cursor(ompt_device_t *Device,
+ ompt_buffer_t *Buffer, size_t Size,
+ ompt_buffer_cursor_t CurrentPos,
+ ompt_buffer_cursor_t *NextPos);
+ompt_record_t
+libomptarget_ompt_get_record_type(ompt_buffer_t *Buffer,
+ ompt_buffer_cursor_t CurrentPos);
+void libomptarget_ompt_set_granted_teams(uint32_t NumTeams);
+void libomptarget_ompt_set_timestamp(uint64_t Start, uint64_t Stop);
+} // extern "C"
+
+/// Function type def used for maintaining unique target region, target
+/// operations ids
+typedef uint64_t (*IdInterfaceTy)();
+
+#pragma pop_macro("DEBUG_PREFIX")
+
+#else
+#define performIfOmptInitialized(stmt)
+#define OMPT_IF_BUILT(stmt)
+#define OMPT_IF_ENABLED(stmts)
+#define OMPT_IF_TRACING_ENABLED(stmts)
+#endif // OMPT_SUPPORT
+
+#endif // OFFLOAD_INCLUDE_OMPTCOMMONDEFS_H
diff --git a/offload/include/OpenMP/OMPT/OmptEventInfoTy.h b/offload/include/OpenMP/OMPT/OmptEventInfoTy.h
new file mode 100644
index 000000000000000..7124b3a3ff501b2
--- /dev/null
+++ b/offload/include/OpenMP/OMPT/OmptEventInfoTy.h
@@ -0,0 +1,39 @@
+//===- OmptEventInfoTy.h - OMPT specific trace record data ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Data structure used to communicate OMPT specific profiler data from the
+// high-level libomptarget into the vendor-specific plugins
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef OFFLOAD_INCLUDE_OPENMP_OMPT_OMPTEVENTINFOTY_H
+#define OFFLOAD_INCLUDE_OPENMP_OMPT_OMPTEVENTINFOTY_H
+
+#include "Shared/Debug.h"
+
+struct ompt_record_ompt_t;
+
+namespace llvm {
+namespace omp {
+namespace target {
+namespace ompt {
+
+/// Holds info needed to fill asynchronous trace records
+struct OmptEventInfoTy {
+ /// The granted number of teams at runtime
+ uint64_t NumTeams;
+ /// Pointer to the actual buffer storage location
+ ompt_record_ompt_t *TraceRecord;
+};
+
+} // namespace ompt
+} // namespace target
+} // namespace omp
+} // namespace llvm
+
+#endif // OFFLOAD_INCLUDE_OPENMP_OMPT_OMPTEVENTINFOTY_H
diff --git a/offload/plugins-nextgen/common/CMakeLists.txt b/offload/plugins-nextgen/common/CMakeLists.txt
index 19ce102309a7245..556b8ddf3311ca2 100644
--- a/offload/plugins-nextgen/common/CMakeLists.txt
+++ b/offload/plugins-nextgen/common/CMakeLists.txt
@@ -37,6 +37,11 @@ endif()
include(FindLibcCommonUtils)
target_link_libraries(PluginCommon PRIVATE llvm-libc-common-utilities)
+if (TARGET flang_rt.runtime.static)
+ target_link_libraries(PluginCommon PRIVATE flang_rt.runtime.static)
+ target_compile_definitions(PluginCommon PRIVATE OFFLOAD_HAS_FLANG_RT)
+endif()
+
# Define the TARGET_NAME and DEBUG_PREFIX.
target_compile_definitions(PluginCommon PRIVATE
TARGET_NAME=PluginInterface
diff --git a/offload/plugins-nextgen/common/OMPT/OmptDeviceTracing.h b/offload/plugins-nextgen/common/OMPT/OmptDeviceTracing.h
new file mode 100644
index 000000000000000..adc3695b1398761
--- /dev/null
+++ b/offload/plugins-nextgen/common/OMPT/OmptDeviceTracing.h
@@ -0,0 +1,100 @@
+//===- OmptDeviceTracing.h - Target independent OMPT callbacks --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Interface used by target-independent runtimes to coordinate registration and
+// invocation of OMPT tracing functionality.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_OMPTDEVICETRACING_H
+#define OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_OMPTDEVICETRACING_H
+
+#ifdef OMPT_SUPPORT
+
+#include "OpenMP/OMPT/OmptCommonDefs.h"
+
+#include <map>
+#include <mutex>
+
+#pragma push_macro("DEBUG_PREFIX")
+#undef DEBUG_PREFIX
+#define DEBUG_PREFIX "OMPT"
+
+extern void setOmptAsyncCopyProfile(bool Enable);
+extern void setGlobalOmptKernelProfile(void *Device, int Enable);
+extern uint64_t getSystemTimestampInNs();
+
+namespace llvm {
+namespace omp {
+namespace target {
+namespace ompt {
+
+// Declare OMPT device tracing function mutexes
+#define declareOmptTracingFnMutex(Name) extern std::mutex Name##_mutex;
+FOREACH_OMPT_DEVICE_TRACING_FN_IMPLEMENTAIONS(declareOmptTracingFnMutex)
+#undef declareOmptTracingFnMutex
+
+extern std::mutex DeviceIdWritingMutex;
+
+/// Activate tracing on the given device
+void enableDeviceTracing(int DeviceId);
+
+/// Deactivate tracing on the given device
+void disableDeviceTracing(int DeviceId);
+
+/// Set 'start' and 'stop' in trace records
+void setOmptTimestamp(uint64_t StartTime, uint64_t EndTime);
+
+/// Set the linear function correlation between host and device clocks
+void setOmptHostToDeviceRate(double Slope, double Offset);
+
+/// Set / store the number of granted teams in trace records
+void setOmptGrantedNumTeams(uint64_t NumTeams);
+
+/// Lookup the given device pointer and return its RTL device ID
+int getDeviceId(ompt_device_t *Device);
+
+/// Map the given device pointer to the given DeviceId
+void setDeviceId(ompt_device_t *Device, int32_t DeviceId);
+
+/// Rempve the given device pointer from the current mapping
+void removeDeviceId(ompt_device_t *Device);
+
+/// Check whether the provided device is currently traced.
+bool isTracedDevice(int32_t DeviceId);
+
+/// Provide name based lookup for the device tracing functions
+extern ompt_interface_fn_t
+lookupDeviceTracingFn(const char *InterfaceFunctionName);
+
+/// Host to device linear clock correlation
+extern double HostToDeviceSlope;
+
+/// Host to device constant clock offset
+extern double HostToDeviceOffset;
+
+/// Mapping of device pointers to their corresponding RTL device ID
+extern std::map<ompt_device_t *, int32_t> Devices;
+
+/// Mapping of RTL device IDs to their currently enabled tracing event types.
+/// Note: Event type '0' (bit position) indicates if this device is traced.
+extern std::map<int32_t, uint64_t> TracedDevices;
+
+/// OMPT global tracing status. Indicates if at least one device is traced.
+extern bool TracingActive;
+
+} // namespace ompt
+} // namespace target
+} // namespace omp
+} // namespace llvm
+
+#pragma pop_macro("DEBUG_PREFIX")
+
+#endif // OMPT_SUPPORT
+
+#endif // OPENMP_LIBOMPTARGET_PLUGINS_NEXTGEN_COMMON_OMPTDEVICETRACING_H
diff --git a/offload/plugins-nextgen/common/OMPT/OmptProfiler.cpp b/offload/plugins-nextgen/common/OMPT/OmptProfiler.cpp
new file mode 100644
index 000000000000000..d74e6e3b9b82acf
--- /dev/null
+++ b/offload/plugins-nextgen/common/OMPT/OmptProfiler.cpp
@@ -0,0 +1,110 @@
+//===- OmptProfiler.cpp - OMPT impl of GenericProfilerTy --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of OmptProfilerTy
+//
+//===----------------------------------------------------------------------===//
+
+#include "OmptProfiler.h"
+#include "OpenMP/OMPT/Interface.h"
+#include "PluginInterface.h"
+#include "Shared/Debug.h"
+
+#include <memory>
+
+using namespace llvm::omp::target;
+
+void ompt::OmptProfilerTy::handleDataAlloc(uint64_t StartNanos,
+ uint64_t EndNanos, void *HostPtr,
+ uint64_t Size, void *Data) {
+ ompt::setOmptTimestamp(StartNanos, EndNanos);
+}
+
+void ompt::OmptProfilerTy::handleDataDelete(uint64_t StartNanos,
+ uint64_t EndNanos, void *TgtPtr,
+ void *Data) {
+ ompt::setOmptTimestamp(StartNanos, EndNanos);
+}
+
+void ompt::OmptProfilerTy::handlePreKernelLaunch(
+ plugin::GenericDeviceTy *Device, uint32_t NumBlocks[3],
+ __tgt_async_info *AI) {
+ if (!ompt::isTracedDevice(
+ ompt::getDeviceId(reinterpret_cast<ompt_device_t *>(Device))))
+ return;
+
+ if (AI->ProfilerData == nullptr)
+ return;
+
+ auto ProfilerSpecificData =
+ reinterpret_cast<ompt::OmptEventInfoTy *>(AI->ProfilerData);
+ assert(ProfilerSpecificData && "Invalid ProfilerSpecificData");
+ // Set number of granted teams for OMPT
+ setOmptGrantedNumTeams(NumBlocks[0]);
+ ProfilerSpecificData->NumTeams = NumBlocks[0];
+}
+
+void ompt::OmptProfilerTy::handleKernelCompletion(uint64_t StartNanos,
+ uint64_t EndNanos,
+ void *Data) {
+
+ if (!isProfilingEnabled())
+ return;
+
+ // Null data means no trace record was assigned for this event, see
+ // TracerInterfaceRAII in OpenMP/OMPT/Interface.h.
+ if (!Data)
+ return;
+
+ ODBG(ODT_Tool) << "OMPT-Async: Time kernel for asynchronous execution: Start "
+ << StartNanos << " End " << EndNanos;
+
+ auto OmptEventInfo = reinterpret_cast<ompt::OmptEventInfoTy *>(Data);
+ assert(OmptEventInfo && "Invalid OmptEventInfo");
+ assert(OmptEventInfo->TraceRecord && "Invalid TraceRecord");
+
+ ompt::RegionInterface.stopTargetSubmitTraceAsync(OmptEventInfo->TraceRecord,
+ OmptEventInfo->NumTeams,
+ StartNanos, EndNanos);
+
+ // Done processing, our responsibility to free the memory
+ freeProfilerDataEntry(OmptEventInfo);
+}
+
+void ompt::OmptProfilerTy::handleDataTransfer(uint64_t StartNanos,
+ uint64_t EndNanos, void *Data) {
+
+ if (!isProfilingEnabled())
+ return;
+
+ // Null data means no trace record was assigned for this event, see
+ // TracerInterfaceRAII in OpenMP/OMPT/Interface.h.
+ if (!Data)
+ return;
+
+ ODBG(ODT_Tool) << "OMPT-Async: Time data for asynchronous execution: Start "
+ << StartNanos << " End " << EndNanos;
+
+ auto OmptEventInfo = reinterpret_cast<ompt::OmptEventInfoTy *>(Data);
+ assert(OmptEventInfo && "Invalid OmptEventInfo");
+ assert(OmptEventInfo->TraceRecord && "Invalid TraceRecord");
+
+ ompt::RegionInterface.stopTargetDataMovementTraceAsync(
+ OmptEventInfo->TraceRecord, StartNanos, EndNanos);
+
+ // Done processing, our responsibility to free the memory
+ freeProfilerDataEntry(OmptEventInfo);
+}
+
+bool ompt::OmptProfilerTy::isProfilingEnabled() { return ompt::TracingActive; }
+
+void ompt::OmptProfilerTy::setTimeConversionFactorsImpl(double Slope,
+ double Offset) {
+ ODBG(ODT_Tool) << "Using Time Slope: " << Slope << " and Offset: " << Offset;
+ setOmptHostToDeviceRate(Slope, Offset);
+}
diff --git a/offload/plugins-nextgen/common/OMPT/OmptProfiler.h b/offload/plugins-nextgen/common/OMPT/OmptProfiler.h
new file mode 100644
index 000000000000000..4c2c90e3f385add
--- /dev/null
+++ b/offload/plugins-nextgen/common/OMPT/OmptProfiler.h
@@ -0,0 +1,122 @@
+//===- OmptProfiler.h - OMPT specific impl of GenericProfilerTy -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// OMPT specific implementation of the GenericProfilerTy class.
+// This class uses the already existing implementation of OMPT to invoke
+// callbacks and perform tracing.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef OFFLOAD_PLUGINS_NEXTGEN_COMMON_OMPT_OMPTPROFILERTY_H
+#define OFFLOAD_PLUGINS_NEXTGEN_COMMON_OMPT_OMPTPROFILERTY_H
+
+#include "GenericProfiler.h"
+
+#include "OmptDeviceTracing.h"
+#include "OpenMP/OMPT/Callback.h"
+#include "OpenMP/OMPT/OmptEventInfoTy.h"
+#include "Shared/Debug.h"
+#include "omp-tools.h"
+
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <tuple>
+
+#pragma push_macro("DEBUG_PREFIX")
+#undef DEBUG_PREFIX
+#define DEBUG_PREFIX "OMPT"
+
+extern uint64_t getSystemTimestampInNs();
+
+using namespace llvm::omp::target::debug;
+
+namespace llvm {
+namespace omp {
+namespace target {
+namespace plugin {
+struct GenericDeviceTy;
+class GenericProfilerTy;
+
+} // namespace plugin
+
+namespace ompt {
+
+/**
+ * Implements an OMPT backend for the Profiler interface used in the plugins.
+ *
+ * Forwards / Implements the different generic hooks with OMPT semantics.
+ */
+class OmptProfilerTy : public plugin::GenericProfilerTy {
+public:
+ bool isProfilingEnabled() override;
+
+ void handleDataAlloc(uint64_t StartNanos, uint64_t EndNanos, void *HostPtr,
+ uint64_t Size, void *Data) override;
+ void handleDataDelete(uint64_t StartNanos, uint64_t EndNanos, void *TgtPtr,
+ void *Data) override;
+
+ void handlePreKernelLaunch(plugin::GenericDeviceTy *Device,
+ uint32_t NumBlocks[3],
+ __tgt_async_info *AI) override;
+
+ void handleKernelCompletion(uint64_t StartNanos, uint64_t EndNanos,
+ void *Data) override;
+
+ void handleDataTransfer(uint64_t StartNanos, uint64_t EndNanos,
+ void *Data) override;
+
+ void setTimeConversionFactorsImpl(double Slope, double Offset) override;
+
+ /// Allocate the event info that carries \p Record into the plugins for
+ /// asynchronous completion. The profiler owns the returned object and frees
+ /// it via freeProfilerDataEntry once the plugin completed the record.
+ OmptEventInfoTy *trackAsyncRecord(ompt_record_ompt_t *Record) {
+ // TODO: This is ID is not used currently
+ uint64_t Id = OmptProfDataId.fetch_add(1);
+ std::scoped_lock<std::mutex> Lock(ProfilerDataMutex);
+ auto &Info = ProfilerData[Id];
+ Info = std::make_unique<OmptEventInfoTy>();
+ Info->TraceRecord = Record;
+ Info->NumTeams = 0;
+ return Info.get();
+ }
+
+ void freeProfilerDataEntry(OmptEventInfoTy *DataPtr) {
+ std::scoped_lock<std::mutex> Lock(ProfilerDataMutex);
+
+ for (auto &Entry : ProfilerData)
+ if (Entry.second.get() == DataPtr) {
+ ProfilerData.erase(Entry.first);
+ break;
+ }
+ }
+
+private:
+ /// Holds a unique ID for each allocation of OmptEventInfoTy
+ std::atomic<uint64_t> OmptProfDataId{0};
+
+ /// Holds memory used to store OMPT specific data and pass it down from
+ /// libomptarget into the plugins.
+ std::map<uint64_t, std::unique_ptr<OmptEventInfoTy>> ProfilerData;
+
+ /// Lock to guard STL ProfilerData map
+ std::mutex ProfilerDataMutex;
+};
+
+/// Process-wide OMPT profile...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/229410
More information about the llvm-branch-commits
mailing list