brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.4 KiB · 23d6dfe Raw
292 lines · c
1//===- OmptAsserter.h - Asserter-related classes, enums, etc. ---*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// Contains all asserter-related class declarations and important enums.11///12//===----------------------------------------------------------------------===//13 14#ifndef OPENMP_TOOLS_OMPTEST_INCLUDE_OMPTASSERTER_H15#define OPENMP_TOOLS_OMPTEST_INCLUDE_OMPTASSERTER_H16 17#include "Logging.h"18#include "OmptAssertEvent.h"19 20#include <cassert>21#include <iostream>22#include <map>23#include <mutex>24#include <set>25#include <vector>26 27namespace omptest {28 29// Forward declaration.30class OmptEventGroupInterface;31 32enum class AssertMode { Strict, Relaxed };33enum class AssertState { Pass, Fail };34 35/// General base class for the subscriber/notification pattern in36/// OmptCallbackHandler. Derived classes need to implement the notify method.37class OmptListener {38public:39  virtual ~OmptListener() = default;40 41  /// Called for each registered OMPT event of the OmptCallbackHandler42  virtual void notify(omptest::OmptAssertEvent &&AE) = 0;43 44  /// Control whether this asserter should be considered 'active'.45  void setActive(bool Enabled);46 47  /// Check if this asserter is considered 'active'.48  bool isActive();49 50  /// Check if the given event type is from the set of suppressed event types.51  bool isSuppressedEventType(omptest::internal::EventTy EvTy);52 53  /// Remove the given event type to the set of suppressed events.54  void permitEvent(omptest::internal::EventTy EvTy);55 56  /// Add the given event type to the set of suppressed events.57  void suppressEvent(omptest::internal::EventTy EvTy);58 59private:60  bool Active{true};61 62  // Add event types to the set of suppressed events by default.63  std::set<omptest::internal::EventTy> SuppressedEvents{64      omptest::internal::EventTy::ThreadBegin,65      omptest::internal::EventTy::ThreadEnd,66      omptest::internal::EventTy::ParallelBegin,67      omptest::internal::EventTy::ParallelEnd,68      omptest::internal::EventTy::Work,69      omptest::internal::EventTy::Dispatch,70      omptest::internal::EventTy::TaskCreate,71      omptest::internal::EventTy::Dependences,72      omptest::internal::EventTy::TaskDependence,73      omptest::internal::EventTy::TaskSchedule,74      omptest::internal::EventTy::ImplicitTask,75      omptest::internal::EventTy::Masked,76      omptest::internal::EventTy::SyncRegion,77      omptest::internal::EventTy::MutexAcquire,78      omptest::internal::EventTy::Mutex,79      omptest::internal::EventTy::NestLock,80      omptest::internal::EventTy::Flush,81      omptest::internal::EventTy::Cancel};82};83 84/// Base class for asserting on OMPT events85class OmptAsserter : public OmptListener {86public:87  OmptAsserter();88  virtual ~OmptAsserter() = default;89 90  /// Add an event to the asserter's internal data structure.91  virtual void insert(omptest::OmptAssertEvent &&AE);92 93  /// Called from the CallbackHandler with a corresponding AssertEvent to which94  /// callback was handled.95  void notify(omptest::OmptAssertEvent &&AE) override;96 97  /// Implemented in subclasses to implement what should actually be done with98  /// the notification.99  virtual void notifyImpl(omptest::OmptAssertEvent &&AE) = 0;100 101  /// Get the number of currently remaining events, with: ObserveState::Always.102  virtual size_t getRemainingEventCount() = 0;103 104  /// Get the total number of received, effective notifications.105  int getNotificationCount() { return NumNotifications; }106 107  /// Get the total number of successful assertion checks.108  int getSuccessfulAssertionCount() { return NumSuccessfulAsserts; }109 110  /// Get the asserter's current operationmode: e.g.: Strict or Relaxed.111  AssertMode getOperationMode() { return OperationMode; }112 113  /// Return the asserter's current state.114  omptest::AssertState getState() { return State; }115 116  /// Determine and return the asserter's state.117  virtual omptest::AssertState checkState();118 119  /// Accessor for the event group interface.120  std::shared_ptr<OmptEventGroupInterface> getEventGroups() const {121    return EventGroups;122  }123 124  /// Accessor for the event group interface.125  std::shared_ptr<logging::Logger> getLog() const { return Log; }126 127  /// Check the observed events' group association. If the event indicates the128  /// begin/end of an OpenMP target region, we will create/deprecate the129  /// expected event's group. Return true if the expected event group exists130  /// (and is active), otherwise: false. Note: BufferRecords may also match with131  /// deprecated groups as they may be delivered asynchronously.132  bool verifyEventGroups(const omptest::OmptAssertEvent &ExpectedEvent,133                         const omptest::OmptAssertEvent &ObservedEvent);134 135  /// Set the asserter's mode of operation w.r.t. assertion.136  void setOperationMode(AssertMode Mode);137 138protected:139  /// The asserter's current state.140  omptest::AssertState State{omptest::AssertState::Pass};141 142  /// Mutex to avoid data races w.r.t. event notifications and/or insertions.143  std::mutex AssertMutex;144 145  /// Pointer to the OmptEventGroupInterface.146  std::shared_ptr<OmptEventGroupInterface> EventGroups{nullptr};147 148  /// Pointer to the logging instance.149  std::shared_ptr<logging::Logger> Log{nullptr};150 151  /// Operation mode during assertion / notification.152  AssertMode OperationMode{AssertMode::Strict};153 154  /// The total number of effective notifications. For example, if specific155  /// notifications are to be ignored, they will not count towards this total.156  int NumNotifications{0};157 158  /// The number of successful assertion checks.159  int NumSuccessfulAsserts{0};160 161private:162  /// Mutex for creating/accessing the singleton members163  static std::mutex StaticMemberAccessMutex;164 165  /// Static member to manage the singleton event group interface instance166  static std::weak_ptr<OmptEventGroupInterface> EventGroupInterfaceInstance;167 168  /// Static member to manage the singleton logging instance169  static std::weak_ptr<logging::Logger> LoggingInstance;170};171 172/// Class that can assert in a sequenced fashion, i.e., events have to occur in173/// the order they were registered174class OmptSequencedAsserter : public OmptAsserter {175public:176  OmptSequencedAsserter() : OmptAsserter(), NextEvent(0) {}177 178  /// Add the event to the in-sequence set of events that the asserter should179  /// check for.180  void insert(omptest::OmptAssertEvent &&AE) override;181 182  /// Implements the asserter's actual logic183  virtual void notifyImpl(omptest::OmptAssertEvent &&AE) override;184 185  size_t getRemainingEventCount() override;186 187  omptest::AssertState checkState() override;188 189  bool AssertionSuspended{false};190 191protected:192  /// Notification helper function, implementing SyncPoint logic. Returns true193  /// in case of consumed event, indicating early exit of notification.194  bool consumeSyncPoint(const omptest::OmptAssertEvent &AE);195 196  /// Notification helper function, implementing excess event notification197  /// logic. Returns true when no more events were expected, indicating early198  /// exit of notification.199  bool checkExcessNotify(const omptest::OmptAssertEvent &AE);200 201  /// Notification helper function, implementing Suspend logic. Returns true202  /// in case of consumed event, indicating early exit of notification.203  bool consumeSuspend();204 205  /// Notification helper function, implementing regular event notification206  /// logic. Returns true when a matching event was encountered, indicating207  /// early exit of notification.208  bool consumeRegularEvent(const omptest::OmptAssertEvent &AE);209 210public:211  /// Index of the next, expected event.212  size_t NextEvent{0};213  std::vector<omptest::OmptAssertEvent> Events{};214};215 216/// Class that asserts with set semantics, i.e., unordered217struct OmptEventAsserter : public OmptAsserter {218  OmptEventAsserter() : OmptAsserter(), NumEvents(0), Events() {}219 220  /// Add the event to the set of events that the asserter should check for.221  void insert(omptest::OmptAssertEvent &&AE) override;222 223  /// Implements the asserter's logic224  virtual void notifyImpl(omptest::OmptAssertEvent &&AE) override;225 226  size_t getRemainingEventCount() override;227 228  omptest::AssertState checkState() override;229 230  size_t NumEvents{0};231 232  /// For now use vector (but do set semantics)233  // TODO std::unordered_set?234  std::vector<omptest::OmptAssertEvent> Events{};235};236 237/// Class that reports the occurred events238class OmptEventReporter : public OmptListener {239public:240  OmptEventReporter(std::ostream &OutStream = std::cout)241      : OutStream(OutStream) {}242 243  /// Called from the CallbackHandler with a corresponding AssertEvent to which244  /// callback was handled.245  void notify(omptest::OmptAssertEvent &&AE) override;246 247private:248  std::ostream &OutStream;249};250 251/// This class provides the members and methods to manage event groups and252/// SyncPoints in conjunction with asserters. Most importantly it maintains a253/// coherent view of active and past events or SyncPoints.254class OmptEventGroupInterface {255public:256  OmptEventGroupInterface() = default;257  ~OmptEventGroupInterface() = default;258 259  /// Non-copyable and non-movable260  OmptEventGroupInterface(const OmptEventGroupInterface &) = delete;261  OmptEventGroupInterface &operator=(const OmptEventGroupInterface &) = delete;262  OmptEventGroupInterface(OmptEventGroupInterface &&) = delete;263  OmptEventGroupInterface &operator=(OmptEventGroupInterface &&) = delete;264 265  /// Add given group to the set of active event groups. Effectively connecting266  /// the given groupname (expected) with a target region id (observed).267  bool addActiveEventGroup(const std::string &GroupName,268                           omptest::AssertEventGroup Group);269 270  /// Move given group from the set of active event groups to the set of271  /// previously active event groups.272  bool deprecateActiveEventGroup(const std::string &GroupName);273 274  /// Check if given group is currently part of the active event groups.275  bool checkActiveEventGroups(const std::string &GroupName,276                              omptest::AssertEventGroup Group);277 278  /// Check if given group is currently part of the deprecated event groups.279  bool checkDeprecatedEventGroups(const std::string &GroupName,280                                  omptest::AssertEventGroup Group);281 282private:283  mutable std::mutex GroupMutex;284  std::map<std::string, omptest::AssertEventGroup> ActiveEventGroups{};285  std::map<std::string, omptest::AssertEventGroup> DeprecatedEventGroups{};286  std::set<std::string> EncounteredSyncPoints{};287};288 289} // namespace omptest290 291#endif292