classiq 0.74.0__py3-none-any.whl → 0.76.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 +36 -0
- classiq/analyzer/show_interactive_hack.py +58 -2
- classiq/applications/chemistry/chemistry_model_constructor.py +8 -1
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +2 -0
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +4 -4
- classiq/applications/qnn/gradients/quantum_gradient.py +3 -5
- classiq/applications/qnn/gradients/simple_quantum_gradient.py +2 -2
- classiq/applications/qnn/qlayer.py +23 -19
- classiq/applications/qnn/types.py +1 -4
- classiq/execution/__init__.py +3 -0
- classiq/execution/execution_session.py +3 -16
- classiq/execution/qnn.py +2 -2
- classiq/execution/user_budgets.py +38 -0
- classiq/executor.py +7 -19
- classiq/interface/_version.py +1 -1
- classiq/interface/debug_info/debug_info.py +18 -13
- classiq/interface/executor/user_budget.py +56 -0
- classiq/interface/generator/application_apis/finance_declarations.py +3 -0
- classiq/interface/generator/expressions/atomic_expression_functions.py +3 -0
- classiq/interface/generator/expressions/proxies/classical/any_classical_value.py +30 -124
- classiq/interface/generator/expressions/proxies/classical/classical_array_proxy.py +46 -22
- classiq/interface/generator/expressions/proxies/classical/qmod_struct_instance.py +7 -0
- classiq/interface/generator/expressions/proxies/classical/utils.py +14 -13
- classiq/interface/generator/expressions/proxies/quantum/qmod_qscalar_proxy.py +9 -2
- classiq/interface/generator/expressions/proxies/quantum/qmod_sized_proxy.py +4 -1
- classiq/interface/generator/expressions/sympy_supported_expressions.py +1 -0
- classiq/interface/generator/functions/classical_type.py +36 -1
- classiq/interface/generator/functions/type_name.py +32 -5
- classiq/interface/generator/functions/type_qualifier.py +15 -0
- classiq/interface/generator/generated_circuit_data.py +11 -25
- classiq/interface/generator/model/preferences/preferences.py +7 -0
- classiq/interface/generator/quantum_program.py +5 -19
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +10 -13
- classiq/interface/helpers/backward_compatibility.py +9 -0
- classiq/interface/helpers/datastructures.py +6 -0
- classiq/interface/helpers/versioned_model.py +12 -0
- classiq/interface/interface_version.py +1 -1
- classiq/interface/model/handle_binding.py +12 -0
- classiq/interface/model/port_declaration.py +1 -2
- classiq/interface/model/quantum_lambda_function.py +2 -1
- classiq/interface/model/statement_block.py +9 -1
- classiq/interface/model/within_apply_operation.py +12 -0
- classiq/interface/server/routes.py +6 -0
- classiq/model_expansions/atomic_expression_functions_defs.py +82 -23
- classiq/model_expansions/capturing/captured_vars.py +2 -0
- classiq/model_expansions/closure.py +18 -0
- classiq/model_expansions/evaluators/argument_types.py +6 -5
- classiq/model_expansions/evaluators/classical_type_inference.py +17 -6
- classiq/model_expansions/evaluators/parameter_types.py +26 -13
- classiq/model_expansions/evaluators/type_type_match.py +2 -2
- classiq/model_expansions/expression_evaluator.py +1 -1
- classiq/model_expansions/generative_functions.py +66 -33
- classiq/model_expansions/interpreters/base_interpreter.py +27 -19
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +26 -0
- classiq/model_expansions/interpreters/generative_interpreter.py +25 -1
- classiq/model_expansions/quantum_operations/allocate.py +27 -11
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +220 -19
- classiq/model_expansions/quantum_operations/bind.py +54 -30
- classiq/model_expansions/quantum_operations/block_evaluator.py +42 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +14 -12
- classiq/model_expansions/quantum_operations/composite_emitter.py +1 -1
- classiq/model_expansions/quantum_operations/declarative_call_emitter.py +23 -9
- classiq/model_expansions/quantum_operations/emitter.py +21 -8
- classiq/model_expansions/quantum_operations/expression_evaluator.py +1 -0
- classiq/model_expansions/quantum_operations/handle_evaluator.py +1 -0
- classiq/model_expansions/quantum_operations/quantum_function_call.py +4 -3
- classiq/model_expansions/scope.py +10 -7
- classiq/model_expansions/sympy_conversion/arithmetics.py +18 -0
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +2 -0
- classiq/model_expansions/sympy_conversion/sympy_to_python.py +10 -1
- classiq/model_expansions/transformers/model_renamer.py +48 -8
- classiq/model_expansions/utils/handles_collector.py +1 -1
- classiq/model_expansions/visitors/symbolic_param_inference.py +197 -0
- classiq/model_expansions/visitors/variable_references.py +45 -9
- classiq/qmod/builtins/functions/allocation.py +2 -2
- classiq/qmod/builtins/functions/arithmetic.py +14 -12
- classiq/qmod/builtins/functions/standard_gates.py +23 -23
- classiq/qmod/declaration_inferrer.py +19 -7
- classiq/qmod/generative.py +9 -1
- classiq/qmod/native/expression_to_qmod.py +4 -0
- classiq/qmod/native/pretty_printer.py +8 -3
- classiq/qmod/pretty_print/pretty_printer.py +1 -1
- classiq/qmod/python_classical_type.py +4 -5
- classiq/qmod/qmod_constant.py +15 -7
- classiq/qmod/qmod_variable.py +30 -2
- classiq/qmod/quantum_function.py +19 -6
- classiq/qmod/semantics/lambdas.py +6 -2
- classiq/qmod/semantics/validation/main_validation.py +17 -4
- classiq/qmod/symbolic.py +8 -19
- classiq/qmod/symbolic_expr.py +34 -2
- classiq/qmod/write_qmod.py +5 -1
- classiq/synthesis.py +17 -31
- classiq/visualization.py +35 -0
- {classiq-0.74.0.dist-info → classiq-0.76.0.dist-info}/METADATA +1 -1
- {classiq-0.74.0.dist-info → classiq-0.76.0.dist-info}/RECORD +96 -91
- {classiq-0.74.0.dist-info → classiq-0.76.0.dist-info}/WHEEL +1 -1
classiq/qmod/symbolic_expr.py
CHANGED
@@ -4,6 +4,8 @@ import ast
|
|
4
4
|
from enum import Enum as PythonEnum
|
5
5
|
from typing import Any
|
6
6
|
|
7
|
+
import sympy
|
8
|
+
|
7
9
|
from classiq.qmod.utilities import qmod_val_to_expr_str
|
8
10
|
|
9
11
|
|
@@ -33,10 +35,14 @@ class SymbolicExpr(Symbolic):
|
|
33
35
|
|
34
36
|
@staticmethod
|
35
37
|
def _binary_op(lhs: Any, rhs: Any, op: str) -> SymbolicExpr:
|
36
|
-
if not isinstance(
|
38
|
+
if not isinstance(
|
39
|
+
lhs, (SymbolicExpr, int, float, bool, PythonEnum, sympy.Basic)
|
40
|
+
):
|
37
41
|
raise TypeError(f"Invalid lhs argument {lhs!r} for binary operation {op!r}")
|
38
42
|
|
39
|
-
if not isinstance(
|
43
|
+
if not isinstance(
|
44
|
+
rhs, (SymbolicExpr, int, float, bool, PythonEnum, sympy.Basic)
|
45
|
+
):
|
40
46
|
raise TypeError(f"Invalid lhs argument {rhs!r} for binary operation {op!r}")
|
41
47
|
|
42
48
|
lhs_str = qmod_val_to_expr_str(lhs)
|
@@ -171,3 +177,29 @@ class SymbolicEquality(SymbolicExpr):
|
|
171
177
|
super().__init__(sym_expr._expr, sym_expr.is_quantum)
|
172
178
|
self.lhs = lhs
|
173
179
|
self.rhs = rhs
|
180
|
+
|
181
|
+
|
182
|
+
class SymbolicSubscriptAndField(SymbolicExpr):
|
183
|
+
def __getattr__(self, item: str) -> SymbolicSubscriptAndField:
|
184
|
+
return SymbolicSubscriptAndField(f"{self}.{item}", is_quantum=self.is_quantum)
|
185
|
+
|
186
|
+
def __getitem__(self, item: Any) -> SymbolicExpr:
|
187
|
+
if isinstance(item, slice):
|
188
|
+
start = item.start
|
189
|
+
stop = item.stop
|
190
|
+
step = item.step
|
191
|
+
item_is_quantum = (
|
192
|
+
(isinstance(start, SymbolicExpr) and start.is_quantum)
|
193
|
+
or (isinstance(stop, SymbolicExpr) and stop.is_quantum)
|
194
|
+
or (isinstance(step, SymbolicExpr) and step.is_quantum)
|
195
|
+
)
|
196
|
+
start_str = "" if start is None else qmod_val_to_expr_str(start)
|
197
|
+
stop_str = "" if stop is None else qmod_val_to_expr_str(stop)
|
198
|
+
step_str = "" if step is None else qmod_val_to_expr_str(step)
|
199
|
+
item_str = f"{start_str}:{stop_str}:{step_str}"
|
200
|
+
else:
|
201
|
+
item_is_quantum = isinstance(item, SymbolicExpr) and item.is_quantum
|
202
|
+
item_str = qmod_val_to_expr_str(item)
|
203
|
+
return SymbolicSubscriptAndField(
|
204
|
+
f"{self}[{item_str}]", is_quantum=self.is_quantum or item_is_quantum
|
205
|
+
)
|
classiq/qmod/write_qmod.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import json
|
2
2
|
from pathlib import Path
|
3
|
-
from typing import Optional, Union
|
3
|
+
from typing import Any, Optional, Union
|
4
4
|
|
5
5
|
from classiq.interface.model.model import Model, SerializedModel
|
6
6
|
|
@@ -17,6 +17,8 @@ def write_qmod(
|
|
17
17
|
name: str,
|
18
18
|
directory: Optional[Path] = None,
|
19
19
|
decimal_precision: int = DEFAULT_DECIMAL_PRECISION,
|
20
|
+
*args: Any,
|
21
|
+
**kwargs: Any,
|
20
22
|
) -> None:
|
21
23
|
"""
|
22
24
|
Creates a native Qmod file from a serialized model and outputs the synthesis options (Preferences and Constraints) to a file.
|
@@ -27,6 +29,8 @@ def write_qmod(
|
|
27
29
|
name: The name to save the file by.
|
28
30
|
directory: The directory to save the files in. If None, the current working directory is used.
|
29
31
|
decimal_precision: The number of decimal places to use for numbers, set to 4 by default.
|
32
|
+
args: (placeholder)
|
33
|
+
kwargs: (placeholder)
|
30
34
|
|
31
35
|
Returns:
|
32
36
|
None
|
classiq/synthesis.py
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
from typing import Any,
|
2
|
-
|
3
|
-
import pydantic
|
1
|
+
from typing import Any, Optional, Union
|
4
2
|
|
5
3
|
from classiq.interface.analyzer.result import QasmCode
|
6
4
|
from classiq.interface.exceptions import ClassiqError, ClassiqValueError
|
@@ -12,43 +10,33 @@ from classiq.interface.model.model import MAIN_FUNCTION_NAME, Model, SerializedM
|
|
12
10
|
from classiq import QuantumProgram
|
13
11
|
from classiq._internals import async_utils
|
14
12
|
from classiq._internals.api_wrapper import ApiWrapper
|
15
|
-
from classiq.qmod.quantum_function import
|
16
|
-
|
17
|
-
SerializedQuantumProgram = NewType("SerializedQuantumProgram", str)
|
13
|
+
from classiq.qmod.quantum_function import BaseQFunc
|
18
14
|
|
19
|
-
|
20
|
-
"Can not parse quantum_program into GeneratedCircuit, \n"
|
21
|
-
)
|
15
|
+
SerializedQuantumProgram = QuantumProgram
|
22
16
|
|
23
17
|
|
24
|
-
def show(quantum_program:
|
18
|
+
def show(quantum_program: QuantumProgram, display_url: bool = True) -> None:
|
25
19
|
"""
|
26
20
|
Displays the interactive representation of the quantum program in the Classiq IDE.
|
27
21
|
|
28
22
|
Args:
|
29
23
|
quantum_program:
|
30
|
-
The
|
24
|
+
The quantum program to be displayed.
|
31
25
|
display_url:
|
32
26
|
Whether to print the url
|
33
27
|
|
34
28
|
Links:
|
35
29
|
[Visualization tool](https://docs.classiq.io/latest/reference-manual/analyzer/quantum-program-visualization-tool/)
|
36
30
|
"""
|
37
|
-
|
38
|
-
|
39
|
-
except pydantic.ValidationError as exc:
|
40
|
-
raise ClassiqValueError(CANT_PARSE_QUANTUM_PROGRAM_MSG) from exc
|
41
|
-
circuit.show() # type: ignore[attr-defined]
|
31
|
+
QuantumProgram.model_validate(quantum_program)
|
32
|
+
quantum_program.show() # type: ignore[attr-defined]
|
42
33
|
|
43
34
|
|
44
|
-
async def quantum_program_from_qasm_async(qasm: str) ->
|
45
|
-
|
46
|
-
QasmCode(code=qasm)
|
47
|
-
)
|
48
|
-
return SerializedQuantumProgram(quantum_program.model_dump_json())
|
35
|
+
async def quantum_program_from_qasm_async(qasm: str) -> QuantumProgram:
|
36
|
+
return await ApiWrapper.get_generated_circuit_from_qasm(QasmCode(code=qasm))
|
49
37
|
|
50
38
|
|
51
|
-
def quantum_program_from_qasm(qasm: str) ->
|
39
|
+
def quantum_program_from_qasm(qasm: str) -> QuantumProgram:
|
52
40
|
"""
|
53
41
|
generate a quantum program from a QASM file.
|
54
42
|
|
@@ -56,25 +44,24 @@ def quantum_program_from_qasm(qasm: str) -> SerializedQuantumProgram:
|
|
56
44
|
qasm: A QASM2/3 string.
|
57
45
|
|
58
46
|
Returns:
|
59
|
-
|
47
|
+
QuantumProgram: Quantum program. (See: QuantumProgram)
|
60
48
|
"""
|
61
49
|
return async_utils.run(quantum_program_from_qasm_async(qasm))
|
62
50
|
|
63
51
|
|
64
52
|
async def synthesize_async(
|
65
53
|
serialized_model: SerializedModel,
|
66
|
-
) ->
|
54
|
+
) -> QuantumProgram:
|
67
55
|
model = Model.model_validate_json(serialized_model)
|
68
|
-
|
69
|
-
return SerializedQuantumProgram(quantum_program.model_dump_json(indent=2))
|
56
|
+
return await ApiWrapper.call_generation_task(model)
|
70
57
|
|
71
58
|
|
72
59
|
def synthesize(
|
73
|
-
model: Union[SerializedModel,
|
60
|
+
model: Union[SerializedModel, BaseQFunc],
|
74
61
|
auto_show: bool = False,
|
75
62
|
constraints: Optional[Constraints] = None,
|
76
63
|
preferences: Optional[Preferences] = None,
|
77
|
-
) ->
|
64
|
+
) -> QuantumProgram:
|
78
65
|
"""
|
79
66
|
Synthesize a model with the Classiq engine to receive a quantum program.
|
80
67
|
[More details](https://docs.classiq.io/latest/reference-manual/synthesis/)
|
@@ -86,9 +73,9 @@ def synthesize(
|
|
86
73
|
preferences: Preferences for the synthesis of the model. See Preferences (Optional).
|
87
74
|
|
88
75
|
Returns:
|
89
|
-
|
76
|
+
QuantumProgram: Quantum program. (See: QuantumProgram)
|
90
77
|
"""
|
91
|
-
if isinstance(model,
|
78
|
+
if isinstance(model, BaseQFunc):
|
92
79
|
func_name = model._py_callable.__name__
|
93
80
|
if func_name != MAIN_FUNCTION_NAME:
|
94
81
|
raise ClassiqError(
|
@@ -252,7 +239,6 @@ def update_execution_preferences(
|
|
252
239
|
|
253
240
|
__all__ = [
|
254
241
|
"SerializedModel",
|
255
|
-
"SerializedQuantumProgram",
|
256
242
|
"set_constraints",
|
257
243
|
"set_execution_preferences",
|
258
244
|
"set_preferences",
|
classiq/visualization.py
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
from typing import NewType
|
2
|
+
|
3
|
+
from classiq.interface.analyzer.result import DataID
|
4
|
+
from classiq.interface.exceptions import ClassiqAPIError
|
5
|
+
|
6
|
+
from classiq._internals import async_utils
|
7
|
+
from classiq._internals.api_wrapper import ApiWrapper
|
8
|
+
|
9
|
+
SerializedVisualModel = NewType("SerializedVisualModel", str)
|
10
|
+
|
11
|
+
|
12
|
+
async def visualize_async(
|
13
|
+
data_id: DataID,
|
14
|
+
) -> SerializedVisualModel:
|
15
|
+
try:
|
16
|
+
visual_model = await ApiWrapper.call_get_visual_model(data_id.id)
|
17
|
+
except ClassiqAPIError as error:
|
18
|
+
if error.status_code != 404:
|
19
|
+
raise error
|
20
|
+
analyzer_data = await ApiWrapper.get_analyzer_app_data(data_id)
|
21
|
+
visual_model = await ApiWrapper.call_visualization_task(analyzer_data)
|
22
|
+
return SerializedVisualModel(visual_model.model_dump_json(indent=2))
|
23
|
+
|
24
|
+
|
25
|
+
def visualize(
|
26
|
+
data_id: DataID,
|
27
|
+
) -> SerializedVisualModel:
|
28
|
+
result = async_utils.run(visualize_async(data_id))
|
29
|
+
return result
|
30
|
+
|
31
|
+
|
32
|
+
__all__ = [
|
33
|
+
"SerializedVisualModel",
|
34
|
+
"visualize",
|
35
|
+
]
|