classiq 0.46.1__py3-none-any.whl → 0.48.0__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.
- classiq/_internals/api_wrapper.py +45 -8
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +2 -7
- classiq/applications/grover/grover_model_constructor.py +2 -1
- classiq/execution/execution_session.py +133 -45
- classiq/execution/jobs.py +120 -1
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/quantum_backend_providers.py +0 -1
- classiq/interface/debug_info/debug_info.py +23 -1
- classiq/interface/execution/primitives.py +17 -0
- classiq/interface/executor/iqae_result.py +3 -3
- classiq/interface/executor/result.py +3 -1
- classiq/interface/generator/arith/arithmetic_operations.py +5 -2
- classiq/interface/generator/arith/binary_ops.py +21 -14
- classiq/interface/generator/arith/extremum_operations.py +9 -1
- classiq/interface/generator/arith/number_utils.py +6 -0
- classiq/interface/generator/arith/register_user_input.py +30 -21
- classiq/interface/generator/arith/unary_ops.py +13 -1
- classiq/interface/generator/expressions/expression.py +8 -0
- classiq/interface/generator/functions/type_name.py +1 -3
- classiq/interface/generator/generated_circuit_data.py +47 -2
- classiq/interface/generator/quantum_program.py +10 -2
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +17 -3
- classiq/interface/ide/visual_model.py +10 -5
- classiq/interface/interface_version.py +1 -1
- classiq/interface/model/bind_operation.py +0 -3
- classiq/interface/model/phase_operation.py +11 -0
- classiq/interface/model/port_declaration.py +1 -12
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +34 -6
- classiq/interface/model/quantum_lambda_function.py +4 -1
- classiq/interface/model/quantum_statement.py +16 -1
- classiq/interface/model/quantum_variable_declaration.py +0 -22
- classiq/interface/model/statement_block.py +3 -0
- classiq/interface/server/global_versions.py +4 -4
- classiq/interface/server/routes.py +0 -3
- classiq/model_expansions/capturing/propagated_var_stack.py +5 -2
- classiq/model_expansions/closure.py +7 -2
- classiq/model_expansions/evaluators/quantum_type_utils.py +0 -7
- classiq/model_expansions/generative_functions.py +146 -28
- classiq/model_expansions/interpreter.py +17 -5
- classiq/model_expansions/quantum_operations/classicalif.py +27 -10
- classiq/model_expansions/quantum_operations/control.py +22 -15
- classiq/model_expansions/quantum_operations/emitter.py +68 -7
- classiq/model_expansions/quantum_operations/expression_operation.py +25 -16
- classiq/model_expansions/quantum_operations/inplace_binary_operation.py +167 -95
- classiq/model_expansions/quantum_operations/invert.py +12 -6
- classiq/model_expansions/quantum_operations/phase.py +189 -0
- classiq/model_expansions/quantum_operations/power.py +9 -8
- classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +20 -5
- classiq/model_expansions/quantum_operations/quantum_function_call.py +1 -1
- classiq/model_expansions/quantum_operations/repeat.py +32 -13
- classiq/model_expansions/quantum_operations/within_apply.py +19 -6
- classiq/model_expansions/scope.py +16 -5
- classiq/model_expansions/scope_initialization.py +11 -1
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +23 -1
- classiq/model_expansions/visitors/variable_references.py +11 -7
- classiq/qmod/builtins/__init__.py +10 -0
- classiq/qmod/builtins/constants.py +10 -0
- classiq/qmod/builtins/functions/state_preparation.py +4 -1
- classiq/qmod/builtins/operations.py +55 -161
- classiq/qmod/create_model_function.py +1 -1
- classiq/qmod/generative.py +14 -5
- classiq/qmod/native/pretty_printer.py +14 -4
- classiq/qmod/pretty_print/pretty_printer.py +14 -4
- classiq/qmod/qmod_constant.py +28 -18
- classiq/qmod/qmod_variable.py +43 -23
- classiq/qmod/quantum_expandable.py +14 -1
- classiq/qmod/semantics/static_semantics_visitor.py +10 -0
- classiq/qmod/semantics/validation/constants_validation.py +16 -0
- {classiq-0.46.1.dist-info → classiq-0.48.0.dist-info}/METADATA +9 -4
- {classiq-0.46.1.dist-info → classiq-0.48.0.dist-info}/RECORD +71 -66
- {classiq-0.46.1.dist-info → classiq-0.48.0.dist-info}/WHEEL +0 -0
classiq/qmod/qmod_variable.py
CHANGED
@@ -48,6 +48,7 @@ from classiq.interface.model.quantum_expressions.amplitude_loading_operation imp
|
|
48
48
|
)
|
49
49
|
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
50
50
|
ArithmeticOperation,
|
51
|
+
ArithmeticOperationKind,
|
51
52
|
)
|
52
53
|
from classiq.interface.model.quantum_type import (
|
53
54
|
QuantumBit,
|
@@ -57,10 +58,10 @@ from classiq.interface.model.quantum_type import (
|
|
57
58
|
)
|
58
59
|
from classiq.interface.source_reference import SourceReference
|
59
60
|
|
60
|
-
from classiq.qmod.cparam import ArrayBase,
|
61
|
+
from classiq.qmod.cparam import ArrayBase, CInt, CParamScalar
|
61
62
|
from classiq.qmod.generative import (
|
62
63
|
generative_mode_context,
|
63
|
-
|
64
|
+
interpret_expression,
|
64
65
|
is_generative_mode,
|
65
66
|
)
|
66
67
|
from classiq.qmod.model_state_container import QMODULE, ModelStateContainer
|
@@ -95,10 +96,6 @@ def _no_current_expandable() -> Iterator[None]:
|
|
95
96
|
QCallable.CURRENT_EXPANDABLE = current_expandable
|
96
97
|
|
97
98
|
|
98
|
-
def _evaluate_expression(expr: str) -> Any:
|
99
|
-
return get_frontend_interpreter().evaluate(Expression(expr=expr)).value
|
100
|
-
|
101
|
-
|
102
99
|
class QVar(Symbolic):
|
103
100
|
def __init__(
|
104
101
|
self,
|
@@ -171,7 +168,7 @@ class QVar(Symbolic):
|
|
171
168
|
def size(self) -> Union[CParamScalar, int]:
|
172
169
|
if is_generative_mode():
|
173
170
|
with generative_mode_context(False):
|
174
|
-
return
|
171
|
+
return interpret_expression(str(self.size))
|
175
172
|
return CParamScalar(f"get_field({self}, 'size')")
|
176
173
|
|
177
174
|
|
@@ -192,7 +189,10 @@ class QScalar(QVar, SymbolicExpr):
|
|
192
189
|
SymbolicExpr.__init__(self, str(origin), True)
|
193
190
|
|
194
191
|
def _insert_arith_operation(
|
195
|
-
self,
|
192
|
+
self,
|
193
|
+
expr: SymbolicTypes,
|
194
|
+
kind: ArithmeticOperationKind,
|
195
|
+
source_ref: SourceReference,
|
196
196
|
) -> None:
|
197
197
|
# Fixme: Arithmetic operations are not yet supported on slices (see CAD-12670)
|
198
198
|
if TYPE_CHECKING:
|
@@ -201,7 +201,7 @@ class QScalar(QVar, SymbolicExpr):
|
|
201
201
|
ArithmeticOperation(
|
202
202
|
expression=Expression(expr=str(expr)),
|
203
203
|
result_var=self.get_handle_binding(),
|
204
|
-
|
204
|
+
operation_kind=kind,
|
205
205
|
source_ref=source_ref,
|
206
206
|
)
|
207
207
|
)
|
@@ -225,7 +225,9 @@ class QScalar(QVar, SymbolicExpr):
|
|
225
225
|
f"Invalid argument {other!r} for out-of-place arithmetic operation"
|
226
226
|
)
|
227
227
|
|
228
|
-
self._insert_arith_operation(
|
228
|
+
self._insert_arith_operation(
|
229
|
+
other, ArithmeticOperationKind.Assignment, get_source_ref(sys._getframe(1))
|
230
|
+
)
|
229
231
|
return self
|
230
232
|
|
231
233
|
def __ixor__(self, other: Any) -> Self:
|
@@ -234,7 +236,20 @@ class QScalar(QVar, SymbolicExpr):
|
|
234
236
|
f"Invalid argument {other!r} for in-place arithmetic operation"
|
235
237
|
)
|
236
238
|
|
237
|
-
self._insert_arith_operation(
|
239
|
+
self._insert_arith_operation(
|
240
|
+
other, ArithmeticOperationKind.InplaceXor, get_source_ref(sys._getframe(1))
|
241
|
+
)
|
242
|
+
return self
|
243
|
+
|
244
|
+
def __iadd__(self, other: Any) -> Self:
|
245
|
+
if not isinstance(other, get_args(SymbolicTypes)):
|
246
|
+
raise TypeError(
|
247
|
+
f"Invalid argument {other!r} for in-place arithmetic operation"
|
248
|
+
)
|
249
|
+
|
250
|
+
self._insert_arith_operation(
|
251
|
+
other, ArithmeticOperationKind.InplaceAdd, get_source_ref(sys._getframe(1))
|
252
|
+
)
|
238
253
|
return self
|
239
254
|
|
240
255
|
def __imul__(self, other: Any) -> Self:
|
@@ -273,18 +288,21 @@ class QNum(Generic[_P], QScalar):
|
|
273
288
|
self,
|
274
289
|
name: Union[str, HandleBinding],
|
275
290
|
size: Union[int, CInt, Expression, None] = None,
|
276
|
-
is_signed: Union[bool,
|
291
|
+
is_signed: Union[bool, Expression, SymbolicExpr, None] = None,
|
277
292
|
fraction_digits: Union[int, CInt, Expression, None] = None,
|
278
293
|
_expr_str: Optional[str] = None,
|
279
294
|
):
|
280
|
-
if (
|
281
|
-
size is None
|
282
|
-
and (is_signed is not None or fraction_digits is not None)
|
283
|
-
or size is not None
|
284
|
-
and (is_signed is None or fraction_digits is None)
|
285
|
-
):
|
295
|
+
if size is None and (is_signed is not None or fraction_digits is not None):
|
286
296
|
raise ClassiqValueError(
|
287
|
-
"
|
297
|
+
"Cannot assign 'is_signed' and 'fraction_digits' without 'size'"
|
298
|
+
)
|
299
|
+
if is_signed is not None and fraction_digits is None:
|
300
|
+
raise ClassiqValueError(
|
301
|
+
"Cannot assign 'is_signed' without 'fraction_digits'"
|
302
|
+
)
|
303
|
+
if is_signed is None and fraction_digits is not None:
|
304
|
+
raise ClassiqValueError(
|
305
|
+
"Cannot assign 'fraction_digits' without 'is_signed'"
|
288
306
|
)
|
289
307
|
self._size = (
|
290
308
|
size
|
@@ -308,11 +326,13 @@ class QNum(Generic[_P], QScalar):
|
|
308
326
|
type_args = version_portable_get_args(type_hint)
|
309
327
|
if len(type_args) == 0:
|
310
328
|
return None, None, None
|
311
|
-
if len(type_args)
|
329
|
+
if len(type_args) not in (1, 3):
|
312
330
|
raise ClassiqValueError(
|
313
331
|
"QNum receives three type arguments: QNum[size: int | CInt, "
|
314
332
|
"is_signed: bool | CBool, fraction_digits: int | CInt]"
|
315
333
|
)
|
334
|
+
if len(type_args) == 1:
|
335
|
+
return type_args[0], None, None
|
316
336
|
return type_args[0], type_args[1], type_args[2]
|
317
337
|
|
318
338
|
@classmethod
|
@@ -354,14 +374,14 @@ class QNum(Generic[_P], QScalar):
|
|
354
374
|
def fraction_digits(self) -> Union[CParamScalar, int]:
|
355
375
|
if is_generative_mode():
|
356
376
|
with generative_mode_context(False):
|
357
|
-
return
|
377
|
+
return interpret_expression(str(self.fraction_digits))
|
358
378
|
return CParamScalar(f"get_field({self}, 'fraction_digits')")
|
359
379
|
|
360
380
|
@property
|
361
381
|
def is_signed(self) -> Union[CParamScalar, bool]:
|
362
382
|
if is_generative_mode():
|
363
383
|
with generative_mode_context(False):
|
364
|
-
return
|
384
|
+
return interpret_expression(str(self.is_signed))
|
365
385
|
return CParamScalar(f"get_field({self}, 'is_signed')")
|
366
386
|
|
367
387
|
# Support comma-separated generic args in older Python versions
|
@@ -466,7 +486,7 @@ class QArray(ArrayBase[_P], QVar):
|
|
466
486
|
def len(self) -> Union[CParamScalar, int]:
|
467
487
|
if is_generative_mode():
|
468
488
|
with generative_mode_context(False):
|
469
|
-
return
|
489
|
+
return interpret_expression(str(self.len))
|
470
490
|
if self._length is not None:
|
471
491
|
return CParamScalar(f"{self._length}")
|
472
492
|
return CParamScalar(f"get_field({self}, 'len')")
|
@@ -122,8 +122,17 @@ class QExpandable(QCallable, QExpandableInterface, ABC):
|
|
122
122
|
|
123
123
|
def _get_positional_args(self) -> List[ArgType]:
|
124
124
|
result: List[ArgType] = []
|
125
|
+
rename_params = self.infer_rename_params()
|
126
|
+
if rename_params is not None and len(rename_params) != len(
|
127
|
+
self.func_decl.positional_arg_declarations
|
128
|
+
):
|
129
|
+
op_name = (
|
130
|
+
f" {self.func_decl.name!r}" if self.func_decl.name is not None else ""
|
131
|
+
)
|
132
|
+
raise ClassiqValueError(
|
133
|
+
f"Operand{op_name} takes {len(self.func_decl.positional_arg_declarations)} arguments but the received function takes {len(rename_params)} argument"
|
134
|
+
)
|
125
135
|
for idx, arg in enumerate(self.func_decl.positional_arg_declarations):
|
126
|
-
rename_params = self.infer_rename_params()
|
127
136
|
actual_name = (
|
128
137
|
rename_params[idx] if rename_params is not None else arg.get_name()
|
129
138
|
)
|
@@ -303,6 +312,10 @@ def prepare_arg(
|
|
303
312
|
return [prepare_arg(arg_decl, v, func_name, param_name) for v in val]
|
304
313
|
|
305
314
|
if not isinstance(val, QCallable):
|
315
|
+
if not callable(val):
|
316
|
+
raise ClassiqValueError(
|
317
|
+
f"Operand argument to {param_name!r} must be a callable object"
|
318
|
+
)
|
306
319
|
new_arg_decl = decl_without_type_attributes(arg_decl)
|
307
320
|
val = QLambdaFunction(new_arg_decl, val)
|
308
321
|
val.expand()
|
@@ -51,6 +51,9 @@ from classiq.interface.model.within_apply_operation import WithinApply
|
|
51
51
|
from classiq.qmod.builtins.functions import BUILTIN_FUNCTION_DECLARATIONS
|
52
52
|
from classiq.qmod.semantics.annotation import annotate_function_call_decl
|
53
53
|
from classiq.qmod.semantics.error_manager import ErrorManager
|
54
|
+
from classiq.qmod.semantics.validation.constants_validation import (
|
55
|
+
check_duplicate_constants,
|
56
|
+
)
|
54
57
|
from classiq.qmod.semantics.validation.func_call_validation import (
|
55
58
|
check_no_overlapping_quantum_args,
|
56
59
|
validate_call_arguments,
|
@@ -110,6 +113,7 @@ class StaticSemanticsVisitor(Visitor):
|
|
110
113
|
|
111
114
|
def visit_Model(self, model: Model) -> None:
|
112
115
|
check_duplicate_types([*model.enums, *model.types, *model.qstructs])
|
116
|
+
check_duplicate_constants(model.constants)
|
113
117
|
for qstruct in model.qstructs:
|
114
118
|
check_qstruct_has_fields(qstruct)
|
115
119
|
if check_qstruct_fields_are_defined(
|
@@ -318,6 +322,12 @@ class StaticSemanticsVisitor(Visitor):
|
|
318
322
|
|
319
323
|
for handle_metadata in inouts:
|
320
324
|
handle_binding = handle_metadata.handle
|
325
|
+
|
326
|
+
if handle_binding.name not in self.current_scope.variable_states:
|
327
|
+
ErrorManager().add_error(
|
328
|
+
f"Variable {handle_binding.name!r} is not defined"
|
329
|
+
)
|
330
|
+
return
|
321
331
|
handle_wiring_state = self.current_scope.variable_states[
|
322
332
|
handle_binding.name
|
323
333
|
]
|
@@ -0,0 +1,16 @@
|
|
1
|
+
from typing import Sequence
|
2
|
+
|
3
|
+
from classiq.interface.generator.constant import Constant
|
4
|
+
|
5
|
+
from classiq.qmod.builtins import BUILTIN_CONSTANTS
|
6
|
+
from classiq.qmod.semantics.error_manager import ErrorManager
|
7
|
+
|
8
|
+
|
9
|
+
def check_duplicate_constants(constants: Sequence[Constant]) -> None:
|
10
|
+
known_constants = {constant.name: constant for constant in BUILTIN_CONSTANTS}
|
11
|
+
for constant in constants:
|
12
|
+
if constant.name in known_constants:
|
13
|
+
with ErrorManager().node_context(constant):
|
14
|
+
ErrorManager().add_error(f"Constant {constant.name!r} already exists")
|
15
|
+
else:
|
16
|
+
known_constants[constant.name] = constant
|
@@ -1,13 +1,13 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: classiq
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.48.0
|
4
4
|
Summary: Classiq's Python SDK for quantum computing
|
5
5
|
Home-page: https://classiq.io
|
6
6
|
License: Proprietary
|
7
7
|
Keywords: quantum computing,quantum circuits,quantum algorithms,QAD,QDL
|
8
8
|
Author: Classiq Technologies
|
9
9
|
Author-email: support@classiq.io
|
10
|
-
Requires-Python: >=3.8,<3.
|
10
|
+
Requires-Python: >=3.8,<3.13
|
11
11
|
Classifier: Development Status :: 4 - Beta
|
12
12
|
Classifier: Intended Audience :: Developers
|
13
13
|
Classifier: Intended Audience :: Education
|
@@ -20,6 +20,7 @@ Classifier: Programming Language :: Python :: 3.8
|
|
20
20
|
Classifier: Programming Language :: Python :: 3.9
|
21
21
|
Classifier: Programming Language :: Python :: 3.10
|
22
22
|
Classifier: Programming Language :: Python :: 3.11
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
23
24
|
Classifier: Programming Language :: Python :: 3 :: Only
|
24
25
|
Classifier: Topic :: Scientific/Engineering
|
25
26
|
Classifier: Topic :: Software Development
|
@@ -34,16 +35,20 @@ Requires-Dist: Pyomo (>=6.5,<6.6)
|
|
34
35
|
Requires-Dist: black (>=24.0,<25.0)
|
35
36
|
Requires-Dist: httpx (>=0.23.0,<1)
|
36
37
|
Requires-Dist: ipywidgets (>=7.7.1,<8.0.0) ; extra == "analyzer-sdk"
|
38
|
+
Requires-Dist: jupyterlab (>=4.2.5,<5.0.0) ; extra == "analyzer-sdk"
|
37
39
|
Requires-Dist: keyring (>=23.5.0,<24.0.0)
|
38
40
|
Requires-Dist: matplotlib (>=3.4.3,<4.0.0)
|
39
41
|
Requires-Dist: networkx (>=2.5.1,<3.0.0)
|
42
|
+
Requires-Dist: notebook (>=7.2.2,<8.0.0) ; extra == "analyzer-sdk"
|
40
43
|
Requires-Dist: numexpr (>=2.7.3,<3.0.0)
|
41
|
-
Requires-Dist: numpy (>=1.20.1,<2.0.0)
|
44
|
+
Requires-Dist: numpy (>=1.20.1,<2.0.0) ; python_version < "3.12"
|
45
|
+
Requires-Dist: numpy (>=1.26.0,<2.0.0) ; python_version >= "3.12"
|
42
46
|
Requires-Dist: packaging (>=23.2,<24.0)
|
43
47
|
Requires-Dist: pandas (>=1.4.0,<3.0.0)
|
44
48
|
Requires-Dist: plotly (>=5.7.0,<6.0.0)
|
45
49
|
Requires-Dist: pydantic (>=1.9.1,<2.0.0)
|
46
|
-
Requires-Dist: scipy (>=1.10.
|
50
|
+
Requires-Dist: scipy (>=1.10.0,<2.0.0) ; python_version < "3.12"
|
51
|
+
Requires-Dist: scipy (>=1.11.0,<2.0.0) ; python_version >= "3.12"
|
47
52
|
Requires-Dist: sympy (>=1.13.0,<2.0.0)
|
48
53
|
Requires-Dist: tabulate (>=0.8.9,<1)
|
49
54
|
Requires-Dist: torch (>=2.0,<3.0) ; extra == "qml"
|