classiq 0.63.1__py3-none-any.whl → 0.65.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.
- classiq/_internals/api_wrapper.py +30 -0
- classiq/analyzer/url_utils.py +2 -3
- classiq/applications/chemistry/chemistry_model_constructor.py +8 -9
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +4 -6
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +2 -5
- classiq/applications/finance/finance_model_constructor.py +7 -12
- classiq/applications/grover/grover_model_constructor.py +4 -6
- classiq/applications/qsvm/qsvm_model_constructor.py +6 -4
- classiq/execution/execution_session.py +14 -13
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/result.py +1 -2
- classiq/interface/backend/backend_preferences.py +1 -9
- classiq/interface/executor/result.py +6 -3
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +11 -13
- classiq/interface/generator/functions/type_name.py +6 -0
- classiq/interface/helpers/datastructures.py +26 -0
- classiq/interface/interface_version.py +1 -1
- classiq/interface/model/allocate.py +16 -0
- classiq/interface/model/handle_binding.py +11 -3
- classiq/interface/model/quantum_type.py +26 -0
- classiq/interface/model/statement_block.py +2 -0
- classiq/interface/server/routes.py +5 -0
- classiq/model_expansions/atomic_expression_functions_defs.py +6 -6
- classiq/model_expansions/capturing/captured_vars.py +27 -10
- classiq/model_expansions/evaluators/arg_type_match.py +4 -7
- classiq/model_expansions/evaluators/quantum_type_utils.py +25 -8
- classiq/model_expansions/expression_evaluator.py +8 -2
- classiq/model_expansions/function_builder.py +35 -11
- classiq/model_expansions/generative_functions.py +6 -4
- classiq/model_expansions/interpreters/__init__.py +0 -0
- classiq/model_expansions/interpreters/base_interpreter.py +263 -0
- classiq/model_expansions/interpreters/frontend_generative_interpreter.py +28 -0
- classiq/model_expansions/interpreters/generative_interpreter.py +249 -0
- classiq/model_expansions/model_tables.py +1 -92
- classiq/model_expansions/quantum_operations/__init__.py +0 -10
- classiq/model_expansions/quantum_operations/call_emitter.py +45 -93
- classiq/model_expansions/quantum_operations/declarative_call_emitter.py +87 -0
- classiq/model_expansions/quantum_operations/emitter.py +7 -2
- classiq/model_expansions/quantum_operations/quantum_function_call.py +11 -2
- classiq/model_expansions/quantum_operations/shallow_emitter.py +22 -3
- classiq/model_expansions/scope.py +15 -15
- classiq/model_expansions/scope_initialization.py +11 -5
- classiq/open_library/functions/discrete_sine_cosine_transform.py +8 -2
- classiq/open_library/functions/grover.py +1 -1
- classiq/open_library/functions/modular_exponentiation.py +8 -2
- classiq/open_library/functions/state_preparation.py +23 -13
- classiq/open_library/functions/swap_test.py +1 -2
- classiq/open_library/functions/variational.py +1 -2
- classiq/qmod/builtins/__init__.py +1 -1
- classiq/qmod/builtins/operations.py +51 -0
- classiq/qmod/declaration_inferrer.py +0 -3
- classiq/qmod/generative.py +4 -4
- classiq/qmod/native/pretty_printer.py +9 -1
- classiq/qmod/pretty_print/pretty_printer.py +12 -1
- classiq/qmod/qfunc.py +4 -2
- classiq/qmod/qmod_variable.py +55 -48
- classiq/qmod/quantum_function.py +7 -5
- classiq/qmod/semantics/annotation/__init__.py +0 -0
- classiq/qmod/semantics/annotation/call_annotation.py +92 -0
- classiq/qmod/semantics/lambdas.py +25 -0
- classiq/qmod/semantics/static_semantics_visitor.py +8 -46
- classiq/qmod/utilities.py +23 -1
- {classiq-0.63.1.dist-info → classiq-0.65.1.dist-info}/METADATA +1 -1
- {classiq-0.63.1.dist-info → classiq-0.65.1.dist-info}/RECORD +66 -67
- classiq/interface/helpers/dotdict.py +0 -18
- classiq/model_expansions/interpreter.py +0 -475
- classiq/model_expansions/quantum_operations/control.py +0 -290
- classiq/model_expansions/quantum_operations/expression_operation.py +0 -103
- classiq/model_expansions/quantum_operations/inplace_binary_operation.py +0 -535
- classiq/model_expansions/quantum_operations/invert.py +0 -36
- classiq/model_expansions/quantum_operations/phase.py +0 -187
- classiq/model_expansions/quantum_operations/power.py +0 -71
- classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +0 -230
- classiq/model_expansions/quantum_operations/within_apply.py +0 -25
- classiq/qmod/semantics/annotation.py +0 -36
- /classiq/qmod/semantics/{qstruct_annotator.py → annotation/qstruct_annotator.py} +0 -0
- {classiq-0.63.1.dist-info → classiq-0.65.1.dist-info}/WHEEL +0 -0
@@ -1,475 +0,0 @@
|
|
1
|
-
from collections import defaultdict
|
2
|
-
from collections.abc import Sequence
|
3
|
-
from contextlib import nullcontext
|
4
|
-
from functools import singledispatchmethod
|
5
|
-
from typing import Any, Optional, cast
|
6
|
-
|
7
|
-
import numpy as np
|
8
|
-
from numpy.random import permutation
|
9
|
-
from pydantic import ValidationError
|
10
|
-
|
11
|
-
from classiq.interface.exceptions import (
|
12
|
-
ClassiqError,
|
13
|
-
ClassiqExpansionError,
|
14
|
-
ClassiqInternalExpansionError,
|
15
|
-
)
|
16
|
-
from classiq.interface.generator.constant import Constant
|
17
|
-
from classiq.interface.generator.expressions.expression import Expression
|
18
|
-
from classiq.interface.generator.functions.builtins.internal_operators import (
|
19
|
-
CONTROL_OPERATOR_NAME,
|
20
|
-
INVERT_OPERATOR_NAME,
|
21
|
-
WITHIN_APPLY_NAME,
|
22
|
-
)
|
23
|
-
from classiq.interface.generator.types.compilation_metadata import CompilationMetadata
|
24
|
-
from classiq.interface.model.bind_operation import BindOperation
|
25
|
-
from classiq.interface.model.classical_if import ClassicalIf
|
26
|
-
from classiq.interface.model.control import Control
|
27
|
-
from classiq.interface.model.handle_binding import (
|
28
|
-
FieldHandleBinding,
|
29
|
-
HandleBinding,
|
30
|
-
SlicedHandleBinding,
|
31
|
-
SubscriptHandleBinding,
|
32
|
-
)
|
33
|
-
from classiq.interface.model.inplace_binary_operation import InplaceBinaryOperation
|
34
|
-
from classiq.interface.model.invert import Invert
|
35
|
-
from classiq.interface.model.model import MAIN_FUNCTION_NAME, Model
|
36
|
-
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
37
|
-
from classiq.interface.model.phase_operation import PhaseOperation
|
38
|
-
from classiq.interface.model.power import Power
|
39
|
-
from classiq.interface.model.quantum_expressions.quantum_expression import (
|
40
|
-
QuantumAssignmentOperation,
|
41
|
-
)
|
42
|
-
from classiq.interface.model.quantum_function_call import (
|
43
|
-
QuantumFunctionCall,
|
44
|
-
)
|
45
|
-
from classiq.interface.model.quantum_function_declaration import (
|
46
|
-
NamedParamsQuantumFunctionDeclaration,
|
47
|
-
QuantumFunctionDeclaration,
|
48
|
-
)
|
49
|
-
from classiq.interface.model.quantum_lambda_function import (
|
50
|
-
OperandIdentifier,
|
51
|
-
QuantumLambdaFunction,
|
52
|
-
)
|
53
|
-
from classiq.interface.model.quantum_statement import QuantumStatement
|
54
|
-
from classiq.interface.model.repeat import Repeat
|
55
|
-
from classiq.interface.model.variable_declaration_statement import (
|
56
|
-
VariableDeclarationStatement,
|
57
|
-
)
|
58
|
-
from classiq.interface.model.within_apply_operation import WithinApply
|
59
|
-
|
60
|
-
from classiq.model_expansions.closure import (
|
61
|
-
Closure,
|
62
|
-
FunctionClosure,
|
63
|
-
GenerativeClosure,
|
64
|
-
GenerativeFunctionClosure,
|
65
|
-
)
|
66
|
-
from classiq.model_expansions.debug_flag import debug_mode
|
67
|
-
from classiq.model_expansions.evaluators.classical_expression import (
|
68
|
-
evaluate_classical_expression,
|
69
|
-
)
|
70
|
-
from classiq.model_expansions.expression_renamer import ExpressionRenamer
|
71
|
-
from classiq.model_expansions.function_builder import (
|
72
|
-
FunctionContext,
|
73
|
-
OperationBuilder,
|
74
|
-
OperationContext,
|
75
|
-
)
|
76
|
-
from classiq.model_expansions.generative_functions import emit_generative_statements
|
77
|
-
from classiq.model_expansions.quantum_operations import (
|
78
|
-
BindEmitter,
|
79
|
-
ClassicalIfEmitter,
|
80
|
-
ControlEmitter,
|
81
|
-
InplaceBinaryOperationEmitter,
|
82
|
-
InvertEmitter,
|
83
|
-
PowerEmitter,
|
84
|
-
QuantumAssignmentOperationEmitter,
|
85
|
-
QuantumFunctionCallEmitter,
|
86
|
-
RepeatEmitter,
|
87
|
-
VariableDeclarationStatementEmitter,
|
88
|
-
WithinApplyEmitter,
|
89
|
-
)
|
90
|
-
from classiq.model_expansions.quantum_operations.phase import PhaseEmitter
|
91
|
-
from classiq.model_expansions.quantum_operations.shallow_emitter import ShallowEmitter
|
92
|
-
from classiq.model_expansions.scope import Evaluated, QuantumSymbol, Scope
|
93
|
-
from classiq.model_expansions.scope_initialization import (
|
94
|
-
add_constants_to_scope,
|
95
|
-
add_entry_point_params_to_scope,
|
96
|
-
add_functions_to_scope,
|
97
|
-
add_generative_functions_to_scope,
|
98
|
-
get_main_renamer,
|
99
|
-
init_top_level_scope,
|
100
|
-
)
|
101
|
-
from classiq.model_expansions.utils.counted_name_allocator import CountedNameAllocator
|
102
|
-
from classiq.qmod.builtins.functions import permute
|
103
|
-
from classiq.qmod.model_state_container import QMODULE, ModelStateContainer
|
104
|
-
from classiq.qmod.quantum_function import GenerativeQFunc
|
105
|
-
from classiq.qmod.semantics.error_manager import ErrorManager
|
106
|
-
|
107
|
-
|
108
|
-
class Interpreter:
|
109
|
-
def __init__(
|
110
|
-
self,
|
111
|
-
model: Model,
|
112
|
-
generative_functions: Optional[list[GenerativeQFunc]] = None,
|
113
|
-
is_normalizer: bool = False,
|
114
|
-
is_shallow: bool = False,
|
115
|
-
) -> None:
|
116
|
-
self._is_normalizer = is_normalizer
|
117
|
-
self._is_shallow = is_shallow
|
118
|
-
self._model = model
|
119
|
-
self._top_level_scope = Scope()
|
120
|
-
self._counted_name_allocator = CountedNameAllocator()
|
121
|
-
self._builder = OperationBuilder(
|
122
|
-
self._top_level_scope, self._counted_name_allocator
|
123
|
-
)
|
124
|
-
self._expanded_functions: dict[str, NativeFunctionDefinition] = {}
|
125
|
-
|
126
|
-
init_top_level_scope(model, generative_functions or [], self._top_level_scope)
|
127
|
-
self._main_renamer: Optional[ExpressionRenamer] = (
|
128
|
-
get_main_renamer(self._get_function_declarations())
|
129
|
-
if self._is_normalizer
|
130
|
-
else None
|
131
|
-
)
|
132
|
-
self._functions_compilation_metadata: dict[str, CompilationMetadata] = dict(
|
133
|
-
self._model.functions_compilation_metadata
|
134
|
-
)
|
135
|
-
self._expanded_functions_compilation_metadata: dict[
|
136
|
-
str, CompilationMetadata
|
137
|
-
] = defaultdict(CompilationMetadata)
|
138
|
-
self._counted_name_allocator = CountedNameAllocator()
|
139
|
-
self._error_manager: ErrorManager = ErrorManager()
|
140
|
-
|
141
|
-
def _expand_main_func(self) -> None:
|
142
|
-
main_func = self._top_level_scope[MAIN_FUNCTION_NAME].value
|
143
|
-
closure_constructor: Any
|
144
|
-
if isinstance(main_func, GenerativeFunctionClosure):
|
145
|
-
closure_constructor = GenerativeFunctionClosure
|
146
|
-
extra_args = {
|
147
|
-
"generative_blocks": {"body": main_func.generative_blocks["body"]}
|
148
|
-
}
|
149
|
-
else:
|
150
|
-
closure_constructor = FunctionClosure
|
151
|
-
extra_args = {"body": main_func.body}
|
152
|
-
main_closure = closure_constructor.create(
|
153
|
-
name=main_func.name,
|
154
|
-
positional_arg_declarations=main_func.positional_arg_declarations,
|
155
|
-
scope=Scope(parent=self._top_level_scope),
|
156
|
-
expr_renamer=self._main_renamer,
|
157
|
-
_depth=0,
|
158
|
-
**extra_args,
|
159
|
-
)
|
160
|
-
|
161
|
-
add_entry_point_params_to_scope(
|
162
|
-
main_closure.positional_arg_declarations, main_closure
|
163
|
-
)
|
164
|
-
context = self._expand_operation(main_closure)
|
165
|
-
self._expanded_functions[main_closure.closure_id] = (
|
166
|
-
self._builder.create_definition(cast(FunctionContext, context))
|
167
|
-
)
|
168
|
-
|
169
|
-
def expand(self) -> Model:
|
170
|
-
try:
|
171
|
-
with self._error_manager.call("main"):
|
172
|
-
self._expand_main_func()
|
173
|
-
except Exception as e:
|
174
|
-
if isinstance(e, ClassiqInternalExpansionError) or debug_mode.get():
|
175
|
-
raise e
|
176
|
-
if not isinstance(e, (ClassiqError, ValidationError)):
|
177
|
-
raise ClassiqInternalExpansionError(str(e)) from None
|
178
|
-
prefix = ""
|
179
|
-
if not isinstance(e, ClassiqExpansionError):
|
180
|
-
prefix = f"{type(e).__name__}: "
|
181
|
-
self._error_manager.add_error(f"{prefix}{e}")
|
182
|
-
finally:
|
183
|
-
self._error_manager.report_errors(ClassiqExpansionError)
|
184
|
-
|
185
|
-
return Model(
|
186
|
-
constraints=self._model.constraints,
|
187
|
-
preferences=self._model.preferences,
|
188
|
-
classical_execution_code=self._model.classical_execution_code,
|
189
|
-
execution_preferences=self._model.execution_preferences,
|
190
|
-
functions=list(self._expanded_functions.values()),
|
191
|
-
constants=self._model.constants,
|
192
|
-
enums=list(QMODULE.enum_decls.values()),
|
193
|
-
types=list(QMODULE.type_decls.values()),
|
194
|
-
qstructs=list(QMODULE.qstruct_decls.values()),
|
195
|
-
debug_info=self._model.debug_info,
|
196
|
-
functions_compilation_metadata=self._expanded_functions_compilation_metadata,
|
197
|
-
)
|
198
|
-
|
199
|
-
@singledispatchmethod
|
200
|
-
def evaluate(self, expression: Any) -> Evaluated:
|
201
|
-
raise NotImplementedError(f"Cannot evaluate {expression!r}")
|
202
|
-
|
203
|
-
@evaluate.register
|
204
|
-
def evaluate_classical_expression(self, expression: Expression) -> Evaluated:
|
205
|
-
return evaluate_classical_expression(expression, self._builder.current_scope)
|
206
|
-
|
207
|
-
@evaluate.register
|
208
|
-
def evaluate_identifier(self, identifier: str) -> Evaluated:
|
209
|
-
return self._builder.current_scope[identifier]
|
210
|
-
|
211
|
-
@evaluate.register
|
212
|
-
def evaluate_lambda(self, function: QuantumLambdaFunction) -> Evaluated:
|
213
|
-
renamed_params = [
|
214
|
-
param.rename(function.pos_rename_params[idx])
|
215
|
-
for idx, param in enumerate(function.func_decl.positional_arg_declarations)
|
216
|
-
]
|
217
|
-
func_decl = NamedParamsQuantumFunctionDeclaration(
|
218
|
-
name=self._counted_name_allocator.allocate(
|
219
|
-
function.func_decl.name or "<lambda>"
|
220
|
-
),
|
221
|
-
positional_arg_declarations=renamed_params,
|
222
|
-
)
|
223
|
-
|
224
|
-
closure_class: type[FunctionClosure]
|
225
|
-
extra_args: dict[str, Any]
|
226
|
-
if function.is_generative():
|
227
|
-
closure_class = GenerativeFunctionClosure
|
228
|
-
extra_args = {
|
229
|
-
"generative_blocks": {
|
230
|
-
"body": GenerativeQFunc(function.py_callable, func_decl),
|
231
|
-
}
|
232
|
-
}
|
233
|
-
else:
|
234
|
-
closure_class = FunctionClosure
|
235
|
-
extra_args = {}
|
236
|
-
|
237
|
-
return Evaluated(
|
238
|
-
value=closure_class.create(
|
239
|
-
name=func_decl.name,
|
240
|
-
positional_arg_declarations=func_decl.positional_arg_declarations,
|
241
|
-
body=function.body,
|
242
|
-
scope=Scope(parent=self._builder.current_scope),
|
243
|
-
is_lambda=True,
|
244
|
-
**extra_args,
|
245
|
-
),
|
246
|
-
defining_function=self._builder.current_function,
|
247
|
-
)
|
248
|
-
|
249
|
-
@evaluate.register
|
250
|
-
def evaluate_handle_binding(self, handle_binding: HandleBinding) -> Evaluated:
|
251
|
-
return self.evaluate(handle_binding.name)
|
252
|
-
|
253
|
-
@evaluate.register
|
254
|
-
def evaluate_sliced_handle_binding(
|
255
|
-
self, sliced_handle_binding: SlicedHandleBinding
|
256
|
-
) -> Evaluated:
|
257
|
-
quantum_variable = self.evaluate(sliced_handle_binding.base_handle).as_type(
|
258
|
-
QuantumSymbol
|
259
|
-
)
|
260
|
-
start = self.evaluate(sliced_handle_binding.start).as_type(int)
|
261
|
-
end = self.evaluate(sliced_handle_binding.end).as_type(int)
|
262
|
-
return Evaluated(value=quantum_variable[start:end])
|
263
|
-
|
264
|
-
@evaluate.register
|
265
|
-
def evaluate_list(self, value: list) -> Evaluated:
|
266
|
-
return Evaluated(value=[self.evaluate(arg).value for arg in value])
|
267
|
-
|
268
|
-
@evaluate.register
|
269
|
-
def evaluate_subscript_handle(self, subscript: SubscriptHandleBinding) -> Evaluated:
|
270
|
-
base_value = self.evaluate(subscript.base_handle)
|
271
|
-
index_value = self.evaluate(subscript.index).as_type(int)
|
272
|
-
return Evaluated(value=base_value.value[index_value])
|
273
|
-
|
274
|
-
@evaluate.register
|
275
|
-
def evaluate_subscript_operand(self, subscript: OperandIdentifier) -> Evaluated:
|
276
|
-
base_value = self.evaluate(subscript.name)
|
277
|
-
index_value = self.evaluate(subscript.index).as_type(int)
|
278
|
-
return Evaluated(value=base_value.value[index_value])
|
279
|
-
|
280
|
-
@evaluate.register
|
281
|
-
def evaluate_field_access(self, field_access: FieldHandleBinding) -> Evaluated:
|
282
|
-
base_value = self.evaluate(field_access.base_handle)
|
283
|
-
return Evaluated(value=base_value.value.fields[field_access.field])
|
284
|
-
|
285
|
-
@singledispatchmethod
|
286
|
-
def emit(self, statement: QuantumStatement) -> None:
|
287
|
-
raise NotImplementedError(f"Cannot emit {statement!r}")
|
288
|
-
|
289
|
-
@emit.register
|
290
|
-
def emit_quantum_function_call(self, call: QuantumFunctionCall) -> None:
|
291
|
-
QuantumFunctionCallEmitter(self).emit(call)
|
292
|
-
|
293
|
-
@emit.register
|
294
|
-
def emit_bind(self, bind: BindOperation) -> None:
|
295
|
-
BindEmitter(self).emit(bind)
|
296
|
-
|
297
|
-
@emit.register
|
298
|
-
def emit_quantum_assignment_operation(self, op: QuantumAssignmentOperation) -> None:
|
299
|
-
if self._is_normalizer:
|
300
|
-
ShallowEmitter(
|
301
|
-
self, "assignment_operation", components=["expression", "result_var"]
|
302
|
-
).emit(op)
|
303
|
-
else:
|
304
|
-
QuantumAssignmentOperationEmitter(self).emit(op)
|
305
|
-
|
306
|
-
@emit.register
|
307
|
-
def emit_inplace_binary_operation(self, op: InplaceBinaryOperation) -> None:
|
308
|
-
if self._is_normalizer:
|
309
|
-
ShallowEmitter(
|
310
|
-
self, "inplace_binary_operation", components=["target", "value"]
|
311
|
-
).emit(op)
|
312
|
-
else:
|
313
|
-
InplaceBinaryOperationEmitter(self).emit(op)
|
314
|
-
|
315
|
-
@emit.register
|
316
|
-
def emit_variable_declaration(
|
317
|
-
self, variable_declaration: VariableDeclarationStatement
|
318
|
-
) -> None:
|
319
|
-
VariableDeclarationStatementEmitter(self).emit(variable_declaration)
|
320
|
-
|
321
|
-
@emit.register
|
322
|
-
def emit_classical_if(self, classical_if: ClassicalIf) -> None:
|
323
|
-
ClassicalIfEmitter(self).emit(classical_if)
|
324
|
-
|
325
|
-
@emit.register
|
326
|
-
def emit_within_apply(self, within_apply: WithinApply) -> None:
|
327
|
-
if self._is_normalizer:
|
328
|
-
ShallowEmitter(
|
329
|
-
self,
|
330
|
-
WITHIN_APPLY_NAME,
|
331
|
-
components=["within", "apply", "compute", "action"],
|
332
|
-
).emit(within_apply)
|
333
|
-
else:
|
334
|
-
WithinApplyEmitter(self).emit(within_apply)
|
335
|
-
|
336
|
-
@emit.register
|
337
|
-
def emit_invert(self, invert: Invert) -> None:
|
338
|
-
if self._is_normalizer:
|
339
|
-
ShallowEmitter(self, INVERT_OPERATOR_NAME, components=["body"]).emit(invert)
|
340
|
-
else:
|
341
|
-
InvertEmitter(self).emit(invert)
|
342
|
-
|
343
|
-
@emit.register
|
344
|
-
def emit_repeat(self, repeat: Repeat) -> None:
|
345
|
-
RepeatEmitter(self).emit(repeat)
|
346
|
-
|
347
|
-
@emit.register
|
348
|
-
def emit_control(self, control: Control) -> None:
|
349
|
-
if self._is_normalizer:
|
350
|
-
ShallowEmitter(
|
351
|
-
self,
|
352
|
-
CONTROL_OPERATOR_NAME,
|
353
|
-
components=["expression", "body", "else_block"],
|
354
|
-
).emit(control)
|
355
|
-
else:
|
356
|
-
ControlEmitter(self).emit(control)
|
357
|
-
|
358
|
-
@emit.register
|
359
|
-
def emit_power(self, power: Power) -> None:
|
360
|
-
if self._is_normalizer:
|
361
|
-
ShallowEmitter(
|
362
|
-
self, CONTROL_OPERATOR_NAME, components=["power", "body"]
|
363
|
-
).emit(power)
|
364
|
-
else:
|
365
|
-
PowerEmitter(self).emit(power)
|
366
|
-
|
367
|
-
@emit.register
|
368
|
-
def emit_phase(self, phase: PhaseOperation) -> None:
|
369
|
-
if self._is_normalizer:
|
370
|
-
ShallowEmitter(self, "phase", components=["expression", "theta"]).emit(
|
371
|
-
phase
|
372
|
-
)
|
373
|
-
else:
|
374
|
-
PhaseEmitter(self).emit(phase)
|
375
|
-
|
376
|
-
def _expand_block(self, block: Sequence[QuantumStatement], block_name: str) -> None:
|
377
|
-
with self._builder.block_context(block_name):
|
378
|
-
for statement in block:
|
379
|
-
self.emit_statement(statement)
|
380
|
-
|
381
|
-
def emit_statement(self, statement: QuantumStatement) -> None:
|
382
|
-
source_ref = statement.source_ref
|
383
|
-
error_context = (
|
384
|
-
self._error_manager.node_context(statement)
|
385
|
-
if source_ref is not None
|
386
|
-
else nullcontext()
|
387
|
-
)
|
388
|
-
with error_context, self._builder.source_ref_context(source_ref):
|
389
|
-
self.emit(statement)
|
390
|
-
|
391
|
-
def _expand_operation(self, operation: Closure) -> OperationContext:
|
392
|
-
with self._builder.operation_context(operation) as context:
|
393
|
-
if isinstance(operation, FunctionClosure) and (
|
394
|
-
(func_def := self._expanded_functions.get(operation.closure_id))
|
395
|
-
is not None
|
396
|
-
):
|
397
|
-
captured_vars = self._top_level_scope[func_def.name].value.captured_vars
|
398
|
-
operation.captured_vars.update(captured_vars)
|
399
|
-
elif isinstance(operation, FunctionClosure) and operation.name == "permute":
|
400
|
-
# special expansion since permute is generative
|
401
|
-
self._expand_permute()
|
402
|
-
elif isinstance(operation, GenerativeClosure):
|
403
|
-
args = [
|
404
|
-
self.evaluate(param.name)
|
405
|
-
for param in operation.positional_arg_declarations
|
406
|
-
]
|
407
|
-
emit_generative_statements(self, operation, args)
|
408
|
-
else:
|
409
|
-
for block, block_body in operation.blocks.items():
|
410
|
-
self._expand_block(block_body, block)
|
411
|
-
|
412
|
-
return context
|
413
|
-
|
414
|
-
def _expand_permute(self) -> None:
|
415
|
-
functions = self.evaluate("functions").as_type(list)
|
416
|
-
functions_permutation = permutation(np.array(range(len(functions))))
|
417
|
-
calls: list[QuantumFunctionCall] = []
|
418
|
-
for function_index in functions_permutation:
|
419
|
-
permute_call = QuantumFunctionCall(
|
420
|
-
function=OperandIdentifier(
|
421
|
-
name="functions", index=Expression(expr=f"{function_index}")
|
422
|
-
)
|
423
|
-
)
|
424
|
-
permute_call.set_func_decl(permute.func_decl)
|
425
|
-
calls.append(permute_call)
|
426
|
-
self._expand_block(calls, "body")
|
427
|
-
|
428
|
-
def _get_function_declarations(self) -> Sequence[QuantumFunctionDeclaration]:
|
429
|
-
return [
|
430
|
-
QuantumFunctionDeclaration(
|
431
|
-
name=func_closure.name,
|
432
|
-
positional_arg_declarations=func_closure.positional_arg_declarations,
|
433
|
-
)
|
434
|
-
for func in self._top_level_scope.values()
|
435
|
-
if isinstance(func_closure := func.value, FunctionClosure)
|
436
|
-
]
|
437
|
-
|
438
|
-
def add_constant(self, constant: Constant) -> None:
|
439
|
-
add_constants_to_scope([constant], self._top_level_scope)
|
440
|
-
|
441
|
-
def update_declarative_functions(
|
442
|
-
self,
|
443
|
-
functions: dict[str, NativeFunctionDefinition],
|
444
|
-
qmodule: ModelStateContainer,
|
445
|
-
) -> None:
|
446
|
-
add_functions_to_scope(list(functions.values()), self._top_level_scope)
|
447
|
-
for dec_func_name in functions:
|
448
|
-
if dec_func_name in qmodule.functions_compilation_metadata:
|
449
|
-
self._functions_compilation_metadata[dec_func_name] = (
|
450
|
-
qmodule.functions_compilation_metadata[dec_func_name]
|
451
|
-
)
|
452
|
-
|
453
|
-
def update_generative_functions(
|
454
|
-
self, generative_functions: dict[str, GenerativeQFunc]
|
455
|
-
) -> None:
|
456
|
-
add_generative_functions_to_scope(
|
457
|
-
list(generative_functions.values()), self._top_level_scope
|
458
|
-
)
|
459
|
-
for name, gen_func in generative_functions.items():
|
460
|
-
if gen_func.compilation_metadata is not None:
|
461
|
-
self._functions_compilation_metadata[name] = (
|
462
|
-
gen_func.compilation_metadata
|
463
|
-
)
|
464
|
-
|
465
|
-
def add_purely_declarative_function(self, function: FunctionClosure) -> None:
|
466
|
-
functions_to_add = [function.name] + QMODULE.function_dependencies[
|
467
|
-
function.name
|
468
|
-
]
|
469
|
-
for func in functions_to_add:
|
470
|
-
if func not in self._expanded_functions and func in QMODULE.native_defs:
|
471
|
-
self._expanded_functions[func] = QMODULE.native_defs[func]
|
472
|
-
if func in QMODULE.functions_compilation_metadata:
|
473
|
-
self._expanded_functions_compilation_metadata[func] = (
|
474
|
-
QMODULE.functions_compilation_metadata[func]
|
475
|
-
)
|