microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
copilot/replace-qsharp-with-qdk-python-tests

Branches

Tags

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

Clone

HTTPS

Download ZIP

source/pip/qsharp/interop/qiskit/backends/qirtarget.py

191lines · modecode

1# Copyright (c) Microsoft Corporation.
2# Licensed under the MIT License.
3
4import logging
5from typing import Union
6
7from qiskit.circuit import (
8 Barrier,
9 Delay,
10 Measure,
11 Parameter,
12 Reset,
13 Store,
14)
15from qiskit.circuit.controlflow import (
16 ControlFlowOp,
17 ForLoopOp,
18 IfElseOp,
19 SwitchCaseOp,
20 WhileLoopOp,
21)
22from qiskit.circuit.library.standard_gates import (
23 CHGate,
24 CCXGate,
25 CXGate,
26 CYGate,
27 CZGate,
28 CRXGate,
29 CRYGate,
30 CRZGate,
31 RXGate,
32 RXXGate,
33 RYGate,
34 RYYGate,
35 RZGate,
36 RZZGate,
37 HGate,
38 SGate,
39 SdgGate,
40 SXGate,
41 SwapGate,
42 TGate,
43 TdgGate,
44 XGate,
45 YGate,
46 ZGate,
47 IGate,
48)
49
50from qiskit.transpiler.target import Target
51from .... import TargetProfile
52
53logger = logging.getLogger(__name__)
54
55
56class QirTarget:
57 """Factory for QIR-compatible Qiskit ``Target`` instances."""
58
59 def __init__(
60 self,
61 num_qubits=None,
62 target_profile=TargetProfile.Base,
63 supports_barrier=False,
64 supports_delay=False,
65 ) -> None:
66 logger.warning(
67 "QirTarget should not be instantiated directly. Use the 'build_target' class method"
68 + " instead. This will be enforced in a future release. You can replace"
69 + " 'QirTarget(...)' with 'QirTarget.build_target(...)'."
70 )
71 self._target = self.build_target(
72 num_qubits=num_qubits,
73 target_profile=target_profile,
74 supports_barrier=supports_barrier,
75 supports_delay=supports_delay,
76 )
77
78 def __getattr__(self, item):
79 """
80 Delegate attribute access to the underlying _target object.
81
82 This method is called when an attribute is not found in the current instance.
83 It forwards the attribute lookup to the internal _target object, effectively
84 making this class act as a proxy or wrapper around the target.
85
86 :param item: The name of the attribute being accessed.
87 :return: The value of the requested attribute from the ``_target`` object.
88 :raises AttributeError: If the requested item is ``"_target"`` or if the attribute
89 does not exist on the ``_target`` object.
90 """
91 if item == "_target":
92 raise AttributeError(item)
93 return getattr(self._target, item)
94
95 def to_target(self) -> Target:
96 """Return the underlying Qiskit Target instance."""
97 return self._target
98
99 @classmethod
100 def build_target(
101 cls,
102 num_qubits: Union[int, None] = None,
103 target_profile=TargetProfile.Base,
104 supports_barrier=False,
105 supports_delay=False,
106 ) -> Target:
107 """
108 Create a Qiskit Target object with quantum gates and operations for QIR compilation.
109
110 This class method creates a Target instance that defines the available quantum
111 operations and gates that can be used when compiling Q#/OpenQASM code to QIR (Quantum
112 Intermediate Representation) format.
113
114 :param num_qubits: The number of qubits for the target.
115 If ``None``, the target will support any number of qubits. Defaults to ``None``.
116 :param target_profile: The target profile that determines which control flow operations
117 are supported. If not ``TargetProfile.Base``, adds control flow operations like
118 ``if_else``, ``switch_case``, and ``while_loop``. Defaults to ``TargetProfile.Base``.
119 :param supports_barrier: Whether to include barrier operations in the target.
120 Defaults to ``False``.
121 :param supports_delay: Whether to include delay operations in the target.
122 Defaults to ``False``.
123 :return: A Qiskit ``Target`` object configured with quantum gates and operations.
124 """
125
126 target = Target(num_qubits=num_qubits)
127
128 if target_profile != TargetProfile.Base:
129 target.add_instruction(ControlFlowOp, name="control_flow")
130 target.add_instruction(IfElseOp, name="if_else")
131 target.add_instruction(SwitchCaseOp, name="switch_case")
132 target.add_instruction(WhileLoopOp, name="while_loop")
133
134 # We don't currently support break or continue statements in Q#,
135 # so we don't include them yet.
136 # target.add_instruction(BreakLoopOp, name="break")
137 # target.add_instruction(ContinueLoopOp, name="continue")
138
139 target.add_instruction(Store, name="store")
140
141 if supports_barrier:
142 target.add_instruction(Barrier, name="barrier")
143 if supports_delay:
144 target.add_instruction(Delay, name="delay")
145
146 # For loops should be fully deterministic in Qiskit/QASM.
147 target.add_instruction(ForLoopOp, name="for_loop")
148 target.add_instruction(Measure, name="measure")
149
150 # While reset is technically not supported in base profile, the
151 # compiler can use decompositions to implement workarounds.
152 target.add_instruction(Reset, name="reset")
153
154 target.add_instruction(CCXGate, name="ccx")
155 target.add_instruction(CXGate, name="cx")
156 target.add_instruction(CYGate, name="cy")
157 target.add_instruction(CZGate, name="cz")
158
159 target.add_instruction(RXGate(Parameter("theta")), name="rx")
160 target.add_instruction(RXXGate(Parameter("theta")), name="rxx")
161 target.add_instruction(CRXGate(Parameter("theta")), name="crx")
162
163 target.add_instruction(RYGate(Parameter("theta")), name="ry")
164 target.add_instruction(RYYGate(Parameter("theta")), name="ryy")
165 target.add_instruction(CRYGate(Parameter("theta")), name="cry")
166
167 target.add_instruction(RZGate(Parameter("theta")), name="rz")
168 target.add_instruction(RZZGate(Parameter("theta")), name="rzz")
169 target.add_instruction(CRZGate(Parameter("theta")), name="crz")
170
171 target.add_instruction(HGate, name="h")
172
173 target.add_instruction(SGate, name="s")
174 target.add_instruction(SdgGate, name="sdg")
175
176 target.add_instruction(SXGate, name="sx")
177
178 target.add_instruction(SwapGate, name="swap")
179
180 target.add_instruction(TGate, name="t")
181 target.add_instruction(TdgGate, name="tdg")
182
183 target.add_instruction(XGate, name="x")
184 target.add_instruction(YGate, name="y")
185 target.add_instruction(ZGate, name="z")
186
187 target.add_instruction(IGate, name="id")
188
189 target.add_instruction(CHGate, name="ch")
190
191 return target
192