Skip to content

Commit

Permalink
feature: events deadlock detection in validation layer
Browse files Browse the repository at this point in the history
Related-To: NEO-12810

Signed-off-by: Chandio, Bibrak Qamar <bibrak.qamar.chandio@intel.com>
  • Loading branch information
bibrak committed Nov 1, 2024
1 parent c689bbe commit 12596b5
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 65 deletions.
17 changes: 0 additions & 17 deletions source/layers/validation/checkers/events_deadlock/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
# Process Abseil's CMake build system
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp)

target_sources(${TARGET_NAME}
PRIVATE
${CMAKE_CURRENT_LIST_DIR}/zel_events_deadlock_checker.h
Expand All @@ -13,17 +10,3 @@ target_include_directories(${TARGET_NAME}
PRIVATE
${CMAKE_SOURCE_DIR}/third_party
)

cmake_policy(SET CMP0079 NEW)

# Declare dependency on the absl:: libraries
target_link_libraries(${TARGET_NAME}
absl::strings
absl::container_memory
absl::hash_container_defaults
absl::raw_hash_set
absl::algorithm_container
absl::core_headers
absl::memory
absl::type_traits
)
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace validation_layer {
class eventsDeadlockChecker eventsDeadlock_checker;

eventsDeadlockChecker::eventsDeadlockChecker() {
std::cout << "eventsDeadlockChecker() called!\n";
enableEventsDeadlock = getenv_tobool("ZEL_ENABLE_EVENTSDEADLOCK_CHECKER");
if (enableEventsDeadlock) {
eventsDeadlockChecker::ZEeventsDeadlockChecker *zeChecker = new eventsDeadlockChecker::ZEeventsDeadlockChecker;
Expand Down Expand Up @@ -81,6 +82,7 @@ eventsDeadlockChecker::ZEeventsDeadlockChecker::zeEventDestroyEpilogue(
eventToDagID[hEvent] = invalidDagID;
}


return ZE_RESULT_SUCCESS;
}

Expand Down
70 changes: 38 additions & 32 deletions third_party/xla/graphcycles.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,22 @@ limitations under the License.
#include <utility>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/container/flat_hash_set.h"
#include "absl/strings/str_cat.h"
#include "absl/types/span.h"
// #include "absl/algorithm/container.h"
// #include "absl/container/flat_hash_set.h"
// #include "absl/strings/str_cat.h"
// #include "absl/types/span.h"

//#include "xla/service/graphcycles/ordered_set.h"
#include "ordered_set.h"
#include <unordered_set>
#include <iostream>
//#include "tsl/platform/logging.h"

namespace xla {

namespace {

using NodeSet = absl::flat_hash_set<int32_t>;
using NodeSet = std::unordered_set<int32_t>;
using OrderedNodeSet = OrderedSet<int32_t>;

struct Node {
Expand Down Expand Up @@ -181,11 +183,11 @@ void GraphCycles::RemoveEdge(int32_t x, int32_t y) {
static bool ForwardDFS(GraphCycles::Rep* r, int32_t n, int32_t upper_bound);
static void BackwardDFS(GraphCycles::Rep* r, int32_t n, int32_t lower_bound);
static void Reorder(GraphCycles::Rep* r);
static void Sort(absl::Span<const Node>, std::vector<int32_t>* delta);
static void Sort(const std::vector<Node>& nodes, std::vector<int32_t>* delta);
static void MoveToList(GraphCycles::Rep* r, std::vector<int32_t>* src,
std::vector<int32_t>* dst);
static void ClearVisitedBits(GraphCycles::Rep* r,
absl::Span<const int32_t> visited_indices);
const std::vector<int32_t>& visited_indices);

bool GraphCycles::InsertEdge(int32_t x, int32_t y) {
if (x == y) return false;
Expand Down Expand Up @@ -294,7 +296,7 @@ static void Reorder(GraphCycles::Rep* r) {
}
}

static void Sort(absl::Span<const Node> nodes, std::vector<int32_t>* delta) {
static void Sort(const std::vector<Node>& nodes, std::vector<int32_t>* delta) {
std::sort(delta->begin(), delta->end(), [&](int32_t a, int32_t b) {
return nodes[a].rank < nodes[b].rank;
});
Expand All @@ -311,9 +313,9 @@ static void MoveToList(GraphCycles::Rep* r, std::vector<int32_t>* src,
}

static void ClearVisitedBits(GraphCycles::Rep* r,
absl::Span<const int32_t> visited_indices) {
const std::vector<int32_t>& visited_indices) {
for (auto index : visited_indices) {
r->nodes_[index].visited = false;
r->nodes_[index].visited = false;
}
}

Expand Down Expand Up @@ -390,15 +392,15 @@ bool GraphCycles::CanContractEdge(int32_t a, int32_t b) {
return !reachable;
}

//std::optional<int32_t> GraphCycles::ContractEdge(int32_t a, int32_t b) {
int32_t GraphCycles::ContractEdge(int32_t a, int32_t b) {
int32_t GraphCycles::ContractEdge(int32_t a, int32_t b, bool &success) {
CHECK(HasEdge(a, b));
RemoveEdge(a, b);

if (IsReachableNonConst(a, b)) {
// Restore the graph to its original state.
InsertEdge(a, b);
return -1; //std::nullopt;
success = false;
return -1;
}

if (rep_->node_io_[b].in.Size() + rep_->node_io_[b].out.Size() >
Expand Down Expand Up @@ -429,46 +431,50 @@ bool GraphCycles::CanContractEdge(int32_t a, int32_t b) {
}

// Note, if the swap happened it might be what originally was called "b".
success = true;
return a;
}

absl::Span<const int32_t> GraphCycles::Successors(int32_t node) const {
std::vector<int32_t> GraphCycles::Successors(int32_t node) const {
return rep_->node_io_[node].out.GetSequence();
}

absl::Span<const int32_t> GraphCycles::Predecessors(int32_t node) const {
std::vector<int32_t> GraphCycles::Predecessors(int32_t node) const {
return rep_->node_io_[node].in.GetSequence();
}

std::vector<int32_t> GraphCycles::SuccessorsCopy(int32_t node) const {
absl::Span<const int32_t> successors = Successors(node);
return std::vector<int32_t>(successors.begin(), successors.end());
return Successors(node);
}

std::vector<int32_t> GraphCycles::PredecessorsCopy(int32_t node) const {
absl::Span<const int32_t> predecessors = Predecessors(node);
return std::vector<int32_t>(predecessors.begin(), predecessors.end());
return Predecessors(node);
}

namespace {
void SortInPostOrder(absl::Span<const Node> nodes,
std::vector<int32_t>* to_sort) {
absl::c_sort(*to_sort, [&](int32_t a, int32_t b) {
DCHECK(a == b || nodes[a].rank != nodes[b].rank);
return nodes[a].rank > nodes[b].rank;
void SortInPostOrder(const std::vector<Node>& nodes,
std::vector<int32_t>* to_sort) {
std::sort(to_sort->begin(), to_sort->end(), [&](int32_t a, int32_t b) {
DCHECK(a == b || nodes[a].rank != nodes[b].rank);
return nodes[a].rank > nodes[b].rank;
});
}
} // namespace

auto contains = [](const std::unordered_set<int32_t>& set, int32_t key) {
return set.find(key) != set.end();
};

std::vector<int32_t> GraphCycles::AllNodesInPostOrder() const {
absl::flat_hash_set<int32_t> free_nodes_set;
absl::c_copy(rep_->free_nodes_,
std::inserter(free_nodes_set, free_nodes_set.begin()));
std::unordered_set<int32_t> free_nodes_set;
std::copy(rep_->free_nodes_.begin(), rep_->free_nodes_.end(),
std::inserter(free_nodes_set, free_nodes_set.begin()));

std::vector<int32_t> all_nodes;
all_nodes.reserve(rep_->nodes_.size() - free_nodes_set.size());

for (int64_t i = 0, e = rep_->nodes_.size(); i < e; i++) {
if (!free_nodes_set.contains(i)) {
if (!contains(free_nodes_set, i)) {
all_nodes.push_back(i);
}
}
Expand All @@ -478,21 +484,21 @@ std::vector<int32_t> GraphCycles::AllNodesInPostOrder() const {
}

std::string GraphCycles::DebugString() const {
absl::flat_hash_set<int32_t> free_nodes_set(rep_->free_nodes_.begin(),
std::unordered_set<int32_t> free_nodes_set(rep_->free_nodes_.begin(),
rep_->free_nodes_.end());

std::string result = "digraph {\n";
for (int i = 0, end = rep_->nodes_.size(); i < end; i++) {
if (free_nodes_set.contains(i)) {
if (!contains(free_nodes_set, i)) {
continue;
}

for (int32_t succ : rep_->node_io_[i].out.GetSequence()) {
absl::StrAppend(&result, " \"", i, "\" -> \"", succ, "\"\n");
result += " \"" + std::to_string(i) + "\" -> \"" + std::to_string(succ) + "\"\n";
}
}

absl::StrAppend(&result, "}\n");
result += "}\n";

return result;
}
Expand Down
13 changes: 7 additions & 6 deletions third_party/xla/graphcycles.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ limitations under the License.
// FindPath() is linear in the size of the graph.
// The current implementation uses O(|V|+|E|) space.

#include <optional>
// #include <optional>

#include "absl/types/span.h"
// #include "absl/types/span.h"
// #include <span>
#include <string>

#define ASSERT_TRUE(condition) \
do \
Expand Down Expand Up @@ -127,8 +129,7 @@ class GraphCycles {
// the nodes is removed from the graph, and edges to/from it are added to
// the remaining one, which is returned. If contracting the edge would create
// a cycle, does nothing and return no value.
// std::optional<int32_t> ContractEdge(int32_t a, int32_t b);
int32_t ContractEdge(int32_t a, int32_t b);
int32_t ContractEdge(int32_t a, int32_t b, bool &success);

// Return true if can contract edge, otherwise return false.
bool CanContractEdge(int32_t a, int32_t b);
Expand Down Expand Up @@ -165,8 +166,8 @@ class GraphCycles {

// Warning: Do not use these if iterating over the span and modifying the
// GraphCycles at the same time. Instead use SuccessorsCopy/PredecessorsCopy.
absl::Span<const int32_t> Successors(int32_t node) const;
absl::Span<const int32_t> Predecessors(int32_t node) const;
std::vector<int32_t> Successors(int32_t node) const;
std::vector<int32_t> Predecessors(int32_t node) const;

// Return a copy of the successors set. This is needed for code using the
// collection while modifying the GraphCycles.
Expand Down
20 changes: 10 additions & 10 deletions third_party/xla/ordered_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ limitations under the License.
#define XLA_SERVICE_GRAPHCYCLES_ORDERED_SET_H_

#include <vector>
#include <iostream>
#include <unordered_map>

// #include "absl/container/flat_hash_map.h"
// #include "absl/types/span.h"

#include "absl/container/flat_hash_map.h"
#include "absl/types/span.h"
//using absl = std;
//#include "tsl/platform/logging.h"

namespace xla {
Expand Down Expand Up @@ -48,9 +50,7 @@ class OrderedSet {
// set.
void Erase(T value) {
auto it = value_to_index_.find(value);
//DCHECK(it != value_to_index_.end());
assert(it != value_to_index_.end());

CHECK(it != value_to_index_.end());

// Since we don't want to move values around in `value_sequence_` we swap
// the value in the last position and with value to be deleted and then
Expand All @@ -71,18 +71,18 @@ class OrderedSet {
value_sequence_.clear();
}

bool Contains(T value) const { return value_to_index_.contains(value); }
bool Contains(T value) const { return value_to_index_.find(value) != value_to_index_.end(); }
size_t Size() const { return value_sequence_.size(); }

absl::Span<T const> GetSequence() const { return value_sequence_; }
std::vector<T> const& GetSequence() const { return value_sequence_; }

private:
// The stable order that we maintain through insertions and deletions.
std::vector<T> value_sequence_;

// Maps values to their indices in `value_sequence_`.
absl::flat_hash_map<T, int> value_to_index_;
};
std::unordered_map<T, int> value_to_index_;
};;
} // namespace xla

#endif // XLA_SERVICE_GRAPHCYCLES_ORDERED_SET_H_

0 comments on commit 12596b5

Please sign in to comment.