bloqade-circuit 0.7.7__py3-none-any.whl → 0.7.9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of bloqade-circuit might be problematic. Click here for more details.

@@ -2,7 +2,7 @@ from . import noise as noise
2
2
  from .parallelize import (
3
3
  transpile as transpile,
4
4
  parallelize as parallelize,
5
- no_similarity as no_similarity,
5
+ remove_tags as remove_tags,
6
6
  auto_similarity as auto_similarity,
7
7
  block_similarity as block_similarity,
8
8
  moment_similarity as moment_similarity,
@@ -357,9 +357,10 @@ class GeminiOneZoneNoiseModelConflictGraphMoves(GeminiOneZoneNoiseModel):
357
357
  def noisy_moment(self, moment, system_qubits):
358
358
  # Moment with original ops
359
359
  original_moment = moment
360
- assert np.all(
361
- [isinstance(q, cirq.GridQubit) for q in system_qubits]
362
- ), "Found a qubit that is not a GridQubit."
360
+ assert np.all([isinstance(q, cirq.GridQubit) for q in system_qubits]), (
361
+ "Found a qubit that is not a GridQubit. In order for the conflict graph to know the qubit geometry, "
362
+ "all qubits in the circuit must be defined as cirq.GridQubit objects."
363
+ )
363
364
  # Check if the moment is empty
364
365
  if len(moment.operations) == 0:
365
366
  move_moments = []
@@ -136,7 +136,7 @@ def auto_similarity(
136
136
  return cirq.Circuit(flattened_circuit), weights
137
137
 
138
138
 
139
- def no_similarity(circuit: cirq.Circuit) -> cirq.Circuit:
139
+ def remove_tags(circuit: cirq.Circuit) -> cirq.Circuit:
140
140
  """
141
141
  Removes all tags from the circuit
142
142
 
@@ -146,10 +146,11 @@ def no_similarity(circuit: cirq.Circuit) -> cirq.Circuit:
146
146
  Returns:
147
147
  [0] - cirq.Circuit - the circuit with all tags removed.
148
148
  """
149
- new_moments = []
150
- for moment in circuit.moments:
151
- new_moments.append([gate.untagged for gate in moment.operations])
152
- return cirq.Circuit(new_moments)
149
+
150
+ def remove_tag(op: cirq.Operation, _):
151
+ return op.untagged
152
+
153
+ return cirq.map_operations(circuit, remove_tag)
153
154
 
154
155
 
155
156
  def to_dag_circuit(circuit: cirq.Circuit, can_reorder=None) -> nx.DiGraph:
@@ -399,4 +400,6 @@ def parallelize(
399
400
  )
400
401
  # Convert the epochs to a cirq circuit.
401
402
  moments = map(cirq.Moment, epochs)
402
- return cirq.Circuit(moments)
403
+ circuit = cirq.Circuit(moments)
404
+
405
+ return remove_tags(circuit)
bloqade/pyqrack/base.py CHANGED
@@ -146,7 +146,13 @@ class PyQrackInterpreter(Interpreter, typing.Generic[MemoryType]):
146
146
  loss_m_result: Measurement = field(default=Measurement.One, kw_only=True)
147
147
  """The value of a measurement result when a qubit is lost."""
148
148
 
149
+ global_measurement_id: int = field(init=False, default=0)
150
+
149
151
  def initialize(self) -> Self:
150
152
  super().initialize()
151
153
  self.memory.reset() # reset allocated qubits
152
154
  return self
155
+
156
+ def set_global_measurement_id(self, m: Measurement):
157
+ m.measurement_id = self.global_measurement_id
158
+ self.global_measurement_id += 1
bloqade/pyqrack/reg.py CHANGED
@@ -3,14 +3,19 @@ from typing import TYPE_CHECKING
3
3
  from dataclasses import dataclass
4
4
 
5
5
  from bloqade.qasm2.types import Qubit
6
+ from bloqade.squin.types import MeasurementResult
6
7
 
7
8
  if TYPE_CHECKING:
8
9
  from pyqrack import QrackSimulator
9
10
 
10
11
 
11
- class Measurement(enum.IntEnum):
12
+ class Measurement(MeasurementResult, enum.IntEnum):
12
13
  """Enumeration of measurement results."""
13
14
 
15
+ def __init__(self, measurement_id: int = 0) -> None:
16
+ super().__init__()
17
+ self.measurement_id = measurement_id
18
+
14
19
  Zero = 0
15
20
  One = 1
16
21
  Lost = enum.auto()
@@ -46,7 +46,7 @@ class QubitLossRuntime(OperatorRuntimeABC):
46
46
  return 1
47
47
 
48
48
  def apply(self, qubit: PyQrackQubit, adjoint: bool = False) -> None:
49
- if random.uniform(0.0, 1.0) < self.p:
49
+ if random.uniform(0.0, 1.0) <= self.p:
50
50
  qubit.state = QubitState.Lost
51
51
 
52
52
 
@@ -4,7 +4,7 @@ from kirin import interp
4
4
  from kirin.dialects import ilist
5
5
 
6
6
  from bloqade.squin import qubit
7
- from bloqade.pyqrack.reg import QubitState, PyQrackQubit
7
+ from bloqade.pyqrack.reg import QubitState, Measurement, PyQrackQubit
8
8
  from bloqade.pyqrack.base import PyQrackInterpreter
9
9
 
10
10
  from .runtime import OperatorRuntimeABC
@@ -41,9 +41,12 @@ class PyQrackMethods(interp.MethodTable):
41
41
 
42
42
  def _measure_qubit(self, qbit: PyQrackQubit, interp: PyQrackInterpreter):
43
43
  if qbit.is_active():
44
- return bool(qbit.sim_reg.m(qbit.addr))
44
+ m = Measurement(bool(qbit.sim_reg.m(qbit.addr)))
45
45
  else:
46
- return interp.loss_m_result
46
+ m = Measurement(interp.loss_m_result)
47
+
48
+ interp.set_global_measurement_id(m)
49
+ return m
47
50
 
48
51
  @interp.impl(qubit.MeasureQubitList)
49
52
  def measure_qubit_list(
@@ -63,3 +66,17 @@ class PyQrackMethods(interp.MethodTable):
63
66
  qbit: PyQrackQubit = frame.get(stmt.qubit)
64
67
  result = self._measure_qubit(qbit, interp)
65
68
  return (result,)
69
+
70
+ @interp.impl(qubit.QubitId)
71
+ def qubit_id(
72
+ self, interp: PyQrackInterpreter, frame: interp.Frame, stmt: qubit.QubitId
73
+ ):
74
+ qbit: PyQrackQubit = frame.get(stmt.qubit)
75
+ return (qbit.addr,)
76
+
77
+ @interp.impl(qubit.MeasurementId)
78
+ def measurement_id(
79
+ self, interp: PyQrackInterpreter, frame: interp.Frame, stmt: qubit.MeasurementId
80
+ ):
81
+ measurement: Measurement = frame.get(stmt.measurement)
82
+ return (measurement.measurement_id,)
@@ -1,27 +1,12 @@
1
1
  from dataclasses import field, dataclass
2
2
 
3
3
  from kirin import ir
4
- from kirin.passes import Pass, TypeInfer
5
- from kirin.rewrite import (
6
- Walk,
7
- Chain,
8
- Inline,
9
- Fixpoint,
10
- WrapConst,
11
- Call2Invoke,
12
- ConstantFold,
13
- CFGCompactify,
14
- InlineGetItem,
15
- InlineGetField,
16
- DeadCodeElimination,
17
- CommonSubexpressionElimination,
18
- )
19
- from kirin.analysis import const
20
- from kirin.dialects import scf, ilist
4
+ from kirin.passes import Pass
21
5
  from kirin.ir.method import Method
22
6
  from kirin.rewrite.abc import RewriteResult
23
7
 
24
8
  from bloqade.qasm2.dialects import expr
9
+ from bloqade.rewrite.passes import AggressiveUnroll
25
10
 
26
11
  from .unroll_if import UnrollIfs
27
12
 
@@ -30,71 +15,27 @@ from .unroll_if import UnrollIfs
30
15
  class QASM2Fold(Pass):
31
16
  """Fold pass for qasm2.extended"""
32
17
 
33
- constprop: const.Propagate = field(init=False)
34
18
  inline_gate_subroutine: bool = True
35
19
  unroll_ifs: bool = True
20
+ aggressive_unroll: AggressiveUnroll = field(init=False)
36
21
 
37
22
  def __post_init__(self):
38
- self.constprop = const.Propagate(self.dialects)
39
- self.typeinfer = TypeInfer(self.dialects)
23
+ def inline_simple(node: ir.Statement):
24
+ if isinstance(node, expr.GateFunction):
25
+ return self.inline_gate_subroutine
40
26
 
41
- def unsafe_run(self, mt: Method) -> RewriteResult:
42
- result = RewriteResult()
43
- frame, _ = self.constprop.run_analysis(mt)
44
- result = Walk(WrapConst(frame)).rewrite(mt.code).join(result)
45
- rule = Chain(
46
- ConstantFold(),
47
- Call2Invoke(),
48
- InlineGetField(),
49
- InlineGetItem(),
50
- DeadCodeElimination(),
51
- CommonSubexpressionElimination(),
52
- )
53
- result = Fixpoint(Walk(rule)).rewrite(mt.code).join(result)
27
+ return True
54
28
 
55
- result = (
56
- Walk(
57
- Chain(
58
- scf.unroll.PickIfElse(),
59
- scf.unroll.ForLoop(),
60
- scf.trim.UnusedYield(),
61
- )
62
- )
63
- .rewrite(mt.code)
64
- .join(result)
29
+ self.aggressive_unroll = AggressiveUnroll(
30
+ self.dialects, inline_simple, no_raise=self.no_raise
65
31
  )
66
32
 
67
- if self.unroll_ifs:
68
- UnrollIfs(mt.dialects).unsafe_run(mt).join(result)
69
-
70
- # run typeinfer again after unroll etc. because we now insert
71
- # a lot of new nodes, which might have more precise types
72
- self.typeinfer.unsafe_run(mt)
73
- result = (
74
- Walk(Chain(ilist.rewrite.ConstList2IList(), ilist.rewrite.Unroll()))
75
- .rewrite(mt.code)
76
- .join(result)
77
- )
78
-
79
- def inline_simple(node: ir.Statement):
80
- if isinstance(node, expr.GateFunction):
81
- return self.inline_gate_subroutine
33
+ def unsafe_run(self, mt: Method) -> RewriteResult:
34
+ result = RewriteResult()
82
35
 
83
- if not isinstance(node.parent_stmt, (scf.For, scf.IfElse)):
84
- return True # always inline calls outside of loops and if-else
36
+ if self.unroll_ifs:
37
+ result = UnrollIfs(mt.dialects).unsafe_run(mt).join(result)
85
38
 
86
- # inside loops and if-else, only inline simple functions, i.e. functions with a single block
87
- if (trait := node.get_trait(ir.CallableStmtInterface)) is None:
88
- return False # not a callable, don't inline to be safe
89
- region = trait.get_callable_region(node)
90
- return len(region.blocks) == 1
39
+ result = self.aggressive_unroll.unsafe_run(mt).join(result)
91
40
 
92
- result = (
93
- Walk(
94
- Inline(inline_simple),
95
- )
96
- .rewrite(mt.code)
97
- .join(result)
98
- )
99
- result = Walk(Fixpoint(CFGCompactify())).rewrite(mt.code).join(result)
100
41
  return result
@@ -1 +1,2 @@
1
+ from .aggressive_unroll import AggressiveUnroll as AggressiveUnroll
1
2
  from .canonicalize_ilist import CanonicalizeIList as CanonicalizeIList
@@ -0,0 +1,93 @@
1
+ from typing import Callable
2
+ from dataclasses import field, dataclass
3
+
4
+ from kirin import ir
5
+ from kirin.passes import Pass, HintConst, TypeInfer
6
+ from kirin.rewrite import (
7
+ Walk,
8
+ Chain,
9
+ Inline,
10
+ Fixpoint,
11
+ Call2Invoke,
12
+ ConstantFold,
13
+ CFGCompactify,
14
+ InlineGetItem,
15
+ InlineGetField,
16
+ DeadCodeElimination,
17
+ )
18
+ from kirin.dialects import scf, ilist
19
+ from kirin.ir.method import Method
20
+ from kirin.rewrite.abc import RewriteResult
21
+ from kirin.rewrite.cse import CommonSubexpressionElimination
22
+ from kirin.passes.aggressive import UnrollScf
23
+
24
+
25
+ @dataclass
26
+ class Fold(Pass):
27
+ hint_const: HintConst = field(init=False)
28
+
29
+ def __post_init__(self):
30
+ self.hint_const = HintConst(self.dialects, no_raise=self.no_raise)
31
+
32
+ def unsafe_run(self, mt: Method) -> RewriteResult:
33
+ result = RewriteResult()
34
+ result = self.hint_const.unsafe_run(mt).join(result)
35
+ rule = Chain(
36
+ ConstantFold(),
37
+ Call2Invoke(),
38
+ InlineGetField(),
39
+ InlineGetItem(),
40
+ ilist.rewrite.InlineGetItem(),
41
+ ilist.rewrite.HintLen(),
42
+ )
43
+ result = Fixpoint(Walk(rule)).rewrite(mt.code).join(result)
44
+
45
+ return result
46
+
47
+
48
+ @dataclass
49
+ class AggressiveUnroll(Pass):
50
+ """A pass to unroll structured control flow"""
51
+
52
+ additional_inline_heuristic: Callable[[ir.Statement], bool] = lambda node: True
53
+
54
+ fold: Fold = field(init=False)
55
+ typeinfer: TypeInfer = field(init=False)
56
+ scf_unroll: UnrollScf = field(init=False)
57
+
58
+ def __post_init__(self):
59
+ self.fold = Fold(self.dialects, no_raise=self.no_raise)
60
+ self.typeinfer = TypeInfer(self.dialects, no_raise=self.no_raise)
61
+ self.scf_unroll = UnrollScf(self.dialects, no_raise=self.no_raise)
62
+
63
+ def unsafe_run(self, mt: Method) -> RewriteResult:
64
+ result = RewriteResult()
65
+ result = self.scf_unroll.unsafe_run(mt).join(result)
66
+ result = (
67
+ Walk(Chain(ilist.rewrite.ConstList2IList(), ilist.rewrite.Unroll()))
68
+ .rewrite(mt.code)
69
+ .join(result)
70
+ )
71
+ result = self.typeinfer.unsafe_run(mt).join(result)
72
+ result = self.fold.unsafe_run(mt).join(result)
73
+ result = Walk(Inline(self.inline_heuristic)).rewrite(mt.code).join(result)
74
+ result = Walk(Fixpoint(CFGCompactify())).rewrite(mt.code).join(result)
75
+
76
+ rule = Chain(
77
+ CommonSubexpressionElimination(),
78
+ DeadCodeElimination(),
79
+ )
80
+ result = Fixpoint(Walk(rule)).rewrite(mt.code).join(result)
81
+
82
+ return result
83
+
84
+ def inline_heuristic(self, node: ir.Statement) -> bool:
85
+ """The heuristic to decide whether to inline a function call or not.
86
+ inside loops and if-else, only inline simple functions, i.e.
87
+ functions with a single block
88
+ """
89
+ return not isinstance(
90
+ node.parent_stmt, (scf.For, scf.IfElse)
91
+ ) and self.additional_inline_heuristic(
92
+ node
93
+ ) # always inline calls outside of loops and if-else
@@ -1,28 +1,32 @@
1
- from dataclasses import dataclass
1
+ from dataclasses import field, dataclass
2
2
 
3
- from kirin import ir
4
- from kirin.passes import Pass
3
+ from kirin import ir, passes
5
4
  from kirin.rewrite import (
6
5
  Walk,
7
6
  Chain,
8
7
  Fixpoint,
9
8
  )
10
- from kirin.analysis import const
11
-
12
- from ..rules.flatten_ilist import FlattenAddOpIList
13
- from ..rules.inline_getitem_ilist import InlineGetItemFromIList
9
+ from kirin.dialects.ilist import rewrite
14
10
 
15
11
 
16
12
  @dataclass
17
- class CanonicalizeIList(Pass):
13
+ class CanonicalizeIList(passes.Pass):
18
14
 
19
- def unsafe_run(self, mt: ir.Method):
15
+ fold_pass: passes.Fold = field(init=False)
20
16
 
21
- cp_result_frame, _ = const.Propagate(dialects=mt.dialects).run_analysis(mt)
17
+ def __post_init__(self):
18
+ self.fold_pass = passes.Fold(self.dialects, no_raise=self.no_raise)
22
19
 
23
- return Fixpoint(
24
- Chain(
25
- Walk(InlineGetItemFromIList(constprop_result=cp_result_frame.entries)),
26
- Walk(FlattenAddOpIList()),
20
+ def unsafe_run(self, mt: ir.Method):
21
+ result = Fixpoint(
22
+ Walk(
23
+ Chain(
24
+ rewrite.InlineGetItem(),
25
+ rewrite.FlattenAdd(),
26
+ rewrite.HintLen(),
27
+ )
27
28
  )
28
29
  ).rewrite(mt.code)
30
+
31
+ result = self.fold_pass(mt).join(result)
32
+ return result
@@ -144,6 +144,11 @@ class Squin(lowering.LoweringABC[CirqNode]):
144
144
  qbits = self.lower_qubit_getindices(state, node.qubits)
145
145
  return state.current_frame.push(qubit.Apply(operator=op_, qubits=qbits))
146
146
 
147
+ def visit_TaggedOperation(
148
+ self, state: lowering.State[CirqNode], node: cirq.TaggedOperation
149
+ ):
150
+ state.lower(node.untagged)
151
+
147
152
  def lower_measurement(
148
153
  self, state: lowering.State[CirqNode], node: cirq.GateOperation
149
154
  ):
bloqade/squin/qubit.py CHANGED
@@ -79,6 +79,20 @@ class MeasureQubitList(ir.Statement):
79
79
  result: ir.ResultValue = info.result(ilist.IListType[MeasurementResultType])
80
80
 
81
81
 
82
+ @statement(dialect=dialect)
83
+ class QubitId(ir.Statement):
84
+ traits = frozenset({lowering.FromPythonCall(), ir.Pure()})
85
+ qubit: ir.SSAValue = info.argument(QubitType)
86
+ result: ir.ResultValue = info.result(types.Int)
87
+
88
+
89
+ @statement(dialect=dialect)
90
+ class MeasurementId(ir.Statement):
91
+ traits = frozenset({lowering.FromPythonCall(), ir.Pure()})
92
+ measurement: ir.SSAValue = info.argument(MeasurementResultType)
93
+ result: ir.ResultValue = info.result(types.Int)
94
+
95
+
82
96
  # NOTE: no dependent types in Python, so we have to mark it Any...
83
97
  @wraps(New)
84
98
  def new(n_qubits: int) -> ilist.IList[Qubit, Any]:
@@ -127,9 +141,10 @@ def measure(input: Any) -> Any:
127
141
  input: A qubit or a list of qubits to measure.
128
142
 
129
143
  Returns:
130
- bool | list[bool]: The result of the measurement. If a single qubit is measured,
131
- a single boolean is returned. If a list of qubits is measured, a list of booleans
144
+ MeasurementResult | list[MeasurementResult]: The result of the measurement. If a single qubit is measured,
145
+ a single result is returned. If a list of qubits is measured, a list of results
132
146
  is returned.
147
+ A MeasurementResult can represent both 0 and 1, but also atoms that are lost.
133
148
  """
134
149
  ...
135
150
 
@@ -169,3 +184,11 @@ def broadcast(operator: Op, *qubits: ilist.IList[Qubit, OpSize] | list[Qubit]) -
169
184
  None
170
185
  """
171
186
  ...
187
+
188
+
189
+ @wraps(QubitId)
190
+ def get_qubit_id(qubit: Qubit) -> int: ...
191
+
192
+
193
+ @wraps(MeasurementId)
194
+ def get_measurement_id(measurement: MeasurementResult) -> int: ...
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bloqade-circuit
3
- Version: 0.7.7
3
+ Version: 0.7.9
4
4
  Summary: The software development toolkit for neutral atom arrays.
5
5
  Author-email: Roger-luo <rluo@quera.com>, kaihsin <khwu@quera.com>, weinbe58 <pweinberg@quera.com>, johnzl-777 <jlong@quera.com>
6
6
  License-File: LICENSE
@@ -9,8 +9,7 @@ Requires-Dist: kirin-toolchain~=0.17.23
9
9
  Requires-Dist: numpy>=1.22.0
10
10
  Requires-Dist: pandas>=2.2.3
11
11
  Requires-Dist: pydantic<2.11.0,>=1.3.0
12
- Requires-Dist: pyqrack-cpu>=1.69.0; sys_platform != 'darwin-arm64'
13
- Requires-Dist: pyqrack>=1.69.0; sys_platform == 'darwin-arm64'
12
+ Requires-Dist: pyqrack-cpu>=1.69.1
14
13
  Requires-Dist: rich>=13.9.4
15
14
  Requires-Dist: scipy>=1.13.1
16
15
  Provides-Extra: cirq
@@ -18,9 +17,9 @@ Requires-Dist: cirq-core>=1.4.1; extra == 'cirq'
18
17
  Requires-Dist: cirq-core[contrib]>=1.4.1; extra == 'cirq'
19
18
  Requires-Dist: qpsolvers[clarabel]>=4.7.0; extra == 'cirq'
20
19
  Provides-Extra: pyqrack-cuda
21
- Requires-Dist: pyqrack-cuda>=1.69.0; extra == 'pyqrack-cuda'
20
+ Requires-Dist: pyqrack-cuda>=1.69.1; extra == 'pyqrack-cuda'
22
21
  Provides-Extra: pyqrack-opencl
23
- Requires-Dist: pyqrack>=1.69.0; (sys_platform == 'darwin-arm64') and extra == 'pyqrack-opencl'
22
+ Requires-Dist: pyqrack>=1.69.1; extra == 'pyqrack-opencl'
24
23
  Provides-Extra: qasm2
25
24
  Requires-Dist: lark>=1.2.2; extra == 'qasm2'
26
25
  Provides-Extra: qbraid
@@ -13,13 +13,13 @@ bloqade/analysis/measure_id/__init__.py,sha256=r_R_br1e3H7ZzwkeQw4TnDAP4M_bUaRlR
13
13
  bloqade/analysis/measure_id/analysis.py,sha256=D8KcV8aL1yrqKhtqgaqMArX-PGXYcFXumEC5tx36plU,1974
14
14
  bloqade/analysis/measure_id/impls.py,sha256=q_HKSxptGfOvvGrRcpl42UGoe7eRL2-5dIGiA0tDyrA,6866
15
15
  bloqade/analysis/measure_id/lattice.py,sha256=WPrn0R79umCH909BFWsUJ64qx9n_3KYimIW5UaXNuGU,1891
16
- bloqade/cirq_utils/__init__.py,sha256=1DRDCF3PpgJCOr0z7iULdrn3dqm7GLpRGs9AlqE7XA8,280
16
+ bloqade/cirq_utils/__init__.py,sha256=NOChrzb4vxb3xHKxM0gg7HdZ7R76X5yU8RJZ9hECXWs,276
17
17
  bloqade/cirq_utils/lineprog.py,sha256=JosrhfeOHI9FycUT_sYFj8TBzLpo97TL8zK-Ap2U4eQ,11021
18
- bloqade/cirq_utils/parallelize.py,sha256=E2MsPm61Dkm3n0v4EFPJFGOc4B_Aw01yfhu-ViOKGiA,13812
18
+ bloqade/cirq_utils/parallelize.py,sha256=u9AP6l7YwBatFfIvrcCjbcYMiavk7MU6HKSKPkqlxtY,13803
19
19
  bloqade/cirq_utils/noise/__init__.py,sha256=hUBi53U0wE4u3AqGh5cNdgdCspt3O-Vw-SR68cfBZYc,421
20
20
  bloqade/cirq_utils/noise/_two_zone_utils.py,sha256=iq4nwdJQITFlGB61wfrV7vyPA2194p-i_nv36powZ90,17883
21
21
  bloqade/cirq_utils/noise/conflict_graph.py,sha256=ZUwPWTknrb6SgtZUVPeICn3YA-nUeWQJDuKKX5jL9tE,7179
22
- bloqade/cirq_utils/noise/model.py,sha256=8qovvB50oHzDszXkuMAs2I9BQV3eS1IU2D7Wux_dsGE,18459
22
+ bloqade/cirq_utils/noise/model.py,sha256=tKzK_d1u81miQu1LMeum7wKRXeuyP1M182SEJ8lNTbo,18605
23
23
  bloqade/cirq_utils/noise/transform.py,sha256=pauFnOKbk2QjxeyXEV_x2zyRGypr5wiQ6ySirU7C2zg,2278
24
24
  bloqade/native/__init__.py,sha256=MtQZmq7KqNGkjxsO_22DpY-13X23Ovw8JKs7lfuv55w,443
25
25
  bloqade/native/_prelude.py,sha256=znle4mSTLZtRMCmmiZ-bCPfHqNdgVxsKuY64Fgj2kko,1258
@@ -32,10 +32,10 @@ bloqade/native/stdlib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
32
32
  bloqade/native/stdlib/broadcast.py,sha256=0DEK6pRcz0IG5BZHt0sV1wZpDvlJgvw4-Qwd1xYLSYM,6141
33
33
  bloqade/native/stdlib/simple.py,sha256=mK_p9x_TUr4g-q-Q4LfbVBtXxBS21XPh1meyCC4to_k,5416
34
34
  bloqade/pyqrack/__init__.py,sha256=OV8-2fw44gP_JgY8mAUiwISO_qYxS-t0fKsbuUB-r9Y,861
35
- bloqade/pyqrack/base.py,sha256=g0GRlEgyJ_P8z-lR8RK2CAuRTj6KPfglKX0iwrgg4DM,4408
35
+ bloqade/pyqrack/base.py,sha256=Q2GjAcqEZBo-Lhe2jpXuNCB0xXVIdwtdy6cUmDM_OZI,4623
36
36
  bloqade/pyqrack/device.py,sha256=ruseNWt3scvjw0KyHZjwnM6Z6lFjROgmW3Zdi1lucgQ,15195
37
37
  bloqade/pyqrack/native.py,sha256=ErbVQCatn_JT3Ej-iQzMMfb_q50JF_K1Iv1vRYvu5VA,1857
38
- bloqade/pyqrack/reg.py,sha256=uTL07CT1R0xUsInLmwU9YuuNdV6lV0lCs1zhdUz1qIs,1660
38
+ bloqade/pyqrack/reg.py,sha256=2GK7QW1dhCfqDHtwzYK-C37fNtnbGK8DhdhMrMidP_w,1859
39
39
  bloqade/pyqrack/target.py,sha256=c78VtLWAiDNp_0sXwvVzhaEoeFsr1fUVsupxWuo6p3s,3661
40
40
  bloqade/pyqrack/task.py,sha256=nRmI3tM_y4134_Uld-D9xwNXG9ie-OHNAqwRT5Ss-Y0,5266
41
41
  bloqade/pyqrack/noise/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -47,11 +47,11 @@ bloqade/pyqrack/qasm2/parallel.py,sha256=ITetuXOH2KUDpDOBuFnJoz2DhduvyBC72cOAOOi
47
47
  bloqade/pyqrack/qasm2/uop.py,sha256=bLZONsEK15ymFGIQwy7muQv-TX0mvLrECuMp1Y3XTfA,8612
48
48
  bloqade/pyqrack/squin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
49
49
  bloqade/pyqrack/squin/op.py,sha256=m9QiQgQnKy1tYvrieU6MjXf_b9i2fovj4r2novcQwIc,5535
50
- bloqade/pyqrack/squin/qubit.py,sha256=IXoAN_wOAzmKsKMKUakTQd_TbeJrFrtvH5Fd9SlQVLo,2277
50
+ bloqade/pyqrack/squin/qubit.py,sha256=M32AhO3HRc_-FrOj7h_1Arj6jr9WiaHoxc4aeU1KoIY,2859
51
51
  bloqade/pyqrack/squin/runtime.py,sha256=3iVCN3XMUL8uk-bm0y4HSaVU7i5xZsNm5sY285rUKQE,15583
52
52
  bloqade/pyqrack/squin/wire.py,sha256=rqlAeU-r_EHOwJMqHrEAxpZ_rKsvUpwGG7MP4BW75Nw,1658
53
53
  bloqade/pyqrack/squin/noise/__init__.py,sha256=uXgRQPOrHNRp3k2ff2HD8mheUEaqxZPKEnwV-s4BiV4,31
54
- bloqade/pyqrack/squin/noise/native.py,sha256=KF4VGzU5Ps92DeLcIDIMsxQQtQ97z_3KUHqBPPkZFaM,2286
54
+ bloqade/pyqrack/squin/noise/native.py,sha256=gs2At4fDKTN3LJl5DVZ-Z3Pn3YTSwZCQCAoPrMJxEcQ,2287
55
55
  bloqade/qasm2/__init__.py,sha256=W9dR4Qnvigc7e7Ay7puSJHAIuiQk8vWqY-W64SMu5oU,515
56
56
  bloqade/qasm2/_qasm_loading.py,sha256=dSfjlB6Bm1ednfxc9L42dEa48s5q4N5SGQ9Iw21sBZQ,4753
57
57
  bloqade/qasm2/_wrappers.py,sha256=4x3fldC4sV2K_XZ0FPZOorQKAbs_7pualListXtak4A,11148
@@ -104,7 +104,7 @@ bloqade/qasm2/parse/qasm2.lark,sha256=IYrBydUoVLn1VCNDPP5uNN5BHDET3fQ2yG11cOy900
104
104
  bloqade/qasm2/parse/visitor.py,sha256=W4NUkBw97e3Z4Y1ek6jVNn-5lLVd3A5HXxc-FYTGYbY,427
105
105
  bloqade/qasm2/parse/visitor.pyi,sha256=JafCo1QztL6fvmWtJXu4dlqwbTJ6iLVrSa8L-Zd72t4,1851
106
106
  bloqade/qasm2/passes/__init__.py,sha256=9vz9F9Mgb5OFgnPWqw8pOJ-7r-tShoa7XevJ41ZmPXM,262
107
- bloqade/qasm2/passes/fold.py,sha256=NMT9MVpc7eWtqmdCztcztrfVewk5SCz5OTDMjSNPGaE,3046
107
+ bloqade/qasm2/passes/fold.py,sha256=OA4mVarUYRAfZSODOA9wgoW7HNNmpQWfPG5qGVEbA6I,1117
108
108
  bloqade/qasm2/passes/glob.py,sha256=qGmUTJSvDPf6qatapg4U69bTRKOAwZEHcFdts3mRxjI,3563
109
109
  bloqade/qasm2/passes/lift_qubits.py,sha256=VgIuqaZecozA3cwGAq8Nzqdv8IqQlzyQv2XlaqY4H4g,759
110
110
  bloqade/qasm2/passes/noise.py,sha256=w7U91jOAabcCZZXm8uPxojsVRtcIkxtpZS2hwEDsDN0,2709
@@ -130,18 +130,17 @@ bloqade/qbraid/schema.py,sha256=dTPexUFOiBNBnFv0GEbGh6jpIbMIFHk4hFXmXbeihxA,7854
130
130
  bloqade/qbraid/simulation_result.py,sha256=zdCJcAdbQkEDzFFuC2q3gqOFTOLAXHk4wh8RRDB6cgc,3956
131
131
  bloqade/qbraid/target.py,sha256=LcFHHyLe74yBmrHI9251xHgLN_nUz35lN8RPNwrT6mI,3149
132
132
  bloqade/rewrite/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
133
- bloqade/rewrite/passes/__init__.py,sha256=Qfe1PDADGySGuqNn5UuXiH48P70EykEMDaEKkd80ikk,71
134
- bloqade/rewrite/passes/canonicalize_ilist.py,sha256=LmX09aPjagT6NzU-M87V8kZaCGkYR_qvmtRNCRuVK1U,689
133
+ bloqade/rewrite/passes/__init__.py,sha256=-J8Ng97AlSCy6hJGmQORbVPjSCWhXdyU4EJx6XHnqXE,139
134
+ bloqade/rewrite/passes/aggressive_unroll.py,sha256=bXXOjooo_qJVIejniSfPMxa9ySrTaK3C57PgkpYa1dw,3025
135
+ bloqade/rewrite/passes/canonicalize_ilist.py,sha256=Y7twcmmtEEnXb4ulKhLi7JFBicCMxaP76_KiQMkOq7w,749
135
136
  bloqade/rewrite/rules/__init__.py,sha256=3e1Z5T3INqNtP6OU0Vivu_SdMOR_2KDixeA0Yjoddgg,82
136
- bloqade/rewrite/rules/flatten_ilist.py,sha256=QoIxMaBXSlatpWzi5s_MAPnV3bV3GeoWc31RBw0WQ3s,1465
137
- bloqade/rewrite/rules/inline_getitem_ilist.py,sha256=uIXQRCsr3_GPMciDT4ghI-ezhQmkDcGcC6pguABPUVw,875
138
137
  bloqade/rewrite/rules/split_ifs.py,sha256=KhwvUx-oBrBO2F1j-J5kwNbdnrnEZcZtJflzyQm-UOI,2613
139
138
  bloqade/squin/__init__.py,sha256=j9jgH39eQHedbVR9poKx2YHxOihclAI0GpIA05NejHM,675
140
139
  bloqade/squin/_typeinfer.py,sha256=bilWfC6whTMwewFCqDgB6vDHZsgXPr3azNOYqqnvtB4,780
141
140
  bloqade/squin/groups.py,sha256=RXGJnNZUSXF_f5ljjhZ9At8UhaijayoxFoWvxEsUOWc,1310
142
141
  bloqade/squin/lowering.py,sha256=bfrPjx6t2mnd1qoBshF_RW-FXMWg3TOUA6XKUeONyig,2560
143
142
  bloqade/squin/parallel.py,sha256=X6Ps9kQIgnFMlZO14y2ntdxvivqbIP28PAWF8KmxByM,5172
144
- bloqade/squin/qubit.py,sha256=cRy2a2jFLlor4KPHWk_05fMqr8Gmj5ixk624dLdWKmY,4911
143
+ bloqade/squin/qubit.py,sha256=eX24PLk0CILaooQZDD6gv5MwSAXSncazv86M-cyT3cc,5649
145
144
  bloqade/squin/types.py,sha256=T3lkqid4HEWuAK_wRns_p-K5DbLDwlldoyZtVay7A3o,119
146
145
  bloqade/squin/wire.py,sha256=GZhF0EHCu7OU70zTV_N83yann-eQnYG_lM2u0QYFoAs,6596
147
146
  bloqade/squin/analysis/__init__.py,sha256=DvnFHmEqMxRG92jVT3ZWwAQDTb6DC4fZDTV8ZSLZgP0,43
@@ -152,7 +151,7 @@ bloqade/squin/analysis/nsites/analysis.py,sha256=rIe1RU1MZRItcE2aB8DYahLrv73HfD3
152
151
  bloqade/squin/analysis/nsites/impls.py,sha256=wSNWjNmgwCP35FgmreyLKmRYedxlebWi7LhsEq9jPs4,3097
153
152
  bloqade/squin/analysis/nsites/lattice.py,sha256=ruh0808SHtj3ecuT-C3AZTsLY2j3DRhtezGiTZvcuVs,942
154
153
  bloqade/squin/cirq/__init__.py,sha256=7OYYboSl5lPwdWOKk4AJgm1s1lBX_WAstVqPfaynSv8,10156
155
- bloqade/squin/cirq/lowering.py,sha256=trrcBDQQzy2r3JVKb2x6i2BdzBMYkjQNBzH_Va6JOu0,17789
154
+ bloqade/squin/cirq/lowering.py,sha256=i5-IakuJGo3CYw7VNHqB0uM3AiFMw__a3oizKce3F7I,17937
156
155
  bloqade/squin/cirq/emit/emit_circuit.py,sha256=JVFXiaSB7A9kamRwCjLqs03Sel4PVCBT-6kRNRWX-jo,4393
157
156
  bloqade/squin/cirq/emit/noise.py,sha256=rESjGC_66s2Y4FwwYda4rY3mYHYjbqLlKE_vnqpZDYI,1534
158
157
  bloqade/squin/cirq/emit/op.py,sha256=u1FoOlbz7NNXPlU-hMbnX_yRB5suKbsEm2jF3Ts4f68,5764
@@ -243,7 +242,7 @@ bloqade/visual/animation/runtime/atoms.py,sha256=EmjxhujLiHHPS_HtH_B-7TiqeHgvW5u
243
242
  bloqade/visual/animation/runtime/ppoly.py,sha256=JB9IP53N1w6adBJEue6J5Nmj818Id9JvrlgrmiQTU1I,1385
244
243
  bloqade/visual/animation/runtime/qpustate.py,sha256=rlmxQeJSvaohXrTpXQL5y-NJcpvfW33xPaYM1slv7cc,4270
245
244
  bloqade/visual/animation/runtime/utils.py,sha256=ju9IzOWX-vKwfpqUjlUKu3Ssr_UFPFFq-tzH_Nqyo_c,1212
246
- bloqade_circuit-0.7.7.dist-info/METADATA,sha256=PoLZ_Qd3XjiPu-9u9HaIJv-07GZAu0XIyuoUwCXVCic,3856
247
- bloqade_circuit-0.7.7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
248
- bloqade_circuit-0.7.7.dist-info/licenses/LICENSE,sha256=S5GIJwR6QCixPA9wryYb44ZEek0Nz4rt_zLUqP05UbU,13160
249
- bloqade_circuit-0.7.7.dist-info/RECORD,,
245
+ bloqade_circuit-0.7.9.dist-info/METADATA,sha256=VhYLXjeRULFvq59sRDSx_0bLWHDbVbK1sF4CTNTmSOY,3724
246
+ bloqade_circuit-0.7.9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
247
+ bloqade_circuit-0.7.9.dist-info/licenses/LICENSE,sha256=S5GIJwR6QCixPA9wryYb44ZEek0Nz4rt_zLUqP05UbU,13160
248
+ bloqade_circuit-0.7.9.dist-info/RECORD,,
@@ -1,51 +0,0 @@
1
- from dataclasses import dataclass
2
-
3
- from kirin import ir
4
- from kirin.dialects import py, ilist
5
- from kirin.rewrite.abc import RewriteRule, RewriteResult
6
-
7
-
8
- @dataclass
9
- class FlattenAddOpIList(RewriteRule):
10
-
11
- def rewrite_Statement(self, node: ir.Statement) -> RewriteResult:
12
- if not isinstance(node, py.binop.Add):
13
- return RewriteResult()
14
-
15
- # check if we are adding two ilist.New objects
16
- new_data = ()
17
-
18
- # lhs:
19
- if not isinstance(node.lhs.owner, ilist.New):
20
- if not (
21
- isinstance(node.lhs.owner, py.Constant)
22
- and isinstance(
23
- const_ilist := node.lhs.owner.value.unwrap(), ilist.IList
24
- )
25
- and len(const_ilist.data) == 0
26
- ):
27
- return RewriteResult()
28
-
29
- else:
30
- new_data += node.lhs.owner.values
31
-
32
- # rhs:
33
- if not isinstance(node.rhs.owner, ilist.New):
34
- if not (
35
- isinstance(node.rhs.owner, py.Constant)
36
- and isinstance(
37
- const_ilist := node.rhs.owner.value.unwrap(), ilist.IList
38
- )
39
- and len(const_ilist.data) == 0
40
- ):
41
- return RewriteResult()
42
-
43
- else:
44
- new_data += node.rhs.owner.values
45
-
46
- new_stmt = ilist.New(values=new_data)
47
- node.replace_by(new_stmt)
48
-
49
- return RewriteResult(
50
- has_done_something=True,
51
- )
@@ -1,31 +0,0 @@
1
- from dataclasses import dataclass
2
-
3
- from kirin import ir
4
- from kirin.analysis import const
5
- from kirin.dialects import py, ilist
6
- from kirin.rewrite.abc import RewriteRule, RewriteResult
7
-
8
-
9
- @dataclass
10
- class InlineGetItemFromIList(RewriteRule):
11
- constprop_result: dict[ir.SSAValue, const.Result]
12
-
13
- def rewrite_Statement(self, node: ir.Statement) -> RewriteResult:
14
- if not isinstance(node, py.indexing.GetItem):
15
- return RewriteResult()
16
-
17
- if not isinstance(node.obj.owner, ilist.New):
18
- return RewriteResult()
19
-
20
- if not isinstance(
21
- index_value := self.constprop_result.get(node.index), const.Value
22
- ):
23
- return RewriteResult()
24
-
25
- elem_ssa = node.obj.owner.values[index_value.data]
26
-
27
- node.result.replace_by(elem_ssa)
28
-
29
- return RewriteResult(
30
- has_done_something=True,
31
- )