From e08403334c72f16223fde14687fa8c70df052e2f Mon Sep 17 00:00:00 2001 From: Ibrahim Date: Tue, 9 Jan 2024 10:18:23 -0500 Subject: [PATCH] fix bug and update notebook --- .../circuit_interface.py | 10 +-- .../disjoint_subcircuits_state.py | 10 +-- .../tutorials/LO_circuit_cut_finder.ipynb | 77 +++++++------------ 3 files changed, 37 insertions(+), 60 deletions(-) diff --git a/circuit_knitting/cutting/cut_finding/LO_circuit_cut_optimizer/circuit_interface.py b/circuit_knitting/cutting/cut_finding/LO_circuit_cut_optimizer/circuit_interface.py index d7049e21c..ae8a70daa 100644 --- a/circuit_knitting/cutting/cut_finding/LO_circuit_cut_optimizer/circuit_interface.py +++ b/circuit_knitting/cutting/cut_finding/LO_circuit_cut_optimizer/circuit_interface.py @@ -243,7 +243,8 @@ def insertWireCut(self, gate_ID, input_ID, src_wire_ID, dest_wire_ID, cut_type): wire/qubit ID of the source wire to be cut is also provided as input to allow the wire choice to be verified. The ID of the (new) destination wire/qubit must also be provided. The cut - type can be "LO", "LOCCWithAncillas", or "LOCCNoAncillas". + type as of now can only be "LO", with the options "LOCCWithAncillas" + and "LOCCNoAncillas" being added in the future. """ gate_pos = self.new_gate_ID_map[gate_ID] @@ -344,15 +345,10 @@ def exportSubcircuitsAsString(self, name_mapping="default"): out = list(range(self.getNumWires())) alphabet = string.ascii_uppercase + string.ascii_lowercase - #print(out) - + for k, subcircuit in enumerate(self.subcircuits): for wire in subcircuit: out[wire_map[wire]] = alphabet[k] - - # print (wire_map) - # print(self.subcircuits) - # print(out) return "".join(out) def makeWireMapping(self, name_mapping): diff --git a/circuit_knitting/cutting/cut_finding/LO_circuit_cut_optimizer/disjoint_subcircuits_state.py b/circuit_knitting/cutting/cut_finding/LO_circuit_cut_optimizer/disjoint_subcircuits_state.py index 0f7aff206..5c872bb7c 100644 --- a/circuit_knitting/cutting/cut_finding/LO_circuit_cut_optimizer/disjoint_subcircuits_state.py +++ b/circuit_knitting/cutting/cut_finding/LO_circuit_cut_optimizer/disjoint_subcircuits_state.py @@ -167,10 +167,8 @@ def print(self, simple=False): cut_actions_sublist = [] # Output formatting for LO gate and wire cuts. - # Temporary and needs to be updated later on. - for i in range(len(cut_actions)): - if cut_actions[i][0] == ("CutLeftWire" or "CutRightWire"): + if (cut_actions[i][0] == "CutLeftWire") or (cut_actions[i][0] == ("CutRightWire")): cut_actions_sublist.append( { "Cut action": cut_actions[i][0], @@ -187,12 +185,14 @@ def print(self, simple=False): "Cut Gate": [cut_actions[i][1][0], cut_actions[i][1][1]], } ) + if not cut_actions_sublist: + cut_actions_sublist = cut_actions if simple: # print only a subset of properties. # print(self.lowerBoundGamma(), self.gamma_UB, self.getMaxWidth()) - print('Actions:', PrintActionListWithNames(self.actions)) + # print('Actions:', PrintActionListWithNames(self.actions)) # print(self.no_merge) - #print(cut_actions_sublist) + print(cut_actions_sublist) else: print("wiremap", self.wiremap) print("num_wires", self.num_wires) diff --git a/docs/circuit_cutting/tutorials/LO_circuit_cut_finder.ipynb b/docs/circuit_cutting/tutorials/LO_circuit_cut_finder.ipynb index 461e7c9b9..b019095d5 100644 --- a/docs/circuit_cutting/tutorials/LO_circuit_cut_finder.ipynb +++ b/docs/circuit_cutting/tutorials/LO_circuit_cut_finder.ipynb @@ -67,7 +67,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -77,30 +77,28 @@ "\n", "\n", "---------- 4 Qubits per QPU, 2 QPUs ----------\n", - " Gamma = 1.0 , min_reached = True\n", - "Actions: []\n", + " Gamma = 1.0 , Min_gamma_reached = True\n", + "[]\n", "Subcircuits: AAAA \n", "\n", "\n", "\n", "---------- 3 Qubits per QPU, 2 QPUs ----------\n", - " Gamma = 9.0 , min_reached = True\n", - "Actions: [['CutTwoQubitGate', [17, ['cx', 2, 3], None], ((1, 2), (2, 3))], ['CutTwoQubitGate', [25, ['cx', 2, 3], None], ((1, 2), (2, 3))]]\n", + " Gamma = 9.0 , Min_gamma_reached = True\n", + "[{'Cut action': 'CutTwoQubitGate', 'Cut Gate': [17, ['cx', 2, 3]]}, {'Cut action': 'CutTwoQubitGate', 'Cut Gate': [25, ['cx', 2, 3]]}]\n", "Subcircuits: AAAB \n", "\n", "\n", "\n", "---------- 2 Qubits per QPU, 2 QPUs ----------\n", - " Gamma = 9.0 , min_reached = True\n", - "Actions: [['CutTwoQubitGate', [9, ['cx', 1, 2], None], ((1, 1), (2, 2))], ['CutTwoQubitGate', [20, ['cx', 1, 2], None], ((1, 1), (2, 2))]]\n", + " Gamma = 9.0 , Min_gamma_reached = True\n", + "[{'Cut action': 'CutTwoQubitGate', 'Cut Gate': [9, ['cx', 1, 2]]}, {'Cut action': 'CutTwoQubitGate', 'Cut Gate': [20, ['cx', 1, 2]]}]\n", "Subcircuits: AABB \n", "\n" ] } ], "source": [ - "interface = SimpleGateList(circuit_ckt)\n", - "\n", "settings = OptimizationSettings(rand_seed = 12345)\n", "\n", "settings.setEngineSelection('CutOptimization', 'BestFirst')\n", @@ -117,6 +115,8 @@ " \n", " constraint_obj = DeviceConstraints(qubits_per_QPU = qpu_qubits, \n", " num_QPUs = num_QPUs)\n", + " \n", + " interface = SimpleGateList(circuit_ckt)\n", "\n", " op = LOCutsOptimizer(interface, \n", " settings, \n", @@ -125,7 +125,7 @@ " out = op.optimize()\n", "\n", " print(' Gamma =', None if (out is None) else out.upperBoundGamma(),\n", - " ', min_reached =', op.minimumReached())\n", + " ', Min_gamma_reached =', op.minimumReached())\n", " if (out is not None):\n", " out.print(simple=True)\n", " else:\n", @@ -189,7 +189,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -199,55 +199,45 @@ "\n", "\n", "---------- 7 Qubits per QPU, 2 QPUs ----------\n", - " Gamma = 1.0 , min_reached = True\n", - "Actions: []\n", + " Gamma = 1.0 , Min_gamma_reached = True\n", + "[]\n", "Subcircuits: AAAAAAA \n", "\n", "\n", "\n", "---------- 6 Qubits per QPU, 2 QPUs ----------\n", - " Gamma = 3.0 , min_reached = True\n", - "Actions: [['CutTwoQubitGate', [12, ['cx', 3, 6], None], ((1, 3), (2, 6))]]\n", + " Gamma = 3.0 , Min_gamma_reached = True\n", + "[{'Cut action': 'CutTwoQubitGate', 'Cut Gate': [12, ['cx', 3, 6]]}]\n", "Subcircuits: AAAAAAB \n", "\n", "\n", "\n", "---------- 5 Qubits per QPU, 2 QPUs ----------\n", - " Gamma = 4.0 , min_reached = True\n", - "Actions: [['CutLeftWire', [11, ['cx', 3, 5], None], ((1, 3, 7),)]]\n", + " Gamma = 4.0 , Min_gamma_reached = True\n", + "[{'Cut action': 'CutLeftWire', 'Cut location:': {'Gate': [11, ['cx', 3, 5]]}, 'Input wire': 1}]\n", "Subcircuits: AAAABABB \n", "\n", "\n", "\n", "---------- 4 Qubits per QPU, 2 QPUs ----------\n", - " Gamma = 4.0 , min_reached = True\n", - "Actions: [['CutLeftWire', [10, ['cx', 3, 4], None], ((1, 3, 7),)]]\n", + " Gamma = 4.0 , Min_gamma_reached = True\n", + "[{'Cut action': 'CutLeftWire', 'Cut location:': {'Gate': [10, ['cx', 3, 4]]}, 'Input wire': 1}]\n", "Subcircuits: AAAABBBB \n", "\n", "\n", "\n", "---------- 3 Qubits per QPU, 2 QPUs ----------\n", - " Gamma = 16.0 , min_reached = True\n", - "Actions: [['CutRightWire', [9, ['cx', 2, 3], None], ((2, 3, 7),)], ['CutLeftWire', [11, ['cx', 3, 5], None], ((1, 7, 8),)]]\n", + " Gamma = 16.0 , Min_gamma_reached = True\n", + "[{'Cut action': 'CutRightWire', 'Cut location:': {'Gate': [9, ['cx', 2, 3]]}, 'Input wire': 2}, {'Cut action': 'CutLeftWire', 'Cut location:': {'Gate': [11, ['cx', 3, 5]]}, 'Input wire': 1}]\n", "Subcircuits: AABABCBCC \n", "\n", "\n", "\n", "---------- 2 Qubits per QPU, 2 QPUs ----------\n", - " Gamma = 243.0 , min_reached = True\n", - "Actions: [['CutTwoQubitGate', [7, ['cx', 0, 3], None], ((1, 0), (2, 3))], ['CutTwoQubitGate', [8, ['cx', 1, 3], None], ((1, 1), (2, 3))], ['CutTwoQubitGate', [9, ['cx', 2, 3], None], ((1, 2), (2, 3))], ['CutTwoQubitGate', [11, ['cx', 3, 5], None], ((1, 3), (2, 5))], ['CutTwoQubitGate', [12, ['cx', 3, 6], None], ((1, 3), (2, 6))]]\n" - ] - }, - { - "ename": "TypeError", - "evalue": "sequence item 4: expected str instance, int found", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[5], line 45\u001b[0m\n\u001b[1;32m 34\u001b[0m \u001b[38;5;28mprint\u001b[39m(out)\n\u001b[1;32m 36\u001b[0m \u001b[38;5;66;03m# print('\\nAfter Cuts\\n\\nGate Positions:', interface.new_gate_ID_map)\u001b[39;00m\n\u001b[1;32m 37\u001b[0m \u001b[38;5;66;03m# for k, gate in enumerate(interface.new_circuit):\u001b[39;00m\n\u001b[1;32m 38\u001b[0m \u001b[38;5;66;03m# print(k, gate, interface.cut_type[k])\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 43\u001b[0m \u001b[38;5;66;03m# print(k, gate, interface.cut_type[k])\u001b[39;00m\n\u001b[1;32m 44\u001b[0m \u001b[38;5;66;03m# print('Output Wire Mapping:', interface.exportOutputWires(name_mapping='default'))\u001b[39;00m\n\u001b[0;32m---> 45\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mSubcircuits:\u001b[39m\u001b[38;5;124m'\u001b[39m, \u001b[43minterface\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexportSubcircuitsAsString\u001b[49m\u001b[43m(\u001b[49m\u001b[43mname_mapping\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mdefault\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m,\u001b[38;5;124m'\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124m'\u001b[39m)\n", - "File \u001b[0;32m~/circuit-knitting-toolbox/circuit_knitting/cutting/cut_finding/LO_circuit_cut_optimizer/circuit_interface.py:356\u001b[0m, in \u001b[0;36mSimpleGateList.exportSubcircuitsAsString\u001b[0;34m(self, name_mapping)\u001b[0m\n\u001b[1;32m 351\u001b[0m out[wire_map[wire]] \u001b[38;5;241m=\u001b[39m alphabet[k]\n\u001b[1;32m 353\u001b[0m \u001b[38;5;66;03m# print (wire_map)\u001b[39;00m\n\u001b[1;32m 354\u001b[0m \u001b[38;5;66;03m# print(self.subcircuits) \u001b[39;00m\n\u001b[1;32m 355\u001b[0m \u001b[38;5;66;03m# print(out)\u001b[39;00m\n\u001b[0;32m--> 356\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mjoin\u001b[49m\u001b[43m(\u001b[49m\u001b[43mout\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[0;31mTypeError\u001b[0m: sequence item 4: expected str instance, int found" + " Gamma = 243.0 , Min_gamma_reached = True\n", + "[{'Cut action': 'CutTwoQubitGate', 'Cut Gate': [7, ['cx', 0, 3]]}, {'Cut action': 'CutTwoQubitGate', 'Cut Gate': [8, ['cx', 1, 3]]}, {'Cut action': 'CutTwoQubitGate', 'Cut Gate': [9, ['cx', 2, 3]]}, {'Cut action': 'CutTwoQubitGate', 'Cut Gate': [11, ['cx', 3, 5]]}, {'Cut action': 'CutTwoQubitGate', 'Cut Gate': [12, ['cx', 3, 6]]}]\n", + "Subcircuits: ABCDDEF \n", + "\n" ] } ], @@ -256,8 +246,6 @@ "\n", "circuit_ckt_wirecut=QCtoCCOCircuit(qc_0)\n", "\n", - "interface = SimpleGateList(circuit_ckt_wirecut)\n", - "\n", "settings = OptimizationSettings(rand_seed = 12345)\n", "\n", "settings.setEngineSelection('CutOptimization', 'BestFirst')\n", @@ -274,6 +262,8 @@ " constraint_obj = DeviceConstraints(qubits_per_QPU = qpu_qubits, \n", " num_QPUs = num_QPUs)\n", "\n", + " interface = SimpleGateList(circuit_ckt_wirecut)\n", + " \n", " op = LOCutsOptimizer(interface, \n", " settings, \n", " constraint_obj)\n", @@ -281,21 +271,12 @@ " out = op.optimize()\n", "\n", " print(' Gamma =', None if (out is None) else out.upperBoundGamma(),\n", - " ', min_reached =', op.minimumReached())\n", + " ', Min_gamma_reached =', op.minimumReached())\n", " if (out is not None):\n", " out.print(simple=True)\n", " else:\n", " print(out)\n", - " \n", - " # print('\\nAfter Cuts\\n\\nGate Positions:', interface.new_gate_ID_map)\n", - " # for k, gate in enumerate(interface.new_circuit):\n", - " # print(k, gate, interface.cut_type[k])\n", - " # print('Output Wires:', interface.output_wires,'\\n')\n", - " \n", - " # print('Name Mapping = \"default\"')\n", - " # for k, gate in enumerate(interface.exportCutCircuit(name_mapping='default')):\n", - " # print(k, gate, interface.cut_type[k])\n", - " # print('Output Wire Mapping:', interface.exportOutputWires(name_mapping='default'))\n", + "\n", " print('Subcircuits:', interface.exportSubcircuitsAsString(name_mapping='default'),'\\n')" ] }