Skip to content

Commit

Permalink
Merge pull request #9 from cda-tum/Failing_Junctions
Browse files Browse the repository at this point in the history
Failing junctions Option
  • Loading branch information
danielschoenberger authored Nov 14, 2024
2 parents 6893cde + 65bd09a commit 202dbd5
Show file tree
Hide file tree
Showing 16 changed files with 79 additions and 61 deletions.
Binary file modified .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ __pycache__/

# Ignore macOS system files
.DS_Store

QASM_files/
22 changes: 6 additions & 16 deletions Cycles.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import matplotlib.pyplot as plt
import networkx as nx
import numpy as np
from more_itertools import distinct_combinations, pairwise
from graph_utils import get_idc_from_idx, get_idx_from_idc, get_path_to_node, calc_dist_to_pz, MZGraphCreator, GraphCreator
from graph_utils import get_idc_from_idx, get_idx_from_idc, get_path_to_node, calc_dist_to_pz, order_edges, MZGraphCreator, GraphCreator

class MemoryZone:
def __init__(
Expand Down Expand Up @@ -206,20 +205,7 @@ def find_next_edge(self, edge_idc, towards=(0, 0)):
return get_idc_from_idx(self.idc_dict, next_edge_idx)

def find_ordered_edges(self, edge1, edge2):
# Find the common node shared between the two edges
common_node = set(edge1).intersection(set(edge2))

if len(common_node) != 1 and edge1 != edge2:
msg = f"The input edges are not connected. Edges: {edge1}, {edge2}"
raise ValueError(msg)

common_node = common_node.pop()
if edge1[0] == common_node:
edge1_in_order = (edge1[1], common_node)
edge2_in_order = (common_node, edge2[1]) if edge2[0] == common_node else (common_node, edge2[0])
else:
edge1_in_order = (edge1[0], common_node)
edge2_in_order = (common_node, edge2[1]) if edge2[0] == common_node else (common_node, edge2[0])
edge1_in_order, edge2_in_order = order_edges(edge1, edge2)

# new if same edge twice don't change order
if get_idx_from_idc(self.idc_dict, edge1_in_order) == get_idx_from_idc(self.idc_dict, edge2_in_order):
Expand All @@ -245,6 +231,10 @@ def have_common_junction_node(self, edge1, edge2):
return len(common_junction_nodes) == 1

def create_outer_circle(self, edge_idc, next_edge, other_next_edges, towards=(0, 0)):
if towards == (0, 0):
# towards is first edge in graph (can't be (0,0) because it may be deleted)
towards = list(self.graph.edges())[0][0]

# move from entry to memory zone
if get_idx_from_idc(self.idc_dict, edge_idc) == get_idx_from_idc(
self.idc_dict, self.graph_creator.entry_edge
Expand Down
Binary file modified QASM_files/.DS_Store
Binary file not shown.
Binary file modified QASM_files/full_register_access/.DS_Store
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
OPENQASM 2.0;
include "qelib1.inc";

qreg q[64];
qreg q[50];
h q[0];
h q[1];
h q[2];
Expand Down
Binary file modified __pycache__/Cycles.cpython-311.pyc
Binary file not shown.
Binary file modified __pycache__/compilation.cpython-311.pyc
Binary file not shown.
Binary file modified __pycache__/graph_utils.cpython-311.pyc
Binary file not shown.
Binary file modified __pycache__/plotting.cpython-311.pyc
Binary file not shown.
Binary file modified __pycache__/scheduling.cpython-311.pyc
Binary file not shown.
53 changes: 38 additions & 15 deletions graph_utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import networkx as nx
from more_itertools import distinct_combinations, pairwise
# global delete_node
# delete_node = (3, 4)

# create dictionary to swap from idx to idc and vice versa
def create_idc_dictionary(nx_g):
Expand All @@ -15,6 +17,23 @@ def get_idx_from_idc(edge_dictionary, idc):
def get_idc_from_idx(edge_dictionary, idx):
return edge_dictionary[idx]

def order_edges(edge1, edge2):
# Find the common node shared between the two edges
common_node = set(edge1).intersection(set(edge2))

if len(common_node) != 1 and edge1 != edge2:
msg = f"The input edges are not connected. Edges: {edge1}, {edge2}"
raise ValueError(msg)

common_node = common_node.pop()
if edge1[0] == common_node:
edge1_in_order = (edge1[1], common_node)
edge2_in_order = (common_node, edge2[1]) if edge2[0] == common_node else (common_node, edge2[0])
else:
edge1_in_order = (edge1[0], common_node)
edge2_in_order = (common_node, edge2[1]) if edge2[0] == common_node else (common_node, edge2[0])

return edge1_in_order, edge2_in_order

def get_path_to_node(nx_g, src, tar, exclude_exit=False, exclude_first_entry_connection=True):
edge_path = []
Expand Down Expand Up @@ -93,6 +112,7 @@ def create_graph(self):
if self.pz == 'mid':
self._remove_mid_part(networkx_graph)
nx.set_edge_attributes(networkx_graph, "trap", "edge_type")
#self._delete_junction(networkx_graph, delete_node)

return networkx_graph

Expand Down Expand Up @@ -134,6 +154,10 @@ def _set_junction_nodes(self, networkx_graph):
for j in range(0, self.n_extended, self.ion_chain_size_horizontal):
networkx_graph.add_node((i, j), node_type="junction_node", color="g")

def _delete_junction(self, networkx_graph, junction_node):
# Remove the junction node
networkx_graph.remove_node(junction_node)

def get_graph(self):
return self.networkx_graph

Expand Down Expand Up @@ -177,6 +201,7 @@ def create_graph(self):
self._remove_mid_part(networkx_graph)
nx.set_edge_attributes(networkx_graph, "trap", "edge_type")
self._set_processing_zone(networkx_graph)
#self._delete_junction(networkx_graph, delete_node)

return networkx_graph

Expand Down Expand Up @@ -333,36 +358,34 @@ def _set_processing_zone(self, networkx_graph):
networkx_graph.add_edge(self.parking_edge[0], self.parking_edge[1], edge_type="parking_edge", color="g")

else:
raise ValueError("pz must be 'mid' or 'outer'")
raise ValueError("pz must be 'mid' or 'outer'")

def _delete_junction(self, networkx_graph, junction_node):
# Remove the junction node
networkx_graph.remove_node(junction_node)


def get_graph(self):
return self.networkx_graph


def find_connected_edges(self):
connected_edge_pairs = set()

for edge in self.networkx_graph.edges():
node1, node2 = edge
# Find edges connected to node1
for neighbor in self.networkx_graph.neighbors(node1):
if neighbor != node2: # avoid the original edge
connected_edge_pairs.add(tuple(sorted([edge, (node1, neighbor)])))
edge_pair = tuple(sorted([edge, (node1, neighbor)]))
connected_edge_pairs.add(edge_pair)
# Find edges connected to node2
for neighbor in self.networkx_graph.neighbors(node2):
if neighbor != node1: # avoid the original edge
connected_edge_pairs.add(tuple(sorted([edge, (node2, neighbor)])))

edge_pair = tuple(sorted([edge, (node2, neighbor)]))
connected_edge_pairs.add(edge_pair)
# order edges (also include reverse order -> opposite direction moves are now needed if a junction fails)
connected_edge_pairs = [order_edges(edge_pair[0], edge_pair[1]) for edge_pair in connected_edge_pairs] + [order_edges(edge_pair[1], edge_pair[0]) for edge_pair in connected_edge_pairs]
# Convert set of tuples to a list of lists
connected_edge_pairs = [list(pair) for pair in connected_edge_pairs]

return connected_edge_pairs

# Example of how to call this method
def print_connected_edges(self):
connected_edges = self.find_connected_edges()
for edge_pair in connected_edges:
print(edge_pair)

# gc = GraphCreator(m=3, n=3, ion_chain_size_vertical=2, ion_chain_size_horizontal=2, pz='mid')
# gc.print_connected_edges()
return connected_edge_pairs
2 changes: 1 addition & 1 deletion plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def plot_state(graph, ion_moves, labels, plot_ions=True, show_plot=False, save_p
edge_labels = nx.get_edge_attributes(graph, "ion_chain")

# plt.figure(figsize=(25, 15))
plt.figure(figsize=(max(pos.keys())[0]*10, max(pos.keys())[1]*10))#self.n * self.ion_chain_size_horizontal, self.m * self.ion_chain_size_vertical))
plt.figure(figsize=(max(pos.keys())[0]*3, max(pos.keys())[1]*3))#self.n * self.ion_chain_size_horizontal, self.m * self.ion_chain_size_vertical))
nx.draw_networkx(
graph,
pos=pos,
Expand Down
18 changes: 10 additions & 8 deletions run_benchmarks.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,18 @@ def run_simulation_for_architecture(arch, seeds, pz, max_timesteps, compilation=
m, n, v, h = arch
graph = GraphCreator(m, n, v, h, pz).get_graph()
n_of_traps = len([trap for trap in graph.edges() if graph.get_edge_data(trap[0], trap[1])["edge_type"] == "trap"])
num_ion_chains = 24#math.ceil(n_of_traps / 2)
num_ion_chains = math.ceil(n_of_traps / 2)

try:
ion_chains, number_of_registers = create_starting_config(num_ion_chains, graph, seed=seed)
except:
continue
print(f"ion chains: {ion_chains}, number of registers: {number_of_registers}")
#filename = f"QASM_files/full_register_access/full_register_access_{num_ion_chains}.qasm"
filename = f"QASM_files/QFT_no_swaps/qft_no_swaps_nativegates_quantinuum_tket_{num_ion_chains}.qasm"
filename = f"QASM_files/full_register_access/full_register_access_{num_ion_chains}.qasm"
#filename = f"QASM_files/QFT_no_swaps/qft_no_swaps_nativegates_quantinuum_tket_{num_ion_chains}.qasm"
print(f"arch: {arch}, seed: {seed}, registers: {number_of_registers}\n")

time_2qubit_gate = 3
time_2qubit_gate = 1
time_1qubit_gate = 1
max_chains_in_parking = 3

Expand All @@ -52,8 +52,9 @@ def run_simulation_for_architecture(arch, seeds, pz, max_timesteps, compilation=
memorygrid.distance_map, filename, compilation=compilation
)
seq_length = len(seq)
print(f"seq: {seq}")
timestep = run_simulation(
memorygrid, max_timesteps, seq, flat_seq, dag_dep, next_node_initial, max_length=10, show_plot=False
memorygrid, max_timesteps, seq, flat_seq, dag_dep, next_node_initial, max_length=10
)
timestep_arr.append(timestep)
cpu_time = time.time() - start_time
Expand Down Expand Up @@ -93,17 +94,18 @@ def log_results(arch, timestep_arr, cpu_time_arr, number_of_registers, n_of_trap

def main():
archs = [
[7, 7, 2, 2],
[3, 3, 2, 2],
]
seeds = [0]#, 1, 2, 3, 4]
pz = 'outer'
max_timesteps = 10000000
compilation = False

for arch in archs:
timestep_arr, cpu_time_arr, number_of_registers, n_of_traps, seq_length = run_simulation_for_architecture(
arch, seeds, pz, max_timesteps, compilation=True
arch, seeds, pz, max_timesteps, compilation=compilation
)
log_results(arch, timestep_arr, cpu_time_arr, number_of_registers, n_of_traps, seq_length, compilation=True)
log_results(arch, timestep_arr, cpu_time_arr, number_of_registers, n_of_traps, seq_length, compilation=compilation)

if __name__ == "__main__":
main()
2 changes: 1 addition & 1 deletion run_heuristic.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ def run_simulation_for_architecture(arch, seeds, pz, max_timesteps, time_1qubit_
memorygrid.distance_map, filename, compilation=compilation
)
timestep = run_simulation(
memorygrid, max_timesteps, seq, flat_seq, dag_dep, next_node_initial, max_length=10, show_plot=False
memorygrid, max_timesteps, seq, flat_seq, dag_dep, next_node_initial, max_length=10
)
timestep_arr.append(timestep)
cpu_time = time.time() - start_time
Expand Down
39 changes: 20 additions & 19 deletions scheduling.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from Cycles import get_idc_from_idx, get_idx_from_idc
from plotting import plot_state

show_plot = False
save_plot = False
if save_plot:
# Create a folder for each run with a timestamp (plot widget)
Expand Down Expand Up @@ -358,16 +359,16 @@ def update_sequence_and_process_gate(
gate_execution_finished = False

time_in_pz_counter += 1
# plot_state(memorygrid.graph,
# [get_idx_from_idc(memorygrid.idc_dict, edge_idc) for edge_idc in memorygrid.ion_chains.values()],
# labels=[
# "time step %s" % timestep,
# f"seq elem {seq[0]} execution",
# ],
# show_plot=show_plot,
# save_plot=save_plot,
# filename=[plot_filename if save_plot else None][0],
# )
plot_state(memorygrid.graph,
[get_idx_from_idc(memorygrid.idc_dict, edge_idc) for edge_idc in memorygrid.ion_chains.values()],
labels=[
"time step %s" % timestep,
f"seq elem {seq[0]} execution",
],
show_plot=show_plot,
save_plot=save_plot,
filename=[plot_filename if save_plot else None][0],
)

# print time step and gate (gate x out of y)
print(f"time step: {timestep}, execution of gate ({memorygrid.seq_length-len(seq)+1}/{memorygrid.seq_length}) on qubit(s) {seq[0]}")
Expand Down Expand Up @@ -415,14 +416,14 @@ def update_sequence_and_process_gate(
for gate_element in seq[0]:
new_gate_starting = gate_element in chains_in_parking

# else:
# plot_state(memorygrid.graph,
# [get_idx_from_idc(memorygrid.idc_dict, edge_idc) for edge_idc in memorygrid.ion_chains.values()],
# labels=["time step %s" % timestep, f"next seq elem: {seq[0]}"],
# show_plot=show_plot,
# save_plot=save_plot,
# filename=[plot_filename if save_plot else None][0],
# )
else:
plot_state(memorygrid.graph,
[get_idx_from_idc(memorygrid.idc_dict, edge_idc) for edge_idc in memorygrid.ion_chains.values()],
labels=["time step %s" % timestep, f"next seq elem: {seq[0]}"],
show_plot=show_plot,
save_plot=save_plot,
filename=[plot_filename if save_plot else None][0],
)

return (
False,
Expand Down Expand Up @@ -454,7 +455,7 @@ def check_duplicates(lst, memorygrid, parking_idc, max_number_parking):
raise AssertionError(message)


def run_simulation(memorygrid, max_timesteps, seq, flat_seq, dag_dep, next_node_initial, max_length, show_plot):
def run_simulation(memorygrid, max_timesteps, seq, flat_seq, dag_dep, next_node_initial, max_length):
time_in_pz_counter = 0
next_gate_is_two_qubit_gate = len(seq[0]) == 2
gate_execution_finished = True
Expand Down

0 comments on commit 202dbd5

Please sign in to comment.