-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
Fully port Depth
and Size
passes to Rust
#13040
Changes from 1 commit
5b41efa
80ff154
af244c2
3c70630
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2168,14 +2168,15 @@ def _format(operand): | |
} | ||
|
||
let circuit_to_dag = imports::CIRCUIT_TO_DAG.get_bound(py); | ||
for node_index in | ||
self.op_nodes_by_py_type(imports::CONTROL_FLOW_OP.get_bound(py).downcast()?, true) | ||
{ | ||
let NodeType::Operation(node) = &self.dag[node_index] else { | ||
return Err(DAGCircuitError::new_err("unknown control-flow type")); | ||
for node in self.dag.node_weights() { | ||
let NodeType::Operation(node) = node else { | ||
continue; | ||
}; | ||
if !node.op.control_flow() { | ||
continue; | ||
} | ||
let OperationRef::Instruction(inst) = node.op.view() else { | ||
unreachable!("Control Flow operations must be a PyInstruction"); | ||
panic!("control flow op must be an instruction"); | ||
}; | ||
let inst_bound = inst.instruction.bind(py); | ||
if inst_bound.is_instance(imports::FOR_LOOP_OP.get_bound(py))? { | ||
|
@@ -2239,34 +2240,33 @@ def _format(operand): | |
Ok(if recurse { | ||
let circuit_to_dag = imports::CIRCUIT_TO_DAG.get_bound(py); | ||
let mut node_lookup: HashMap<NodeIndex, usize> = HashMap::new(); | ||
|
||
for node_index in | ||
self.op_nodes_by_py_type(imports::CONTROL_FLOW_OP.get_bound(py).downcast()?, true) | ||
{ | ||
if let NodeType::Operation(node) = &self.dag[node_index] { | ||
if let OperationRef::Instruction(inst) = node.op.view() { | ||
let inst_bound = inst.instruction.bind(py); | ||
let weight = | ||
if inst_bound.is_instance(imports::FOR_LOOP_OP.get_bound(py))? { | ||
node.params_view().len() | ||
} else { | ||
1 | ||
}; | ||
if weight == 0 { | ||
node_lookup.insert(node_index, 0); | ||
} else { | ||
let raw_blocks = inst_bound.getattr("blocks")?; | ||
let blocks = raw_blocks.downcast::<PyTuple>()?; | ||
let mut block_weights: Vec<usize> = Vec::with_capacity(blocks.len()); | ||
for block in blocks.iter() { | ||
let inner_dag: &DAGCircuit = | ||
&circuit_to_dag.call1((block,))?.extract()?; | ||
block_weights.push(inner_dag.depth(py, true)?); | ||
} | ||
node_lookup | ||
.insert(node_index, weight * block_weights.iter().max().unwrap()); | ||
} | ||
for (node_index, node) in self.dag.node_references() { | ||
let NodeType::Operation(node) = node else { | ||
continue; | ||
}; | ||
if !node.op.control_flow() { | ||
continue; | ||
} | ||
let OperationRef::Instruction(inst) = node.op.view() else { | ||
panic!("control flow op must be an instruction") | ||
}; | ||
let inst_bound = inst.instruction.bind(py); | ||
let weight = if inst_bound.is_instance(imports::FOR_LOOP_OP.get_bound(py))? { | ||
node.params_view().len() | ||
} else { | ||
1 | ||
}; | ||
if weight == 0 { | ||
node_lookup.insert(node_index, 0); | ||
} else { | ||
let raw_blocks = inst_bound.getattr("blocks")?; | ||
let blocks = raw_blocks.downcast::<PyTuple>()?; | ||
let mut block_weights: Vec<usize> = Vec::with_capacity(blocks.len()); | ||
for block in blocks.iter() { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need the PyTuple downcast here? Should we be able to just call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea. Done in 80ff154. |
||
let inner_dag: &DAGCircuit = &circuit_to_dag.call1((block,))?.extract()?; | ||
block_weights.push(inner_dag.depth(py, true)?); | ||
} | ||
node_lookup.insert(node_index, weight * block_weights.iter().max().unwrap()); | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we want an
&& CONTROL_FLOW_OP_NAMES.iter().any(|x| self.op_names.contains_key(&x.to_string()))
on this condition so we don't bother with the for loop if we know there are no control flow instructions. The same question applies tosize()
as well.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea, and allowed me to make the code a bit cleaner across both methods. I added a helper as well, which is private to
DAGCircuit
for now.Done in af244c2.