classiq 0.42.2__py3-none-any.whl → 0.43.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/__init__.py +2 -6
- classiq/_internals/api_wrapper.py +6 -12
- classiq/_internals/authentication/token_manager.py +5 -2
- classiq/_internals/jobs.py +5 -10
- classiq/analyzer/rb.py +3 -3
- classiq/applications/chemistry/chemistry_model_constructor.py +12 -8
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +2 -2
- classiq/applications/finance/finance_model_constructor.py +16 -13
- classiq/applications/qsvm/__init__.py +1 -3
- classiq/applications/qsvm/qsvm_model_constructor.py +7 -6
- classiq/exceptions.py +9 -4
- classiq/execution/execution_session.py +5 -2
- classiq/execution/qnn.py +1 -1
- classiq/executor.py +0 -2
- classiq/interface/_version.py +1 -1
- classiq/interface/chemistry/operator.py +19 -5
- classiq/interface/executor/constants.py +1 -0
- classiq/interface/finance/function_input.py +16 -10
- classiq/interface/generator/application_apis/chemistry_declarations.py +2 -2
- classiq/interface/generator/application_apis/qsvm_declarations.py +4 -2
- classiq/interface/generator/arith/argument_utils.py +20 -3
- classiq/interface/generator/arith/arithmetic_expression_validator.py +3 -26
- classiq/interface/generator/arith/binary_ops.py +8 -14
- classiq/interface/generator/arith/extremum_operations.py +30 -0
- classiq/interface/generator/arith/number_utils.py +1 -1
- classiq/interface/generator/arith/unary_ops.py +1 -3
- classiq/interface/generator/compiler_keywords.py +1 -1
- classiq/interface/generator/expressions/atomic_expression_functions.py +13 -3
- classiq/interface/generator/expressions/enums/__init__.py +0 -20
- classiq/interface/generator/expressions/enums/finance_functions.py +11 -18
- classiq/interface/generator/expressions/non_symbolic_expr.py +119 -0
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +52 -37
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +16 -11
- classiq/interface/generator/expressions/qmod_sized_proxy.py +5 -5
- classiq/interface/generator/function_param_list_without_self_reference.py +0 -10
- classiq/interface/generator/function_params.py +0 -4
- classiq/interface/generator/functions/__init__.py +0 -20
- classiq/interface/generator/functions/builtins/core_library/exponentiation_functions.py +2 -2
- classiq/interface/generator/functions/builtins/open_lib_functions.py +530 -1
- classiq/interface/generator/functions/classical_type.py +22 -69
- classiq/interface/generator/functions/port_declaration.py +0 -11
- classiq/interface/generator/model/__init__.py +0 -1
- classiq/interface/generator/model/model.py +9 -185
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +3 -1
- classiq/interface/generator/types/builtin_enum_declarations.py +69 -0
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +2 -2
- classiq/interface/generator/types/enum_declaration.py +57 -0
- classiq/interface/jobs.py +36 -65
- classiq/interface/model/bind_operation.py +3 -0
- classiq/interface/model/classical_parameter_declaration.py +3 -0
- classiq/interface/model/handle_binding.py +7 -0
- classiq/interface/model/inplace_binary_operation.py +13 -15
- classiq/interface/model/model.py +8 -20
- classiq/interface/model/native_function_definition.py +0 -17
- classiq/interface/model/quantum_function_call.py +63 -182
- classiq/interface/model/quantum_type.py +71 -10
- classiq/interface/server/routes.py +0 -6
- classiq/qmod/__init__.py +3 -3
- classiq/qmod/builtins/__init__.py +10 -1
- classiq/qmod/builtins/classical_execution_primitives.py +4 -2
- classiq/qmod/builtins/enums.py +177 -0
- classiq/qmod/builtins/functions.py +1 -2
- classiq/qmod/builtins/operations.py +2 -4
- classiq/qmod/builtins/structs.py +16 -17
- classiq/qmod/declaration_inferrer.py +23 -20
- classiq/qmod/model_state_container.py +2 -0
- classiq/qmod/native/pretty_printer.py +31 -13
- classiq/qmod/pretty_print/pretty_printer.py +52 -27
- classiq/qmod/qmod_constant.py +7 -3
- classiq/qmod/qmod_parameter.py +2 -1
- classiq/qmod/qmod_struct.py +9 -33
- classiq/qmod/qmod_variable.py +55 -22
- classiq/qmod/quantum_callable.py +6 -1
- classiq/qmod/quantum_expandable.py +29 -11
- classiq/qmod/quantum_function.py +8 -4
- classiq/qmod/semantics/annotation.py +38 -0
- classiq/qmod/semantics/error_manager.py +49 -0
- classiq/qmod/semantics/static_semantics_visitor.py +308 -0
- classiq/qmod/semantics/validation/func_call_validation.py +149 -0
- classiq/qmod/semantics/validation/types_validation.py +21 -0
- classiq/qmod/symbolic.py +6 -6
- classiq/qmod/symbolic_expr.py +26 -11
- classiq/qmod/utilities.py +23 -1
- {classiq-0.42.2.dist-info → classiq-0.43.1.dist-info}/METADATA +2 -2
- {classiq-0.42.2.dist-info → classiq-0.43.1.dist-info}/RECORD +88 -103
- classiq/_internals/_qfunc_ext.py +0 -6
- classiq/applications/libraries/ampltitude_estimation_library.py +0 -11
- classiq/interface/generator/credit_risk_example/linear_gci.py +0 -122
- classiq/interface/generator/credit_risk_example/weighted_adder.py +0 -69
- classiq/interface/generator/expressions/enums/chemistry.py +0 -28
- classiq/interface/generator/expressions/enums/classical_enum.py +0 -20
- classiq/interface/generator/expressions/enums/ladder_operator.py +0 -6
- classiq/interface/generator/expressions/enums/optimizers.py +0 -9
- classiq/interface/generator/expressions/enums/pauli.py +0 -8
- classiq/interface/generator/expressions/enums/qsvm_feature_map_entanglement.py +0 -9
- classiq/interface/generator/functions/foreign_function_definition.py +0 -114
- classiq/interface/generator/functions/function_implementation.py +0 -107
- classiq/interface/generator/functions/native_function_definition.py +0 -155
- classiq/interface/generator/functions/quantum_function_declaration.py +0 -69
- classiq/interface/generator/functions/register.py +0 -44
- classiq/interface/generator/functions/register_mapping_data.py +0 -106
- classiq/interface/generator/inequality_mixer.py +0 -51
- classiq/interface/generator/model/classical_main_validator.py +0 -106
- classiq/interface/generator/range_mixer.py +0 -56
- classiq/interface/generator/state_propagator.py +0 -74
- classiq/interface/model/resolvers/function_call_resolver.py +0 -64
- classiq/interface/model/validations/__init__.py +0 -0
- classiq/interface/model/validations/handle_validation_base.py +0 -55
- classiq/interface/model/validations/handles_validator.py +0 -153
- classiq/interface/model/validations/port_to_wire_name_generator.py +0 -12
- /classiq/{interface/generator/credit_risk_example → qmod/semantics}/__init__.py +0 -0
- /classiq/{interface/model/resolvers → qmod/semantics/validation}/__init__.py +0 -0
- {classiq-0.42.2.dist-info → classiq-0.43.1.dist-info}/WHEEL +0 -0
@@ -1,4 +1,3 @@
|
|
1
|
-
from abc import abstractmethod
|
2
1
|
from typing import Any, Dict, List, Literal, Union
|
3
2
|
|
4
3
|
import pydantic
|
@@ -7,11 +6,6 @@ from sympy import IndexedBase, Symbol
|
|
7
6
|
from typing_extensions import Annotated
|
8
7
|
|
9
8
|
from classiq.interface.ast_node import HashableASTNode
|
10
|
-
from classiq.interface.generator.expressions.enums.classical_enum import ClassicalEnum
|
11
|
-
from classiq.interface.generator.expressions.enums.ladder_operator import (
|
12
|
-
LadderOperator as LadderOperatorEnum,
|
13
|
-
)
|
14
|
-
from classiq.interface.generator.expressions.enums.pauli import Pauli as PauliEnum
|
15
9
|
from classiq.interface.generator.expressions.expression_types import RuntimeExpression
|
16
10
|
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
17
11
|
|
@@ -24,13 +18,6 @@ class ClassicalType(HashableASTNode):
|
|
24
18
|
def as_symbolic(self, name: str) -> Union[NamedSymbol, List[NamedSymbol]]:
|
25
19
|
return Symbol(name)
|
26
20
|
|
27
|
-
@property
|
28
|
-
@abstractmethod
|
29
|
-
def default_value(self) -> Any:
|
30
|
-
raise NotImplementedError(
|
31
|
-
f"{self.__class__.__name__} type has no default value"
|
32
|
-
)
|
33
|
-
|
34
21
|
@property
|
35
22
|
def qmod_type(self) -> type:
|
36
23
|
raise NotImplementedError(
|
@@ -44,20 +31,12 @@ class ClassicalType(HashableASTNode):
|
|
44
31
|
return str(type(self).__name__)
|
45
32
|
|
46
33
|
|
47
|
-
class EnumType(ClassicalType):
|
48
|
-
pass
|
49
|
-
|
50
|
-
|
51
34
|
class Integer(ClassicalType):
|
52
35
|
kind: Literal["int"]
|
53
36
|
|
54
37
|
def as_symbolic(self, name: str) -> Symbol:
|
55
38
|
return Symbol(name, integer=True)
|
56
39
|
|
57
|
-
@property
|
58
|
-
def default_value(self) -> int:
|
59
|
-
return 0
|
60
|
-
|
61
40
|
@pydantic.root_validator(pre=True)
|
62
41
|
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
63
42
|
return values_with_discriminator(values, "kind", "int")
|
@@ -75,10 +54,6 @@ class Real(ClassicalType):
|
|
75
54
|
def as_symbolic(self, name: str) -> Symbol:
|
76
55
|
return Symbol(name, real=True)
|
77
56
|
|
78
|
-
@property
|
79
|
-
def default_value(self) -> float:
|
80
|
-
return 0.0
|
81
|
-
|
82
57
|
@pydantic.root_validator(pre=True)
|
83
58
|
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
84
59
|
return values_with_discriminator(values, "kind", "real")
|
@@ -93,10 +68,6 @@ class Real(ClassicalType):
|
|
93
68
|
class Bool(ClassicalType):
|
94
69
|
kind: Literal["bool"]
|
95
70
|
|
96
|
-
@property
|
97
|
-
def default_value(self) -> bool:
|
98
|
-
return False
|
99
|
-
|
100
71
|
@pydantic.root_validator(pre=True)
|
101
72
|
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
102
73
|
return values_with_discriminator(values, "kind", "bool")
|
@@ -115,10 +86,6 @@ class ClassicalList(ClassicalType):
|
|
115
86
|
def as_symbolic(self, name: str) -> Symbol:
|
116
87
|
return IndexedBase(name)
|
117
88
|
|
118
|
-
@property
|
119
|
-
def default_value(self) -> List:
|
120
|
-
return []
|
121
|
-
|
122
89
|
@pydantic.root_validator(pre=True)
|
123
90
|
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
124
91
|
return values_with_discriminator(values, "kind", "list")
|
@@ -130,45 +97,31 @@ class ClassicalList(ClassicalType):
|
|
130
97
|
return CArray[self.element_type.qmod_type] # type:ignore[name-defined]
|
131
98
|
|
132
99
|
|
133
|
-
class Pauli(
|
100
|
+
class Pauli(ClassicalType):
|
134
101
|
kind: Literal["pauli"]
|
135
102
|
|
136
|
-
@property
|
137
|
-
def default_value(self) -> PauliEnum:
|
138
|
-
return PauliEnum.I
|
139
|
-
|
140
103
|
@pydantic.root_validator(pre=True)
|
141
104
|
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
142
105
|
return values_with_discriminator(values, "kind", "pauli")
|
143
106
|
|
144
107
|
@property
|
145
108
|
def qmod_type(self) -> type:
|
146
|
-
|
109
|
+
from classiq.qmod.builtins.enums import Pauli
|
110
|
+
|
111
|
+
return Pauli
|
147
112
|
|
148
113
|
|
149
114
|
class StructMetaType(ClassicalType):
|
150
115
|
kind: Literal["type_proxy"]
|
151
116
|
|
152
|
-
@property
|
153
|
-
def default_value(self) -> Any:
|
154
|
-
return super().default_value
|
155
|
-
|
156
117
|
@pydantic.root_validator(pre=True)
|
157
118
|
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
158
119
|
return values_with_discriminator(values, "kind", "type_proxy")
|
159
120
|
|
160
121
|
|
161
|
-
class
|
162
|
-
pass
|
163
|
-
|
164
|
-
|
165
|
-
class Struct(ClassicalType):
|
122
|
+
class TypeName(ClassicalType):
|
166
123
|
kind: Literal["struct_instance"]
|
167
|
-
name: str = pydantic.Field(description="The
|
168
|
-
|
169
|
-
@property
|
170
|
-
def default_value(self) -> Any:
|
171
|
-
return super().default_value
|
124
|
+
name: str = pydantic.Field(description="The type name of the instance")
|
172
125
|
|
173
126
|
@pydantic.root_validator(pre=True)
|
174
127
|
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
@@ -176,7 +129,15 @@ class Struct(ClassicalType):
|
|
176
129
|
|
177
130
|
@property
|
178
131
|
def qmod_type(self) -> type:
|
179
|
-
return type(self.name, (
|
132
|
+
return type(self.name, (TypeName,), dict())
|
133
|
+
|
134
|
+
|
135
|
+
class Enum(TypeName):
|
136
|
+
pass
|
137
|
+
|
138
|
+
|
139
|
+
class Struct(TypeName):
|
140
|
+
pass
|
180
141
|
|
181
142
|
|
182
143
|
class ClassicalArray(ClassicalType):
|
@@ -187,10 +148,6 @@ class ClassicalArray(ClassicalType):
|
|
187
148
|
def as_symbolic(self, name: str) -> list:
|
188
149
|
return [self.element_type.as_symbolic(f"{name}_{i}") for i in range(self.size)]
|
189
150
|
|
190
|
-
@property
|
191
|
-
def default_value(self) -> Any:
|
192
|
-
return super().default_value
|
193
|
-
|
194
151
|
@pydantic.root_validator(pre=True)
|
195
152
|
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
196
153
|
return values_with_discriminator(values, "kind", "array")
|
@@ -205,9 +162,7 @@ class ClassicalArray(ClassicalType):
|
|
205
162
|
|
206
163
|
|
207
164
|
class OpaqueHandle(ClassicalType):
|
208
|
-
|
209
|
-
def default_value(self) -> int:
|
210
|
-
return 0
|
165
|
+
pass
|
211
166
|
|
212
167
|
|
213
168
|
class VQEResult(OpaqueHandle):
|
@@ -242,20 +197,18 @@ class IQAERes(OpaqueHandle):
|
|
242
197
|
return values_with_discriminator(values, "kind", "iqae_result")
|
243
198
|
|
244
199
|
|
245
|
-
class LadderOperator(
|
200
|
+
class LadderOperator(ClassicalType):
|
246
201
|
kind: Literal["ladder_operator"]
|
247
202
|
|
248
|
-
@property
|
249
|
-
def default_value(self) -> LadderOperatorEnum:
|
250
|
-
return LadderOperatorEnum.PLUS
|
251
|
-
|
252
203
|
@pydantic.root_validator(pre=True)
|
253
204
|
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
254
205
|
return values_with_discriminator(values, "kind", "ladder_operator")
|
255
206
|
|
256
207
|
@property
|
257
208
|
def qmod_type(self) -> type:
|
258
|
-
|
209
|
+
from classiq.qmod.builtins.enums import LadderOperator
|
210
|
+
|
211
|
+
return LadderOperator
|
259
212
|
|
260
213
|
|
261
214
|
ConcreteClassicalType = Annotated[
|
@@ -266,7 +219,7 @@ ConcreteClassicalType = Annotated[
|
|
266
219
|
ClassicalList,
|
267
220
|
Pauli,
|
268
221
|
StructMetaType,
|
269
|
-
|
222
|
+
TypeName,
|
270
223
|
ClassicalArray,
|
271
224
|
VQEResult,
|
272
225
|
Histogram,
|
@@ -279,7 +232,7 @@ ConcreteClassicalType = Annotated[
|
|
279
232
|
ClassicalList.update_forward_refs()
|
280
233
|
ClassicalArray.update_forward_refs()
|
281
234
|
|
282
|
-
PythonClassicalTypes = (int, float, bool, list,
|
235
|
+
PythonClassicalTypes = (int, float, bool, list, Enum)
|
283
236
|
|
284
237
|
|
285
238
|
def as_symbolic(symbols: Dict[str, ClassicalType]) -> Dict[str, RuntimeExpression]:
|
@@ -1,8 +1,5 @@
|
|
1
1
|
from typing import Any
|
2
2
|
|
3
|
-
import pydantic
|
4
|
-
from pydantic import BaseModel
|
5
|
-
|
6
3
|
from classiq.interface.generator.function_params import PortDirection
|
7
4
|
|
8
5
|
from classiq._internals.enum_utils import StrEnum
|
@@ -39,11 +36,3 @@ class PortDeclarationDirection(StrEnum):
|
|
39
36
|
cls, port_direction: PortDirection
|
40
37
|
) -> "PortDeclarationDirection":
|
41
38
|
return cls(port_direction.value)
|
42
|
-
|
43
|
-
|
44
|
-
class SynthesisPortDeclaration(BaseModel):
|
45
|
-
name: str
|
46
|
-
size: int
|
47
|
-
direction: PortDeclarationDirection
|
48
|
-
is_signed: bool = pydantic.Field(default=False)
|
49
|
-
fraction_places: int = pydantic.Field(default=0)
|
@@ -5,7 +5,6 @@ from classiq.interface.generator.model.constraints import (
|
|
5
5
|
OptimizationParameter,
|
6
6
|
TranspilerBasisGates,
|
7
7
|
)
|
8
|
-
from classiq.interface.generator.model.model import SynthesisModel
|
9
8
|
from classiq.interface.generator.model.preferences import (
|
10
9
|
CustomHardwareSettings,
|
11
10
|
Preferences,
|
@@ -1,68 +1,36 @@
|
|
1
1
|
from abc import ABC
|
2
|
-
from typing import
|
2
|
+
from typing import List
|
3
3
|
|
4
4
|
import pydantic
|
5
5
|
|
6
6
|
from classiq.interface.executor.execution_preferences import ExecutionPreferences
|
7
7
|
from classiq.interface.generator.constant import Constant
|
8
|
-
from classiq.interface.generator.function_params import ArithmeticIODict
|
9
|
-
from classiq.interface.generator.
|
10
|
-
SynthesisNativeFunctionDefinition,
|
11
|
-
SynthesisPortDeclaration,
|
12
|
-
SynthesisQuantumFunctionDeclaration,
|
13
|
-
)
|
14
|
-
from classiq.interface.generator.functions.port_declaration import (
|
15
|
-
PortDeclarationDirection,
|
16
|
-
)
|
17
|
-
from classiq.interface.generator.model.constraints import Constraints
|
18
|
-
from classiq.interface.generator.model.preferences.preferences import Preferences
|
19
|
-
from classiq.interface.generator.model.quantum_register import QReg, QRegGenericAlias
|
20
|
-
from classiq.interface.generator.quantum_function_call import (
|
21
|
-
SUFFIX_RANDOMIZER,
|
22
|
-
SynthesisQuantumFunctionCall,
|
23
|
-
WireDict,
|
24
|
-
WireName,
|
25
|
-
)
|
8
|
+
from classiq.interface.generator.function_params import ArithmeticIODict
|
9
|
+
from classiq.interface.generator.types.enum_declaration import EnumDeclaration
|
26
10
|
from classiq.interface.generator.types.struct_declaration import StructDeclaration
|
27
|
-
from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
|
28
11
|
from classiq.interface.helpers.validation_helpers import is_list_unique
|
29
12
|
from classiq.interface.helpers.versioned_model import VersionedModel
|
30
13
|
|
31
|
-
from classiq import ForeignFunctionDefinition as SynthesisForeignFunctionDefinition
|
32
14
|
from classiq.exceptions import ClassiqValueError
|
33
15
|
|
34
|
-
MAIN_FUNCTION_NAME = "main"
|
35
|
-
CLASSICAL_ENTRY_FUNCTION_NAME = "cmain"
|
36
|
-
|
37
|
-
DEFAULT_PORT_SIZE = 1
|
38
|
-
|
39
|
-
|
40
|
-
SerializedModel = NewType("SerializedModel", str)
|
41
|
-
|
42
|
-
# We need to define ConcreteFunctionData so pydantic will know
|
43
|
-
# what class to use when deserializing from object (pydantic attempts to
|
44
|
-
# parse as each of the classes in the Union, in order).
|
45
|
-
ConcreteFunctionDefinition = Union[
|
46
|
-
SynthesisForeignFunctionDefinition, SynthesisNativeFunctionDefinition
|
47
|
-
]
|
48
|
-
|
49
16
|
TYPE_LIBRARY_DUPLICATED_TYPE_NAMES = (
|
50
17
|
"Cannot have multiple struct types with the same name"
|
51
18
|
)
|
52
19
|
|
53
20
|
|
54
|
-
def _create_default_functions() -> List[ConcreteFunctionDefinition]:
|
55
|
-
return [SynthesisNativeFunctionDefinition(name=MAIN_FUNCTION_NAME)]
|
56
|
-
|
57
|
-
|
58
21
|
class ClassiqBaseModel(VersionedModel, ABC):
|
59
22
|
"""
|
60
23
|
All the relevant data for evaluating execution in one place.
|
61
24
|
"""
|
62
25
|
|
26
|
+
enums: List[EnumDeclaration] = pydantic.Field(
|
27
|
+
default_factory=list,
|
28
|
+
description="user-defined enums",
|
29
|
+
)
|
30
|
+
|
63
31
|
types: List[StructDeclaration] = pydantic.Field(
|
64
32
|
default_factory=list,
|
65
|
-
description="
|
33
|
+
description="user-defined structs",
|
66
34
|
)
|
67
35
|
|
68
36
|
constants: List[Constant] = pydantic.Field(
|
@@ -90,147 +58,3 @@ class ExecutionModel(ClassiqBaseModel):
|
|
90
58
|
description="Mapping between a measured register name and its arithmetic type",
|
91
59
|
default_factory=dict,
|
92
60
|
)
|
93
|
-
|
94
|
-
|
95
|
-
class SynthesisModel(ClassiqBaseModel):
|
96
|
-
"""
|
97
|
-
All the relevant data for generating quantum circuit in one place.
|
98
|
-
"""
|
99
|
-
|
100
|
-
kind: Literal["synthesis"] = pydantic.Field(default="synthesis")
|
101
|
-
|
102
|
-
# Must be validated before logic_flow
|
103
|
-
functions: List[ConcreteFunctionDefinition] = pydantic.Field(
|
104
|
-
default_factory=_create_default_functions,
|
105
|
-
description="The quantum functions of the model.",
|
106
|
-
)
|
107
|
-
|
108
|
-
constraints: Constraints = pydantic.Field(default_factory=Constraints)
|
109
|
-
preferences: Preferences = pydantic.Field(default_factory=Preferences)
|
110
|
-
|
111
|
-
def __init__(
|
112
|
-
self,
|
113
|
-
*,
|
114
|
-
body: Optional[List[SynthesisQuantumFunctionCall]] = None,
|
115
|
-
inputs: Optional[WireDict] = None,
|
116
|
-
outputs: Optional[WireDict] = None,
|
117
|
-
**kwargs: Any,
|
118
|
-
) -> None:
|
119
|
-
super().__init__(**kwargs)
|
120
|
-
if body:
|
121
|
-
self.main_func.body.extend(body)
|
122
|
-
if inputs:
|
123
|
-
self.set_inputs(
|
124
|
-
{
|
125
|
-
name: QRegGenericAlias(
|
126
|
-
QReg(DEFAULT_PORT_SIZE), (DEFAULT_PORT_SIZE, 0)
|
127
|
-
)
|
128
|
-
for name in inputs.keys()
|
129
|
-
},
|
130
|
-
inputs,
|
131
|
-
)
|
132
|
-
if outputs:
|
133
|
-
self.set_outputs(
|
134
|
-
{name: QReg(DEFAULT_PORT_SIZE) for name in outputs.keys()}, outputs
|
135
|
-
)
|
136
|
-
|
137
|
-
@property
|
138
|
-
def main_func(self) -> SynthesisNativeFunctionDefinition:
|
139
|
-
return self.function_dict[MAIN_FUNCTION_NAME] # type:ignore[return-value]
|
140
|
-
|
141
|
-
@property
|
142
|
-
def body(self) -> List[SynthesisQuantumFunctionCall]:
|
143
|
-
return self.main_func.body
|
144
|
-
|
145
|
-
@property
|
146
|
-
def inputs(self) -> WireDict:
|
147
|
-
return self.main_func.input_ports_wiring
|
148
|
-
|
149
|
-
def set_inputs(
|
150
|
-
self,
|
151
|
-
inputs: Mapping[IOName, QRegGenericAlias],
|
152
|
-
input_wiring: Mapping[IOName, WireName],
|
153
|
-
) -> None:
|
154
|
-
self._update_main_declarations(inputs, PortDeclarationDirection.Input)
|
155
|
-
self.main_func.input_ports_wiring.update(input_wiring)
|
156
|
-
|
157
|
-
@property
|
158
|
-
def outputs(self) -> WireDict:
|
159
|
-
return self.main_func.output_ports_wiring
|
160
|
-
|
161
|
-
def set_outputs(
|
162
|
-
self, outputs: Mapping[IOName, QReg], output_wiring: Mapping[IOName, WireName]
|
163
|
-
) -> None:
|
164
|
-
self._update_main_declarations(outputs, PortDeclarationDirection.Output)
|
165
|
-
self.main_func.output_ports_wiring.update(output_wiring)
|
166
|
-
|
167
|
-
@pydantic.validator("preferences", always=True)
|
168
|
-
def _seed_suffix_randomizer(cls, preferences: Preferences) -> Preferences:
|
169
|
-
SUFFIX_RANDOMIZER.seed(preferences.random_seed)
|
170
|
-
return preferences
|
171
|
-
|
172
|
-
def _get_qualified_direction(
|
173
|
-
self, port_name: str, direction: PortDeclarationDirection
|
174
|
-
) -> PortDeclarationDirection:
|
175
|
-
if port_name in self.main_func.port_declarations:
|
176
|
-
return PortDeclarationDirection.Inout
|
177
|
-
return direction
|
178
|
-
|
179
|
-
def _update_main_declarations(
|
180
|
-
self,
|
181
|
-
value: Union[Mapping[IOName, QReg], Mapping[IOName, QRegGenericAlias]],
|
182
|
-
direction: PortDeclarationDirection,
|
183
|
-
) -> None:
|
184
|
-
for port_name, register in value.items():
|
185
|
-
if isinstance(register, QReg):
|
186
|
-
size = len(register)
|
187
|
-
is_signed = getattr(register, "is_signed", False) or False
|
188
|
-
fraction_places = getattr(register, "fraction_places", 0) or 0
|
189
|
-
else:
|
190
|
-
size = register.size if register.size is not None else DEFAULT_PORT_SIZE
|
191
|
-
is_signed = False
|
192
|
-
fraction_places = (
|
193
|
-
register.fraction_places
|
194
|
-
if register.fraction_places is not None
|
195
|
-
else 0
|
196
|
-
)
|
197
|
-
|
198
|
-
self.main_func.port_declarations[port_name] = SynthesisPortDeclaration(
|
199
|
-
name=port_name,
|
200
|
-
size=size,
|
201
|
-
direction=self._get_qualified_direction(port_name, direction),
|
202
|
-
is_signed=is_signed,
|
203
|
-
fraction_places=fraction_places,
|
204
|
-
)
|
205
|
-
|
206
|
-
@property
|
207
|
-
def function_dict(self) -> Dict[str, SynthesisQuantumFunctionDeclaration]:
|
208
|
-
return nameables_to_dict(self.functions)
|
209
|
-
|
210
|
-
@pydantic.validator("functions", each_item=True)
|
211
|
-
def validate_static_correctness(
|
212
|
-
cls, func_def: ConcreteFunctionDefinition
|
213
|
-
) -> ConcreteFunctionDefinition:
|
214
|
-
if isinstance(func_def, SynthesisNativeFunctionDefinition):
|
215
|
-
func_def.validate_body()
|
216
|
-
return func_def
|
217
|
-
|
218
|
-
@pydantic.validator("functions")
|
219
|
-
def validate_main_function_exists(
|
220
|
-
cls, func_defs: List[ConcreteFunctionDefinition]
|
221
|
-
) -> List[ConcreteFunctionDefinition]:
|
222
|
-
if MAIN_FUNCTION_NAME not in {func.name for func in func_defs}:
|
223
|
-
raise ClassiqValueError("The model must contain a `main` function")
|
224
|
-
return func_defs
|
225
|
-
|
226
|
-
def get_model(self) -> SerializedModel:
|
227
|
-
return SerializedModel(self.json(exclude_defaults=True, indent=2))
|
228
|
-
|
229
|
-
def classical_model(self) -> ExecutionModel:
|
230
|
-
return ExecutionModel(
|
231
|
-
types=self.types,
|
232
|
-
constants=self.constants,
|
233
|
-
classical_execution_code=self.classical_execution_code,
|
234
|
-
execution_preferences=self.execution_preferences,
|
235
|
-
circuit_outputs=self.main_func.outputs,
|
236
|
-
)
|
@@ -1,9 +1,11 @@
|
|
1
|
-
from typing import Dict, Optional, Set
|
1
|
+
from typing import Dict, Final, Optional, Set
|
2
2
|
|
3
3
|
import pydantic
|
4
4
|
|
5
5
|
from classiq.interface.backend.pydantic_backend import PydanticExecutionParameter
|
6
6
|
|
7
|
+
CPARAM_EXECUTION_SUFFIX: Final[str] = "_param"
|
8
|
+
|
7
9
|
|
8
10
|
class FunctionExecutionData(pydantic.BaseModel):
|
9
11
|
power_parameter: Optional[PydanticExecutionParameter] = pydantic.Field(default=None)
|
@@ -0,0 +1,69 @@
|
|
1
|
+
from classiq.interface.chemistry.elements import ELEMENTS
|
2
|
+
from classiq.interface.chemistry.ground_state_problem import FermionMapping
|
3
|
+
from classiq.interface.generator.types.enum_declaration import EnumDeclaration
|
4
|
+
|
5
|
+
ELEMENT = EnumDeclaration(
|
6
|
+
name="Element", members={element: idx for idx, element in enumerate(ELEMENTS)}
|
7
|
+
)
|
8
|
+
|
9
|
+
FERMION_MAPPING = EnumDeclaration(
|
10
|
+
name="FermionMapping",
|
11
|
+
members={
|
12
|
+
mapping.name: idx # type:ignore[attr-defined]
|
13
|
+
for idx, mapping in enumerate(FermionMapping)
|
14
|
+
},
|
15
|
+
)
|
16
|
+
|
17
|
+
FINANCE_FUNCTION_TYPE = EnumDeclaration(
|
18
|
+
name="FinanceFunctionType",
|
19
|
+
members={
|
20
|
+
"VAR": 0,
|
21
|
+
"SHORTFALL": 1,
|
22
|
+
"X_SQUARE": 2,
|
23
|
+
"EUROPEAN_CALL_OPTION": 3,
|
24
|
+
},
|
25
|
+
)
|
26
|
+
|
27
|
+
LADDER_OPERATOR = EnumDeclaration(
|
28
|
+
name="LadderOperator",
|
29
|
+
members={
|
30
|
+
"PLUS": 0,
|
31
|
+
"MINUS": 1,
|
32
|
+
},
|
33
|
+
)
|
34
|
+
|
35
|
+
OPTIMIZER = EnumDeclaration(
|
36
|
+
name="Optimizer",
|
37
|
+
members={
|
38
|
+
"COBYLA": 1,
|
39
|
+
"SPSA": 2,
|
40
|
+
"L_BFGS_B": 3,
|
41
|
+
"NELDER_MEAD": 4,
|
42
|
+
"ADAM": 5,
|
43
|
+
},
|
44
|
+
)
|
45
|
+
|
46
|
+
PAULI = EnumDeclaration(
|
47
|
+
name="Pauli",
|
48
|
+
members={
|
49
|
+
"I": 0,
|
50
|
+
"X": 1,
|
51
|
+
"Y": 2,
|
52
|
+
"Z": 3,
|
53
|
+
},
|
54
|
+
)
|
55
|
+
|
56
|
+
QSVM_FEATURE_MAP_ENTANGLEMENT = EnumDeclaration(
|
57
|
+
name="QSVMFeatureMapEntanglement",
|
58
|
+
members={
|
59
|
+
"FULL": 0,
|
60
|
+
"LINEAR": 1,
|
61
|
+
"CIRCULAR": 2,
|
62
|
+
"SCA": 3,
|
63
|
+
"PAIRWISE": 4,
|
64
|
+
},
|
65
|
+
)
|
66
|
+
|
67
|
+
for enum_decl in list(vars().values()):
|
68
|
+
if isinstance(enum_decl, EnumDeclaration):
|
69
|
+
EnumDeclaration.BUILTIN_ENUM_DECLARATIONS[enum_decl.name] = enum_decl
|
@@ -2,7 +2,7 @@ import functools
|
|
2
2
|
|
3
3
|
from classiq.interface.generator.functions.classical_type import (
|
4
4
|
ClassicalList,
|
5
|
-
|
5
|
+
Enum,
|
6
6
|
Real,
|
7
7
|
Struct,
|
8
8
|
)
|
@@ -12,7 +12,7 @@ from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
|
|
12
12
|
PAULI_TERM = StructDeclaration(
|
13
13
|
name="PauliTerm",
|
14
14
|
variables={
|
15
|
-
"pauli": ClassicalList(element_type=Pauli
|
15
|
+
"pauli": ClassicalList(element_type=Enum(name="Pauli")),
|
16
16
|
"coefficient": Real(),
|
17
17
|
},
|
18
18
|
)
|
@@ -0,0 +1,57 @@
|
|
1
|
+
from collections import Counter
|
2
|
+
from enum import Enum, EnumMeta, IntEnum
|
3
|
+
from typing import ClassVar, Dict
|
4
|
+
|
5
|
+
import pydantic
|
6
|
+
|
7
|
+
from classiq.interface.ast_node import HashableASTNode
|
8
|
+
|
9
|
+
from classiq.exceptions import ClassiqValueError
|
10
|
+
|
11
|
+
|
12
|
+
class EnumDeclaration(HashableASTNode):
|
13
|
+
name: str
|
14
|
+
|
15
|
+
members: Dict[str, int] = pydantic.Field(
|
16
|
+
default_factory=dict,
|
17
|
+
description="Dictionary of member names and their values",
|
18
|
+
)
|
19
|
+
|
20
|
+
BUILTIN_ENUM_DECLARATIONS: ClassVar[Dict[str, "EnumDeclaration"]] = {}
|
21
|
+
|
22
|
+
@pydantic.validator("members")
|
23
|
+
def _validate_members(cls, members: Dict[str, int]) -> Dict[str, int]:
|
24
|
+
underscore_members = [
|
25
|
+
member for member in members.keys() if member.startswith("_")
|
26
|
+
]
|
27
|
+
if len(underscore_members) > 0:
|
28
|
+
raise ClassiqValueError(
|
29
|
+
f"Enum member names must not start with an underscore. The offending "
|
30
|
+
f"members: {underscore_members}"
|
31
|
+
)
|
32
|
+
|
33
|
+
counter = Counter(members.values())
|
34
|
+
repeating_members = [
|
35
|
+
member for member, value in members.items() if counter[value] > 1
|
36
|
+
]
|
37
|
+
if len(repeating_members) > 0:
|
38
|
+
raise ClassiqValueError(
|
39
|
+
f"Cannot assign the same value to more than one enum member. The "
|
40
|
+
f"offending members: {repeating_members}"
|
41
|
+
)
|
42
|
+
|
43
|
+
return members
|
44
|
+
|
45
|
+
def create_enum(self) -> IntEnum:
|
46
|
+
return IntEnum(self.name, self.members)
|
47
|
+
|
48
|
+
|
49
|
+
def declaration_from_enum(enum_type: EnumMeta) -> EnumDeclaration:
|
50
|
+
members: list[Enum] = list(enum_type)
|
51
|
+
return EnumDeclaration(
|
52
|
+
name=enum_type.__name__,
|
53
|
+
members={
|
54
|
+
member.name: member.value
|
55
|
+
for member in sorted(members, key=lambda member: member.value)
|
56
|
+
},
|
57
|
+
)
|