classiq 0.99.0__py3-none-any.whl → 0.102.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 +3 -0
- classiq/_internals/api_wrapper.py +29 -4
- classiq/applications/chemistry/op_utils.py +31 -1
- classiq/applications/chemistry/problems.py +18 -6
- classiq/applications/chemistry/ucc.py +2 -2
- classiq/evaluators/parameter_types.py +1 -4
- classiq/evaluators/qmod_node_evaluators/utils.py +6 -3
- classiq/execution/__init__.py +11 -1
- classiq/execution/jobs.py +122 -5
- classiq/interface/_version.py +1 -1
- classiq/interface/exceptions.py +0 -42
- classiq/interface/executor/execution_request.py +1 -0
- classiq/interface/executor/quantum_code.py +0 -6
- classiq/interface/executor/user_budget.py +2 -6
- classiq/interface/generator/generation_request.py +40 -0
- classiq/interface/generator/quantum_program.py +8 -36
- classiq/interface/generator/transpiler_basis_gates.py +1 -3
- classiq/interface/generator/types/compilation_metadata.py +1 -1
- classiq/interface/helpers/model_normalizer.py +24 -0
- classiq/interface/helpers/text_utils.py +20 -5
- classiq/interface/model/bind_operation.py +3 -0
- classiq/interface/model/invert.py +7 -0
- classiq/interface/model/model.py +42 -3
- classiq/interface/model/quantum_function_call.py +17 -5
- classiq/model_expansions/arithmetic_compute_result_attrs.py +10 -1
- classiq/model_expansions/interpreters/base_interpreter.py +3 -2
- classiq/model_expansions/quantum_operations/call_emitter.py +0 -3
- classiq/model_expansions/visitors/uncomputation_signature_inference.py +15 -38
- classiq/open_library/functions/__init__.py +55 -27
- classiq/open_library/functions/bit_operations.py +30 -0
- classiq/open_library/functions/encodings.py +182 -0
- classiq/open_library/functions/modular_arithmetics.py +597 -0
- classiq/open_library/functions/qft_space_arithmetics.py +81 -0
- classiq/open_library/functions/state_preparation.py +13 -7
- classiq/open_library/functions/utility_functions.py +22 -3
- classiq/qmod/builtins/functions/exponentiation.py +2 -2
- classiq/qmod/builtins/operations.py +29 -4
- classiq/qmod/native/pretty_printer.py +15 -4
- classiq/qmod/pretty_print/pretty_printer.py +14 -2
- classiq/qmod/qmod_variable.py +1 -1
- classiq/qmod/quantum_callable.py +8 -2
- classiq/qmod/quantum_expandable.py +3 -1
- classiq/qmod/quantum_function.py +2 -1
- classiq/qmod/semantics/error_manager.py +11 -1
- classiq/qmod/utilities.py +7 -4
- classiq/synthesis_action/__init__.py +20 -0
- classiq/synthesis_action/actions.py +106 -0
- {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/METADATA +1 -1
- {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/RECORD +51 -47
- classiq/interface/executor/register_initialization.py +0 -36
- classiq/open_library/functions/modular_exponentiation.py +0 -272
- classiq/open_library/functions/qsvt_temp.py +0 -536
- {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/WHEEL +0 -0
- {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -10,12 +10,10 @@ from classiq.interface.compression_utils import decompress
|
|
|
10
10
|
from classiq.interface.exceptions import (
|
|
11
11
|
ClassiqDeprecationWarning,
|
|
12
12
|
ClassiqMissingOutputFormatError,
|
|
13
|
-
ClassiqStateInitializationError,
|
|
14
13
|
)
|
|
15
14
|
from classiq.interface.execution.primitives import PrimitivesInput
|
|
16
15
|
from classiq.interface.executor import quantum_code
|
|
17
16
|
from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
|
|
18
|
-
from classiq.interface.executor.register_initialization import RegisterInitialization
|
|
19
17
|
from classiq.interface.generator.circuit_code.circuit_code import CircuitCodeInterface
|
|
20
18
|
from classiq.interface.generator.circuit_code.types_and_constants import (
|
|
21
19
|
INSTRUCTION_SET_TO_FORMAT,
|
|
@@ -29,9 +27,9 @@ from classiq.interface.generator.hardware.hardware_data import SynthesisHardware
|
|
|
29
27
|
from classiq.interface.generator.model.model import ExecutionModel
|
|
30
28
|
from classiq.interface.helpers.versioned_model import VersionedModel
|
|
31
29
|
from classiq.interface.ide.visual_model import CircuitMetrics
|
|
30
|
+
from classiq.interface.model.model import Model
|
|
32
31
|
|
|
33
32
|
RegisterName: TypeAlias = str
|
|
34
|
-
InitialConditions: TypeAlias = dict[RegisterName, int]
|
|
35
33
|
|
|
36
34
|
|
|
37
35
|
class TranspiledCircuitData(CircuitCodeInterface):
|
|
@@ -56,7 +54,6 @@ def _get_formatted_utc_current_time() -> str:
|
|
|
56
54
|
|
|
57
55
|
class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
|
58
56
|
hardware_data: SynthesisHardwareData
|
|
59
|
-
initial_values: InitialConditions | None = pydantic.Field(default=None)
|
|
60
57
|
data: GeneratedCircuitData
|
|
61
58
|
model: ExecutionModel
|
|
62
59
|
transpiled_circuit: TranspiledCircuitData | None = pydantic.Field(default=None)
|
|
@@ -65,7 +62,7 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
|
|
65
62
|
program_id: str = pydantic.Field(default_factory=get_uuid_as_str)
|
|
66
63
|
execution_primitives_input: PrimitivesInput | None = pydantic.Field(default=None)
|
|
67
64
|
synthesis_warnings: list[str] | None = pydantic.Field(default=None)
|
|
68
|
-
|
|
65
|
+
compiled_qmod: Model | None = pydantic.Field(default=None)
|
|
69
66
|
|
|
70
67
|
def __str__(self) -> str:
|
|
71
68
|
return self.model_dump_json(indent=2)
|
|
@@ -85,10 +82,8 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
|
|
85
82
|
|
|
86
83
|
def to_program(
|
|
87
84
|
self,
|
|
88
|
-
initial_values: InitialConditions | None = None,
|
|
89
85
|
instruction_set: QuantumInstructionSet | None = None,
|
|
90
86
|
) -> quantum_code.QuantumCode:
|
|
91
|
-
initial_values = initial_values or self.initial_values
|
|
92
87
|
if instruction_set is not None:
|
|
93
88
|
code, syntax = (
|
|
94
89
|
self.program_circuit.get_code(instruction_set),
|
|
@@ -97,40 +92,17 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
|
|
97
92
|
else:
|
|
98
93
|
code, syntax = self._default_program_code()
|
|
99
94
|
|
|
100
|
-
if initial_values is not None:
|
|
101
|
-
registers_initialization = self.get_registers_initialization(
|
|
102
|
-
initial_values=initial_values
|
|
103
|
-
)
|
|
104
|
-
else:
|
|
105
|
-
registers_initialization = None
|
|
106
95
|
return quantum_code.QuantumCode(
|
|
107
96
|
code=code,
|
|
108
97
|
syntax=syntax,
|
|
109
|
-
output_qubits_map=
|
|
110
|
-
|
|
98
|
+
output_qubits_map=(
|
|
99
|
+
self.data.qubit_mapping.physical_outputs
|
|
100
|
+
if self._can_use_transpiled_code
|
|
101
|
+
else self.data.qubit_mapping.logical_outputs
|
|
102
|
+
),
|
|
111
103
|
synthesis_execution_data=self.data.execution_data,
|
|
112
104
|
)
|
|
113
105
|
|
|
114
|
-
def _get_initialization_qubits(self, name: str) -> tuple[int, ...]:
|
|
115
|
-
qubits = self.data.qubit_mapping.logical_inputs.get(name)
|
|
116
|
-
if qubits is None:
|
|
117
|
-
raise ClassiqStateInitializationError(
|
|
118
|
-
f"Cannot initialize register {name}, it does not appear in circuit inputs"
|
|
119
|
-
)
|
|
120
|
-
return qubits
|
|
121
|
-
|
|
122
|
-
def get_registers_initialization(
|
|
123
|
-
self, initial_values: InitialConditions
|
|
124
|
-
) -> dict[RegisterName, RegisterInitialization]:
|
|
125
|
-
return {
|
|
126
|
-
name: RegisterInitialization(
|
|
127
|
-
name=name,
|
|
128
|
-
qubits=list(self._get_initialization_qubits(name)),
|
|
129
|
-
initial_condition=init_value,
|
|
130
|
-
)
|
|
131
|
-
for name, init_value in initial_values.items()
|
|
132
|
-
}
|
|
133
|
-
|
|
134
106
|
def save_results(self, filename: str | Path | None = None) -> None:
|
|
135
107
|
"""
|
|
136
108
|
Saves quantum program results as json into a file.
|
|
@@ -148,7 +120,7 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
|
|
148
120
|
|
|
149
121
|
@property
|
|
150
122
|
def _can_use_transpiled_code(self) -> bool:
|
|
151
|
-
return (
|
|
123
|
+
return self.transpiled_circuit is not None and (
|
|
152
124
|
self.data.execution_data is None
|
|
153
125
|
or not self.data.execution_data.function_execution
|
|
154
126
|
)
|
|
@@ -71,9 +71,7 @@ DEFAULT_BASIS_GATES: BasisGates = SINGLE_QUBIT_GATES | BASIC_TWO_QUBIT_GATES
|
|
|
71
71
|
ALL_GATES: BasisGates = (
|
|
72
72
|
SINGLE_QUBIT_GATES | TWO_QUBIT_GATES | THREE_QUBIT_GATES | NON_UNITARY_GATES
|
|
73
73
|
)
|
|
74
|
-
ALL_NON_3_QBIT_GATES: BasisGates =
|
|
75
|
-
SINGLE_QUBIT_GATES | TWO_QUBIT_GATES | NON_UNITARY_GATES
|
|
76
|
-
)
|
|
74
|
+
ALL_NON_3_QBIT_GATES: BasisGates = ALL_GATES - THREE_QUBIT_GATES
|
|
77
75
|
|
|
78
76
|
ROUTING_TWO_QUBIT_BASIS_GATES: BasisGates = frozenset(
|
|
79
77
|
("cx", "ecr", "rzx", "ryy", "rxx", "rzz", "cy", "cz", "cp", "swap")
|
|
@@ -3,7 +3,7 @@ from pydantic import BaseModel, Field, NonNegativeInt, PrivateAttr
|
|
|
3
3
|
|
|
4
4
|
class CompilationMetadata(BaseModel):
|
|
5
5
|
should_synthesize_separately: bool = Field(default=False)
|
|
6
|
-
occurrences_number: NonNegativeInt = Field(default=
|
|
6
|
+
occurrences_number: NonNegativeInt = Field(default=0)
|
|
7
7
|
_occupation_number: NonNegativeInt = PrivateAttr(default=0)
|
|
8
8
|
disable_perm_check: bool = Field(default=False)
|
|
9
9
|
disable_const_checks: list[str] | bool = Field(default=False)
|
|
@@ -7,10 +7,16 @@ from classiq.interface.generator.functions.classical_type import ClassicalType
|
|
|
7
7
|
from classiq.interface.generator.functions.type_modifier import TypeModifier
|
|
8
8
|
from classiq.interface.generator.visitor import Transformer, Visitor
|
|
9
9
|
from classiq.interface.model.model import Model
|
|
10
|
+
from classiq.interface.model.native_function_definition import NativeFunctionDefinition
|
|
10
11
|
from classiq.interface.model.port_declaration import AnonPortDeclaration
|
|
12
|
+
from classiq.interface.model.quantum_function_call import QuantumFunctionCall
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
class ModelNormalizer(Visitor):
|
|
16
|
+
def __init__(self, normalize_names: bool = False) -> None:
|
|
17
|
+
self._normalize_names = normalize_names
|
|
18
|
+
self._funcs_renames: dict[str, str] = {}
|
|
19
|
+
|
|
14
20
|
def visit(self, node: Any) -> None:
|
|
15
21
|
if isinstance(node, ASTNode):
|
|
16
22
|
node.model_config["frozen"] = False
|
|
@@ -23,8 +29,26 @@ class ModelNormalizer(Visitor):
|
|
|
23
29
|
def visit_Model(self, model: Model) -> None:
|
|
24
30
|
model.debug_info = DebugInfoCollection()
|
|
25
31
|
model.functions.sort(key=lambda x: x.name)
|
|
32
|
+
self._funcs_renames = {
|
|
33
|
+
func.name: f"___func_{index}" for index, func in enumerate(model.functions)
|
|
34
|
+
}
|
|
26
35
|
self.generic_visit(model)
|
|
27
36
|
|
|
37
|
+
def visit_NativeFunctionDefinition(self, func: NativeFunctionDefinition) -> None:
|
|
38
|
+
if self._normalize_names:
|
|
39
|
+
func.name = self._funcs_renames[func.name]
|
|
40
|
+
self.generic_visit(func)
|
|
41
|
+
|
|
42
|
+
def visit_QuantumFunctionCall(self, call: QuantumFunctionCall) -> None:
|
|
43
|
+
if self._normalize_names:
|
|
44
|
+
if isinstance(call.function, str):
|
|
45
|
+
if call.function in self._funcs_renames:
|
|
46
|
+
call.function = self._funcs_renames[call.function]
|
|
47
|
+
else:
|
|
48
|
+
if call.function.name in self._funcs_renames:
|
|
49
|
+
call.function.name = self._funcs_renames[call.function.name]
|
|
50
|
+
self.generic_visit(call)
|
|
51
|
+
|
|
28
52
|
def visit_AnonPortDeclaration(self, decl: AnonPortDeclaration) -> None:
|
|
29
53
|
decl.type_modifier = TypeModifier.Mutable
|
|
30
54
|
|
|
@@ -1,18 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
from collections.abc import Sequence, Sized
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def s(items: Sized | int) -> str:
|
|
5
|
+
if isinstance(items, Sized):
|
|
3
6
|
items = len(items)
|
|
4
7
|
return "" if items == 1 else "s"
|
|
5
8
|
|
|
6
9
|
|
|
7
|
-
def are(items:
|
|
10
|
+
def are(items: Sized) -> str:
|
|
8
11
|
return "is" if len(items) == 1 else "are"
|
|
9
12
|
|
|
10
13
|
|
|
11
|
-
def
|
|
14
|
+
def were(items: Sized) -> str:
|
|
15
|
+
return "was" if len(items) == 1 else "were"
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def an(items: Sized) -> str:
|
|
19
|
+
return "an " if len(items) == 1 else ""
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def they(items: Sized) -> str:
|
|
12
23
|
return "it" if len(items) == 1 else "they"
|
|
13
24
|
|
|
14
25
|
|
|
15
|
-
def
|
|
26
|
+
def conj(items: Sized) -> str:
|
|
27
|
+
return "s" if len(items) == 1 else ""
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def readable_list(items: Sequence, quote: bool = False) -> str:
|
|
16
31
|
if quote:
|
|
17
32
|
items = [repr(str(item)) for item in items]
|
|
18
33
|
if len(items) == 1:
|
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING, Literal
|
|
2
2
|
|
|
3
3
|
from classiq.interface.ast_node import ASTNodeType, reset_lists
|
|
4
|
+
from classiq.interface.enum_utils import StrEnum
|
|
4
5
|
from classiq.interface.model.quantum_statement import QuantumOperation
|
|
5
6
|
|
|
6
7
|
if TYPE_CHECKING:
|
|
7
8
|
from classiq.interface.model.statement_block import StatementBlock
|
|
8
9
|
|
|
9
10
|
|
|
11
|
+
class BlockKind(StrEnum):
|
|
12
|
+
SingleCall = "single_call"
|
|
13
|
+
Compound = "compound"
|
|
14
|
+
|
|
15
|
+
|
|
10
16
|
class Invert(QuantumOperation):
|
|
11
17
|
kind: Literal["Invert"]
|
|
12
18
|
|
|
13
19
|
body: "StatementBlock"
|
|
20
|
+
block_kind: BlockKind = BlockKind.Compound
|
|
14
21
|
|
|
15
22
|
def _as_back_ref(self: ASTNodeType) -> ASTNodeType:
|
|
16
23
|
return reset_lists(self, ["body"])
|
classiq/interface/model/model.py
CHANGED
|
@@ -5,6 +5,7 @@ from typing import Annotated, Any, Literal, NewType
|
|
|
5
5
|
import pydantic
|
|
6
6
|
|
|
7
7
|
from classiq.interface.ast_node import ASTNode
|
|
8
|
+
from classiq.interface.compression_utils import compress_pydantic, decompress
|
|
8
9
|
from classiq.interface.debug_info.debug_info import DebugInfoCollection
|
|
9
10
|
from classiq.interface.exceptions import ClassiqValueError
|
|
10
11
|
from classiq.interface.executor.execution_preferences import ExecutionPreferences
|
|
@@ -96,9 +97,9 @@ class Model(VersionedModel, ASTNode):
|
|
|
96
97
|
)
|
|
97
98
|
preferences: Preferences = pydantic.Field(default_factory=Preferences)
|
|
98
99
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
_debug_info: DebugInfoCollection | None = pydantic.PrivateAttr(default=None)
|
|
101
|
+
compressed_debug_info: bytes | None = pydantic.Field(default=None)
|
|
102
|
+
|
|
102
103
|
functions_compilation_metadata: defaultdict[
|
|
103
104
|
str,
|
|
104
105
|
Annotated[
|
|
@@ -198,3 +199,41 @@ class Model(VersionedModel, ASTNode):
|
|
|
198
199
|
return model.model_dump(
|
|
199
200
|
exclude={"constraints", "execution_preferences", "preferences"},
|
|
200
201
|
)
|
|
202
|
+
|
|
203
|
+
# TODO (CLS-4966): remove
|
|
204
|
+
@pydantic.model_validator(mode="wrap")
|
|
205
|
+
@classmethod
|
|
206
|
+
def get_deprecated_debug_info(
|
|
207
|
+
cls, data: Any, handler: pydantic.ModelWrapValidatorHandler
|
|
208
|
+
) -> "Model":
|
|
209
|
+
model = handler(data)
|
|
210
|
+
if isinstance(data, dict) and "debug_info" in data:
|
|
211
|
+
model._debug_info = DebugInfoCollection.model_validate(data["debug_info"])
|
|
212
|
+
return model
|
|
213
|
+
|
|
214
|
+
@property
|
|
215
|
+
def debug_info(self) -> DebugInfoCollection:
|
|
216
|
+
if self._debug_info is None:
|
|
217
|
+
if self.compressed_debug_info is None:
|
|
218
|
+
self._debug_info = DebugInfoCollection()
|
|
219
|
+
else:
|
|
220
|
+
self._debug_info = DebugInfoCollection.model_validate(
|
|
221
|
+
decompress(self.compressed_debug_info)
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
return self._debug_info
|
|
225
|
+
|
|
226
|
+
@debug_info.setter
|
|
227
|
+
def debug_info(self, value: DebugInfoCollection) -> None:
|
|
228
|
+
self._debug_info = value
|
|
229
|
+
self.compressed_debug_info = None
|
|
230
|
+
|
|
231
|
+
def clear_debug_info(self) -> None:
|
|
232
|
+
self._debug_info = None
|
|
233
|
+
self.compressed_debug_info = None
|
|
234
|
+
|
|
235
|
+
def compress_debug_info(self) -> None:
|
|
236
|
+
if self._debug_info is None:
|
|
237
|
+
self.compressed_debug_info = None
|
|
238
|
+
else:
|
|
239
|
+
self.compressed_debug_info = compress_pydantic(self._debug_info)
|
|
@@ -29,6 +29,13 @@ from classiq.interface.model.quantum_lambda_function import (
|
|
|
29
29
|
)
|
|
30
30
|
from classiq.interface.model.quantum_statement import HandleMetadata, QuantumOperation
|
|
31
31
|
|
|
32
|
+
|
|
33
|
+
def _split_concatenation(var: HandleBinding | HandlesList) -> list[HandleBinding]:
|
|
34
|
+
if isinstance(var, HandleBinding):
|
|
35
|
+
return [var]
|
|
36
|
+
return list(chain.from_iterable(_split_concatenation(item) for item in var.handles))
|
|
37
|
+
|
|
38
|
+
|
|
32
39
|
ArgValue = Union[
|
|
33
40
|
Expression,
|
|
34
41
|
QuantumOperand,
|
|
@@ -221,18 +228,23 @@ class QuantumFunctionCall(QuantumOperation):
|
|
|
221
228
|
def _get_handles_with_declarations(
|
|
222
229
|
self,
|
|
223
230
|
) -> Iterable[tuple[int, AnonPortDeclaration, HandleBinding]]:
|
|
231
|
+
"""
|
|
232
|
+
Get variable arguments attached to their position and parameter declaration.
|
|
233
|
+
Splits concatenations into variables.
|
|
234
|
+
"""
|
|
224
235
|
return [
|
|
225
|
-
(
|
|
226
|
-
for
|
|
236
|
+
(positional_idx, port, var)
|
|
237
|
+
for positional_idx, (port, var_or_concatenation) in enumerate(
|
|
227
238
|
zip(
|
|
228
239
|
(port_decl for port_decl in self.func_decl.port_declarations),
|
|
229
240
|
(
|
|
230
|
-
|
|
231
|
-
for
|
|
232
|
-
if isinstance(
|
|
241
|
+
arg
|
|
242
|
+
for arg in self.positional_args
|
|
243
|
+
if isinstance(arg, (HandleBinding, HandlesList))
|
|
233
244
|
),
|
|
234
245
|
)
|
|
235
246
|
)
|
|
247
|
+
for var in _split_concatenation(var_or_concatenation)
|
|
236
248
|
]
|
|
237
249
|
|
|
238
250
|
def _get_readable_location(
|
|
@@ -64,11 +64,20 @@ def compute_result_attrs_bitwise_and(
|
|
|
64
64
|
if left.fraction_digits > 0 or right.fraction_digits > 0:
|
|
65
65
|
raise ClassiqValueError("Bitwise AND is only defined for integers")
|
|
66
66
|
|
|
67
|
+
if left.is_signed and not right.is_signed:
|
|
68
|
+
size = right.size
|
|
69
|
+
elif not left.is_signed and right.is_signed:
|
|
70
|
+
size = left.size
|
|
71
|
+
elif not left.is_signed and not right.is_signed:
|
|
72
|
+
size = min(left.size, right.size)
|
|
73
|
+
else:
|
|
74
|
+
size = max(left.size, right.size)
|
|
75
|
+
|
|
67
76
|
# we comply with python, which uses arbitrary precision, so a positive number can
|
|
68
77
|
# always be represented by "0..." and a negative number by "1...", thus their
|
|
69
78
|
# bitwise AND is always non-negative
|
|
70
79
|
return NumericAttributes(
|
|
71
|
-
size=
|
|
80
|
+
size=size,
|
|
72
81
|
is_signed=left.is_signed and right.is_signed,
|
|
73
82
|
fraction_digits=0,
|
|
74
83
|
)
|
|
@@ -159,7 +159,7 @@ class BaseInterpreter:
|
|
|
159
159
|
finally:
|
|
160
160
|
self._error_manager.report_errors(ClassiqExpansionError)
|
|
161
161
|
|
|
162
|
-
|
|
162
|
+
model = Model(
|
|
163
163
|
constraints=self._model.constraints,
|
|
164
164
|
preferences=self._model.preferences,
|
|
165
165
|
classical_execution_code=self._model.classical_execution_code,
|
|
@@ -181,9 +181,10 @@ class BaseInterpreter:
|
|
|
181
181
|
if name not in BUILTIN_STRUCT_DECLARATIONS
|
|
182
182
|
],
|
|
183
183
|
qstructs=list(QMODULE.qstruct_decls.values()),
|
|
184
|
-
debug_info=self._model.debug_info,
|
|
185
184
|
functions_compilation_metadata=self._expanded_functions_compilation_metadata,
|
|
186
185
|
)
|
|
186
|
+
model.debug_info = self._model.debug_info
|
|
187
|
+
return model
|
|
187
188
|
|
|
188
189
|
def process_exception(self, e: Exception) -> None:
|
|
189
190
|
if not isinstance(e, (ClassiqError, ValidationError)):
|
|
@@ -286,9 +286,6 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
|
|
|
286
286
|
if cache_key in self._expanded_functions:
|
|
287
287
|
function_def = self._expanded_functions[cache_key]
|
|
288
288
|
self._expand_cached_function(function, function_def)
|
|
289
|
-
self._expanded_functions_compilation_metadata[
|
|
290
|
-
function_def.name
|
|
291
|
-
].occurrences_number += 1
|
|
292
289
|
return function_def
|
|
293
290
|
|
|
294
291
|
context = self._expand_operation(function)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import warnings
|
|
2
1
|
from collections import defaultdict
|
|
3
2
|
from collections.abc import Iterator
|
|
4
3
|
from contextlib import contextmanager
|
|
@@ -6,10 +5,8 @@ from typing import NamedTuple
|
|
|
6
5
|
|
|
7
6
|
from classiq.interface.ast_node import ASTNode
|
|
8
7
|
from classiq.interface.exceptions import (
|
|
9
|
-
ClassiqDeprecationWarning,
|
|
10
8
|
ClassiqInternalExpansionError,
|
|
11
9
|
)
|
|
12
|
-
from classiq.interface.generator.compiler_keywords import EXPANDED_KEYWORD
|
|
13
10
|
from classiq.interface.generator.functions.port_declaration import (
|
|
14
11
|
PortDeclarationDirection,
|
|
15
12
|
)
|
|
@@ -35,6 +32,8 @@ from classiq.interface.model.skip_control import SkipControl
|
|
|
35
32
|
from classiq.interface.model.within_apply_operation import WithinApply
|
|
36
33
|
from classiq.interface.source_reference import SourceReference
|
|
37
34
|
|
|
35
|
+
from classiq.qmod.semantics.error_manager import ErrorManager
|
|
36
|
+
|
|
38
37
|
|
|
39
38
|
class _BoundVars(NamedTuple):
|
|
40
39
|
in_identifiers: list[str]
|
|
@@ -243,11 +242,7 @@ def infer_and_validate_uncomputation_signature(
|
|
|
243
242
|
PortDeclarationDirection.Input,
|
|
244
243
|
PortDeclarationDirection.Output,
|
|
245
244
|
):
|
|
246
|
-
|
|
247
|
-
_input_output_const(port.name, port.direction, func_def.name),
|
|
248
|
-
ClassiqDeprecationWarning,
|
|
249
|
-
stacklevel=1,
|
|
250
|
-
)
|
|
245
|
+
ErrorManager().add_error(_input_output_const(port.name, port.direction))
|
|
251
246
|
|
|
252
247
|
if disable_perm_check and (disable_const_checks is True) and not tighten_signature:
|
|
253
248
|
return
|
|
@@ -257,10 +252,9 @@ def infer_and_validate_uncomputation_signature(
|
|
|
257
252
|
|
|
258
253
|
if not disable_perm_check and func_def.permutation and not visitor.is_permutation():
|
|
259
254
|
for source_ref in visitor.non_permutation_reasons():
|
|
260
|
-
|
|
261
|
-
_non_permutation_usage(
|
|
262
|
-
|
|
263
|
-
stacklevel=1,
|
|
255
|
+
ErrorManager().add_error(
|
|
256
|
+
_non_permutation_usage(),
|
|
257
|
+
source_ref=source_ref,
|
|
264
258
|
)
|
|
265
259
|
|
|
266
260
|
if tighten_signature and not func_def.permutation and visitor.is_permutation():
|
|
@@ -276,10 +270,8 @@ def infer_and_validate_uncomputation_signature(
|
|
|
276
270
|
and not visitor.is_const(port.name)
|
|
277
271
|
):
|
|
278
272
|
for source_ref in visitor.non_const_reasons(port.name):
|
|
279
|
-
|
|
280
|
-
_non_const_usage(port.name, source_ref
|
|
281
|
-
ClassiqDeprecationWarning,
|
|
282
|
-
stacklevel=1,
|
|
273
|
+
ErrorManager().add_error(
|
|
274
|
+
_non_const_usage(port.name), source_ref=source_ref
|
|
283
275
|
)
|
|
284
276
|
|
|
285
277
|
if (
|
|
@@ -293,36 +285,21 @@ def infer_and_validate_uncomputation_signature(
|
|
|
293
285
|
def _input_output_const(
|
|
294
286
|
port_name: str,
|
|
295
287
|
direction: PortDeclarationDirection,
|
|
296
|
-
function_name: str,
|
|
297
288
|
) -> str:
|
|
298
|
-
return (
|
|
299
|
-
f"{direction.capitalize()} parameters cannot be defined as constants"
|
|
300
|
-
f" (parameter {port_name!r} in function {function_name.split('_' + EXPANDED_KEYWORD)[0]!r}).\n"
|
|
301
|
-
"The deprecation warning will be elevated to an error starting 2025-12-03, at the earliest."
|
|
302
|
-
)
|
|
289
|
+
return f"{direction.capitalize()} parameter {port_name!r} cannot be defined as constant."
|
|
303
290
|
|
|
304
291
|
|
|
305
|
-
def _non_const_usage(
|
|
306
|
-
port_name: str,
|
|
307
|
-
source_ref: SourceReference | None = None,
|
|
308
|
-
) -> str:
|
|
309
|
-
source_ref_str = f"\n\tat {source_ref}" if source_ref else ""
|
|
292
|
+
def _non_const_usage(port_name: str) -> str:
|
|
310
293
|
return (
|
|
311
|
-
f"Non-constant usage of a constant parameter {port_name!r}
|
|
294
|
+
f"Non-constant usage of a constant parameter {port_name!r}.\n"
|
|
312
295
|
"Tip: if the commulative use of the parameter in the function is constant, "
|
|
313
|
-
"use the `disable_const_checks` flag to instruct the compiler to disregard individual operations
|
|
314
|
-
"The deprecation warning will be elevated to an error starting 2025-12-03, at the earliest."
|
|
296
|
+
"use the `disable_const_checks` flag to instruct the compiler to disregard individual operations."
|
|
315
297
|
)
|
|
316
298
|
|
|
317
299
|
|
|
318
|
-
def _non_permutation_usage(
|
|
319
|
-
function_name: str,
|
|
320
|
-
source_ref: SourceReference | None = None,
|
|
321
|
-
) -> str:
|
|
322
|
-
source_ref_str = f"\n\tat {source_ref}" if source_ref else ""
|
|
300
|
+
def _non_permutation_usage() -> str:
|
|
323
301
|
return (
|
|
324
|
-
|
|
302
|
+
"Non-permutation operation used in a permutation function.\n"
|
|
325
303
|
"Tip: if the commulative effect of the function is a permutation, "
|
|
326
|
-
"use the `disable_perm_check` flag to instruct the compiler to disregard individual operations
|
|
327
|
-
"The deprecation warning will be elevated to an error starting 2025-12-03, at the earliest."
|
|
304
|
+
"use the `disable_perm_check` flag to instruct the compiler to disregard individual operations."
|
|
328
305
|
)
|
|
@@ -8,19 +8,20 @@ from .amplitude_estimation import *
|
|
|
8
8
|
from .amplitude_loading import assign_amplitude_table
|
|
9
9
|
from .discrete_sine_cosine_transform import *
|
|
10
10
|
from .discrete_sine_cosine_transform import _qct_d_operator, _qct_pi_operator
|
|
11
|
+
from .encodings import *
|
|
11
12
|
from .grover import *
|
|
12
13
|
from .grover import _cond_phase_flip
|
|
13
14
|
from .hea import *
|
|
14
15
|
from .lcu import *
|
|
15
16
|
from .linear_pauli_rotation import *
|
|
16
17
|
from .linear_pauli_rotation import _single_pauli
|
|
17
|
-
from .
|
|
18
|
-
from .modular_exponentiation import _check_msb
|
|
18
|
+
from .modular_arithmetics import *
|
|
19
19
|
from .qaoa_penalty import *
|
|
20
20
|
from .qft_functions import *
|
|
21
|
+
from .qft_space_arithmetics import *
|
|
22
|
+
from .qft_space_arithmetics import _check_msb
|
|
21
23
|
from .qpe import *
|
|
22
|
-
from .qsvt import
|
|
23
|
-
from .qsvt_temp import * # change to .qsvt after deprecation
|
|
24
|
+
from .qsvt import * # change to .qsvt after deprecation
|
|
24
25
|
from .state_preparation import *
|
|
25
26
|
from .state_preparation import _prepare_uniform_trimmed_state_step
|
|
26
27
|
from .swap_test import *
|
|
@@ -30,6 +31,7 @@ from .variational import *
|
|
|
30
31
|
OPEN_LIBRARY_FUNCTIONS: list[BaseQFunc] = [
|
|
31
32
|
qpe_flexible,
|
|
32
33
|
qpe,
|
|
34
|
+
_check_msb,
|
|
33
35
|
_single_pauli,
|
|
34
36
|
linear_pauli_rotations,
|
|
35
37
|
amplitude_estimation,
|
|
@@ -44,25 +46,14 @@ OPEN_LIBRARY_FUNCTIONS: list[BaseQFunc] = [
|
|
|
44
46
|
apply_to_all,
|
|
45
47
|
qft_no_swap,
|
|
46
48
|
qft_space_add_const,
|
|
47
|
-
cc_modular_add,
|
|
48
|
-
c_modular_multiply,
|
|
49
49
|
multiswap,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
projector_controlled_double_phase_new,
|
|
58
|
-
projector_controlled_phase_old,
|
|
59
|
-
projector_controlled_phase_new,
|
|
60
|
-
qsvt_inversion_old,
|
|
61
|
-
qsvt_inversion_new,
|
|
62
|
-
qsvt_lcu_old,
|
|
63
|
-
qsvt_lcu_new,
|
|
64
|
-
qsvt_lcu_step_old,
|
|
65
|
-
qsvt_lcu_step_new,
|
|
50
|
+
qsvt_step,
|
|
51
|
+
qsvt,
|
|
52
|
+
projector_controlled_double_phase,
|
|
53
|
+
projector_controlled_phase,
|
|
54
|
+
qsvt_inversion,
|
|
55
|
+
qsvt_lcu,
|
|
56
|
+
qsvt_lcu_step,
|
|
66
57
|
gqsp,
|
|
67
58
|
qaoa_mixer_layer,
|
|
68
59
|
qaoa_cost_layer,
|
|
@@ -88,13 +79,31 @@ OPEN_LIBRARY_FUNCTIONS: list[BaseQFunc] = [
|
|
|
88
79
|
_prepare_uniform_trimmed_state_step,
|
|
89
80
|
_qct_d_operator,
|
|
90
81
|
_qct_pi_operator,
|
|
91
|
-
_check_msb,
|
|
92
82
|
encode_in_angle,
|
|
93
83
|
encode_on_bloch,
|
|
94
84
|
_cond_phase_flip,
|
|
95
85
|
inplace_modular_multiply,
|
|
96
86
|
modular_multiply,
|
|
97
87
|
modular_add_qft_space,
|
|
88
|
+
one_hot_to_unary,
|
|
89
|
+
inplace_one_hot_to_unary,
|
|
90
|
+
unary_to_one_hot,
|
|
91
|
+
modular_negate_inplace,
|
|
92
|
+
modular_subtract_inplace,
|
|
93
|
+
modular_double_inplace,
|
|
94
|
+
modular_add_constant_inplace,
|
|
95
|
+
modular_add_inplace,
|
|
96
|
+
modular_multiply,
|
|
97
|
+
modular_square,
|
|
98
|
+
modular_multiply_constant,
|
|
99
|
+
modular_multiply_constant_inplace,
|
|
100
|
+
modular_to_montgomery_inplace,
|
|
101
|
+
modular_montgomery_to_standard_inplace,
|
|
102
|
+
modular_inverse_inplace,
|
|
103
|
+
kaliski_iteration,
|
|
104
|
+
modular_rsub_inplace,
|
|
105
|
+
modular_exp, # TODO: deprecate when ready
|
|
106
|
+
modular_exponentiate,
|
|
98
107
|
]
|
|
99
108
|
|
|
100
109
|
__all__ = [
|
|
@@ -103,8 +112,8 @@ __all__ = [
|
|
|
103
112
|
"amplitude_estimation",
|
|
104
113
|
"apply_to_all",
|
|
105
114
|
"assign_amplitude_table",
|
|
106
|
-
"
|
|
107
|
-
"
|
|
115
|
+
"binary_to_one_hot",
|
|
116
|
+
"binary_to_unary",
|
|
108
117
|
"encode_in_angle",
|
|
109
118
|
"encode_on_bloch",
|
|
110
119
|
"exact_amplitude_amplification",
|
|
@@ -114,19 +123,36 @@ __all__ = [
|
|
|
114
123
|
"grover_operator",
|
|
115
124
|
"grover_search",
|
|
116
125
|
"hadamard_transform",
|
|
117
|
-
"
|
|
126
|
+
"inplace_binary_to_one_hot",
|
|
118
127
|
"inplace_modular_multiply",
|
|
128
|
+
"inplace_one_hot_to_unary",
|
|
119
129
|
"inplace_prepare_complex_amplitudes",
|
|
120
130
|
"inplace_prepare_int",
|
|
121
131
|
"inplace_prepare_sparse_amplitudes",
|
|
132
|
+
"kaliski_iteration",
|
|
122
133
|
"lcu",
|
|
123
134
|
"lcu_pauli",
|
|
124
135
|
"linear_pauli_rotations",
|
|
136
|
+
"modular_add_constant_inplace",
|
|
137
|
+
"modular_add_inplace",
|
|
125
138
|
"modular_add_qft_space",
|
|
139
|
+
"modular_double_inplace",
|
|
126
140
|
"modular_exp",
|
|
127
|
-
"
|
|
141
|
+
"modular_exponentiate",
|
|
142
|
+
"modular_inverse_inplace",
|
|
143
|
+
"modular_montgomery_to_standard_inplace",
|
|
128
144
|
"modular_multiply",
|
|
145
|
+
"modular_multiply_constant",
|
|
146
|
+
"modular_multiply_constant_inplace",
|
|
147
|
+
"modular_negate_inplace",
|
|
148
|
+
"modular_rsub_inplace",
|
|
149
|
+
"modular_square",
|
|
150
|
+
"modular_subtract_inplace",
|
|
151
|
+
"modular_to_montgomery_inplace",
|
|
129
152
|
"multiswap",
|
|
153
|
+
"one_hot_to_binary",
|
|
154
|
+
"one_hot_to_unary",
|
|
155
|
+
"pad_zeros",
|
|
130
156
|
"phase_oracle",
|
|
131
157
|
"prepare_basis_state",
|
|
132
158
|
"prepare_bell_state",
|
|
@@ -166,4 +192,6 @@ __all__ = [
|
|
|
166
192
|
"suzuki_trotter",
|
|
167
193
|
"swap_test",
|
|
168
194
|
"switch",
|
|
195
|
+
"unary_to_binary",
|
|
196
|
+
"unary_to_one_hot",
|
|
169
197
|
]
|