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

Fix fieldversion2 #1059

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions dawn/src/dawn/IIR/DependencyGraph.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ class DependencyGraph {
};

protected:
// map of Value (i.e. normally accessID to Vertex object
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// map of Value (i.e. normally accessID to Vertex object
// map from accessID to Vertex object

Isn't this always the case?
Also the description of Vertex::Value below could be improved ... doesn't it always correspond to an accessID?

std::unordered_map<int, Vertex> vertices_;
// adjacencyList for each vertex where the position within the vector is the vertexID
std::vector<EdgeList> adjacencyList_;

public:
Expand Down Expand Up @@ -96,8 +98,8 @@ class DependencyGraph {
DependencyGraph() = default;

/// @brief Insert a new node
Vertex& insertNode(int ID) {
auto [iter, inserted] = vertices_.emplace(ID, Vertex{adjacencyList_.size(), ID});
Vertex& insertNode(int Value) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Vertex& insertNode(int Value) {
Vertex& insertNode(int value) {

we Capitalize only public members of classes

auto [iter, inserted] = vertices_.emplace(Value, Vertex{adjacencyList_.size(), Value});
if(inserted)
adjacencyList_.push_back(EdgeList());
return iter->second;
Expand Down
26 changes: 26 additions & 0 deletions dawn/src/dawn/IIR/DependencyGraphAccesses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,32 @@ bool DependencyGraphAccesses::isDAG() const {
return true;
}

bool DependencyGraphAccesses::hasZeroOutdegreeNodes() const {
auto partitions = partitionInSubGraphs();
std::vector<std::size_t> vertices;

for(std::set<std::size_t>& partition : partitions) {
getOutputVertexIDsImpl(
*this, partition, [](std::size_t VertexID) { return VertexID; }, vertices);
if(vertices.empty())
return false;
}
return true;
}

bool DependencyGraphAccesses::hasZeroIndegreeNodes() const {
auto partitions = partitionInSubGraphs();
std::vector<std::size_t> vertices;

for(std::set<std::size_t>& partition : partitions) {
getInputVertexIDsImpl(
*this, partition, [](std::size_t VertexID) { return VertexID; }, vertices);
if(vertices.empty())
return false;
}
return true;
}

std::vector<std::size_t> DependencyGraphAccesses::getOutputVertexIDs() const {
std::vector<std::size_t> outputVertexIDs;
getOutputVertexIDsImpl(
Expand Down
5 changes: 5 additions & 0 deletions dawn/src/dawn/IIR/DependencyGraphAccesses.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ class DependencyGraphAccesses
/// In our context, a DAG is defined as having a non-empty set of input as well as output nodes.
bool isDAG() const;

/// @brief true if graph has nodes with indegree=0
bool hasZeroIndegreeNodes() const;
/// @brief true if graph has nodes with outdegree=0
bool hasZeroOutdegreeNodes() const;

/// @brief Get the VertexIDs of the pure `output` vertices
///
/// Output vertices are vertices which do not have incoming edges from other vertices.
Expand Down
17 changes: 1 addition & 16 deletions dawn/src/dawn/Optimizer/PassFieldVersioning.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ bool PassFieldVersioning::run(
newGraph = oldGraph;
newGraph.insertStatement(stmt);
}

doMethod.update(iir::NodeUpdateType::level);
}
stage.update(iir::NodeUpdateType::level);
Expand Down Expand Up @@ -211,22 +212,6 @@ PassFieldVersioning::RCKind PassFieldVersioning::fixRaceCondition(
}
}

// If we only have non-stencil SCCs and there are no input and output fields (i.e we don't have a
// DAG) we have to break (by renaming) one of the SCCs to get a DAG. For example:
//
// field_a = field_b;
// field_b = field_a;
//
// needs to be renamed to
//
// field_a = field_b_0;
// field_b = field_a;
//
// ... and then field_b_0 must be initialized from field_b.
if(stencilSCCs->empty() && !SCCs->empty() && !graph.isDAG()) {
stencilSCCs->emplace_back(std::move(SCCs->front()));
}

if(stencilSCCs->empty())
return RCKind::Nothing;

Expand Down
7 changes: 7 additions & 0 deletions dawn/src/dawn/Optimizer/ReadBeforeWriteConflict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ class ReadBeforeWriteConflictDetector {
ReadBeforeWriteConflict check() const {

std::vector<std::size_t> nodesToVisit = graph_.getOutputVertexIDs();
// if the graph does not have nodes with outdegree=0, there is no seed to start the algorithm
// in this case, there is at least one SCC, which means we can start from any node of the graph
if(nodesToVisit.empty() ) nodesToVisit.push_back(0);

DAWN_ASSERT_MSG(!nodesToVisit.empty(), "invalid graph (probably contains cycles!)");

ReadBeforeWriteConflict conflict;
Expand Down Expand Up @@ -77,6 +81,9 @@ class ReadBeforeWriteConflictDetector {
else
visitedNodes.insert(curNode);

DAWN_ASSERT_MSG((adjacencyList.size() > curNode), "out of bounds access to adjacency list of graph");


// Follow edges of the current node
if(!adjacencyList[curNode].empty()) {
for(const auto& edge : adjacencyList[curNode]) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ class generate_versioned_field {
::dawn::edge_field_t<LibTag, ::dawn::float_type>& m_c;
::dawn::edge_field_t<LibTag, ::dawn::float_type>& m_d;
::dawn::edge_field_t<LibTag, ::dawn::float_type>& m_e;
::dawn::edge_field_t<LibTag, ::dawn::float_type>& m_c_0;
::dawn::unstructured_domain m_unstructured_domain ;
public:

stencil_37(::dawn::mesh_t<LibTag> const &mesh, int k_size, ::dawn::edge_field_t<LibTag, ::dawn::float_type>&a, ::dawn::edge_field_t<LibTag, ::dawn::float_type>&b, ::dawn::edge_field_t<LibTag, ::dawn::float_type>&c, ::dawn::edge_field_t<LibTag, ::dawn::float_type>&d, ::dawn::edge_field_t<LibTag, ::dawn::float_type>&e, ::dawn::edge_field_t<LibTag, ::dawn::float_type>&c_0) : m_mesh(mesh), m_k_size(k_size), m_a(a), m_b(b), m_c(c), m_d(d), m_e(e), m_c_0(c_0){}
stencil_37(::dawn::mesh_t<LibTag> const &mesh, int k_size, ::dawn::edge_field_t<LibTag, ::dawn::float_type>&a, ::dawn::edge_field_t<LibTag, ::dawn::float_type>&b, ::dawn::edge_field_t<LibTag, ::dawn::float_type>&c, ::dawn::edge_field_t<LibTag, ::dawn::float_type>&d, ::dawn::edge_field_t<LibTag, ::dawn::float_type>&e) : m_mesh(mesh), m_k_size(k_size), m_a(a), m_b(b), m_c(c), m_d(d), m_e(e){}

~stencil_37() {
}
Expand All @@ -37,18 +36,14 @@ class generate_versioned_field {
static constexpr ::dawn::driver::unstructured_extent c_extent = {false, 0,0};
static constexpr ::dawn::driver::unstructured_extent d_extent = {false, 0,0};
static constexpr ::dawn::driver::unstructured_extent e_extent = {false, 0,0};
static constexpr ::dawn::driver::unstructured_extent c_0_extent = {false, 0,0};

void run() {
using ::dawn::deref;
{
for(int k = 0+0; k <= ( m_k_size == 0 ? 0 : (m_k_size - 1)) + 0+0; ++k) {
for(auto const& loc : getEdges(LibTag{}, m_mesh)) {
m_c_0(deref(LibTag{}, loc), (k + 0)) = m_c(deref(LibTag{}, loc), (k + 0));
} }}{
for(int k = 0+0; k <= ( m_k_size == 0 ? 0 : (m_k_size - 1)) + 0+0; ++k) {
for(auto const& loc : getEdges(LibTag{}, m_mesh)) {
m_a(deref(LibTag{}, loc), (k + 0)) = ((m_b(deref(LibTag{}, loc), (k + 0)) / m_c_0(deref(LibTag{}, loc), (k + 0))) + (::dawn::float_type) 5);
m_a(deref(LibTag{}, loc), (k + 0)) = ((m_b(deref(LibTag{}, loc), (k + 0)) / m_c(deref(LibTag{}, loc), (k + 0))) + (::dawn::float_type) 5);
} for(auto const& loc : getEdges(LibTag{}, m_mesh)) {
Comment on lines 43 to +46
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test can be removed then. It was testing that a versioned field was generated, but it's not generated anymore.

if(m_d(deref(LibTag{}, loc), (k + 0)))
{
m_a(deref(LibTag{}, loc), (k + 0)) = m_b(deref(LibTag{}, loc), (k + 0));
Expand All @@ -70,13 +65,12 @@ else
generate_versioned_field(const generate_versioned_field&) = delete;

// Members
::dawn::edge_field_t<LibTag, ::dawn::float_type> m_c_0;

void set_splitter_index(::dawn::LocationType loc, ::dawn::UnstructuredIterationSpace space, int offset, int index) {
m_stencil_37.m_unstructured_domain.set_splitter_index({loc, space, offset}, index);
}

generate_versioned_field(const ::dawn::mesh_t<LibTag> &mesh, int k_size, ::dawn::edge_field_t<LibTag, ::dawn::float_type>& a, ::dawn::edge_field_t<LibTag, ::dawn::float_type>& b, ::dawn::edge_field_t<LibTag, ::dawn::float_type>& c, ::dawn::edge_field_t<LibTag, ::dawn::float_type>& d, ::dawn::edge_field_t<LibTag, ::dawn::float_type>& e) : m_stencil_37(mesh, k_size,a,b,c,d,e,m_c_0), m_c_0(allocateFieldLike(LibTag{}, c)){}
generate_versioned_field(const ::dawn::mesh_t<LibTag> &mesh, int k_size, ::dawn::edge_field_t<LibTag, ::dawn::float_type>& a, ::dawn::edge_field_t<LibTag, ::dawn::float_type>& b, ::dawn::edge_field_t<LibTag, ::dawn::float_type>& c, ::dawn::edge_field_t<LibTag, ::dawn::float_type>& d, ::dawn::edge_field_t<LibTag, ::dawn::float_type>& e) : m_stencil_37(mesh, k_size,a,b,c,d,e){}

void run() {
m_stencil_37.run();
Expand Down