[Openmp-commits] [openmp] [OpenMP] Add ompTest library to OpenMP (PR #147381)

Jan Patrick Lehr via Openmp-commits openmp-commits at lists.llvm.org
Tue Aug 5 03:05:03 PDT 2025


================
@@ -0,0 +1,477 @@
+//===- OmptAsserter.cpp - Asserter-related implementations ------*- 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
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Implements all asserter-related class methods, like: notifications, handling
+/// of groups or determination of the testcase state.
+///
+//===----------------------------------------------------------------------===//
+
+#include "OmptAsserter.h"
+#include "Logging.h"
+
+#include <algorithm>
+
+using namespace omptest;
+using namespace internal;
+
+// Initialize static members
+std::mutex OmptAsserter::StaticMemberAccessMutex;
+std::weak_ptr<OmptEventGroupInterface>
+    OmptAsserter::EventGroupInterfaceInstance;
+std::weak_ptr<logging::Logger> OmptAsserter::LoggingInstance;
+
+OmptAsserter::OmptAsserter() {
+  // Protect static members access
+  std::lock_guard<std::mutex> Lock(StaticMemberAccessMutex);
+
+  // Upgrade OmptEventGroupInterface weak_ptr to shared_ptr
+  {
+    EventGroups = EventGroupInterfaceInstance.lock();
+    if (!EventGroups) {
+      // Coordinator doesn't exist or was previously destroyed, create a new
+      // one.
+      EventGroups = std::make_shared<OmptEventGroupInterface>();
+      // Store a weak reference to it
+      EventGroupInterfaceInstance = EventGroups;
+    }
+    // EventGroups is now a valid shared_ptr, either to a new or existing
+    // instance.
+  }
+
+  // Upgrade logging::Logger weak_ptr to shared_ptr
+  {
+    Log = LoggingInstance.lock();
+    if (!Log) {
+      // Coordinator doesn't exist or was previously destroyed, create a new
+      // one.
+      Log = std::make_shared<logging::Logger>();
+      // Store a weak reference to it
+      LoggingInstance = Log;
+    }
+    // Log is now a valid shared_ptr, either to a new or existing instance.
+  }
+}
+
+void OmptListener::setActive(bool Enabled) { Active = Enabled; }
+
+bool OmptListener::isActive() { return Active; }
+
+bool OmptListener::isSuppressedEventType(EventTy EvTy) {
+  return SuppressedEvents.find(EvTy) != SuppressedEvents.end();
+}
+
+void OmptListener::permitEvent(EventTy EvTy) { SuppressedEvents.erase(EvTy); }
+
+void OmptListener::suppressEvent(EventTy EvTy) {
+  SuppressedEvents.insert(EvTy);
+}
+
+void OmptAsserter::insert(OmptAssertEvent &&AE) {
+  assert(false && "Base class 'insert' has undefined semantics.");
+}
+
+void OmptAsserter::notify(OmptAssertEvent &&AE) {
+  // Ignore notifications while inactive
+  if (!isActive() || isSuppressedEventType(AE.getEventType()))
+    return;
+
+  this->notifyImpl(std::move(AE));
+}
+
+AssertState OmptAsserter::checkState() { return State; }
+
+bool OmptAsserter::verifyEventGroups(const OmptAssertEvent &ExpectedEvent,
+                                     const OmptAssertEvent &ObservedEvent) {
+  assert(ExpectedEvent.getEventType() == ObservedEvent.getEventType() &&
+         "Type mismatch: Expected != Observed event type");
+  assert(EventGroups && "Missing EventGroups interface");
+
+  // Ignore all events within "default" group
+  auto GroupName = ExpectedEvent.getEventGroup();
+
+  if (GroupName == "default")
+    return true;
+
+  // Get a pointer to the observed internal event
+  auto Event = ObservedEvent.getEvent();
+
+  switch (Event->getType()) {
+  case EventTy::Target:
+    if (auto E = static_cast<const internal::Target *>(Event)) {
+      if (E->Endpoint == ompt_scope_begin) {
+        // Add new group since we entered a Target Region
+        EventGroups->addActiveEventGroup(GroupName,
+                                         AssertEventGroup{E->TargetId});
+      } else if (E->Endpoint == ompt_scope_end) {
+        // Deprecate group since we return from a Target Region
+        EventGroups->deprecateActiveEventGroup(GroupName);
+      }
+      return true;
+    }
+    return false;
+  case EventTy::TargetEmi:
+    if (auto E = static_cast<const internal::TargetEmi *>(Event)) {
+      if (E->Endpoint == ompt_scope_begin) {
+        // Add new group since we entered a Target Region
+        EventGroups->addActiveEventGroup(
+            GroupName, AssertEventGroup{E->TargetData->value});
+      } else if (E->Endpoint == ompt_scope_end) {
+        // Deprecate group since we return from a Target Region
+        EventGroups->deprecateActiveEventGroup(GroupName);
+      }
+      return true;
+    }
+    return false;
+  case EventTy::TargetDataOp:
+    if (auto E = static_cast<const internal::TargetDataOp *>(Event))
+      return EventGroups->checkActiveEventGroups(GroupName,
+                                                 AssertEventGroup{E->TargetId});
+
+    return false;
+  case EventTy::TargetDataOpEmi:
+    if (auto E = static_cast<const internal::TargetDataOpEmi *>(Event))
+      return EventGroups->checkActiveEventGroups(
+          GroupName, AssertEventGroup{E->TargetData->value});
+
+    return false;
+  case EventTy::TargetSubmit:
+    if (auto E = static_cast<const internal::TargetSubmit *>(Event))
+      return EventGroups->checkActiveEventGroups(GroupName,
+                                                 AssertEventGroup{E->TargetId});
+
+    return false;
+  case EventTy::TargetSubmitEmi:
+    if (auto E = static_cast<const internal::TargetSubmitEmi *>(Event))
+      return EventGroups->checkActiveEventGroups(
+          GroupName, AssertEventGroup{E->TargetData->value});
+
+    return false;
+  case EventTy::BufferRecord:
+    // BufferRecords are delivered asynchronously: also check deprecated groups.
+    if (auto E = static_cast<const internal::BufferRecord *>(Event))
+      return (EventGroups->checkActiveEventGroups(
+                  GroupName, AssertEventGroup{E->Record.target_id}) ||
+              EventGroups->checkDeprecatedEventGroups(
+                  GroupName, AssertEventGroup{E->Record.target_id}));
+    return false;
+  // Some event types do not need any handling
+  case EventTy::ThreadBegin:
+  case EventTy::ThreadEnd:
+  case EventTy::ParallelBegin:
+  case EventTy::ParallelEnd:
+  case EventTy::Work:
+  case EventTy::Dispatch:
+  case EventTy::TaskCreate:
+  case EventTy::Dependences:
+  case EventTy::TaskDependence:
+  case EventTy::TaskSchedule:
+  case EventTy::ImplicitTask:
+  case EventTy::Masked:
+  case EventTy::SyncRegion:
+  case EventTy::MutexAcquire:
+  case EventTy::Mutex:
+  case EventTy::NestLock:
+  case EventTy::Flush:
+  case EventTy::Cancel:
+  case EventTy::DeviceInitialize:
+  case EventTy::DeviceFinalize:
+  case EventTy::DeviceLoad:
+  case EventTy::DeviceUnload:
+  case EventTy::BufferRequest:
+  case EventTy::BufferComplete:
+  case EventTy::BufferRecordDeallocation:
+    return true;
+  // Some event types must not be encountered
+  case EventTy::None:
+  case EventTy::AssertionSyncPoint:
+  case EventTy::AssertionSuspend:
+  default:
+    assert(false && "Encountered invalid event type");
----------------
jplehr wrote:

Should we do something here for build config that do not have asserts enabled?

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


More information about the Openmp-commits mailing list