microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.25.1

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

source/pip/qsharp/_device/_atom/_trace.py

76lines · modecode

1# Copyright (c) Microsoft Corporation.
2# Licensed under the MIT License.
3
4from pyqir import QirModuleVisitor, qubit_id, required_num_qubits
5from .._device import Device
6
7
8class Trace(QirModuleVisitor):
9
10 def __init__(
11 self,
12 device: Device,
13 ):
14 self.in_parallel = False
15 self.trace = {
16 "qubits": device.home_locs,
17 "steps": [],
18 }
19 self.q_cols = {}
20 super().__init__()
21
22 def _next_step(self):
23 self.trace["steps"].append({"id": len(self.trace["steps"]), "ops": []})
24
25 def _on_function(self, function):
26 num_qubits = required_num_qubits(function)
27 if num_qubits:
28 self.trace["qubits"] = self.trace["qubits"][:num_qubits]
29 super()._on_function(function)
30
31 def _on_call_instr(self, call):
32 if call.callee.name == "__quantum__rt__begin_parallel":
33 self._next_step()
34 self.in_parallel = True
35 elif call.callee.name == "__quantum__rt__end_parallel":
36 self.in_parallel = False
37 elif call.callee.name == "__quantum__qis__move__body":
38 self._on_qis_move(call, call.args[0], call.args[1], call.args[2])
39 elif call.callee.name == "__quantum__qis__sx__body":
40 self._on_qis_sx(call, call.args[0])
41 else:
42 super()._on_call_instr(call)
43
44 def _on_qis_move(self, call, qubit, row, col):
45 if not self.in_parallel:
46 self._next_step()
47 q = qubit_id(qubit)
48 self.q_cols[q] = col.value
49 self.trace["steps"][-1]["ops"].append(f"move({row.value}, {col.value}) {q}")
50
51 def _on_qis_sx(self, call, qubit):
52 if not self.in_parallel:
53 self._next_step()
54 q = qubit_id(qubit)
55 self.trace["steps"][-1]["ops"].append(f"sx {q}")
56
57 def _on_qis_rz(self, call, angle, qubit):
58 if not self.in_parallel:
59 self._next_step()
60 q = qubit_id(qubit)
61 self.trace["steps"][-1]["ops"].append(f"rz({angle.value}) {q}")
62
63 def _on_qis_cz(self, call, qubit1, qubit2):
64 if not self.in_parallel:
65 self._next_step()
66 q1 = qubit_id(qubit1)
67 q2 = qubit_id(qubit2)
68 if self.q_cols.get(q1, -1) > self.q_cols.get(q2, -1):
69 q1, q2 = q2, q1
70 self.trace["steps"][-1]["ops"].append(f"cz {q1}, {q2}")
71
72 def _on_qis_mresetz(self, call, target, result):
73 if not self.in_parallel:
74 self._next_step()
75 q = qubit_id(target)
76 self.trace["steps"][-1]["ops"].append(f"mz {q}")
77