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
3 changes: 1 addition & 2 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
ocular:
# path: examples/adder_n28.qasm
path: examples/adder_n64.qasm
# path: examples/adder_n10_medium.qasm
# path: examples/adder_n10_shortened.qasm
path: examples/adder_n64.qasm
# path: examples/adder_n10.qasm
# path: examples/adder_n4.qasm
# path: /home/jakob/Documents/hamiltonians/ham_heis_graph_2D_grid_nonpbc_qubitnodes_Lx_5_Ly_186_h_0_5.qasm
# path: /home/jakob/Documents/hamiltonians/ham_heis_graph_2D_grid_pbc_qubitnodes_Lx_5_Ly_186_h_3.qasm
Expand Down
63 changes: 37 additions & 26 deletions rust/src/routing/multi_sabre.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ impl MultiSABRE {
while !self.front_layer.is_empty() {
let mut current_swaps: Vec<[i32; 2]> = Vec::new();

println!("Are we even in here?");
// println!("Are we even in here?");
// while execute_gate_list.is_empty() && current_swaps.len() < self.num_qubits as usize * 10 {
while execute_gate_list.is_empty() {
if current_swaps.len() > 10 * self.num_qubits as usize {
Expand All @@ -90,7 +90,7 @@ impl MultiSABRE {
let swaps = self.choose_best_swaps(layers as usize);

// We apparently never get here
println!("Chose swaps: {:?}", swaps);
// println!("Chose swaps: {:?}", swaps);

for swap in swaps {
let q0 = swap[0];
Expand Down Expand Up @@ -174,8 +174,16 @@ struct StackState {
layer: usize
}

#[derive(Clone)]
struct StackState {
mapper_state: RoutingState,
current_sequence: Vec<[i32; 2]>,
current_score: f64,
layer: usize
}

impl MultiSABRE {
fn save_state(&self, num_executable_gates: usize) -> RoutingState {
fn save_state(&self) -> RoutingState {
RoutingState {
front_layer: self.front_layer.clone(),
required_predecessors: self.required_predecessors.clone(),
Expand All @@ -193,33 +201,40 @@ impl MultiSABRE {
}

fn choose_best_swaps(&mut self, layers: usize) -> Vec<[i32; 2]> {
let start_state = self.save_state(0);
let start_state = self.save_state();

let mut stack = Vec::new();
let mut scores: FxHashMap<Vec<[i32; 2]>, f64> = FxHashMap::default();

stack.push(StackState {
mapper_state: self.save_state(0),
mapper_state: self.save_state(),
current_sequence: Vec::new(),
current_score: 0.0,
layer: layers
});

while let Some(state) = stack.pop() {
// Shouldn't we also consider if swap_candidates.is_empty()?
if state.layer == 0 {
self.apply_state(state.mapper_state.clone());

let score = self.calculate_heuristic(state.mapper_state.num_executable_gates);
scores.insert(state.current_sequence.clone(), score);
continue;
scores.insert(state.current_sequence.clone(), state.current_score);
continue
}

let initial_state = state.mapper_state.clone();

let swap_candidates = self.compute_swap_candidates();

if swap_candidates.is_empty() {
scores.insert(state.current_sequence.clone(), state.current_score);
continue
}

for &[q0, q1] in &swap_candidates {
self.apply_state(initial_state.clone());

let before = self.calculate_heuristic();
self.apply_swap([q0, q1]);
let after = self.calculate_heuristic();
let diff = after - before;

let mut execute_gate_list = Vec::new();
if let Some(node) = self.executable_node_on_qubit(q0) {
Expand All @@ -236,14 +251,16 @@ impl MultiSABRE {
let mut new_sequence = state.current_sequence.clone();
new_sequence.push([q0, q1]);

stack.push(StackState {
mapper_state: self.save_state(state.mapper_state.num_executable_gates + execute_gate_list.len()),
current_sequence: new_sequence,
layer: state.layer - 1
});
stack.push(
StackState {
mapper_state: self.save_state(),
current_sequence: new_sequence,
current_score: state.current_score + diff,
layer: state.layer - 1
}
)
}
}

self.apply_state(start_state);

min_score(scores)
Expand Down Expand Up @@ -493,17 +510,15 @@ impl MultiSABRE {
fn min_score(scores: FxHashMap<Vec<[i32; 2]>, f64>) -> Vec<[i32; 2]> {
let mut best_swap_sequences = Vec::new();

// println!("Scores length: {:?}", scores.len());
let mut iter = scores.iter();

let (min_swap_sequence, mut min_score) = iter
.next()
.map(|(swap_sequence, &score)| (swap_sequence, score))
.unwrap();
let (min_swap_sequence, mut min_score) = iter.next().unwrap();

best_swap_sequences.push(min_swap_sequence);

// TODO: Consider introducing an epsilon threshold here
for (swap_sequence, &score) in iter {
for (swap_sequence, score) in iter {
if score < min_score {
min_score = score;
best_swap_sequences.clear();
Expand All @@ -515,10 +530,6 @@ fn min_score(scores: FxHashMap<Vec<[i32; 2]>, f64>) -> Vec<[i32; 2]> {

let mut rng = rng();

if best_swap_sequences.len() > 1 {
println!("Actually making a random choice between: {:?}", scores);
}

best_swap_sequences.choose(&mut rng).unwrap().to_vec()
}

Expand Down
39 changes: 23 additions & 16 deletions src/microscope/commands/ocular.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ def ocular(config):
# Generate coupling map
coupling_map = CouplingMap.from_line(input_circuit.num_qubits)

# import math
# n = input_circuit.num_qubits
# rows = math.isqrt(n)
# cols = math.ceil(n / rows)

# # Now create the grid-based coupling map
# coupling_map = CouplingMap.from_grid(rows, cols)
pm = PassManager(
[
Unroll3qOrMore(),
Expand Down Expand Up @@ -189,7 +196,7 @@ def ocular(config):
transpiled_sabre_circuit_boosted = dag_to_circuit(transpiled_sabre_dag_boosted)

# Print resulting circuit
transpiled_sabre_circuit_boosted.draw("mpl", fold=-1)
# transpiled_sabre_circuit_boosted.draw("mpl", fold=-1)
# plt.show()

# Initialize PassManager to check correctness of result
Expand Down Expand Up @@ -275,23 +282,23 @@ def process_results(test_results):
result_table(rows, columns)

# Plot result
_, ax = plt.subplots()
# _, ax = plt.subplots()

for heuristic, axis_data in data.items():
extended_set_size = axis_data[0]
swaps = axis_data[1]
# for heuristic, axis_data in data.items():
# extended_set_size = axis_data[0]
# swaps = axis_data[1]

ax.plot(extended_set_size, swaps, label=f"{heuristic}")
# ax.plot(extended_set_size, swaps, label=f"{heuristic}")

ax.legend()
# ax.legend()

ax.set(
xlabel="Extended-Set Size",
ylabel="Swaps",
title="Extended-Set Size Scaling",
xlim=(0, 8),
xticks=range(0, 101, 10),
)
ax.grid()
# ax.set(
# xlabel="Extended-Set Size",
# ylabel="Swaps",
# title="Extended-Set Size Scaling",
# xlim=(0, 8),
# xticks=range(0, 101, 10),
# )
# ax.grid()

plt.xlim((0, 100))
# plt.xlim((0, 100))
11 changes: 9 additions & 2 deletions src/microscope/commands/qiskit.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ def qiskit(config):

# Generate coupling map
coupling_map = CouplingMap.from_line(input_circuit.num_qubits)
# import math
# n = input_circuit.num_qubits
# rows = math.isqrt(n)
# cols = math.ceil(n / rows)

# # Now create the grid-based coupling map
# coupling_map = CouplingMap.from_grid(rows, cols)

# Generate DAG from circuit
input_dag = circuit_to_dag(input_circuit)
Expand All @@ -46,7 +53,7 @@ def qiskit(config):
Unroll3qOrMore(),
SabreLayout(coupling_map, skip_routing=True),
ApplyLayout(),
# FullAncillaAllocation(coupling_map),
FullAncillaAllocation(coupling_map),
RemoveBarriers(),
]
)
Expand All @@ -61,7 +68,7 @@ def qiskit(config):
)

transpiled_qc = qiskit_pm.run(preprocessed_circuit)
transpiled_qc.draw("mpl", fold=-1)
# transpiled_qc.draw("mpl", fold=-1)
transpiled_qc_dag = circuit_to_dag(transpiled_qc)

if not cm.property_set.get("is_swap_mapped"):
Expand Down
Loading