[llvm] [Offload] Add GenericProfilerTy abstraction and APITypes extensions (PR #225639)

Alex Duran via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 23 06:27:12 PDT 2026


================
@@ -0,0 +1,197 @@
+//===- GenericProfiler.h - GenericProfiler interface for use in Plugins ---===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// The GenericProfiler interface allows to implement profiler logic for various
+// backends, such as OMPT or other tracing mechanisms.
+// This enables the plugins to be agnostic of the actual high-level language
+// that is implemented.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef OFFLOAD_PLUGINS_NEXTGEN_COMMON_INCLUDE_GENERICPROFILER_H
+#define OFFLOAD_PLUGINS_NEXTGEN_COMMON_INCLUDE_GENERICPROFILER_H
+
+#include "Shared/APITypes.h"
+
+#include <cstdint>
+#include <functional>
+#include <tuple>
+
+class OmptTracingBufferMgr;
+
+namespace llvm {
+namespace omp {
+namespace target {
+namespace plugin {
+
+struct GenericDeviceTy;
+struct GenericPluginTy;
+class GenericProfilerTy;
+
+template <typename FunT, typename... ArgsT, size_t... IdxSequence>
+void callViaIndexSeq(FunT F, GenericProfilerTy *P, uint64_t StartNanos,
+                     uint64_t EndNanos, std::tuple<ArgsT...> Args,
+                     std::index_sequence<IdxSequence...>) {
+  F(P, StartNanos, EndNanos, std::get<IdxSequence>(Args)...);
+}
+
+template <typename FunT, typename... ArgsT>
+void callViaUnpack(FunT F, GenericProfilerTy *P, uint64_t StartNanos,
+                   uint64_t EndNanos, std::tuple<ArgsT...> Tup) {
+  callViaIndexSeq(F, P, StartNanos, EndNanos, Tup,
+                  std::index_sequence_for<ArgsT...>{});
+}
+
+/// Abstraction layer to implement different profiler backends.
+///
+/// The plugins call into the GenericProfilerTy to handle the specific events
+/// with whatever specific backend was instantiated. For now, the supported
+/// backends are limited to an OMPT implementation.
+class GenericProfilerTy {
+public:
+  GenericProfilerTy() = default;
+  virtual ~GenericProfilerTy() = default;
+
+  /// Obtain a pointer to profiler-specific data, if any.
+  virtual void *getProfilerSpecificData() { return nullptr; }
+
+  /// Obtain the trace record manager owned by this profiler, if any. Profilers
+  /// that produce trace records own the manager so that the records handed out
+  /// cannot outlive the buffers they point into.
+  virtual OmptTracingBufferMgr *getTraceRecordManager() { return nullptr; }
+
+  virtual bool isProfilingEnabled() { return false; }
+
+  /// Set the factors which are used to interpolate the device clock compared to
+  /// the host clock. This follows a simple linear interpolation: Slope * <time>
+  /// + Offset.
+  void setTimeConversionFactors(double Slope, double Offset) {
+    HostToDeviceSlope = Slope;
+    HostToDeviceOffset = Offset;
+    setTimeConversionFactorsImpl(HostToDeviceSlope, HostToDeviceOffset);
+  }
+
+  /// Hook that is called when the plugin is initialized.
+  virtual void handleInit(GenericDeviceTy *Device, GenericPluginTy *Plugin) {}
+
+  /// Hook that is called when the plugin is de-initialized.
+  virtual void handleDeinit(GenericDeviceTy *Device, GenericPluginTy *Plugin) {}
+
+  /// Hook that is called when the device image is loaded.
+  virtual void handleLoadBinary(GenericDeviceTy *Device,
+                                GenericPluginTy *Plugin,
+                                const StringRef InputTgtImage) {}
+
+  /// Hook that is called when memory is allocated on the device.
+  virtual void handleDataAlloc(uint64_t StartNanos, uint64_t EndNanos,
+                               void *HostPtr, uint64_t Size, void *Data) {}
+
+  /// Hook that is called when memory is freed on the device.
+  virtual void handleDataDelete(uint64_t StartNanos, uint64_t EndNanos,
+                                void *TgtPtr, void *Data) {}
+
+  /// Hook that is called before launching a kernel.
+  virtual void handlePreKernelLaunch(GenericDeviceTy *Device,
+                                     uint32_t NumBlocks[3],
+                                     __tgt_async_info *AI) {}
+
+  /// Hook that is called when the kernel is finished to extract the specific
+  /// timing info for that kernel execution.
+  virtual void handleKernelCompletion(uint64_t StartNanos, uint64_t EndNanos,
+                                      void *Data) {}
+
+  /// Hook that is called when a data transfer happens to extract timing info
+  /// for that transfer.
+  virtual void handleDataTransfer(uint64_t StartNanos, uint64_t EndNanos,
+                                  void *Data) {}
+
+  /// Allow factors for time conversion between host and device.
+  virtual void setTimeConversionFactorsImpl(double Slope, double Offset) {}
+
+  /// RAII style timer that measures the elapsed time between construction and
+  /// destruction, then invokes a callback with the profiler, start/end times,
+  /// and any captured arguments.
+  template <typename FnT, typename... ArgsT> class ProfTimerTy {
+  public:
+    ProfTimerTy(FnT &&F, GenericProfilerTy *P, GenericDeviceTy *D, ArgsT... As)
+        : Fun(F), Prof(P), Dev(D), Args(As...) {
+      assert(Prof && "GenericProfilerTy is null");
+      assert(Dev && "GenericDeviceTy is null");
+      if (Prof)
+        StartTime = Prof->getDeviceTimeStamp(Dev);
+    }
+
+    ~ProfTimerTy() {
+      assert(Prof && "GenericProfilerTy is null");
+      assert(Dev && "GenericDeviceTy is null");
+      if (Prof) {
+        uint64_t EndTime = Prof->getDeviceTimeStamp(Dev);
+        callViaUnpack(Fun, Prof, StartTime, EndTime, Args);
+      }
+    }
+
+  private:
+    FnT Fun;
----------------
adurang wrote:

Definitely! Thanks!

https://github.com/llvm/llvm-project/pull/225639


More information about the llvm-commits mailing list