bloqade-circuit 0.1.0__py3-none-any.whl → 0.2.1__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.

Files changed (74) hide show
  1. bloqade/analysis/address/impls.py +5 -9
  2. bloqade/analysis/address/lattice.py +1 -1
  3. bloqade/analysis/fidelity/__init__.py +1 -0
  4. bloqade/analysis/fidelity/analysis.py +69 -0
  5. bloqade/device.py +130 -0
  6. bloqade/noise/__init__.py +2 -1
  7. bloqade/noise/fidelity.py +51 -0
  8. bloqade/noise/native/model.py +1 -2
  9. bloqade/noise/native/rewrite.py +5 -5
  10. bloqade/noise/native/stmts.py +40 -11
  11. bloqade/pyqrack/__init__.py +8 -2
  12. bloqade/pyqrack/base.py +24 -3
  13. bloqade/pyqrack/device.py +166 -0
  14. bloqade/pyqrack/noise/native.py +1 -2
  15. bloqade/pyqrack/qasm2/core.py +31 -15
  16. bloqade/pyqrack/qasm2/glob.py +28 -0
  17. bloqade/pyqrack/qasm2/uop.py +9 -1
  18. bloqade/pyqrack/reg.py +17 -49
  19. bloqade/pyqrack/squin/__init__.py +0 -0
  20. bloqade/pyqrack/squin/op.py +154 -0
  21. bloqade/pyqrack/squin/qubit.py +85 -0
  22. bloqade/pyqrack/squin/runtime.py +515 -0
  23. bloqade/pyqrack/squin/wire.py +69 -0
  24. bloqade/pyqrack/target.py +9 -2
  25. bloqade/pyqrack/task.py +30 -0
  26. bloqade/qasm2/_wrappers.py +11 -1
  27. bloqade/qasm2/dialects/core/stmts.py +15 -4
  28. bloqade/qasm2/dialects/expr/_emit.py +9 -8
  29. bloqade/qasm2/emit/base.py +4 -2
  30. bloqade/qasm2/emit/gate.py +0 -14
  31. bloqade/qasm2/emit/main.py +19 -15
  32. bloqade/qasm2/emit/target.py +2 -6
  33. bloqade/qasm2/glob.py +1 -1
  34. bloqade/qasm2/parse/lowering.py +124 -1
  35. bloqade/qasm2/passes/glob.py +3 -3
  36. bloqade/qasm2/passes/lift_qubits.py +26 -0
  37. bloqade/qasm2/passes/noise.py +6 -14
  38. bloqade/qasm2/passes/parallel.py +3 -3
  39. bloqade/qasm2/passes/py2qasm.py +1 -2
  40. bloqade/qasm2/passes/qasm2py.py +1 -2
  41. bloqade/qasm2/rewrite/desugar.py +6 -6
  42. bloqade/qasm2/rewrite/glob.py +9 -9
  43. bloqade/qasm2/rewrite/heuristic_noise.py +30 -38
  44. bloqade/qasm2/rewrite/insert_qubits.py +34 -0
  45. bloqade/qasm2/rewrite/native_gates.py +54 -55
  46. bloqade/qasm2/rewrite/parallel_to_uop.py +9 -9
  47. bloqade/qasm2/rewrite/uop_to_parallel.py +20 -22
  48. bloqade/qasm2/types.py +3 -6
  49. bloqade/qbraid/schema.py +10 -12
  50. bloqade/squin/__init__.py +1 -1
  51. bloqade/squin/analysis/nsites/analysis.py +4 -6
  52. bloqade/squin/analysis/nsites/impls.py +2 -6
  53. bloqade/squin/analysis/schedule.py +1 -1
  54. bloqade/squin/groups.py +15 -7
  55. bloqade/squin/noise/__init__.py +27 -0
  56. bloqade/squin/noise/_dialect.py +3 -0
  57. bloqade/squin/noise/stmts.py +59 -0
  58. bloqade/squin/op/__init__.py +35 -5
  59. bloqade/squin/op/number.py +5 -0
  60. bloqade/squin/op/rewrite.py +46 -0
  61. bloqade/squin/op/stmts.py +23 -2
  62. bloqade/squin/op/types.py +14 -0
  63. bloqade/squin/qubit.py +79 -11
  64. bloqade/squin/rewrite/__init__.py +0 -0
  65. bloqade/squin/rewrite/measure_desugar.py +33 -0
  66. bloqade/squin/wire.py +31 -2
  67. bloqade/stim/emit/stim.py +1 -1
  68. bloqade/task.py +94 -0
  69. bloqade/visual/animation/base.py +25 -15
  70. {bloqade_circuit-0.1.0.dist-info → bloqade_circuit-0.2.1.dist-info}/METADATA +8 -2
  71. {bloqade_circuit-0.1.0.dist-info → bloqade_circuit-0.2.1.dist-info}/RECORD +73 -52
  72. bloqade/squin/op/complex.py +0 -6
  73. {bloqade_circuit-0.1.0.dist-info → bloqade_circuit-0.2.1.dist-info}/WHEEL +0 -0
  74. {bloqade_circuit-0.1.0.dist-info → bloqade_circuit-0.2.1.dist-info}/licenses/LICENSE +0 -0
