Skip to content
Merged
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
2 changes: 2 additions & 0 deletions xls/scheduling/pipeline_schedule.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ class PipelineSchedule {
// been placed in this schedule.
int64_t cycle(const Node* node) const { return cycle_map_.at(node); }

bool empty() const { return cycle_map_.empty(); }

// Returns the nodes scheduled in the given cycle. The node order is
// guaranteed to be topological.
absl::Span<Node* const> nodes_in_cycle(int64_t cycle) const;
Expand Down
56 changes: 39 additions & 17 deletions xls/scheduling/pipeline_scheduling_pass.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,28 +43,50 @@ namespace {
// Adds cycle constraints from a PipelineSchedule into SchedulingOptions.
absl::Status AddCycleConstraints(const PipelineSchedule& schedule,
SchedulingOptions& scheduling_options) {
if (schedule.empty()) {
return absl::OkStatus();
}

absl::flat_hash_map<Node*, int64_t> existing_constraints;
for (const SchedulingConstraint& constraint :
scheduling_options.constraints()) {
if (std::holds_alternative<NodeInCycleConstraint>(constraint)) {
const NodeInCycleConstraint& nic =
std::get<NodeInCycleConstraint>(constraint);
auto [it, inserted] =
existing_constraints.try_emplace(nic.GetNode(), nic.GetCycle());
if (!inserted && it->second != nic.GetCycle()) {
return absl::InvalidArgumentError(absl::StrFormat(
"Node %s has conflicting cycle constraints: constrained to both %d "
"and %d",
nic.GetNode()->GetName(), it->second, nic.GetCycle()));
}
}
}

for (int64_t c = 0; c < schedule.length(); ++c) {
for (Node* node : schedule.nodes_in_cycle(c)) {
bool already_constrained = false;
for (const SchedulingConstraint& constraint :
scheduling_options.constraints()) {
if (std::holds_alternative<NodeInCycleConstraint>(constraint)) {
const NodeInCycleConstraint& nic =
std::get<NodeInCycleConstraint>(constraint);
if (nic.GetNode() == node) {
if (nic.GetCycle() != c) {
return absl::InvalidArgumentError(absl::StrFormat(
"Schedule contradicts cycle constraints for node %s: "
"scheduled for cycle %d, but constrained to cycle %d",
node->GetName(), c, nic.GetCycle()));
}
already_constrained = true;
}
}
if (IsUntimed(node)) {
continue;
}
if (!already_constrained && !IsUntimed(node)) {

auto it = existing_constraints.find(node);
if (it == existing_constraints.end()) {
// No existing constraint; add this one.
scheduling_options.add_constraint(NodeInCycleConstraint(node, c));
continue;
}

// Otherwise, there's an existing constraint; we either match it, or fail
// with a contradiction.
if (it->second == c) {
// Already constrained to this cycle.
continue;
}
return absl::InvalidArgumentError(
absl::StrFormat("Schedule contradicts cycle constraints for node %s: "
"scheduled for cycle %d, but constrained to cycle %d",
node->GetName(), c, it->second));
}
}
return absl::OkStatus();
Expand Down
Loading