CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
292 lines
10 KiB
C++
292 lines
10 KiB
C++
//===- OmptAsserter.h - Asserter-related classes, enums, etc. ---*- 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
|
|
/// Contains all asserter-related class declarations and important enums.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef OPENMP_TOOLS_OMPTEST_INCLUDE_OMPTASSERTER_H
|
|
#define OPENMP_TOOLS_OMPTEST_INCLUDE_OMPTASSERTER_H
|
|
|
|
#include "Logging.h"
|
|
#include "OmptAssertEvent.h"
|
|
|
|
#include <cassert>
|
|
#include <iostream>
|
|
#include <map>
|
|
#include <mutex>
|
|
#include <set>
|
|
#include <vector>
|
|
|
|
namespace omptest {
|
|
|
|
// Forward declaration.
|
|
class OmptEventGroupInterface;
|
|
|
|
enum class AssertMode { Strict, Relaxed };
|
|
enum class AssertState { Pass, Fail };
|
|
|
|
/// General base class for the subscriber/notification pattern in
|
|
/// OmptCallbackHandler. Derived classes need to implement the notify method.
|
|
class OmptListener {
|
|
public:
|
|
virtual ~OmptListener() = default;
|
|
|
|
/// Called for each registered OMPT event of the OmptCallbackHandler
|
|
virtual void notify(omptest::OmptAssertEvent &&AE) = 0;
|
|
|
|
/// Control whether this asserter should be considered 'active'.
|
|
void setActive(bool Enabled);
|
|
|
|
/// Check if this asserter is considered 'active'.
|
|
bool isActive();
|
|
|
|
/// Check if the given event type is from the set of suppressed event types.
|
|
bool isSuppressedEventType(omptest::internal::EventTy EvTy);
|
|
|
|
/// Remove the given event type to the set of suppressed events.
|
|
void permitEvent(omptest::internal::EventTy EvTy);
|
|
|
|
/// Add the given event type to the set of suppressed events.
|
|
void suppressEvent(omptest::internal::EventTy EvTy);
|
|
|
|
private:
|
|
bool Active{true};
|
|
|
|
// Add event types to the set of suppressed events by default.
|
|
std::set<omptest::internal::EventTy> SuppressedEvents{
|
|
omptest::internal::EventTy::ThreadBegin,
|
|
omptest::internal::EventTy::ThreadEnd,
|
|
omptest::internal::EventTy::ParallelBegin,
|
|
omptest::internal::EventTy::ParallelEnd,
|
|
omptest::internal::EventTy::Work,
|
|
omptest::internal::EventTy::Dispatch,
|
|
omptest::internal::EventTy::TaskCreate,
|
|
omptest::internal::EventTy::Dependences,
|
|
omptest::internal::EventTy::TaskDependence,
|
|
omptest::internal::EventTy::TaskSchedule,
|
|
omptest::internal::EventTy::ImplicitTask,
|
|
omptest::internal::EventTy::Masked,
|
|
omptest::internal::EventTy::SyncRegion,
|
|
omptest::internal::EventTy::MutexAcquire,
|
|
omptest::internal::EventTy::Mutex,
|
|
omptest::internal::EventTy::NestLock,
|
|
omptest::internal::EventTy::Flush,
|
|
omptest::internal::EventTy::Cancel};
|
|
};
|
|
|
|
/// Base class for asserting on OMPT events
|
|
class OmptAsserter : public OmptListener {
|
|
public:
|
|
OmptAsserter();
|
|
virtual ~OmptAsserter() = default;
|
|
|
|
/// Add an event to the asserter's internal data structure.
|
|
virtual void insert(omptest::OmptAssertEvent &&AE);
|
|
|
|
/// Called from the CallbackHandler with a corresponding AssertEvent to which
|
|
/// callback was handled.
|
|
void notify(omptest::OmptAssertEvent &&AE) override;
|
|
|
|
/// Implemented in subclasses to implement what should actually be done with
|
|
/// the notification.
|
|
virtual void notifyImpl(omptest::OmptAssertEvent &&AE) = 0;
|
|
|
|
/// Get the number of currently remaining events, with: ObserveState::Always.
|
|
virtual size_t getRemainingEventCount() = 0;
|
|
|
|
/// Get the total number of received, effective notifications.
|
|
int getNotificationCount() { return NumNotifications; }
|
|
|
|
/// Get the total number of successful assertion checks.
|
|
int getSuccessfulAssertionCount() { return NumSuccessfulAsserts; }
|
|
|
|
/// Get the asserter's current operationmode: e.g.: Strict or Relaxed.
|
|
AssertMode getOperationMode() { return OperationMode; }
|
|
|
|
/// Return the asserter's current state.
|
|
omptest::AssertState getState() { return State; }
|
|
|
|
/// Determine and return the asserter's state.
|
|
virtual omptest::AssertState checkState();
|
|
|
|
/// Accessor for the event group interface.
|
|
std::shared_ptr<OmptEventGroupInterface> getEventGroups() const {
|
|
return EventGroups;
|
|
}
|
|
|
|
/// Accessor for the event group interface.
|
|
std::shared_ptr<logging::Logger> getLog() const { return Log; }
|
|
|
|
/// Check the observed events' group association. If the event indicates the
|
|
/// begin/end of an OpenMP target region, we will create/deprecate the
|
|
/// expected event's group. Return true if the expected event group exists
|
|
/// (and is active), otherwise: false. Note: BufferRecords may also match with
|
|
/// deprecated groups as they may be delivered asynchronously.
|
|
bool verifyEventGroups(const omptest::OmptAssertEvent &ExpectedEvent,
|
|
const omptest::OmptAssertEvent &ObservedEvent);
|
|
|
|
/// Set the asserter's mode of operation w.r.t. assertion.
|
|
void setOperationMode(AssertMode Mode);
|
|
|
|
protected:
|
|
/// The asserter's current state.
|
|
omptest::AssertState State{omptest::AssertState::Pass};
|
|
|
|
/// Mutex to avoid data races w.r.t. event notifications and/or insertions.
|
|
std::mutex AssertMutex;
|
|
|
|
/// Pointer to the OmptEventGroupInterface.
|
|
std::shared_ptr<OmptEventGroupInterface> EventGroups{nullptr};
|
|
|
|
/// Pointer to the logging instance.
|
|
std::shared_ptr<logging::Logger> Log{nullptr};
|
|
|
|
/// Operation mode during assertion / notification.
|
|
AssertMode OperationMode{AssertMode::Strict};
|
|
|
|
/// The total number of effective notifications. For example, if specific
|
|
/// notifications are to be ignored, they will not count towards this total.
|
|
int NumNotifications{0};
|
|
|
|
/// The number of successful assertion checks.
|
|
int NumSuccessfulAsserts{0};
|
|
|
|
private:
|
|
/// Mutex for creating/accessing the singleton members
|
|
static std::mutex StaticMemberAccessMutex;
|
|
|
|
/// Static member to manage the singleton event group interface instance
|
|
static std::weak_ptr<OmptEventGroupInterface> EventGroupInterfaceInstance;
|
|
|
|
/// Static member to manage the singleton logging instance
|
|
static std::weak_ptr<logging::Logger> LoggingInstance;
|
|
};
|
|
|
|
/// Class that can assert in a sequenced fashion, i.e., events have to occur in
|
|
/// the order they were registered
|
|
class OmptSequencedAsserter : public OmptAsserter {
|
|
public:
|
|
OmptSequencedAsserter() : OmptAsserter(), NextEvent(0) {}
|
|
|
|
/// Add the event to the in-sequence set of events that the asserter should
|
|
/// check for.
|
|
void insert(omptest::OmptAssertEvent &&AE) override;
|
|
|
|
/// Implements the asserter's actual logic
|
|
virtual void notifyImpl(omptest::OmptAssertEvent &&AE) override;
|
|
|
|
size_t getRemainingEventCount() override;
|
|
|
|
omptest::AssertState checkState() override;
|
|
|
|
bool AssertionSuspended{false};
|
|
|
|
protected:
|
|
/// Notification helper function, implementing SyncPoint logic. Returns true
|
|
/// in case of consumed event, indicating early exit of notification.
|
|
bool consumeSyncPoint(const omptest::OmptAssertEvent &AE);
|
|
|
|
/// Notification helper function, implementing excess event notification
|
|
/// logic. Returns true when no more events were expected, indicating early
|
|
/// exit of notification.
|
|
bool checkExcessNotify(const omptest::OmptAssertEvent &AE);
|
|
|
|
/// Notification helper function, implementing Suspend logic. Returns true
|
|
/// in case of consumed event, indicating early exit of notification.
|
|
bool consumeSuspend();
|
|
|
|
/// Notification helper function, implementing regular event notification
|
|
/// logic. Returns true when a matching event was encountered, indicating
|
|
/// early exit of notification.
|
|
bool consumeRegularEvent(const omptest::OmptAssertEvent &AE);
|
|
|
|
public:
|
|
/// Index of the next, expected event.
|
|
size_t NextEvent{0};
|
|
std::vector<omptest::OmptAssertEvent> Events{};
|
|
};
|
|
|
|
/// Class that asserts with set semantics, i.e., unordered
|
|
struct OmptEventAsserter : public OmptAsserter {
|
|
OmptEventAsserter() : OmptAsserter(), NumEvents(0), Events() {}
|
|
|
|
/// Add the event to the set of events that the asserter should check for.
|
|
void insert(omptest::OmptAssertEvent &&AE) override;
|
|
|
|
/// Implements the asserter's logic
|
|
virtual void notifyImpl(omptest::OmptAssertEvent &&AE) override;
|
|
|
|
size_t getRemainingEventCount() override;
|
|
|
|
omptest::AssertState checkState() override;
|
|
|
|
size_t NumEvents{0};
|
|
|
|
/// For now use vector (but do set semantics)
|
|
// TODO std::unordered_set?
|
|
std::vector<omptest::OmptAssertEvent> Events{};
|
|
};
|
|
|
|
/// Class that reports the occurred events
|
|
class OmptEventReporter : public OmptListener {
|
|
public:
|
|
OmptEventReporter(std::ostream &OutStream = std::cout)
|
|
: OutStream(OutStream) {}
|
|
|
|
/// Called from the CallbackHandler with a corresponding AssertEvent to which
|
|
/// callback was handled.
|
|
void notify(omptest::OmptAssertEvent &&AE) override;
|
|
|
|
private:
|
|
std::ostream &OutStream;
|
|
};
|
|
|
|
/// This class provides the members and methods to manage event groups and
|
|
/// SyncPoints in conjunction with asserters. Most importantly it maintains a
|
|
/// coherent view of active and past events or SyncPoints.
|
|
class OmptEventGroupInterface {
|
|
public:
|
|
OmptEventGroupInterface() = default;
|
|
~OmptEventGroupInterface() = default;
|
|
|
|
/// Non-copyable and non-movable
|
|
OmptEventGroupInterface(const OmptEventGroupInterface &) = delete;
|
|
OmptEventGroupInterface &operator=(const OmptEventGroupInterface &) = delete;
|
|
OmptEventGroupInterface(OmptEventGroupInterface &&) = delete;
|
|
OmptEventGroupInterface &operator=(OmptEventGroupInterface &&) = delete;
|
|
|
|
/// Add given group to the set of active event groups. Effectively connecting
|
|
/// the given groupname (expected) with a target region id (observed).
|
|
bool addActiveEventGroup(const std::string &GroupName,
|
|
omptest::AssertEventGroup Group);
|
|
|
|
/// Move given group from the set of active event groups to the set of
|
|
/// previously active event groups.
|
|
bool deprecateActiveEventGroup(const std::string &GroupName);
|
|
|
|
/// Check if given group is currently part of the active event groups.
|
|
bool checkActiveEventGroups(const std::string &GroupName,
|
|
omptest::AssertEventGroup Group);
|
|
|
|
/// Check if given group is currently part of the deprecated event groups.
|
|
bool checkDeprecatedEventGroups(const std::string &GroupName,
|
|
omptest::AssertEventGroup Group);
|
|
|
|
private:
|
|
mutable std::mutex GroupMutex;
|
|
std::map<std::string, omptest::AssertEventGroup> ActiveEventGroups{};
|
|
std::map<std::string, omptest::AssertEventGroup> DeprecatedEventGroups{};
|
|
std::set<std::string> EncounteredSyncPoints{};
|
|
};
|
|
|
|
} // namespace omptest
|
|
|
|
#endif
|