bloqade/squin/qubit.py CHANGED
@@ -7,7 +7,7 @@ Depends on:
7
7
  - `kirin.dialects.ilist`: provides the `ilist.IListType` type for lists of qubits.
8
8
  """
9
9
 
10
- from typing import Any
10
+ from typing import Any, overload
11
11
 
12
12
  from kirin import ir, types, lowering
13
13
  from kirin.decl import info, statement
@@ -35,21 +35,49 @@ class Apply(ir.Statement):
35
35
 
36
36
 
37
37
  @statement(dialect=dialect)
38
- class Measure(ir.Statement):
38
+ class Broadcast(ir.Statement):
39
+ traits = frozenset({lowering.FromPythonCall()})
40
+ operator: ir.SSAValue = info.argument(OpType)
41
+ qubits: ir.SSAValue = info.argument(ilist.IListType[QubitType])
42
+
43
+
44
+ @statement(dialect=dialect)
45
+ class MeasureAny(ir.Statement):
46
+ name = "measure"
47
+
48
+ traits = frozenset({lowering.FromPythonCall()})
49
+ input: ir.SSAValue = info.argument(types.Any)
50
+ result: ir.ResultValue = info.result(types.Any)
51
+
52
+
53
+ @statement(dialect=dialect)
54
+ class MeasureQubit(ir.Statement):
55
+ name = "measure.qubit"
56
+
57
+ traits = frozenset({lowering.FromPythonCall()})
58
+ qubit: ir.SSAValue = info.argument(ilist.IListType[QubitType])
59
+ result: ir.ResultValue = info.result(ilist.IListType[types.Bool])
60
+
61
+
62
+ @statement(dialect=dialect)
63
+ class MeasureQubitList(ir.Statement):
64
+ name = "measure.qubit.list"
65
+
39
66
  traits = frozenset({lowering.FromPythonCall()})
40
67
  qubits: ir.SSAValue = info.argument(ilist.IListType[QubitType])
41
- result: ir.ResultValue = info.result(types.Int)
68
+ result: ir.ResultValue = info.result(ilist.IListType[types.Bool])
42
69
 
43
70
 
44
71
  @statement(dialect=dialect)
45
72
  class MeasureAndReset(ir.Statement):
46
73
  traits = frozenset({lowering.FromPythonCall()})
47
74
  qubits: ir.SSAValue = info.argument(ilist.IListType[QubitType])
48
- result: ir.ResultValue = info.result(types.Int)
75
+ result: ir.ResultValue = info.result(ilist.IListType[types.Bool])
49
76
 
50
77
 
51
78
  @statement(dialect=dialect)
52
79
  class Reset(ir.Statement):
80
+ traits = frozenset({lowering.FromPythonCall()})
53
81
  qubits: ir.SSAValue = info.argument(ilist.IListType[QubitType])
54
82
 
55
83
 
@@ -71,6 +99,8 @@ def new(n_qubits: int) -> ilist.IList[Qubit, Any]:
71
99
  def apply(operator: Op, qubits: ilist.IList[Qubit, Any] | list[Qubit]) -> None:
72
100
  """Apply an operator to a list of qubits.
73
101
 
102
+ Note, that when considering atom loss, lost qubits will be skipped.
103
+
74
104
  Args:
75
105
  operator: The operator to apply.
76
106
  qubits: The list of qubits to apply the operator to. The size of the list
@@ -82,28 +112,66 @@ def apply(operator: Op, qubits: ilist.IList[Qubit, Any] | list[Qubit]) -> None:
82
112
  ...
83
113
 
