Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OpenMP][NFC] Encapsulate profiling logic #74003

Merged
merged 1 commit into from
Nov 30, 2023
Merged

Conversation

jdoerfert
Copy link
Member

This simply puts the profiling logic into the Profiler class and allows non-RAII profiling via beginSection and endSection.

@jdoerfert jdoerfert added openmp openmp:libomptarget OpenMP offload runtime labels Nov 30, 2023
@llvmbot llvmbot added the openmp:libomp OpenMP host runtime label Nov 30, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Nov 30, 2023

@llvm/pr-subscribers-openmp

Author: Johannes Doerfert (jdoerfert)

Changes

This simply puts the profiling logic into the Profiler class and allows non-RAII profiling via beginSection and endSection.


Full diff: https://github.com/llvm/llvm-project/pull/74003.diff

3 Files Affected:

  • (modified) openmp/docs/design/Runtimes.rst (+7)
  • (modified) openmp/libomptarget/include/Shared/Profile.h (+64)
  • (modified) openmp/libomptarget/src/rtl.cpp (+1-14)
diff --git a/openmp/docs/design/Runtimes.rst b/openmp/docs/design/Runtimes.rst
index e7371b34e0350f6..9002fa62348fb16 100644
--- a/openmp/docs/design/Runtimes.rst
+++ b/openmp/docs/design/Runtimes.rst
@@ -708,6 +708,7 @@ variables is defined below.
 
     * ``LIBOMPTARGET_DEBUG=<Num>``
     * ``LIBOMPTARGET_PROFILE=<Filename>``
+    * ``LIBOMPTARGET_PROFILE_GRANULARITY=<Num> (default 500, in us)``
     * ``LIBOMPTARGET_MEMORY_MANAGER_THRESHOLD=<Num>``
     * ``LIBOMPTARGET_INFO=<Num>``
     * ``LIBOMPTARGET_HEAP_SIZE=<Num>``
@@ -749,6 +750,12 @@ for time trace output. Note that this will turn ``libomp`` into a C++ library.
 
 .. _`LLVM Support Library`: https://llvm.org/docs/SupportLibrary.html
 
+LIBOMPTARGET_PROFILE_GRANULARITY
+""""""""""""""""""""""""""""""""
+
+``LIBOMPTARGET_PROFILE_GRANULARITY`` allows to change the time profile
+granularity measured in `us`. Default is 500 (`us`).
+
 LIBOMPTARGET_MEMORY_MANAGER_THRESHOLD
 """""""""""""""""""""""""""""""""""""
 
diff --git a/openmp/libomptarget/include/Shared/Profile.h b/openmp/libomptarget/include/Shared/Profile.h
index bbdefea06d90e85..316b0c3086d0489 100644
--- a/openmp/libomptarget/include/Shared/Profile.h
+++ b/openmp/libomptarget/include/Shared/Profile.h
@@ -10,8 +10,70 @@
 //
 //===----------------------------------------------------------------------===//
 
+#ifndef OMPTARGET_SHARED_PROFILE_H
+#define OMPTARGET_SHARED_PROFILE_H
+
+#include "Shared/Debug.h"
+#include "Shared/EnvironmentVar.h"
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/TimeProfiler.h"
 
