classiq 0.43.3__py3-none-any.whl → 0.44.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 +7 -1
- classiq/_internals/client.py +4 -7
- classiq/_internals/host_checker.py +34 -12
- classiq/_internals/jobs.py +2 -2
- classiq/applications/chemistry/chemistry_model_constructor.py +12 -6
- classiq/applications/combinatorial_helpers/allowed_constraints.py +4 -1
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +1 -1
- classiq/applications/finance/finance_model_constructor.py +3 -2
- classiq/applications/grover/grover_model_constructor.py +7 -5
- classiq/applications/hamiltonian/__init__.py +0 -0
- classiq/applications/hamiltonian/pauli_decomposition.py +113 -0
- classiq/applications/qnn/qlayer.py +1 -1
- classiq/exceptions.py +4 -0
- classiq/interface/_version.py +1 -1
- classiq/interface/ast_node.py +1 -18
- classiq/interface/backend/backend_preferences.py +10 -16
- classiq/interface/backend/ionq/ionq_quantum_program.py +1 -1
- classiq/interface/backend/pydantic_backend.py +0 -5
- classiq/interface/backend/quantum_backend_providers.py +3 -2
- classiq/interface/chemistry/operator.py +5 -1
- classiq/interface/debug_info/__init__.py +0 -0
- classiq/interface/debug_info/debug_info.py +32 -0
- classiq/interface/executor/execution_preferences.py +1 -45
- classiq/interface/executor/result.py +25 -12
- classiq/interface/generator/application_apis/arithmetic_declarations.py +8 -5
- classiq/interface/generator/application_apis/chemistry_declarations.py +78 -60
- classiq/interface/generator/application_apis/combinatorial_optimization_declarations.py +19 -10
- classiq/interface/generator/application_apis/entangler_declarations.py +11 -6
- classiq/interface/generator/application_apis/finance_declarations.py +36 -22
- classiq/interface/generator/application_apis/qsvm_declarations.py +21 -15
- classiq/interface/generator/arith/arithmetic_expression_abc.py +21 -1
- classiq/interface/generator/arith/binary_ops.py +5 -4
- classiq/interface/generator/arith/extremum_operations.py +43 -19
- classiq/interface/generator/constant.py +1 -1
- classiq/interface/generator/expressions/atomic_expression_functions.py +1 -0
- classiq/interface/generator/expressions/expression_constants.py +3 -1
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +52 -66
- classiq/interface/generator/expressions/qmod_qstruct_proxy.py +35 -0
- classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
- classiq/interface/generator/functions/builtins/core_library/__init__.py +4 -2
- classiq/interface/generator/functions/builtins/core_library/atomic_quantum_functions.py +41 -41
- classiq/interface/generator/functions/builtins/core_library/exponentiation_functions.py +52 -42
- classiq/interface/generator/functions/builtins/open_lib_functions.py +1095 -3347
- classiq/interface/generator/functions/builtins/quantum_operators.py +9 -22
- classiq/interface/generator/functions/classical_function_declaration.py +14 -6
- classiq/interface/generator/functions/classical_type.py +7 -76
- classiq/interface/generator/functions/concrete_types.py +55 -0
- classiq/interface/generator/functions/function_declaration.py +10 -10
- classiq/interface/generator/functions/type_name.py +104 -0
- classiq/interface/generator/generated_circuit_data.py +3 -3
- classiq/interface/generator/model/model.py +11 -0
- classiq/interface/generator/model/preferences/preferences.py +5 -0
- classiq/interface/generator/quantum_function_call.py +3 -0
- classiq/interface/generator/quantum_program.py +2 -2
- classiq/interface/generator/register_role.py +7 -1
- classiq/interface/generator/synthesis_metadata/synthesis_execution_data.py +1 -3
- classiq/interface/generator/types/builtin_struct_declarations/pauli_struct_declarations.py +1 -2
- classiq/interface/generator/types/qstruct_declaration.py +17 -0
- classiq/interface/generator/types/struct_declaration.py +1 -1
- classiq/interface/helpers/validation_helpers.py +1 -17
- classiq/interface/ide/visual_model.py +9 -2
- classiq/interface/interface_version.py +1 -0
- classiq/interface/model/bind_operation.py +25 -5
- classiq/interface/model/classical_parameter_declaration.py +8 -5
- classiq/interface/model/control.py +5 -5
- classiq/interface/model/handle_binding.py +185 -12
- classiq/interface/model/inplace_binary_operation.py +16 -4
- classiq/interface/model/model.py +28 -5
- classiq/interface/model/native_function_definition.py +8 -4
- classiq/interface/model/parameter.py +14 -0
- classiq/interface/model/port_declaration.py +20 -2
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +21 -6
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +30 -6
- classiq/interface/model/quantum_expressions/quantum_expression.py +4 -9
- classiq/interface/model/quantum_function_call.py +135 -192
- classiq/interface/model/quantum_function_declaration.py +147 -165
- classiq/interface/model/quantum_lambda_function.py +24 -6
- classiq/interface/model/quantum_statement.py +34 -8
- classiq/interface/model/quantum_type.py +61 -10
- classiq/interface/model/quantum_variable_declaration.py +1 -1
- classiq/interface/model/statement_block.py +2 -0
- classiq/interface/model/validation_handle.py +7 -0
- classiq/interface/server/global_versions.py +4 -4
- classiq/interface/server/routes.py +2 -0
- classiq/interface/source_reference.py +59 -0
- classiq/qmod/__init__.py +2 -3
- classiq/qmod/builtins/functions.py +39 -11
- classiq/qmod/builtins/operations.py +171 -40
- classiq/qmod/declaration_inferrer.py +99 -56
- classiq/qmod/expression_query.py +1 -1
- classiq/qmod/model_state_container.py +2 -0
- classiq/qmod/native/pretty_printer.py +71 -53
- classiq/qmod/pretty_print/pretty_printer.py +98 -52
- classiq/qmod/qfunc.py +11 -5
- classiq/qmod/qmod_parameter.py +1 -2
- classiq/qmod/qmod_variable.py +364 -172
- classiq/qmod/quantum_callable.py +3 -3
- classiq/qmod/quantum_expandable.py +119 -65
- classiq/qmod/quantum_function.py +15 -3
- classiq/qmod/semantics/annotation.py +12 -13
- classiq/qmod/semantics/error_manager.py +36 -10
- classiq/qmod/semantics/static_semantics_visitor.py +163 -75
- classiq/qmod/semantics/validation/func_call_validation.py +42 -96
- classiq/qmod/semantics/validation/handle_validation.py +85 -0
- classiq/qmod/semantics/validation/types_validation.py +108 -1
- classiq/qmod/type_attribute_remover.py +32 -0
- classiq/qmod/utilities.py +26 -5
- {classiq-0.43.3.dist-info → classiq-0.44.0.dist-info}/METADATA +3 -3
- {classiq-0.43.3.dist-info → classiq-0.44.0.dist-info}/RECORD +111 -99
- classiq/qmod/qmod_struct.py +0 -13
- /classiq/{interface/ide/show.py → show.py} +0 -0
- {classiq-0.43.3.dist-info → classiq-0.44.0.dist-info}/WHEEL +0 -0
@@ -1,35 +1,22 @@
|
|
1
|
-
from typing import Any
|
2
|
-
|
3
1
|
from classiq.interface.model.quantum_function_declaration import (
|
4
|
-
|
2
|
+
NamedParamsQuantumFunctionDeclaration,
|
5
3
|
QuantumOperandDeclaration,
|
6
4
|
)
|
7
5
|
|
8
|
-
|
9
|
-
def get_single_empty_operand_operator(
|
10
|
-
operator_name: str, **kwargs: Any
|
11
|
-
) -> QuantumFunctionDeclaration:
|
12
|
-
operand_field_name = "operand"
|
13
|
-
return QuantumFunctionDeclaration(
|
14
|
-
name=operator_name,
|
15
|
-
operand_declarations={
|
16
|
-
operand_field_name: QuantumOperandDeclaration(name=operand_field_name)
|
17
|
-
},
|
18
|
-
**kwargs,
|
19
|
-
)
|
20
|
-
|
21
|
-
|
22
|
-
PERMUTE_OPERATOR = QuantumFunctionDeclaration(
|
6
|
+
PERMUTE_OPERATOR = NamedParamsQuantumFunctionDeclaration(
|
23
7
|
name="permute",
|
24
|
-
|
25
|
-
|
8
|
+
positional_arg_declarations=[
|
9
|
+
QuantumOperandDeclaration(
|
26
10
|
name="functions",
|
27
11
|
is_list=True,
|
28
12
|
)
|
29
|
-
|
13
|
+
],
|
30
14
|
)
|
31
15
|
|
32
|
-
APPLY_OPERATOR =
|
16
|
+
APPLY_OPERATOR = NamedParamsQuantumFunctionDeclaration(
|
17
|
+
name="apply",
|
18
|
+
positional_arg_declarations=[QuantumOperandDeclaration(name="operand")],
|
19
|
+
)
|
33
20
|
|
34
21
|
STD_QMOD_OPERATORS = [
|
35
22
|
PERMUTE_OPERATOR,
|
@@ -1,11 +1,14 @@
|
|
1
|
-
from typing import ClassVar, Dict,
|
1
|
+
from typing import ClassVar, Dict, Optional, Sequence
|
2
2
|
|
3
3
|
import pydantic
|
4
4
|
|
5
|
-
from classiq.interface.generator.functions.
|
5
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
|
6
6
|
from classiq.interface.generator.functions.function_declaration import (
|
7
7
|
FunctionDeclaration,
|
8
8
|
)
|
9
|
+
from classiq.interface.model.classical_parameter_declaration import (
|
10
|
+
ClassicalParameterDeclaration,
|
11
|
+
)
|
9
12
|
|
10
13
|
|
11
14
|
class ClassicalFunctionDeclaration(FunctionDeclaration):
|
@@ -13,6 +16,12 @@ class ClassicalFunctionDeclaration(FunctionDeclaration):
|
|
13
16
|
Facilitates the creation of a common classical function interface object.
|
14
17
|
"""
|
15
18
|
|
19
|
+
name: str
|
20
|
+
|
21
|
+
positional_parameters: Sequence[ClassicalParameterDeclaration] = pydantic.Field(
|
22
|
+
default_factory=list,
|
23
|
+
)
|
24
|
+
|
16
25
|
return_type: Optional[ConcreteClassicalType] = pydantic.Field(
|
17
26
|
description="The type of the classical value that is returned by the function (for classical functions)",
|
18
27
|
default=None,
|
@@ -26,10 +35,9 @@ class ClassicalFunctionDeclaration(FunctionDeclaration):
|
|
26
35
|
Dict[str, "ClassicalFunctionDeclaration"]
|
27
36
|
] = {}
|
28
37
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
pass
|
38
|
+
@property
|
39
|
+
def param_decls(self) -> Sequence[ClassicalParameterDeclaration]:
|
40
|
+
return self.positional_parameters
|
33
41
|
|
34
42
|
|
35
43
|
ClassicalFunctionDeclaration.update_forward_refs()
|
@@ -1,14 +1,18 @@
|
|
1
|
-
from typing import Any, Dict, List, Literal, Union
|
1
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Literal, Union
|
2
2
|
|
3
3
|
import pydantic
|
4
|
-
from pydantic import Extra
|
4
|
+
from pydantic import Extra
|
5
5
|
from sympy import IndexedBase, Symbol
|
6
|
-
from typing_extensions import Annotated
|
7
6
|
|
8
7
|
from classiq.interface.ast_node import HashableASTNode
|
9
8
|
from classiq.interface.generator.expressions.expression_types import RuntimeExpression
|
10
9
|
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
11
10
|
|
11
|
+
if TYPE_CHECKING:
|
12
|
+
from classiq.interface.generator.functions.concrete_types import (
|
13
|
+
ConcreteClassicalType,
|
14
|
+
)
|
15
|
+
|
12
16
|
CLASSICAL_ATTRIBUTES = {"len", "size", "is_signed", "fraction_digits"}
|
13
17
|
|
14
18
|
NamedSymbol = Union[IndexedBase, Symbol]
|
@@ -97,20 +101,6 @@ class ClassicalList(ClassicalType):
|
|
97
101
|
return CArray[self.element_type.qmod_type] # type:ignore[name-defined]
|
98
102
|
|
99
103
|
|
100
|
-
class Pauli(ClassicalType):
|
101
|
-
kind: Literal["pauli"]
|
102
|
-
|
103
|
-
@pydantic.root_validator(pre=True)
|
104
|
-
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
105
|
-
return values_with_discriminator(values, "kind", "pauli")
|
106
|
-
|
107
|
-
@property
|
108
|
-
def qmod_type(self) -> type:
|
109
|
-
from classiq.qmod.builtins.enums import Pauli
|
110
|
-
|
111
|
-
return Pauli
|
112
|
-
|
113
|
-
|
114
104
|
class StructMetaType(ClassicalType):
|
115
105
|
kind: Literal["type_proxy"]
|
116
106
|
|
@@ -119,27 +109,6 @@ class StructMetaType(ClassicalType):
|
|
119
109
|
return values_with_discriminator(values, "kind", "type_proxy")
|
120
110
|
|
121
111
|
|
122
|
-
class TypeName(ClassicalType):
|
123
|
-
kind: Literal["struct_instance"]
|
124
|
-
name: str = pydantic.Field(description="The type name of the instance")
|
125
|
-
|
126
|
-
@pydantic.root_validator(pre=True)
|
127
|
-
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
128
|
-
return values_with_discriminator(values, "kind", "struct_instance")
|
129
|
-
|
130
|
-
@property
|
131
|
-
def qmod_type(self) -> type:
|
132
|
-
return type(self.name, (TypeName,), dict())
|
133
|
-
|
134
|
-
|
135
|
-
class Enum(TypeName):
|
136
|
-
pass
|
137
|
-
|
138
|
-
|
139
|
-
class Struct(TypeName):
|
140
|
-
pass
|
141
|
-
|
142
|
-
|
143
112
|
class ClassicalArray(ClassicalType):
|
144
113
|
kind: Literal["array"]
|
145
114
|
element_type: "ConcreteClassicalType"
|
@@ -197,44 +166,6 @@ class IQAERes(OpaqueHandle):
|
|
197
166
|
return values_with_discriminator(values, "kind", "iqae_result")
|
198
167
|
|
199
168
|
|
200
|
-
class LadderOperator(ClassicalType):
|
201
|
-
kind: Literal["ladder_operator"]
|
202
|
-
|
203
|
-
@pydantic.root_validator(pre=True)
|
204
|
-
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
205
|
-
return values_with_discriminator(values, "kind", "ladder_operator")
|
206
|
-
|
207
|
-
@property
|
208
|
-
def qmod_type(self) -> type:
|
209
|
-
from classiq.qmod.builtins.enums import LadderOperator
|
210
|
-
|
211
|
-
return LadderOperator
|
212
|
-
|
213
|
-
|
214
|
-
ConcreteClassicalType = Annotated[
|
215
|
-
Union[
|
216
|
-
Integer,
|
217
|
-
Real,
|
218
|
-
Bool,
|
219
|
-
ClassicalList,
|
220
|
-
Pauli,
|
221
|
-
StructMetaType,
|
222
|
-
TypeName,
|
223
|
-
ClassicalArray,
|
224
|
-
VQEResult,
|
225
|
-
Histogram,
|
226
|
-
Estimation,
|
227
|
-
LadderOperator,
|
228
|
-
IQAERes,
|
229
|
-
],
|
230
|
-
Field(discriminator="kind"),
|
231
|
-
]
|
232
|
-
ClassicalList.update_forward_refs()
|
233
|
-
ClassicalArray.update_forward_refs()
|
234
|
-
|
235
|
-
PythonClassicalTypes = (int, float, bool, list, Enum)
|
236
|
-
|
237
|
-
|
238
169
|
def as_symbolic(symbols: Dict[str, ClassicalType]) -> Dict[str, RuntimeExpression]:
|
239
170
|
return {
|
240
171
|
param_name: param_type.as_symbolic(param_name)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
from typing import Union
|
2
|
+
|
3
|
+
from pydantic import Field
|
4
|
+
from typing_extensions import Annotated
|
5
|
+
|
6
|
+
from classiq.interface.generator.functions.classical_type import (
|
7
|
+
Bool,
|
8
|
+
ClassicalArray,
|
9
|
+
ClassicalList,
|
10
|
+
Estimation,
|
11
|
+
Histogram,
|
12
|
+
Integer,
|
13
|
+
IQAERes,
|
14
|
+
Real,
|
15
|
+
StructMetaType,
|
16
|
+
VQEResult,
|
17
|
+
)
|
18
|
+
from classiq.interface.generator.functions.type_name import Enum, TypeName
|
19
|
+
from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
|
20
|
+
from classiq.interface.model.quantum_type import (
|
21
|
+
QuantumBit,
|
22
|
+
QuantumBitvector,
|
23
|
+
QuantumNumeric,
|
24
|
+
RegisterQuantumType,
|
25
|
+
)
|
26
|
+
|
27
|
+
ConcreteClassicalType = Annotated[
|
28
|
+
Union[
|
29
|
+
Integer,
|
30
|
+
Real,
|
31
|
+
Bool,
|
32
|
+
ClassicalList,
|
33
|
+
StructMetaType,
|
34
|
+
TypeName,
|
35
|
+
ClassicalArray,
|
36
|
+
VQEResult,
|
37
|
+
Histogram,
|
38
|
+
Estimation,
|
39
|
+
IQAERes,
|
40
|
+
],
|
41
|
+
Field(discriminator="kind"),
|
42
|
+
]
|
43
|
+
ClassicalList.update_forward_refs(ConcreteClassicalType=ConcreteClassicalType)
|
44
|
+
ClassicalArray.update_forward_refs(ConcreteClassicalType=ConcreteClassicalType)
|
45
|
+
|
46
|
+
PythonClassicalTypes = (int, float, bool, list, Enum)
|
47
|
+
|
48
|
+
ConcreteQuantumType = Annotated[
|
49
|
+
Union[QuantumBit, QuantumBitvector, QuantumNumeric, TypeName],
|
50
|
+
Field(discriminator="kind", default_factory=QuantumBitvector),
|
51
|
+
]
|
52
|
+
QuantumBitvector.update_forward_refs(ConcreteQuantumType=ConcreteQuantumType)
|
53
|
+
TypeName.update_forward_refs(ConcreteQuantumType=ConcreteQuantumType)
|
54
|
+
QStructDeclaration.update_forward_refs(ConcreteQuantumType=ConcreteQuantumType)
|
55
|
+
RegisterQuantumType.update_forward_refs(ConcreteQuantumType=ConcreteQuantumType)
|
@@ -1,23 +1,23 @@
|
|
1
1
|
import abc
|
2
|
-
from typing import
|
2
|
+
from typing import Sequence
|
3
3
|
|
4
4
|
import pydantic
|
5
5
|
|
6
|
-
from classiq.interface.
|
7
|
-
|
6
|
+
from classiq.interface.model.classical_parameter_declaration import (
|
7
|
+
AnonClassicalParameterDeclaration,
|
8
|
+
)
|
9
|
+
from classiq.interface.model.parameter import Parameter
|
8
10
|
|
9
11
|
|
10
|
-
class FunctionDeclaration(
|
12
|
+
class FunctionDeclaration(Parameter, abc.ABC):
|
11
13
|
"""
|
12
14
|
Facilitates the creation of a common function interface object.
|
13
15
|
"""
|
14
16
|
|
15
|
-
|
16
|
-
|
17
|
-
param_decls
|
18
|
-
|
19
|
-
default_factory=dict,
|
20
|
-
)
|
17
|
+
@property
|
18
|
+
@abc.abstractmethod
|
19
|
+
def param_decls(self) -> Sequence[AnonClassicalParameterDeclaration]:
|
20
|
+
pass
|
21
21
|
|
22
22
|
class Config:
|
23
23
|
extra = pydantic.Extra.forbid
|
@@ -0,0 +1,104 @@
|
|
1
|
+
from typing import TYPE_CHECKING, Any, Dict, Literal, Mapping, Optional
|
2
|
+
|
3
|
+
import pydantic
|
4
|
+
|
5
|
+
from classiq.interface.generator.expressions.qmod_qstruct_proxy import QmodQStructProxy
|
6
|
+
from classiq.interface.generator.functions.classical_type import (
|
7
|
+
ClassicalType,
|
8
|
+
)
|
9
|
+
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
10
|
+
from classiq.interface.model.handle_binding import FieldHandleBinding, HandleBinding
|
11
|
+
from classiq.interface.model.quantum_type import (
|
12
|
+
QuantumType,
|
13
|
+
)
|
14
|
+
|
15
|
+
if TYPE_CHECKING:
|
16
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
|
17
|
+
|
18
|
+
from classiq.qmod.qmod_variable import QStruct
|
19
|
+
|
20
|
+
|
21
|
+
class TypeName(ClassicalType, QuantumType): # type:ignore[misc]
|
22
|
+
kind: Literal["struct_instance"]
|
23
|
+
name: str = pydantic.Field(description="The type name of the instance")
|
24
|
+
_assigned_fields: Optional[Mapping[str, "ConcreteQuantumType"]] = (
|
25
|
+
pydantic.PrivateAttr(default=None)
|
26
|
+
)
|
27
|
+
|
28
|
+
@pydantic.root_validator(pre=True)
|
29
|
+
def _set_kind(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
30
|
+
return values_with_discriminator(values, "kind", "struct_instance")
|
31
|
+
|
32
|
+
@property
|
33
|
+
def qmod_type(self) -> type:
|
34
|
+
return type(self.name, (TypeName,), dict())
|
35
|
+
|
36
|
+
def _update_size_in_bits_from_declaration(self) -> None:
|
37
|
+
fields_types = list(self.fields.values())
|
38
|
+
for field_type in fields_types:
|
39
|
+
field_type._update_size_in_bits_from_declaration()
|
40
|
+
if all(field_type.has_size_in_bits for field_type in fields_types):
|
41
|
+
self._size_in_bits = sum(
|
42
|
+
field_type.size_in_bits for field_type in fields_types
|
43
|
+
)
|
44
|
+
|
45
|
+
def get_proxy(self, handle: "HandleBinding") -> "QmodQStructProxy":
|
46
|
+
from classiq.interface.generator.expressions.qmod_qstruct_proxy import (
|
47
|
+
QmodQStructProxy,
|
48
|
+
)
|
49
|
+
|
50
|
+
return QmodQStructProxy(
|
51
|
+
handle=handle, struct_name=self.name, fields=self.fields
|
52
|
+
)
|
53
|
+
|
54
|
+
@property
|
55
|
+
def qmod_type_name(self) -> str:
|
56
|
+
return self.name
|
57
|
+
|
58
|
+
@property
|
59
|
+
def type_name(self) -> str:
|
60
|
+
return self.name
|
61
|
+
|
62
|
+
def to_qvar(self, origin: HandleBinding) -> "QStruct":
|
63
|
+
from classiq.qmod.qmod_variable import QStruct
|
64
|
+
|
65
|
+
return QStruct(
|
66
|
+
origin,
|
67
|
+
self.name,
|
68
|
+
{
|
69
|
+
field_name: field_type.to_qvar(
|
70
|
+
FieldHandleBinding(base_handle=origin, field=field_name)
|
71
|
+
)
|
72
|
+
for field_name, field_type in self.fields.items()
|
73
|
+
},
|
74
|
+
)
|
75
|
+
|
76
|
+
@property
|
77
|
+
def fields(self) -> Mapping[str, "ConcreteQuantumType"]:
|
78
|
+
from classiq.qmod.model_state_container import QMODULE
|
79
|
+
|
80
|
+
if self._assigned_fields is None:
|
81
|
+
qstruct_fields = QMODULE.qstruct_decls[self.name].fields
|
82
|
+
self._assigned_fields = {
|
83
|
+
field_name: field_type.copy()
|
84
|
+
for field_name, field_type in qstruct_fields.items()
|
85
|
+
}
|
86
|
+
|
87
|
+
return self._assigned_fields
|
88
|
+
|
89
|
+
def _set_fields(self, fields: Mapping[str, "ConcreteQuantumType"]) -> None:
|
90
|
+
from classiq.qmod.model_state_container import QMODULE
|
91
|
+
|
92
|
+
QMODULE.qstruct_decls[self.name].fields = fields
|
93
|
+
|
94
|
+
|
95
|
+
class Enum(TypeName):
|
96
|
+
pass
|
97
|
+
|
98
|
+
|
99
|
+
class Struct(TypeName):
|
100
|
+
@property
|
101
|
+
def qmod_type(self) -> type:
|
102
|
+
type_ = super().qmod_type
|
103
|
+
type_.__dataclass_fields__ = [] # type:ignore[attr-defined]
|
104
|
+
return type_
|
@@ -21,7 +21,7 @@ VISUALIZATION_HIDE_LIST = [
|
|
21
21
|
"control",
|
22
22
|
"mcx",
|
23
23
|
"iteration",
|
24
|
-
"
|
24
|
+
"stmt_block",
|
25
25
|
]
|
26
26
|
|
27
27
|
|
@@ -94,9 +94,9 @@ class GeneratedCircuitData(pydantic.BaseModel):
|
|
94
94
|
return cls(width=0)
|
95
95
|
|
96
96
|
|
97
|
-
class
|
97
|
+
class FunctionDebugInfoInterface(pydantic.BaseModel):
|
98
98
|
generated_function: Optional[GeneratedFunction]
|
99
|
-
children: List["
|
99
|
+
children: List["FunctionDebugInfoInterface"]
|
100
100
|
relative_qubits: Tuple[int, ...]
|
101
101
|
absolute_qubits: Optional[Tuple[int, ...]]
|
102
102
|
is_basis_gate: Optional[bool]
|
@@ -7,9 +7,11 @@ from classiq.interface.executor.execution_preferences import ExecutionPreference
|
|
7
7
|
from classiq.interface.generator.constant import Constant
|
8
8
|
from classiq.interface.generator.function_params import ArithmeticIODict
|
9
9
|
from classiq.interface.generator.types.enum_declaration import EnumDeclaration
|
10
|
+
from classiq.interface.generator.types.qstruct_declaration import QStructDeclaration
|
10
11
|
from classiq.interface.generator.types.struct_declaration import StructDeclaration
|
11
12
|
from classiq.interface.helpers.validation_helpers import is_list_unique
|
12
13
|
from classiq.interface.helpers.versioned_model import VersionedModel
|
14
|
+
from classiq.interface.model.quantum_type import RegisterQuantumTypeDict
|
13
15
|
|
14
16
|
from classiq.exceptions import ClassiqValueError
|
15
17
|
|
@@ -33,6 +35,11 @@ class ClassiqBaseModel(VersionedModel, ABC):
|
|
33
35
|
description="user-defined structs",
|
34
36
|
)
|
35
37
|
|
38
|
+
qstructs: List[QStructDeclaration] = pydantic.Field(
|
39
|
+
default_factory=list,
|
40
|
+
description="user-defined quantum structs",
|
41
|
+
)
|
42
|
+
|
36
43
|
constants: List[Constant] = pydantic.Field(
|
37
44
|
default_factory=list,
|
38
45
|
)
|
@@ -58,3 +65,7 @@ class ExecutionModel(ClassiqBaseModel):
|
|
58
65
|
description="Mapping between a measured register name and its arithmetic type",
|
59
66
|
default_factory=dict,
|
60
67
|
)
|
68
|
+
circuit_output_types: RegisterQuantumTypeDict = pydantic.Field(
|
69
|
+
description="Mapping between a measured register name and its qmod type",
|
70
|
+
default=dict(),
|
71
|
+
)
|
@@ -127,6 +127,11 @@ class Preferences(pydantic.BaseModel, extra=pydantic.Extra.forbid):
|
|
127
127
|
"transpiled circuit and its depth",
|
128
128
|
)
|
129
129
|
|
130
|
+
solovay_kitaev_max_iterations: Optional[pydantic.PositiveInt] = pydantic.Field(
|
131
|
+
None,
|
132
|
+
description="Maximum iterations for the Solovay-Kitaev algorithm (if applied).",
|
133
|
+
)
|
134
|
+
|
130
135
|
timeout_seconds: pydantic.PositiveInt = pydantic.Field(
|
131
136
|
default=300, description="Generation timeout in seconds"
|
132
137
|
)
|
@@ -18,6 +18,7 @@ from typing import (
|
|
18
18
|
Tuple,
|
19
19
|
Union,
|
20
20
|
)
|
21
|
+
from uuid import UUID, uuid4
|
21
22
|
|
22
23
|
import pydantic
|
23
24
|
from pydantic import BaseModel, Extra
|
@@ -150,6 +151,8 @@ class SynthesisQuantumFunctionCall(BaseModel):
|
|
150
151
|
"If not set, determined automatically.",
|
151
152
|
)
|
152
153
|
|
154
|
+
uuid: UUID = pydantic.Field(default_factory=uuid4)
|
155
|
+
|
153
156
|
def __eq__(self, other: Any) -> bool:
|
154
157
|
return (
|
155
158
|
isinstance(other, SynthesisQuantumFunctionCall) and self.name == other.name
|
@@ -17,7 +17,7 @@ from classiq.interface.generator.circuit_code.types_and_constants import (
|
|
17
17
|
CodeAndSyntax,
|
18
18
|
)
|
19
19
|
from classiq.interface.generator.generated_circuit_data import (
|
20
|
-
|
20
|
+
FunctionDebugInfoInterface,
|
21
21
|
GeneratedCircuitData,
|
22
22
|
)
|
23
23
|
from classiq.interface.generator.hardware.hardware_data import SynthesisHardwareData
|
@@ -59,7 +59,7 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
|
|
59
59
|
transpiled_circuit: Optional[TranspiledCircuitData]
|
60
60
|
creation_time: str = pydantic.Field(default_factory=datetime.utcnow().isoformat)
|
61
61
|
synthesis_duration: Optional[SynthesisStepDurations]
|
62
|
-
debug_info: Optional[List[
|
62
|
+
debug_info: Optional[List[FunctionDebugInfoInterface]]
|
63
63
|
program_id: str = pydantic.Field(default_factory=get_uuid_as_str)
|
64
64
|
|
65
65
|
def _hardware_agnostic_program_code(self) -> CodeAndSyntax:
|
@@ -10,6 +10,7 @@ class RegisterRole(StrEnum):
|
|
10
10
|
ZERO_INPUT = "zero_input"
|
11
11
|
ZERO_OUTPUT = "zero_output"
|
12
12
|
GARBAGE_OUTPUT = "garbage_output"
|
13
|
+
EXPLICIT_ZERO_INPUT = "explicit_zero_input"
|
13
14
|
|
14
15
|
@staticmethod
|
15
16
|
def output_roles(include_garbage: bool = False) -> Set["RegisterRole"]:
|
@@ -24,4 +25,9 @@ class RegisterRole(StrEnum):
|
|
24
25
|
|
25
26
|
@staticmethod
|
26
27
|
def input_roles() -> Set["RegisterRole"]:
|
27
|
-
return {
|
28
|
+
return {
|
29
|
+
RegisterRole.INPUT,
|
30
|
+
RegisterRole.ZERO_INPUT,
|
31
|
+
RegisterRole.AUXILIARY,
|
32
|
+
RegisterRole.EXPLICIT_ZERO_INPUT,
|
33
|
+
}
|
@@ -1,11 +1,9 @@
|
|
1
|
-
from typing import Dict,
|
1
|
+
from typing import Dict, 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
|
-
|
9
7
|
|
10
8
|
class FunctionExecutionData(pydantic.BaseModel):
|
11
9
|
power_parameter: Optional[PydanticExecutionParameter] = pydantic.Field(default=None)
|
@@ -2,10 +2,9 @@ import functools
|
|
2
2
|
|
3
3
|
from classiq.interface.generator.functions.classical_type import (
|
4
4
|
ClassicalList,
|
5
|
-
Enum,
|
6
5
|
Real,
|
7
|
-
Struct,
|
8
6
|
)
|
7
|
+
from classiq.interface.generator.functions.type_name import Enum, Struct
|
9
8
|
from classiq.interface.generator.types.struct_declaration import StructDeclaration
|
10
9
|
from classiq.interface.helpers.pydantic_model_helpers import nameables_to_dict
|
11
10
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
from typing import TYPE_CHECKING, Mapping
|
2
|
+
|
3
|
+
import pydantic
|
4
|
+
|
5
|
+
from classiq.interface.ast_node import HashableASTNode
|
6
|
+
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteQuantumType
|
9
|
+
|
10
|
+
|
11
|
+
class QStructDeclaration(HashableASTNode):
|
12
|
+
name: str
|
13
|
+
|
14
|
+
fields: Mapping[str, "ConcreteQuantumType"] = pydantic.Field(
|
15
|
+
default_factory=dict,
|
16
|
+
description="Dictionary of field names and their quantum types",
|
17
|
+
)
|
@@ -3,7 +3,7 @@ from typing import Any, ClassVar, Dict, Mapping
|
|
3
3
|
import pydantic
|
4
4
|
|
5
5
|
from classiq.interface.ast_node import HashableASTNode
|
6
|
-
from classiq.interface.generator.functions.
|
6
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
|
7
7
|
|
8
8
|
from classiq.exceptions import ClassiqValueError
|
9
9
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Hashable, List, Mapping
|
1
|
+
from typing import Hashable, List, Mapping
|
2
2
|
|
3
3
|
from classiq.interface.helpers.pydantic_model_helpers import Nameable
|
4
4
|
|
@@ -16,19 +16,3 @@ def validate_nameables_mapping(
|
|
16
16
|
raise ClassiqValueError(
|
17
17
|
f"{declaration_type} declaration names should match the keys of their names."
|
18
18
|
)
|
19
|
-
|
20
|
-
|
21
|
-
def validate_nameables_no_overlap(
|
22
|
-
left_nameables_dict: Optional[Mapping[str, Nameable]],
|
23
|
-
right_nameables_dict: Optional[Mapping[str, Nameable]],
|
24
|
-
left_declaration_type: str,
|
25
|
-
right_declaration_type: str,
|
26
|
-
) -> Optional[str]:
|
27
|
-
if left_nameables_dict is None or right_nameables_dict is None:
|
28
|
-
return None
|
29
|
-
|
30
|
-
matched_names = left_nameables_dict.keys() & right_nameables_dict.keys()
|
31
|
-
if matched_names:
|
32
|
-
return f"{left_declaration_type} declaration names overlap with {right_declaration_type} declaration names: {matched_names}"
|
33
|
-
|
34
|
-
return None
|
@@ -9,8 +9,9 @@ from classiq._internals.enum_utils import StrEnum
|
|
9
9
|
|
10
10
|
|
11
11
|
class OperationLevel(StrEnum):
|
12
|
-
|
13
|
-
|
12
|
+
QMOD_FUNCTION_CALL = "QMOD_CALL"
|
13
|
+
QMOD_STATEMENT = "QMOD_STATEMENT"
|
14
|
+
ENGINE_FUNCTION_CALL = "ENGINE_CALL"
|
14
15
|
BASIS_GATE = "BASIS_GATE"
|
15
16
|
UNKNOWN = "UNKNOWN"
|
16
17
|
|
@@ -41,6 +42,12 @@ class OperationLink(pydantic.BaseModel):
|
|
41
42
|
qubits: Tuple[int, ...]
|
42
43
|
type: str
|
43
44
|
|
45
|
+
class Config:
|
46
|
+
allow_mutation = False
|
47
|
+
|
48
|
+
def __hash__(self) -> int:
|
49
|
+
return hash((type(self), self.label, self.qubits, self.type))
|
50
|
+
|
44
51
|
|
45
52
|
class OperationLinks(pydantic.BaseModel):
|
46
53
|
inputs: List[OperationLink]
|
@@ -0,0 +1 @@
|
|
1
|
+
INTERFACE_VERSION = "2"
|