84
114
 
85
- @wraps(Measure)
86
- def measure(qubits: ilist.IList[Qubit, Any]) -> int:
87
- """Measure the qubits in the list."
115
+ @overload
116
+ def measure(input: Qubit) -> bool: ...
117
+ @overload
118
+ def measure(input: ilist.IList[Qubit, Any] | list[Qubit]) -> ilist.IList[bool, Any]: ...
119
+
120
+
121
+ @wraps(MeasureAny)
122
+ def measure(input: Any) -> Any:
123
+ """Measure a qubit or qubits in the list.
88
124
 
89
125
  Args:
90
- qubits: The list of qubits to measure.
126
+ input: A qubit or a list of qubits to measure.
91
127
 
92
128
  Returns:
93
- int: The result of the measurement.
129
+ bool | list[bool]: The result of the measurement. If a single qubit is measured,
130
+ a single boolean is returned. If a list of qubits is measured, a list of booleans
131
+ is returned.
132
+ """
133
+ ...
134
+
135
+
136
+ @wraps(Broadcast)
137
+ def broadcast(operator: Op, qubits: ilist.IList[Qubit, Any] | list[Qubit]) -> None:
138
+ """Broadcast and apply an operator to a list of qubits. For example, an operator
139
+ that expects 2 qubits can be applied to a list of 2n qubits, where n is an integer > 0.
140
+
141
+ For controlled operators, the list of qubits is interpreted as sets of (controls, targets).
142
+ For example
143
+
144
+ ```
145
+ apply(CX, [q0, q1, q2, q3])
146
+ ```
147
+
148
+ is equivalent to
149
+
150
+ ```
151
+ apply(CX, [q0, q1])
152
+ apply(CX, [q2, q3])
153
+ ```
154
+
155
+ Args:
156
+ operator: The operator to broadcast and apply.
157
+ qubits: The list of qubits to broadcast and apply the operator to. The size of the list
158
+ must be inferable and match the number of qubits expected by the operator.
159
+
160
+ Returns:
161
+ None
94
162
  """
95
163
  ...
96
164
 
97
165
 
98
166
  @wraps(MeasureAndReset)
99
- def measure_and_reset(qubits: ilist.IList[Qubit, Any]) -> int:
167
+ def measure_and_reset(qubits: ilist.IList[Qubit, Any]) -> ilist.IList[bool, Any]:
100
168
  """Measure the qubits in the list and reset them."
101
169
 
102
170
  Args:
103
171
  qubits: The list of qubits to measure and reset.
104
172
 
105
173
  Returns:
