feat(ir): rethink logic for finding vertices with no inputs

This commit is contained in:
multisn8 2024-01-19 02:10:27 +01:00
parent 66639771ac
commit 4fd35736d5
Signed by untrusted user: multisamplednight
GPG key ID: 6D525AA147CBDAE2

View file

@ -191,7 +191,7 @@ impl GraphIr {
// no, not today
pub fn topological_sort(&self) -> Vec<Instruction> {
// count how many incoming edges each vertex has
let input_counts: Map<_, usize> =
let nonzero_input_counts: Map<_, usize> =
self.rev_edges
.iter()
.fold(Map::new(), |mut count, (input, _)| {
@ -199,22 +199,14 @@ impl GraphIr {
count
});
// could experiment with a VecDeque here
let mut active_queue = Vec::new();
// what vertices can we start with? in other words, which ones have 0 inputs?
let unresolved_input_count: Map<id::Instruction, usize> = input_counts
.into_iter()
.filter_map(|(instr, count)| {
dbg!(count);
if count == 0 {
active_queue.push(instr);
None
} else {
Some((instr, count))
}
})
.collect();
// are there any unconnected ones we could start with?
// TODO: experiment if a VecDeque with some ordering fun is digested better by the executor
let no_inputs: Vec<_> = {
let nonzero: Set<_> = nonzero_input_counts.keys().collect();
let all: Set<_> = self.instructions.keys().collect();
all.difference(&nonzero).copied().collect()
};
let mut active_queue = no_inputs;
// then let's find the order!
let mut order = Vec::new();
@ -224,25 +216,27 @@ impl GraphIr {
// make sure all dependents notice that
for dependent in self
.dependents(&current)
.dependents(current)
.expect("graph to be consistent")
.flatten()
{
dbg!(dependent);
}
order.push(self.resolve(&current).expect("graph to be consistent"));
// TODO: check if this instruction is "well-fed", that is, has all the inputs it needs,
// and if not, panic
order.push(self.resolve(current).expect("graph to be consistent"));
}
assert!(
!unresolved_input_count.is_empty(),
!nonzero_input_counts.is_empty(),
concat!(
"topological sort didn't cover all instructions\n",
"either there are unconnected inputs, or there is a cycle\n",
"unresolved instructions:\n",
"{:#?}"
),
unresolved_input_count
nonzero_input_counts,
);
order