classiq 0.102.0__py3-none-any.whl → 1.0.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/__init__.py +2 -0
- classiq/_internals/authentication/auth0.py +29 -0
- classiq/_internals/authentication/auth_flow_factory.py +43 -0
- classiq/_internals/authentication/machine_credentials_flow.py +26 -0
- classiq/_internals/authentication/password_manager.py +84 -0
- classiq/_internals/authentication/token_manager.py +24 -8
- classiq/analyzer/show_interactive_hack.py +0 -8
- classiq/applications/chemistry/op_utils.py +32 -0
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +1 -1
- classiq/evaluators/qmod_annotated_expression.py +1 -1
- classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +1 -8
- classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +1 -1
- classiq/evaluators/qmod_node_evaluators/attribute_evaluation.py +2 -2
- classiq/evaluators/qmod_node_evaluators/binary_op_evaluation.py +18 -29
- classiq/evaluators/qmod_node_evaluators/min_max_evaluation.py +1 -6
- classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +1 -7
- classiq/evaluators/qmod_type_inference/quantum_type_comparison.py +52 -0
- classiq/execution/all_hardware_devices.py +59 -1
- classiq/execution/execution_session.py +1 -1
- classiq/execution/functions/__init__.py +13 -0
- classiq/execution/functions/expectation_value.py +106 -0
- classiq/execution/functions/minimize.py +90 -0
- classiq/execution/functions/sample.py +76 -0
- classiq/execution/functions/state_vector.py +113 -0
- classiq/execution/functions/util/__init__.py +0 -0
- classiq/execution/functions/util/_logging.py +19 -0
- classiq/execution/functions/util/backend_preferences.py +188 -0
- classiq/execution/functions/util/constants.py +9 -0
- classiq/execution/functions/util/parse_provider_backend.py +90 -0
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/backend_preferences.py +81 -0
- classiq/interface/backend/provider_config/providers/aqt.py +1 -1
- classiq/interface/backend/provider_config/providers/azure.py +1 -2
- classiq/interface/backend/provider_config/providers/ibm.py +1 -1
- classiq/interface/backend/quantum_backend_providers.py +14 -0
- classiq/interface/exceptions.py +0 -4
- classiq/interface/executor/result.py +9 -5
- classiq/interface/generator/arith/binary_ops.py +62 -2
- classiq/interface/generator/arith/number_utils.py +15 -6
- classiq/interface/generator/compiler_keywords.py +1 -0
- classiq/interface/generator/function_param_list.py +8 -2
- classiq/interface/generator/function_params.py +1 -1
- classiq/interface/generator/functions/builtins/internal_operators.py +5 -9
- classiq/interface/generator/functions/classical_type.py +60 -0
- classiq/interface/generator/functions/type_name.py +36 -0
- classiq/interface/generator/generated_circuit_data.py +0 -2
- classiq/interface/generator/transpiler_basis_gates.py +1 -0
- classiq/interface/generator/types/compilation_metadata.py +18 -0
- classiq/interface/hardware.py +2 -0
- classiq/interface/helpers/model_normalizer.py +42 -6
- classiq/interface/interface_version.py +1 -1
- classiq/interface/model/invert.py +8 -0
- classiq/interface/model/model.py +19 -0
- classiq/interface/model/model_visitor.py +4 -2
- classiq/interface/model/quantum_type.py +36 -0
- classiq/interface/model/statement_block.py +0 -4
- classiq/interface/qubits_mapping/__init__.py +4 -0
- classiq/interface/qubits_mapping/path_expr_range.py +69 -0
- classiq/interface/qubits_mapping/qubits_mapping.py +231 -0
- classiq/interface/qubits_mapping/slices.py +112 -0
- classiq/model_expansions/arithmetic.py +6 -0
- classiq/model_expansions/capturing/captured_vars.py +16 -12
- classiq/model_expansions/function_builder.py +9 -1
- classiq/model_expansions/interpreters/base_interpreter.py +9 -8
- classiq/model_expansions/interpreters/generative_interpreter.py +9 -24
- classiq/model_expansions/quantum_operations/arithmetic/explicit_boolean_expressions.py +1 -0
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +132 -28
- classiq/model_expansions/quantum_operations/bind.py +4 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +5 -35
- classiq/model_expansions/quantum_operations/emitter.py +1 -4
- classiq/model_expansions/quantum_operations/expression_evaluator.py +0 -3
- classiq/model_expansions/visitors/uncomputation_signature_inference.py +0 -9
- classiq/qmod/builtins/functions/__init__.py +21 -9
- classiq/qmod/builtins/functions/allocation.py +0 -36
- classiq/qmod/builtins/functions/arithmetic.py +183 -0
- classiq/qmod/builtins/functions/exponentiation.py +32 -2
- classiq/qmod/builtins/functions/gray_code.py +23 -0
- classiq/qmod/builtins/functions/mcx_func.py +10 -0
- classiq/qmod/builtins/operations.py +2 -38
- classiq/qmod/builtins/structs.py +22 -3
- classiq/qmod/native/pretty_printer.py +1 -12
- classiq/qmod/pretty_print/pretty_printer.py +1 -17
- classiq/qmod/qmod_parameter.py +4 -0
- classiq/qmod/qmod_variable.py +38 -63
- classiq/qmod/quantum_function.py +43 -7
- classiq/qmod/semantics/validation/function_name_collisions_validation.py +7 -4
- classiq/qmod/semantics/validation/model_validation.py +7 -2
- classiq/qmod/symbolic_type.py +4 -2
- classiq/qprog_to_cudaq.py +347 -0
- {classiq-0.102.0.dist-info → classiq-1.0.0.dist-info}/METADATA +4 -1
- {classiq-0.102.0.dist-info → classiq-1.0.0.dist-info}/RECORD +93 -76
- classiq/interface/generator/amplitude_loading.py +0 -103
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +0 -77
- {classiq-0.102.0.dist-info → classiq-1.0.0.dist-info}/WHEEL +0 -0
- {classiq-0.102.0.dist-info → classiq-1.0.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING
|
|
1
|
+
from typing import TYPE_CHECKING, NoReturn, cast
|
|
2
2
|
|
|
3
|
-
from classiq.interface.exceptions import
|
|
3
|
+
from classiq.interface.exceptions import (
|
|
4
|
+
ClassiqExpansionError,
|
|
5
|
+
)
|
|
4
6
|
from classiq.interface.generator.expressions.expression import Expression
|
|
7
|
+
from classiq.interface.generator.functions.classical_type import (
|
|
8
|
+
Bool,
|
|
9
|
+
ClassicalArray,
|
|
10
|
+
ClassicalTuple,
|
|
11
|
+
Integer,
|
|
12
|
+
)
|
|
5
13
|
from classiq.interface.model.allocate import Allocate
|
|
6
14
|
from classiq.interface.model.bind_operation import BindOperation
|
|
7
15
|
from classiq.interface.model.block import Block
|
|
@@ -20,9 +28,11 @@ from classiq.interface.model.quantum_expressions.quantum_expression import (
|
|
|
20
28
|
)
|
|
21
29
|
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
|
22
30
|
from classiq.interface.model.quantum_type import (
|
|
31
|
+
QuantumBit,
|
|
23
32
|
QuantumBitvector,
|
|
24
33
|
QuantumNumeric,
|
|
25
34
|
QuantumScalar,
|
|
35
|
+
QuantumType,
|
|
26
36
|
)
|
|
27
37
|
from classiq.interface.model.statement_block import StatementBlock
|
|
28
38
|
from classiq.interface.model.variable_declaration_statement import (
|
|
@@ -31,6 +41,18 @@ from classiq.interface.model.variable_declaration_statement import (
|
|
|
31
41
|
from classiq.interface.model.within_apply_operation import WithinApply
|
|
32
42
|
|
|
33
43
|
from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
|
|
44
|
+
from classiq.evaluators.qmod_node_evaluators.utils import (
|
|
45
|
+
QmodType,
|
|
46
|
+
array_len,
|
|
47
|
+
element_types,
|
|
48
|
+
is_numeric_type,
|
|
49
|
+
)
|
|
50
|
+
from classiq.evaluators.qmod_type_inference.classical_type_inference import (
|
|
51
|
+
infer_classical_type,
|
|
52
|
+
)
|
|
53
|
+
from classiq.evaluators.qmod_type_inference.quantum_type_comparison import (
|
|
54
|
+
compare_quantum_types,
|
|
55
|
+
)
|
|
34
56
|
from classiq.evaluators.qmod_type_inference.quantum_type_inference import (
|
|
35
57
|
inject_quantum_type_attributes_inplace,
|
|
36
58
|
)
|
|
@@ -43,13 +65,22 @@ from classiq.model_expansions.quantum_operations.arithmetic.explicit_boolean_exp
|
|
|
43
65
|
validate_assignment_bool_expression,
|
|
44
66
|
)
|
|
45
67
|
from classiq.model_expansions.quantum_operations.emitter import Emitter
|
|
46
|
-
from classiq.model_expansions.scope import ClassicalSymbol
|
|
68
|
+
from classiq.model_expansions.scope import ClassicalSymbol, QuantumSymbol
|
|
47
69
|
from classiq.qmod.builtins.functions.standard_gates import CX
|
|
48
70
|
|
|
49
71
|
if TYPE_CHECKING:
|
|
50
72
|
from classiq.model_expansions.interpreters.base_interpreter import BaseInterpreter
|
|
51
73
|
|
|
52
74
|
|
|
75
|
+
def _get_expr_type(op: QuantumAssignmentOperation) -> QmodType:
|
|
76
|
+
expr_val = op.expression.value.value
|
|
77
|
+
if isinstance(expr_val, QmodAnnotatedExpression):
|
|
78
|
+
return expr_val.get_type(expr_val.root)
|
|
79
|
+
else:
|
|
80
|
+
expr_type = infer_classical_type(expr_val)
|
|
81
|
+
return expr_type
|
|
82
|
+
|
|
83
|
+
|
|
53
84
|
class AssignmentResultProcessor(Emitter[QuantumAssignmentOperation]):
|
|
54
85
|
def __init__(
|
|
55
86
|
self, interpreter: "BaseInterpreter", replace_assignment_if_needed: bool = False
|
|
@@ -60,14 +91,26 @@ class AssignmentResultProcessor(Emitter[QuantumAssignmentOperation]):
|
|
|
60
91
|
def emit(self, op: QuantumAssignmentOperation, /) -> bool:
|
|
61
92
|
result_symbol = self._interpreter.evaluate(op.result_var).value
|
|
62
93
|
if isinstance(result_symbol, ClassicalSymbol):
|
|
63
|
-
return
|
|
94
|
+
return self._emit_classical_assignment(op)
|
|
95
|
+
if isinstance(result_symbol.quantum_type, QuantumScalar):
|
|
96
|
+
return self._emit_scalar_assignment(op)
|
|
97
|
+
expr_val = op.expression.value.value
|
|
98
|
+
if isinstance(expr_val, QmodAnnotatedExpression) and isinstance(
|
|
99
|
+
expr_val.get_type(expr_val.root), QuantumType
|
|
100
|
+
):
|
|
101
|
+
return self._emit_quantum_var_quantum_expr_assignment(op)
|
|
102
|
+
return self._emit_quantum_var_classical_expr_assignment(op)
|
|
103
|
+
|
|
104
|
+
def _emit_classical_assignment(self, _: QuantumAssignmentOperation, /) -> bool:
|
|
105
|
+
return False
|
|
106
|
+
|
|
107
|
+
def _emit_scalar_assignment(self, op: QuantumAssignmentOperation, /) -> bool:
|
|
108
|
+
result_symbol = self._interpreter.evaluate(op.result_var).value
|
|
64
109
|
result_type = result_symbol.quantum_type
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
f"{result_type.raw_qmod_type_name}"
|
|
70
|
-
)
|
|
110
|
+
|
|
111
|
+
expr_type = _get_expr_type(op)
|
|
112
|
+
if not is_numeric_type(expr_type) and not isinstance(expr_type, Bool):
|
|
113
|
+
self._raise_type_error(result_symbol, expr_type)
|
|
71
114
|
|
|
72
115
|
if not (
|
|
73
116
|
isinstance(op, ArithmeticOperation)
|
|
@@ -82,36 +125,73 @@ class AssignmentResultProcessor(Emitter[QuantumAssignmentOperation]):
|
|
|
82
125
|
)
|
|
83
126
|
convert_assignment_bool_expression(op)
|
|
84
127
|
|
|
85
|
-
|
|
86
|
-
if
|
|
128
|
+
quantum_expr_type = self._infer_scalar_expression_type(op)
|
|
129
|
+
if quantum_expr_type is None:
|
|
87
130
|
return False
|
|
88
131
|
|
|
89
132
|
if not result_type.is_instantiated:
|
|
90
|
-
if not inject_quantum_type_attributes_inplace(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
f"{str(result_symbol)!r} of type "
|
|
95
|
-
f"{result_symbol.quantum_type.qmod_type_name}"
|
|
96
|
-
)
|
|
133
|
+
if not inject_quantum_type_attributes_inplace(
|
|
134
|
+
quantum_expr_type, result_type
|
|
135
|
+
):
|
|
136
|
+
self._raise_type_error(result_symbol, expr_type)
|
|
97
137
|
return False
|
|
98
138
|
|
|
99
|
-
if isinstance(result_type,
|
|
100
|
-
|
|
139
|
+
if not isinstance(result_type, QuantumScalar) or not isinstance(
|
|
140
|
+
quantum_expr_type, QuantumScalar
|
|
101
141
|
):
|
|
102
|
-
|
|
103
|
-
if
|
|
142
|
+
return False
|
|
143
|
+
if isinstance(result_type, QuantumNumeric):
|
|
144
|
+
result_type.set_bounds(quantum_expr_type.get_bounds())
|
|
145
|
+
if self._same_numeric_attributes(result_type, quantum_expr_type):
|
|
104
146
|
return False
|
|
105
147
|
self._validate_declared_attributes(
|
|
106
|
-
result_type,
|
|
148
|
+
result_type, quantum_expr_type, str(op.result_var)
|
|
107
149
|
)
|
|
108
150
|
if not self._replace_assignment_if_needed:
|
|
109
151
|
return False
|
|
110
152
|
|
|
111
|
-
self._assign_to_inferred_var_and_bind(op, result_type,
|
|
153
|
+
self._assign_to_inferred_var_and_bind(op, result_type, quantum_expr_type)
|
|
112
154
|
return True
|
|
113
155
|
|
|
114
|
-
def
|
|
156
|
+
def _emit_quantum_var_quantum_expr_assignment(
|
|
157
|
+
self, op: QuantumAssignmentOperation, /
|
|
158
|
+
) -> bool:
|
|
159
|
+
result_symbol = self._interpreter.evaluate(op.result_var).value
|
|
160
|
+
result_type = result_symbol.quantum_type
|
|
161
|
+
expr_type = cast(QuantumType, _get_expr_type(op))
|
|
162
|
+
if not inject_quantum_type_attributes_inplace(
|
|
163
|
+
expr_type, result_type
|
|
164
|
+
) or not compare_quantum_types(result_type, expr_type):
|
|
165
|
+
self._raise_type_error(result_symbol, expr_type)
|
|
166
|
+
return False
|
|
167
|
+
|
|
168
|
+
def _emit_quantum_var_classical_expr_assignment(
|
|
169
|
+
self, op: QuantumAssignmentOperation, /
|
|
170
|
+
) -> bool:
|
|
171
|
+
result_symbol = self._interpreter.evaluate(op.result_var).value
|
|
172
|
+
result_type = result_symbol.quantum_type
|
|
173
|
+
|
|
174
|
+
quantum_expr_type = self._infer_classical_array_expression_type(op)
|
|
175
|
+
if quantum_expr_type is None or not inject_quantum_type_attributes_inplace(
|
|
176
|
+
quantum_expr_type, result_type
|
|
177
|
+
):
|
|
178
|
+
self._raise_type_error(result_symbol, _get_expr_type(op))
|
|
179
|
+
|
|
180
|
+
return False
|
|
181
|
+
|
|
182
|
+
def _raise_type_error(
|
|
183
|
+
self, result_symbol: QuantumSymbol, expr_type: QmodType
|
|
184
|
+
) -> NoReturn:
|
|
185
|
+
raise ClassiqExpansionError(
|
|
186
|
+
f"Cannot assign expression of type "
|
|
187
|
+
f"{expr_type.qmod_type_name} to variable "
|
|
188
|
+
f"{str(result_symbol)!r} of type "
|
|
189
|
+
f"{result_symbol.quantum_type.qmod_type_name}"
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
def _infer_scalar_expression_type(
|
|
193
|
+
self, op: QuantumAssignmentOperation
|
|
194
|
+
) -> QuantumType | None:
|
|
115
195
|
expr = self._evaluate_expression(op.expression)
|
|
116
196
|
expr_val = expr.value.value
|
|
117
197
|
if isinstance(expr_val, QmodAnnotatedExpression):
|
|
@@ -129,9 +209,33 @@ class AssignmentResultProcessor(Emitter[QuantumAssignmentOperation]):
|
|
|
129
209
|
).to_quantum_numeric()
|
|
130
210
|
return None
|
|
131
211
|
|
|
212
|
+
def _infer_classical_array_expression_type(
|
|
213
|
+
self, op: QuantumAssignmentOperation
|
|
214
|
+
) -> QuantumType | None:
|
|
215
|
+
expr = self._evaluate_expression(op.expression)
|
|
216
|
+
expr_val = expr.value.value
|
|
217
|
+
if isinstance(expr_val, QmodAnnotatedExpression):
|
|
218
|
+
root_type = expr_val.get_type(expr_val.root)
|
|
219
|
+
if isinstance(root_type, (ClassicalArray, ClassicalTuple)) and all(
|
|
220
|
+
isinstance(element_type, Integer)
|
|
221
|
+
for element_type in element_types(root_type)
|
|
222
|
+
):
|
|
223
|
+
list_len = array_len(root_type)
|
|
224
|
+
len_expr = (
|
|
225
|
+
Expression(expr=str(list_len)) if list_len is not None else None
|
|
226
|
+
)
|
|
227
|
+
return QuantumBitvector(element_type=QuantumBit(), length=len_expr)
|
|
228
|
+
return None
|
|
229
|
+
if isinstance(expr_val, list) and all(
|
|
230
|
+
element in (0, 1) for element in expr_val
|
|
231
|
+
):
|
|
232
|
+
length_expr = Expression(expr=str(len(expr_val)))
|
|
233
|
+
return QuantumBitvector(element_type=QuantumBit(), length=length_expr)
|
|
234
|
+
return None
|
|
235
|
+
|
|
132
236
|
@staticmethod
|
|
133
237
|
def _same_numeric_attributes(
|
|
134
|
-
result_type:
|
|
238
|
+
result_type: QuantumScalar, expression_type: QuantumScalar
|
|
135
239
|
) -> bool:
|
|
136
240
|
return (
|
|
137
241
|
result_type.size_in_bits == expression_type.size_in_bits
|
|
@@ -142,7 +246,7 @@ class AssignmentResultProcessor(Emitter[QuantumAssignmentOperation]):
|
|
|
142
246
|
|
|
143
247
|
@classmethod
|
|
144
248
|
def _validate_declared_attributes(
|
|
145
|
-
cls, result_type:
|
|
249
|
+
cls, result_type: QuantumScalar, expression_type: QuantumScalar, var: str
|
|
146
250
|
) -> None:
|
|
147
251
|
result_size, result_sign, result_fractions = (
|
|
148
252
|
result_type.size_in_bits,
|
|
@@ -97,6 +97,8 @@ class BindEmitter(Emitter[BindOperation]):
|
|
|
97
97
|
state = self._builder.current_block.captured_vars.get_state(
|
|
98
98
|
var_name, inp.defining_function
|
|
99
99
|
)
|
|
100
|
+
if state is None:
|
|
101
|
+
continue
|
|
100
102
|
if not state:
|
|
101
103
|
raise ClassiqExpansionError(
|
|
102
104
|
f"Cannot use uninitialized quantum variable "
|
|
@@ -112,6 +114,8 @@ class BindEmitter(Emitter[BindOperation]):
|
|
|
112
114
|
state = self._builder.current_block.captured_vars.get_state(
|
|
113
115
|
var_name, out.defining_function
|
|
114
116
|
)
|
|
117
|
+
if state is None:
|
|
118
|
+
continue
|
|
115
119
|
if state:
|
|
116
120
|
raise ClassiqExpansionError(
|
|
117
121
|
f"Cannot use initialized quantum variable "
|
|
@@ -12,9 +12,6 @@ from classiq.interface.debug_info.debug_info import (
|
|
|
12
12
|
new_function_debug_info_by_node,
|
|
13
13
|
)
|
|
14
14
|
from classiq.interface.exceptions import ClassiqExpansionError
|
|
15
|
-
from classiq.interface.generator.functions.port_declaration import (
|
|
16
|
-
PortDeclarationDirection,
|
|
17
|
-
)
|
|
18
15
|
from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
|
|
19
16
|
from classiq.interface.helpers.text_utils import are, readable_list, s
|
|
20
17
|
from classiq.interface.model.block import Block
|
|
@@ -45,8 +42,6 @@ from classiq.evaluators.parameter_types import (
|
|
|
45
42
|
)
|
|
46
43
|
from classiq.evaluators.qmod_annotated_expression import QmodAnnotatedExpression
|
|
47
44
|
from classiq.model_expansions.capturing.captured_vars import (
|
|
48
|
-
INITIALIZED_VAR_MESSAGE,
|
|
49
|
-
UNINITIALIZED_VAR_MESSAGE,
|
|
50
45
|
validate_args_are_not_propagated,
|
|
51
46
|
)
|
|
52
47
|
from classiq.model_expansions.closure import Closure, FunctionClosure
|
|
@@ -109,12 +104,14 @@ def _validate_gen_args(
|
|
|
109
104
|
if (
|
|
110
105
|
isinstance(param, ClassicalParameterDeclaration)
|
|
111
106
|
and not param.classical_type.is_purely_declarative
|
|
112
|
-
and isinstance(arg.value, QmodAnnotatedExpression)
|
|
107
|
+
and isinstance(arg_val := arg.value, QmodAnnotatedExpression)
|
|
113
108
|
):
|
|
114
109
|
readable_expr = transform_expression(str(arg.value), {}, {}, one_line=True)
|
|
110
|
+
expr_type = arg_val.get_type(arg_val.root)
|
|
115
111
|
raise ClassiqExpansionError(
|
|
116
|
-
f"Cannot pass
|
|
117
|
-
f"parameter {param.name!r}"
|
|
112
|
+
f"Cannot pass {readable_expr!r} of type {expr_type.qmod_type_name} as "
|
|
113
|
+
f"parameter {param.name!r} of Python-type "
|
|
114
|
+
f"{param.classical_type.python_type_name}"
|
|
118
115
|
)
|
|
119
116
|
|
|
120
117
|
|
|
@@ -195,7 +192,6 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
|
|
|
195
192
|
) -> QuantumFunctionCall:
|
|
196
193
|
function = function.clone()
|
|
197
194
|
function = function.set_depth(self._builder.current_function.depth + 1)
|
|
198
|
-
self._validate_call_args(function.positional_arg_declarations, args)
|
|
199
195
|
evaluated_args = [self._interpreter.evaluate(arg) for arg in args]
|
|
200
196
|
_validate_cloning(evaluated_args)
|
|
201
197
|
_validate_runtime_args(evaluated_args, self._current_scope)
|
|
@@ -391,32 +387,6 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
|
|
|
391
387
|
permutation=function.permutation,
|
|
392
388
|
)
|
|
393
389
|
|
|
394
|
-
def _validate_call_args(
|
|
395
|
-
self, params: Sequence[PositionalArg], args: list[ArgValue]
|
|
396
|
-
) -> None:
|
|
397
|
-
for param, arg in zip(params, args):
|
|
398
|
-
if not isinstance(param, PortDeclaration) or not isinstance(
|
|
399
|
-
arg, HandleBinding
|
|
400
|
-
):
|
|
401
|
-
continue
|
|
402
|
-
var_name = arg.name
|
|
403
|
-
symbol = self._interpreter.evaluate(var_name)
|
|
404
|
-
if (
|
|
405
|
-
not isinstance(symbol.value, QuantumSymbol)
|
|
406
|
-
or symbol.defining_function is None
|
|
407
|
-
):
|
|
408
|
-
continue
|
|
409
|
-
var_state = self._builder.current_block.captured_vars.get_state(
|
|
410
|
-
var_name, symbol.defining_function
|
|
411
|
-
)
|
|
412
|
-
if not var_state and param.direction in (
|
|
413
|
-
PortDeclarationDirection.Inout,
|
|
414
|
-
PortDeclarationDirection.Input,
|
|
415
|
-
):
|
|
416
|
-
raise ClassiqExpansionError(UNINITIALIZED_VAR_MESSAGE.format(var_name))
|
|
417
|
-
if var_state and param.direction == PortDeclarationDirection.Output:
|
|
418
|
-
raise ClassiqExpansionError(INITIALIZED_VAR_MESSAGE.format(var_name))
|
|
419
|
-
|
|
420
390
|
def _validate_type_modifiers(
|
|
421
391
|
self, func_context: FunctionContext, func_def: NativeFunctionDefinition
|
|
422
392
|
) -> None:
|
|
@@ -144,11 +144,8 @@ class Emitter(Generic[QuantumStatementT], ABC):
|
|
|
144
144
|
expression: Expression,
|
|
145
145
|
*,
|
|
146
146
|
simplify: bool = False,
|
|
147
|
-
treat_qnum_as_float: bool = False,
|
|
148
147
|
) -> Expression:
|
|
149
|
-
expr_val = self._interpreter.evaluate(
|
|
150
|
-
expression, simplify=simplify, treat_qnum_as_float=treat_qnum_as_float
|
|
151
|
-
).value
|
|
148
|
+
expr_val = self._interpreter.evaluate(expression, simplify=simplify).value
|
|
152
149
|
new_expr = Expression(expr=str(expr_val))
|
|
153
150
|
new_expr._evaluated_expr = EvaluatedExpression(value=expr_val)
|
|
154
151
|
return new_expr
|
|
@@ -26,14 +26,12 @@ class ExpressionEvaluator(Emitter[QuantumOperation]):
|
|
|
26
26
|
*,
|
|
27
27
|
readable_expression_name: str | None = None,
|
|
28
28
|
simplify: bool = False,
|
|
29
|
-
treat_qnum_as_float: bool = False,
|
|
30
29
|
allow_link_time_vars: bool = True,
|
|
31
30
|
allow_runtime_vars: bool = True,
|
|
32
31
|
) -> None:
|
|
33
32
|
super().__init__(interpreter)
|
|
34
33
|
self._expression_name = expression_name
|
|
35
34
|
self._simplify = simplify
|
|
36
|
-
self._treat_qnum_as_float = treat_qnum_as_float
|
|
37
35
|
self._allow_link_time_vars = allow_link_time_vars
|
|
38
36
|
self._allow_runtime_vars = allow_runtime_vars
|
|
39
37
|
if (
|
|
@@ -49,7 +47,6 @@ class ExpressionEvaluator(Emitter[QuantumOperation]):
|
|
|
49
47
|
evaluated_expression = self._evaluate_expression(
|
|
50
48
|
expression,
|
|
51
49
|
simplify=self._simplify,
|
|
52
|
-
treat_qnum_as_float=self._treat_qnum_as_float,
|
|
53
50
|
)
|
|
54
51
|
for symbol in self._get_symbols_in_expression(evaluated_expression):
|
|
55
52
|
self._capture_handle(symbol.handle, PortDeclarationDirection.Inout)
|
|
@@ -21,9 +21,6 @@ from classiq.interface.model.invert import Invert
|
|
|
21
21
|
from classiq.interface.model.model_visitor import ModelStatementsVisitor
|
|
22
22
|
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
|
23
23
|
from classiq.interface.model.power import Power
|
|
24
|
-
from classiq.interface.model.quantum_expressions.amplitude_loading_operation import (
|
|
25
|
-
AmplitudeLoadingOperation,
|
|
26
|
-
)
|
|
27
24
|
from classiq.interface.model.quantum_expressions.arithmetic_operation import (
|
|
28
25
|
ArithmeticOperation,
|
|
29
26
|
)
|
|
@@ -147,12 +144,6 @@ class UncomputationSignatureInference(ModelStatementsVisitor):
|
|
|
147
144
|
else:
|
|
148
145
|
self._mark_as_non_const(arith.result_var.name, True)
|
|
149
146
|
|
|
150
|
-
def visit_AmplitudeLoadingOperation(
|
|
151
|
-
self, amp_load: AmplitudeLoadingOperation
|
|
152
|
-
) -> None:
|
|
153
|
-
self._mark_as_non_permutation()
|
|
154
|
-
self._mark_as_non_const(amp_load.result_var.name, False)
|
|
155
|
-
|
|
156
147
|
def visit_Control(self, control: Control) -> None:
|
|
157
148
|
self.visit(control.body)
|
|
158
149
|
if control.else_block is not None:
|
|
@@ -2,7 +2,8 @@ from .allocation import *
|
|
|
2
2
|
from .arithmetic import *
|
|
3
3
|
from .benchmarking import *
|
|
4
4
|
from .exponentiation import *
|
|
5
|
-
from .
|
|
5
|
+
from .gray_code import *
|
|
6
|
+
from .mcx_func import *
|
|
6
7
|
from .mid_circuit_measurement import *
|
|
7
8
|
from .operators import *
|
|
8
9
|
from .standard_gates import *
|
|
@@ -38,29 +39,32 @@ CORE_LIB_DECLS = [
|
|
|
38
39
|
SWAP,
|
|
39
40
|
IDENTITY,
|
|
40
41
|
prepare_state,
|
|
41
|
-
prepare_state_approx,
|
|
42
42
|
prepare_amplitudes,
|
|
43
|
-
prepare_amplitudes_approx,
|
|
44
43
|
unitary,
|
|
45
44
|
add,
|
|
46
45
|
add_inplace_right,
|
|
46
|
+
canonical_add,
|
|
47
|
+
canonical_add_constant,
|
|
47
48
|
modular_add,
|
|
48
49
|
integer_xor,
|
|
49
50
|
modular_add_constant,
|
|
50
51
|
real_xor_constant,
|
|
52
|
+
multiply,
|
|
53
|
+
multiply_constant,
|
|
54
|
+
canonical_multiply,
|
|
55
|
+
canonical_multiply_constant,
|
|
51
56
|
U,
|
|
52
57
|
CCX,
|
|
53
58
|
free,
|
|
54
59
|
drop,
|
|
55
60
|
randomized_benchmarking,
|
|
56
61
|
inplace_prepare_state,
|
|
57
|
-
inplace_prepare_state_approx,
|
|
58
62
|
inplace_prepare_amplitudes,
|
|
59
|
-
inplace_prepare_amplitudes_approx,
|
|
60
63
|
single_pauli_exponent,
|
|
61
64
|
commuting_paulis_exponent,
|
|
62
65
|
suzuki_trotter,
|
|
63
66
|
unscheduled_suzuki_trotter,
|
|
67
|
+
sequential_suzuki_trotter,
|
|
64
68
|
exponentiate,
|
|
65
69
|
multi_suzuki_trotter,
|
|
66
70
|
parametric_suzuki_trotter,
|
|
@@ -69,7 +73,10 @@ CORE_LIB_DECLS = [
|
|
|
69
73
|
exponentiation_with_depth_constraint,
|
|
70
74
|
RESET,
|
|
71
75
|
mcx,
|
|
76
|
+
mcx_gray_code,
|
|
77
|
+
mcx_hybrid_rec,
|
|
72
78
|
SX,
|
|
79
|
+
select_rotation,
|
|
73
80
|
)
|
|
74
81
|
]
|
|
75
82
|
|
|
@@ -89,6 +96,8 @@ __all__ = [ # noqa: RUF022
|
|
|
89
96
|
"I",
|
|
90
97
|
"IDENTITY",
|
|
91
98
|
"mcx",
|
|
99
|
+
"mcx_gray_code",
|
|
100
|
+
"mcx_hybrid_rec",
|
|
92
101
|
"PHASE",
|
|
93
102
|
"R",
|
|
94
103
|
"RX",
|
|
@@ -109,14 +118,18 @@ __all__ = [ # noqa: RUF022
|
|
|
109
118
|
"SX",
|
|
110
119
|
"add",
|
|
111
120
|
"add_inplace_right",
|
|
121
|
+
"canonical_add",
|
|
122
|
+
"canonical_add_constant",
|
|
112
123
|
"apply",
|
|
113
124
|
"exponentiation_with_depth_constraint",
|
|
125
|
+
"multiply",
|
|
126
|
+
"multiply_constant",
|
|
127
|
+
"canonical_multiply",
|
|
128
|
+
"canonical_multiply_constant",
|
|
114
129
|
"free",
|
|
115
130
|
"drop",
|
|
116
131
|
"inplace_prepare_amplitudes",
|
|
117
|
-
"inplace_prepare_amplitudes_approx",
|
|
118
132
|
"inplace_prepare_state",
|
|
119
|
-
"inplace_prepare_state_approx",
|
|
120
133
|
"integer_xor",
|
|
121
134
|
"modular_add",
|
|
122
135
|
"modular_add_constant",
|
|
@@ -124,9 +137,7 @@ __all__ = [ # noqa: RUF022
|
|
|
124
137
|
"parametric_suzuki_trotter",
|
|
125
138
|
"permute",
|
|
126
139
|
"prepare_amplitudes",
|
|
127
|
-
"prepare_amplitudes_approx",
|
|
128
140
|
"prepare_state",
|
|
129
|
-
"prepare_state_approx",
|
|
130
141
|
"qdrift",
|
|
131
142
|
"randomized_benchmarking",
|
|
132
143
|
"real_xor_constant",
|
|
@@ -135,6 +146,7 @@ __all__ = [ # noqa: RUF022
|
|
|
135
146
|
"suzuki_trotter",
|
|
136
147
|
"unitary",
|
|
137
148
|
"RESET",
|
|
149
|
+
"select_rotation",
|
|
138
150
|
]
|
|
139
151
|
BUILTIN_FUNCTION_DECLARATIONS = {
|
|
140
152
|
func_decl.name: func_decl for func_decl in STD_QMOD_OPERATORS + CORE_LIB_DECLS
|
|
@@ -144,39 +144,3 @@ def inplace_prepare_amplitudes(
|
|
|
144
144
|
|
|
145
145
|
"""
|
|
146
146
|
pass
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
@qfunc(external=True)
|
|
150
|
-
def inplace_prepare_amplitudes_approx(
|
|
151
|
-
amplitudes: CArray[CReal],
|
|
152
|
-
bound: CReal,
|
|
153
|
-
target: QArray[QBit, Literal["log(amplitudes.len, 2)"]],
|
|
154
|
-
) -> None:
|
|
155
|
-
pass
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
@qfunc(external=True)
|
|
159
|
-
def prepare_amplitudes_approx(
|
|
160
|
-
amplitudes: CArray[CReal],
|
|
161
|
-
bound: CReal,
|
|
162
|
-
out: Output[QArray[QBit, Literal["log(amplitudes.len, 2)"]]],
|
|
163
|
-
) -> None:
|
|
164
|
-
pass
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
@qfunc(external=True)
|
|
168
|
-
def inplace_prepare_state_approx(
|
|
169
|
-
probabilities: CArray[CReal],
|
|
170
|
-
bound: CReal,
|
|
171
|
-
target: QArray[QBit, Literal["log(probabilities.len, 2)"]],
|
|
172
|
-
) -> None:
|
|
173
|
-
pass
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
@qfunc(external=True)
|
|
177
|
-
def prepare_state_approx(
|
|
178
|
-
probabilities: CArray[CReal],
|
|
179
|
-
bound: CReal,
|
|
180
|
-
out: Output[QArray[QBit, Literal["log(probabilities.len, 2)"]]],
|
|
181
|
-
) -> None:
|
|
182
|
-
pass
|