106
- int: The result of the measurement.
174
+ list[bool]: The result of the measurement.
107
175
  """
108
176
  ...
109
177
 
File without changes
@@ -0,0 +1,33 @@
1
+ from kirin import ir, types
2
+ from kirin.dialects import ilist
3
+ from kirin.rewrite.abc import RewriteRule, RewriteResult
4
+
5
+ from bloqade.squin.qubit import QubitType, MeasureAny, MeasureQubit, MeasureQubitList
6
+
7
+
8
+ class MeasureDesugarRule(RewriteRule):
9
+ """
10
+ Desugar measure operations in the circuit.
11
+ """
12
+
13
+ def rewrite_Statement(self, node: ir.Statement) -> RewriteResult:
14
+
15
+ if not isinstance(node, MeasureAny):
16
+ return RewriteResult()
17
+
18
+ if node.input.type.is_subseteq(QubitType):
19
+ node.replace_by(
20
+ MeasureQubit(
21
+ qubit=node.input,
22
+ )
23
+ )
24
+ return RewriteResult(has_done_something=True)
25
+ elif node.input.type.is_subseteq(ilist.IListType[QubitType, types.Any]):
26
+ node.replace_by(
27
+ MeasureQubitList(
28
+ qubits=node.input,
29
+ )
30
+ )
31
+ return RewriteResult(has_done_something=True)
32
+
33
+ return RewriteResult()
bloqade/squin/wire.py CHANGED
@@ -8,10 +8,11 @@ dialect.
8
8
 
9
9
  from kirin import ir, types, interp, lowering
10
10
  from kirin.decl import info, statement
11
+ from kirin.lowering import wraps
11
12
 
12
- from bloqade.types import QubitType
13
+ from bloqade.types import Qubit, QubitType
13
14
 
14
- from .op.types import OpType
15
+ from .op.types import Op, OpType
15
16
 
16
17
  # from kirin.lowering import wraps
17
18
 
@@ -68,6 +69,25 @@ class Apply(ir.Statement): # apply(op, w1, w2, ...)
68
69
  ) # custom lowering required for wrapper to work here
69
70
 
70
71
 
72
+ # Carry over from Qubit dialect
73
+ @statement(dialect=dialect)
74
+ class Broadcast(ir.Statement):
75
+ traits = frozenset({lowering.FromPythonCall(), ir.Pure()})
76
+ operator: ir.SSAValue = info.argument(OpType)
77
+ inputs: tuple[ir.SSAValue, ...] = info.argument(WireType)
78
+
79
+ def __init__(self, operator: ir.SSAValue, *args: ir.SSAValue):
80
+ result_types = tuple(WireType for _ in args)
81
+ super().__init__(
82
+ args=(operator,) + args,
83
+ result_types=result_types,
84
+ args_slice={
85
+ "operator": 0,
86
+ "inputs": slice(1, None),
87
+ }, # pretty printing + syntax sugar
88
+ ) # custom lowering required for wrapper to work here
89
+
90
+
71
91
  # NOTE: measurement cannot be pure because they will collapse the state
72
92
  # of the qubit. The state is a hidden state that is not visible to
73
93
  # the user in the wire dialect.
@@ -98,6 +118,15 @@ class Reset(ir.Statement):
98
118
  class ConstPropWire(interp.MethodTable):
99
119
 
100
120
  @interp.impl(Apply)
121
+ @interp.impl(Broadcast)
101
122
  def apply(self, interp, frame, stmt: Apply):
102
123
 
103
124
  return frame.get_values(stmt.inputs)
125
+
126
+
127
+ @wraps(Unwrap)
128
+ def unwrap(qubit: Qubit) -> Wire: ...
129
+
130
+
131
+ @wraps(Apply)
132
+ def apply(op: Op, w: Wire) -> Wire: ...
bloqade/stim/emit/stim.py CHANGED
@@ -49,6 +49,6 @@ class FuncEmit(interp.MethodTable):
49
49
 
50
50
  @interp.impl(func.Function)
51
51
  def emit_func(self, emit: EmitStimMain, frame: EmitStrFrame, stmt: func.Function):
52
- _ = emit.run_ssacfg_region(frame, stmt.body)
52
+ _ = emit.run_ssacfg_region(frame, stmt.body, ())
53
53
  # emit.output = "\n".join(frame.body)
54
54
  return ()
bloqade/task.py ADDED
@@ -0,0 +1,94 @@
1
+ import abc
2
+ from typing import Any, Generic, Literal, TypeVar, ParamSpec
3
+ from dataclasses import dataclass
4
+
5
+ from kirin import ir
6
+
7
+ Params = ParamSpec("Params")
8
+ RetType = TypeVar("RetType")
9
+
10
+
11
+ class BatchFuture(abc.ABC, Generic[RetType]):
12
+ """Protocol for future objects that can be awaited."""
13
+
14
+ MISSING_RESULT = Literal[None]
15
+
16
+ @abc.abstractmethod
17
+ def result(self, timeout: float | None) -> list[RetType]:
18
+ """Returns the result of the future, blocking until it is available or the timeout expires."""
19
+
20
+ @abc.abstractmethod
21
+ def partial_result(self) -> list[RetType | MISSING_RESULT]:
22
+ """Return all results that are available so far, or MISSING_RESULT for those that are not yet available."""
23
+
24
+ @abc.abstractmethod
25
+ def fetch(self) -> None:
26
+ """Fetches the result of the future that are currently available."""
27
+
28
+ def cancel(self):
29
+ """Attempts to cancel the execution of the future."""
30
+ raise NotImplementedError(
31
+ f"cancel method not implemented for {self.__class__.__name__}"
32
+ )
33
+
34
+ def cancelled(self) -> bool:
35
+ """Returns True if the future was cancelled, False otherwise."""
36
+ raise NotImplementedError(
37
+ f"cancelled method not implemented for {self.__class__.__name__}"
38
+ )
39
+
40
+ def done(self) -> bool:
41
+ self.fetch()
42
+ return not any(
43
+ result is self.MISSING_RESULT for result in self.partial_result()
44
+ )
45
+
46
+
47
+ ClassRetType = TypeVar("ClassRetType")
48
+
49
+
50
+ @dataclass
51
+ class AbstractTask(abc.ABC, Generic[Params, RetType]):
52
+ kernel: ir.Method[Params, RetType]
53
+ args: tuple[Any, ...]
54
+ kwargs: dict[str, Any]
55
+
56
+
57
+ class DeviceTaskExpectMixin(AbstractTask):
58
+
59
+ ObsType = TypeVar("ObsType")
60
+
61
+ @abc.abstractmethod
62
+ def expect(self, observable: ir.Method[[RetType], ObsType], shots: int) -> ObsType:
63
+ """Returns the expectation value of the given observable after running the task."""
64
+
65
+
66
+ @dataclass
67
+ class AbstractRemoteTask(AbstractTask[Params, RetType]):
68
+ """Base class for tasks generated by the devices."""
69
+
70
+ def run(self, *, shots: int = 1, timeout: float | None = None) -> list[RetType]:
71
+ return self.run_async(shots=shots).result(timeout=timeout)
72
+
73
+ @abc.abstractmethod
74
+ def run_async(self, *, shots: int = 1) -> BatchFuture[RetType]:
75
+ """Executes the kernel asynchronously and returns a Future object."""
76
+
77
+
78
+ StateType = TypeVar("StateType")
79
+
80
+
81
+ @dataclass
82
+ class AbstractSimulatorTask(
83
+ AbstractTask[Params, RetType], Generic[Params, RetType, StateType]
84
+ ):
85
+ """Base class for tasks generated by local simulators."""
86
+
87
+ @abc.abstractmethod
88
+ def run(self) -> RetType:
89
+ """Executes the kernel and returns the result."""
90
+
91
+ @property
92
+ @abc.abstractmethod
93
+ def state(self) -> StateType:
94
+ """Returns the state of the simulator after running the task."""
@@ -45,10 +45,12 @@ class GateArtist:
45
45
  class GlobalGateArtist(GateArtist):
46
46
  mpl_obj: mpatches.Rectangle
47
47
 
48
- def __init__(self, mpl_ax: Any, xmin, ymin, width, height, color):
48
+ def __init__(
49
+ self, mpl_ax: Any, xmin: float, ymin: float, width: float, height: float, color
50
+ ):
49
51
  super().__init__(mpl_ax)
50
52
  rc = mpatches.Rectangle(
51
- [xmin, ymin], width, height, color=color, alpha=0.6, visible=False
53
+ (xmin, ymin), width, height, color=color, alpha=0.6, visible=False
52
54
  )
53
55
  mpl_ax.add_patch(rc)
54
56
  self.mpl_obj = rc
@@ -56,7 +58,7 @@ class GlobalGateArtist(GateArtist):
56
58
  def clear_data(self) -> None:
57
59
  self.mpl_obj.set_width(0)
58
60
  self.mpl_obj.set_height(0)
59
- self.mpl_obj.set_xy([0, 0])
61
+ self.mpl_obj.set_xy((0, 0))
60
62
 
61
63
  def get_artists(self) -> Tuple[Any]:
62
64
  return (self.mpl_obj,)
@@ -86,7 +88,7 @@ class RowRegionGateArtist(GateArtist):
86
88
  self.width = width
87
89
  self.xmin = xmin
88
90
  rc_btm = mpatches.Rectangle(
89
- [xmin, ymin_keepout],
91
+ (xmin, ymin_keepout),
90
92
  width,
91
93
  ymin - ymin_keepout,
92
94
  color=color,
@@ -97,13 +99,13 @@ class RowRegionGateArtist(GateArtist):
97
99
  self.mpl_obj_keepout_btm = rc_btm
98
100
 
99
101
  rc = mpatches.Rectangle(
100
- [xmin, ymin], width, ymax - ymin, color=color, alpha=0.6, visible=False
102
+ (xmin, ymin), width, ymax - ymin, color=color, alpha=0.6, visible=False
101
103
  )
102
104
  mpl_ax.add_patch(rc)
103
105
  self.mpl_obj = rc
104
106
 
105
107
  rc_top = mpatches.Rectangle(
106
- [xmin, ymax],
108
+ (xmin, ymax),
107
109
  width,
108
110
  ymax_keepout - ymax,
109
111
  color=color,
@@ -116,31 +118,31 @@ class RowRegionGateArtist(GateArtist):
116
118
  def clear_data(self) -> None:
117
119
  self.mpl_obj.set_width(0)
118
120
  self.mpl_obj.set_height(0)
119
- self.mpl_obj.set_xy([0, 0])
121
+ self.mpl_obj.set_xy((0, 0))
120
122
 
121
123
  self.mpl_obj_keepout_top.set_width(0)
122
124
  self.mpl_obj_keepout_top.set_height(0)
123
- self.mpl_obj_keepout_top.set_xy([0, 0])
125
+ self.mpl_obj_keepout_top.set_xy((0, 0))
124
126
 
125
127
  self.mpl_obj_keepout_btm.set_width(0)
126
128
  self.mpl_obj_keepout_btm.set_height(0)
127
- self.mpl_obj_keepout_btm.set_xy([0, 0])
129
+ self.mpl_obj_keepout_btm.set_xy((0, 0))
128
130
 
129
- def get_artists(self) -> Tuple[Any]:
131
+ def get_artists(self) -> Tuple[Any, ...]:
130
132
  return (self.mpl_obj, self.mpl_obj_keepout_top, self.mpl_obj_keepout_btm)
131
133
 
132
134
  def update_data(self, ymin, ymax, ymin_keepout, ymax_keepout):
133
135
  self.mpl_obj.set_height(ymax - ymin)
134
136
  self.mpl_obj.set_width(self.width)
135
- self.mpl_obj.set_xy([self.xmin, ymin])
137
+ self.mpl_obj.set_xy((self.xmin, ymin))
136
138
 
137
139
  self.mpl_obj_keepout_top.set_height(ymax_keepout - ymax)
138
140
  self.mpl_obj_keepout_top.set_width(self.width)
139
- self.mpl_obj_keepout_top.set_xy([self.xmin, ymax])
141
+ self.mpl_obj_keepout_top.set_xy((self.xmin, ymax))
140
142
 
141
143
  self.mpl_obj_keepout_btm.set_height(ymin - ymin_keepout)
142
144
  self.mpl_obj_keepout_btm.set_width(self.width)
143
- self.mpl_obj_keepout_btm.set_xy([self.xmin, ymin_keepout])
145
+ self.mpl_obj_keepout_btm.set_xy((self.xmin, ymin_keepout))
144
146
 
145
147
  def set_visible(self, visible: bool):
146
148
  self.mpl_obj.set_visible(visible)
@@ -194,11 +196,19 @@ class FieldOfView:
194
196
  )
195
197
 
196
198
  @property
197
- def width(self):
199
+ def width(self) -> float:
200
+ if self.xmax is None or self.xmin is None:
201
+ raise ValueError(
202
+ "Can't return width of FOV as either xmin or xmax are undefined"
203
+ )
198
204
  return self.xmax - self.xmin
199
205
 
200
206
  @property
201
- def height(self):
207
+ def height(self) -> float:
208
+ if self.ymax is None or self.ymin is None:
209
+ raise ValueError(
210
+ "Can't return width of FOV as either ymin or ymax are undefined"
211
+ )
202
212
  return self.ymax - self.ymin
203
213
 
204
214
  def to_json(self):
@@ -1,19 +1,25 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bloqade-circuit
3
- Version: 0.1.0
3
+ Version: 0.2.1
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
7
7
  Requires-Python: >=3.10
8
- Requires-Dist: kirin-toolchain~=0.16.0
8
+ Requires-Dist: kirin-toolchain~=0.17.0
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.38.2; sys_platform != 'darwin'
13
+ Requires-Dist: pyqrack>=1.38.2; sys_platform == 'darwin'
12
14
  Requires-Dist: rich>=13.9.4
13
15
  Requires-Dist: scipy>=1.13.1
14
16
  Provides-Extra: cirq
15
17
  Requires-Dist: cirq-core>=1.4.1; extra == 'cirq'
16
18
  Requires-Dist: cirq-core[contrib]>=1.4.1; extra == 'cirq'
19
+ Provides-Extra: pyqrack-cuda
20
+ Requires-Dist: pyqrack-cuda>=1.38.2; extra == 'pyqrack-cuda'
21
+ Provides-Extra: pyqrack-opencl
22
+ Requires-Dist: pyqrack>=1.38.2; (sys_platform != 'darwin') and extra == 'pyqrack-opencl'
17
23
  Provides-Extra: qasm2
18
24
  Requires-Dist: lark>=1.2.2; extra == 'qasm2'
19
25
  Provides-Extra: qbraid