+/// Class that holds the singleton profiler and allows to start/end events.
+class Profiler {
+
+  Profiler() {
+    if (!ProfileTraceFile.isPresent())
+      return;
+
+    // TODO: Add an alias without LIBOMPTARGET
+    // Flag to modify the profile granularity (in us).
+    Int32Envar ProfileGranularity =
+        Int32Envar("LIBOMPTARGET_PROFILE_GRANULARITY", 500);
+
+    llvm::timeTraceProfilerInitialize(ProfileGranularity /* us */,
+                                      "libomptarget");
+  }
+
+  ~Profiler() {
+    if (!ProfileTraceFile.isPresent())
+      return;
+
+    if (auto Err = llvm::timeTraceProfilerWrite(ProfileTraceFile.get(), "-"))
+      REPORT("Error writing out the time trace: %s\n",
+             llvm::toString(std::move(Err)).c_str());
+
+    llvm::timeTraceProfilerCleanup();
+  }
+
+  // TODO: Add an alias without LIBOMPTARGET
+  /// Flag to enable profiling which also specifies the file profile information
+  /// is stored in.
+  StringEnvar ProfileTraceFile = StringEnvar("LIBOMPTARGET_PROFILE");
+
+public:
+  static Profiler &get() {
+    static Profiler P;
+    return P;
+  }
+
+  /// Manually begin a time section, with the given \p Name and \p Detail.
+  /// Profiler copies the string data, so the pointers can be given into
+  /// temporaries. Time sections can be hierarchical; every Begin must have a
+  /// matching End pair but they can nest.
+  void beginSection(llvm::StringRef Name, llvm::StringRef Detail) {
+    llvm::timeTraceProfilerBegin(Name, Detail);
+  }
+  void beginSection(llvm::StringRef Name,
+                    llvm::function_ref<std::string()> Detail) {
+    llvm::timeTraceProfilerBegin(Name, Detail);
+  }
+
+  /// Manually end the last time section.
+  void endSection() { llvm::timeTraceProfilerEnd(); }
+};
+
 /// Time spend in the current scope, assigned to the function name.
 #define TIMESCOPE() llvm::TimeTraceScope TimeScope(__FUNCTION__)
 
@@ -34,3 +96,5 @@
   std::string ProfileLocation = SI.getProfileLocation();                       \
   std::string RTM = RegionTypeMsg;                                             \
   llvm::TimeTraceScope TimeScope(__FUNCTION__, ProfileLocation + RTM)
+
+#endif // OMPTARGET_SHARED_PROFILE_H
diff --git a/openmp/libomptarget/src/rtl.cpp b/openmp/libomptarget/src/rtl.cpp
index 09084be12a76e2a..289a3bc552b0cec 100644
--- a/openmp/libomptarget/src/rtl.cpp
+++ b/openmp/libomptarget/src/rtl.cpp
@@ -41,8 +41,6 @@ static const char *RTLNames[] = {
     /* AMDGPU target        */ "libomptarget.rtl.amdgpu",
 };
 
-static char *ProfileTraceFile = nullptr;
-
 #ifdef OMPT_SUPPORT
 extern void ompt::connectLibrary();
 #endif
@@ -64,16 +62,13 @@ __attribute__((constructor(101))) void init() {
 
   PM = new PluginManager(UseEventsForAtomicTransfers);
 
-  ProfileTraceFile = getenv("LIBOMPTARGET_PROFILE");
-  // TODO: add a configuration option for time granularity
-  if (ProfileTraceFile)
-    timeTraceProfilerInitialize(500 /* us */, "libomptarget");
 
 #ifdef OMPT_SUPPORT
   // Initialize OMPT first
   ompt::connectLibrary();
 #endif
 
+  Profiler::get();
   PM->RTLs.loadRTLs();
   PM->registerDelayedLibraries();
 }
@@ -81,14 +76,6 @@ __attribute__((constructor(101))) void init() {
 __attribute__((destructor(101))) void deinit() {
   DP("Deinit target library!\n");
   delete PM;
-
-  if (ProfileTraceFile) {
-    // TODO: add env var for file output
-    if (auto E = timeTraceProfilerWrite(ProfileTraceFile, "-"))
-      fprintf(stderr, "Error writing out the time trace\n");
-
-    timeTraceProfilerCleanup();
-  }
 }
 
 void PluginAdaptorManagerTy::loadRTLs() {

Copy link

github-actions bot commented Nov 30, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

This simply puts the profiling logic into the `Profiler` class and
allows non-RAII profiling via `beginSection` and `endSection`.
@jdoerfert jdoerfert merged commit b8b2a27 into llvm:main Nov 30, 2023
4 checks passed
@jdoerfert jdoerfert deleted the offload_prep3 branch November 30, 2023 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
openmp:libomp OpenMP host runtime openmp:libomptarget OpenMP offload runtime openmp
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants