classiq 0.39.0__py3-none-any.whl → 0.41.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 +5 -2
- classiq/_internals/api_wrapper.py +3 -21
- classiq/applications/chemistry/chemistry_model_constructor.py +87 -101
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +7 -26
- classiq/applications/combinatorial_helpers/optimization_model.py +7 -6
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +33 -55
- classiq/applications/combinatorial_optimization/__init__.py +4 -0
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +29 -26
- classiq/applications/finance/finance_model_constructor.py +23 -26
- classiq/applications/grover/grover_model_constructor.py +37 -38
- classiq/applications/qsvm/qsvm.py +1 -2
- classiq/applications/qsvm/qsvm_model_constructor.py +15 -16
- classiq/execution/__init__.py +4 -0
- classiq/execution/execution_session.py +151 -0
- classiq/execution/qnn.py +80 -0
- classiq/executor.py +2 -109
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +11 -0
- classiq/interface/applications/qsvm.py +0 -8
- classiq/interface/ast_node.py +12 -2
- classiq/interface/backend/backend_preferences.py +30 -6
- classiq/interface/backend/quantum_backend_providers.py +11 -11
- classiq/interface/executor/execution_preferences.py +7 -67
- classiq/interface/executor/execution_result.py +22 -1
- classiq/interface/generator/application_apis/chemistry_declarations.py +2 -4
- classiq/interface/generator/application_apis/finance_declarations.py +1 -1
- classiq/interface/generator/arith/binary_ops.py +88 -25
- classiq/interface/generator/arith/unary_ops.py +28 -19
- classiq/interface/generator/expressions/atomic_expression_functions.py +6 -2
- classiq/interface/generator/expressions/enums/__init__.py +10 -0
- classiq/interface/generator/expressions/enums/classical_enum.py +5 -1
- classiq/interface/generator/expressions/expression.py +9 -2
- classiq/interface/generator/expressions/qmod_qarray_proxy.py +89 -0
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +20 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +22 -0
- classiq/interface/generator/expressions/sympy_supported_expressions.py +10 -1
- classiq/interface/generator/functions/builtins/core_library/atomic_quantum_functions.py +8 -6
- classiq/interface/generator/functions/builtins/core_library/exponentiation_functions.py +10 -4
- classiq/interface/generator/functions/builtins/internal_operators.py +7 -62
- classiq/interface/generator/functions/builtins/open_lib_functions.py +1627 -271
- classiq/interface/generator/functions/classical_type.py +27 -17
- classiq/interface/generator/model/preferences/preferences.py +4 -2
- classiq/interface/generator/synthesis_metadata/synthesis_duration.py +0 -4
- classiq/interface/model/bind_operation.py +3 -1
- classiq/interface/model/call_synthesis_data.py +2 -13
- classiq/interface/model/classical_if.py +3 -1
- classiq/interface/model/classical_parameter_declaration.py +13 -0
- classiq/interface/model/control.py +6 -8
- classiq/interface/model/inplace_binary_operation.py +3 -1
- classiq/interface/model/invert.py +3 -1
- classiq/interface/model/port_declaration.py +8 -1
- classiq/interface/model/power.py +3 -1
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +4 -2
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +3 -1
- classiq/interface/model/quantum_expressions/quantum_expression.py +11 -1
- classiq/interface/model/quantum_function_call.py +4 -10
- classiq/interface/model/quantum_function_declaration.py +26 -4
- classiq/interface/model/quantum_lambda_function.py +1 -20
- classiq/interface/model/quantum_statement.py +9 -2
- classiq/interface/model/quantum_type.py +6 -5
- classiq/interface/model/repeat.py +3 -1
- classiq/interface/model/resolvers/function_call_resolver.py +0 -5
- classiq/interface/model/statement_block.py +19 -16
- classiq/interface/model/validations/handles_validator.py +8 -2
- classiq/interface/model/variable_declaration_statement.py +3 -1
- classiq/interface/model/within_apply_operation.py +3 -1
- classiq/interface/server/routes.py +0 -5
- classiq/qmod/__init__.py +5 -2
- classiq/qmod/builtins/classical_execution_primitives.py +22 -2
- classiq/qmod/builtins/classical_functions.py +30 -35
- classiq/qmod/builtins/functions.py +263 -153
- classiq/qmod/builtins/operations.py +50 -26
- classiq/qmod/builtins/structs.py +50 -48
- classiq/qmod/declaration_inferrer.py +32 -27
- classiq/qmod/native/__init__.py +9 -0
- classiq/qmod/native/expression_to_qmod.py +8 -4
- classiq/qmod/native/pretty_printer.py +11 -18
- classiq/qmod/pretty_print/__init__.py +9 -0
- classiq/qmod/pretty_print/expression_to_python.py +221 -0
- classiq/qmod/pretty_print/pretty_printer.py +421 -0
- classiq/qmod/qmod_constant.py +7 -7
- classiq/qmod/qmod_parameter.py +57 -33
- classiq/qmod/qmod_struct.py +2 -2
- classiq/qmod/qmod_variable.py +40 -29
- classiq/qmod/quantum_callable.py +8 -4
- classiq/qmod/quantum_expandable.py +22 -15
- classiq/qmod/quantum_function.py +15 -4
- classiq/qmod/symbolic.py +73 -68
- classiq/qmod/symbolic_expr.py +1 -1
- classiq/qmod/symbolic_type.py +1 -4
- classiq/qmod/utilities.py +29 -0
- classiq/synthesis.py +15 -16
- {classiq-0.39.0.dist-info → classiq-0.41.0.dist-info}/METADATA +5 -4
- {classiq-0.39.0.dist-info → classiq-0.41.0.dist-info}/RECORD +95 -94
- classiq/interface/executor/error_mitigation.py +0 -6
- classiq/interface/generator/functions/builtins/core_library/chemistry_functions.py +0 -0
- classiq/interface/model/common_model_types.py +0 -23
- classiq/interface/model/quantum_expressions/control_state.py +0 -38
- classiq/interface/model/quantum_if_operation.py +0 -94
- {classiq-0.39.0.dist-info → classiq-0.41.0.dist-info}/WHEEL +0 -0
classiq/execution/qnn.py
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
import functools
|
2
|
+
from typing import List, Optional
|
3
|
+
|
4
|
+
import more_itertools
|
5
|
+
|
6
|
+
from classiq.interface.chemistry.operator import PauliOperator
|
7
|
+
from classiq.interface.executor.execution_result import (
|
8
|
+
ResultsCollection,
|
9
|
+
SavedResultValueType,
|
10
|
+
TaggedEstimationResult,
|
11
|
+
TaggedExecutionDetails,
|
12
|
+
)
|
13
|
+
from classiq.interface.executor.quantum_code import Arguments, MultipleArguments
|
14
|
+
|
15
|
+
from classiq.applications.combinatorial_helpers.pauli_helpers.pauli_utils import (
|
16
|
+
pauli_operator_to_hamiltonian,
|
17
|
+
)
|
18
|
+
from classiq.execution.execution_session import ExecutionSession
|
19
|
+
from classiq.executor import DEFAULT_RESULT_NAME
|
20
|
+
from classiq.synthesis import SerializedQuantumProgram
|
21
|
+
|
22
|
+
_MAX_ARGUMENTS_SIZE = 1024
|
23
|
+
|
24
|
+
|
25
|
+
def _execute_qnn_estimate(
|
26
|
+
session: ExecutionSession,
|
27
|
+
arguments: List[Arguments],
|
28
|
+
observable: PauliOperator,
|
29
|
+
) -> ResultsCollection:
|
30
|
+
hamiltonian = pauli_operator_to_hamiltonian(observable.pauli_list)
|
31
|
+
return [
|
32
|
+
TaggedEstimationResult(
|
33
|
+
name=DEFAULT_RESULT_NAME,
|
34
|
+
value=result,
|
35
|
+
value_type=SavedResultValueType.EstimationResult,
|
36
|
+
)
|
37
|
+
for result in session.batch_estimate(
|
38
|
+
hamiltonian=hamiltonian, parameters=arguments
|
39
|
+
)
|
40
|
+
]
|
41
|
+
|
42
|
+
|
43
|
+
def _execute_qnn_sample(
|
44
|
+
session: ExecutionSession,
|
45
|
+
arguments: List[Arguments],
|
46
|
+
) -> ResultsCollection:
|
47
|
+
return [
|
48
|
+
TaggedExecutionDetails(
|
49
|
+
name=DEFAULT_RESULT_NAME,
|
50
|
+
value=result,
|
51
|
+
value_type=SavedResultValueType.ExecutionDetails,
|
52
|
+
)
|
53
|
+
for result in session.batch_sample(arguments)
|
54
|
+
]
|
55
|
+
|
56
|
+
|
57
|
+
def execute_qnn(
|
58
|
+
quantum_program: SerializedQuantumProgram,
|
59
|
+
arguments: MultipleArguments,
|
60
|
+
observable: Optional[PauliOperator] = None,
|
61
|
+
) -> ResultsCollection:
|
62
|
+
session = ExecutionSession(quantum_program)
|
63
|
+
|
64
|
+
if observable:
|
65
|
+
execute_function = functools.partial(
|
66
|
+
_execute_qnn_estimate,
|
67
|
+
session=session,
|
68
|
+
observable=observable,
|
69
|
+
)
|
70
|
+
else:
|
71
|
+
execute_function = functools.partial(
|
72
|
+
_execute_qnn_sample,
|
73
|
+
session=session,
|
74
|
+
)
|
75
|
+
|
76
|
+
result: ResultsCollection = []
|
77
|
+
for chunk in more_itertools.chunked(arguments, _MAX_ARGUMENTS_SIZE):
|
78
|
+
chunk_result = execute_function(arguments=chunk)
|
79
|
+
result.extend(chunk_result)
|
80
|
+
return result
|
classiq/executor.py
CHANGED
@@ -1,27 +1,13 @@
|
|
1
1
|
"""Executor module, implementing facilities for executing quantum programs using Classiq platform."""
|
2
2
|
|
3
|
-
import
|
4
|
-
from typing import Optional, Tuple, Union
|
3
|
+
from typing import Tuple, Union
|
5
4
|
|
6
|
-
import more_itertools
|
7
5
|
from typing_extensions import TypeAlias
|
8
6
|
|
9
7
|
from classiq.interface.backend.backend_preferences import BackendPreferencesTypes
|
10
|
-
from classiq.interface.chemistry.operator import PauliOperators
|
11
8
|
from classiq.interface.executor.estimation import OperatorsEstimation
|
12
9
|
from classiq.interface.executor.execution_preferences import ExecutionPreferences
|
13
|
-
from classiq.interface.executor.
|
14
|
-
EstimateOperatorsExecution,
|
15
|
-
ExecutionRequest,
|
16
|
-
QuantumCodeExecution,
|
17
|
-
)
|
18
|
-
from classiq.interface.executor.execution_result import (
|
19
|
-
ResultsCollection,
|
20
|
-
SavedResultValueType,
|
21
|
-
TaggedEstimationResult,
|
22
|
-
TaggedExecutionDetails,
|
23
|
-
)
|
24
|
-
from classiq.interface.executor.quantum_code import MultipleArguments, QuantumCode
|
10
|
+
from classiq.interface.executor.quantum_code import QuantumCode
|
25
11
|
from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
|
26
12
|
from classiq.interface.executor.result import ExecutionDetails
|
27
13
|
from classiq.interface.generator.quantum_program import QuantumProgram
|
@@ -38,7 +24,6 @@ ProgramAndResult: TypeAlias = Tuple[QuantumCode, BatchExecutionResult]
|
|
38
24
|
BackendPreferencesAndResult: TypeAlias = Tuple[
|
39
25
|
BackendPreferencesTypes, int, BatchExecutionResult
|
40
26
|
]
|
41
|
-
_MAX_ARGUMENTS_SIZE = 1024
|
42
27
|
|
43
28
|
|
44
29
|
def _parse_serialized_qprog(
|
@@ -56,83 +41,6 @@ async def execute_async(quantum_program: SerializedQuantumProgram) -> ExecutionJ
|
|
56
41
|
execute = syncify_function(execute_async)
|
57
42
|
|
58
43
|
|
59
|
-
async def _execute_qnn_async_estimate(
|
60
|
-
quantum_program: QuantumCode,
|
61
|
-
execution_preferences: ExecutionPreferences,
|
62
|
-
observables: PauliOperators,
|
63
|
-
) -> ResultsCollection:
|
64
|
-
request = ExecutionRequest(
|
65
|
-
execution_payload=EstimateOperatorsExecution(
|
66
|
-
quantum_program=quantum_program,
|
67
|
-
operators=observables,
|
68
|
-
),
|
69
|
-
preferences=execution_preferences,
|
70
|
-
)
|
71
|
-
|
72
|
-
results = await ApiWrapper.call_execute_estimate(request)
|
73
|
-
return [
|
74
|
-
TaggedEstimationResult(
|
75
|
-
name=DEFAULT_RESULT_NAME,
|
76
|
-
value=result,
|
77
|
-
value_type=SavedResultValueType.EstimationResult,
|
78
|
-
)
|
79
|
-
for result in results
|
80
|
-
]
|
81
|
-
|
82
|
-
|
83
|
-
async def _execute_qnn_async_program(
|
84
|
-
quantum_program: QuantumCode,
|
85
|
-
execution_preferences: ExecutionPreferences,
|
86
|
-
) -> ResultsCollection:
|
87
|
-
request = ExecutionRequest(
|
88
|
-
execution_payload=QuantumCodeExecution(**quantum_program.dict()),
|
89
|
-
preferences=execution_preferences,
|
90
|
-
)
|
91
|
-
|
92
|
-
api_result = await ApiWrapper.call_execute_quantum_program(request)
|
93
|
-
return [
|
94
|
-
TaggedExecutionDetails(
|
95
|
-
name=DEFAULT_RESULT_NAME,
|
96
|
-
value=result,
|
97
|
-
value_type=SavedResultValueType.ExecutionDetails,
|
98
|
-
)
|
99
|
-
for result in api_result.details
|
100
|
-
]
|
101
|
-
|
102
|
-
|
103
|
-
async def execute_qnn_async(
|
104
|
-
quantum_program: SerializedQuantumProgram,
|
105
|
-
arguments: MultipleArguments,
|
106
|
-
observables: Optional[PauliOperators] = None,
|
107
|
-
) -> ResultsCollection:
|
108
|
-
circuit = _parse_serialized_qprog(quantum_program)
|
109
|
-
execution_preferences = circuit.model.execution_preferences
|
110
|
-
|
111
|
-
legacy_quantum_program = circuit.to_program()
|
112
|
-
|
113
|
-
if observables:
|
114
|
-
execute_function = functools.partial(
|
115
|
-
_execute_qnn_async_estimate,
|
116
|
-
execution_preferences=execution_preferences,
|
117
|
-
observables=observables,
|
118
|
-
)
|
119
|
-
else:
|
120
|
-
execute_function = functools.partial(
|
121
|
-
_execute_qnn_async_program,
|
122
|
-
execution_preferences=execution_preferences,
|
123
|
-
)
|
124
|
-
|
125
|
-
result: ResultsCollection = []
|
126
|
-
for chunk in more_itertools.chunked(arguments, _MAX_ARGUMENTS_SIZE):
|
127
|
-
legacy_quantum_program.arguments = tuple(chunk)
|
128
|
-
chunk_result = await execute_function(quantum_program=legacy_quantum_program)
|
129
|
-
result.extend(chunk_result)
|
130
|
-
return result
|
131
|
-
|
132
|
-
|
133
|
-
execute_qnn = syncify_function(execute_qnn_async)
|
134
|
-
|
135
|
-
|
136
44
|
def set_quantum_program_execution_preferences(
|
137
45
|
quantum_program: SerializedQuantumProgram,
|
138
46
|
preferences: ExecutionPreferences,
|
@@ -142,24 +50,9 @@ def set_quantum_program_execution_preferences(
|
|
142
50
|
return SerializedQuantumProgram(circuit.json())
|
143
51
|
|
144
52
|
|
145
|
-
def set_initial_values(
|
146
|
-
quantum_program: SerializedQuantumProgram,
|
147
|
-
**kwargs: int,
|
148
|
-
) -> SerializedQuantumProgram:
|
149
|
-
circuit = _parse_serialized_qprog(quantum_program)
|
150
|
-
circuit.initial_values = kwargs
|
151
|
-
|
152
|
-
# Validate the initial values by calling `get_registers_initialization`
|
153
|
-
circuit.get_registers_initialization(circuit.initial_values)
|
154
|
-
|
155
|
-
return SerializedQuantumProgram(circuit.json())
|
156
|
-
|
157
|
-
|
158
53
|
__all__ = [
|
159
54
|
"QuantumCode",
|
160
55
|
"QuantumInstructionSet",
|
161
|
-
"execute_qnn",
|
162
56
|
"OperatorsEstimation",
|
163
57
|
"set_quantum_program_execution_preferences",
|
164
|
-
"set_initial_values",
|
165
58
|
]
|
classiq/interface/_version.py
CHANGED
@@ -44,6 +44,17 @@ class AnalysisOptionalDevicesParams(HardwareListParams):
|
|
44
44
|
)
|
45
45
|
|
46
46
|
|
47
|
+
class GateNamsMapping(pydantic.BaseModel):
|
48
|
+
qasm_name: str
|
49
|
+
display_name: str
|
50
|
+
|
51
|
+
|
52
|
+
class LatexParams(AnalysisParams):
|
53
|
+
gate_names: List[GateNamsMapping] = pydantic.Field(
|
54
|
+
default=..., description="List of gate names as apper in the qasm"
|
55
|
+
)
|
56
|
+
|
57
|
+
|
47
58
|
class AnalysisHardwareTranspilationParams(pydantic.BaseModel):
|
48
59
|
hardware_data: Optional[SynthesisHardwareData]
|
49
60
|
random_seed: int
|
@@ -12,12 +12,10 @@ from typing import (
|
|
12
12
|
import numpy as np
|
13
13
|
import pydantic
|
14
14
|
from numpy.typing import ArrayLike
|
15
|
-
from pydantic import BaseModel
|
16
15
|
|
17
16
|
if TYPE_CHECKING:
|
18
17
|
from pydantic.typing import AnyClassMethod
|
19
18
|
|
20
|
-
from classiq.interface.executor.execution_preferences import ExecutionPreferences
|
21
19
|
from classiq.interface.helpers.versioned_model import VersionedModel
|
22
20
|
|
23
21
|
DataList = List[List[float]]
|
@@ -35,11 +33,6 @@ def listify(obj: Union[IterableType, ArrayLike]) -> list:
|
|
35
33
|
return list(obj) # type: ignore[arg-type]
|
36
34
|
|
37
35
|
|
38
|
-
class QSVMPreferences(BaseModel):
|
39
|
-
execution_preferences: ExecutionPreferences
|
40
|
-
l2_norm_regularization_factor: float = 0.001
|
41
|
-
|
42
|
-
|
43
36
|
def validate_array_to_list(name: str) -> "AnyClassMethod":
|
44
37
|
return pydantic.validator(name, pre=True, allow_reuse=True)(listify)
|
45
38
|
|
@@ -96,7 +89,6 @@ class QSVMData(VersionedModel):
|
|
96
89
|
data: DataList
|
97
90
|
labels: Optional[LabelsInt] = None
|
98
91
|
internal_state: Optional[QSVMInternalState] = None
|
99
|
-
preferences: QSVMPreferences
|
100
92
|
|
101
93
|
class Config:
|
102
94
|
smart_union = True
|
classiq/interface/ast_node.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import os
|
1
2
|
from typing import Optional
|
2
3
|
|
3
4
|
import pydantic
|
@@ -7,15 +8,24 @@ from classiq.interface.helpers.hashable_pydantic_base_model import (
|
|
7
8
|
)
|
8
9
|
|
9
10
|
|
10
|
-
class SourceReference(
|
11
|
+
class SourceReference(HashablePydanticBaseModel):
|
11
12
|
start_line: int
|
12
13
|
start_column: int
|
13
14
|
end_line: int
|
14
15
|
end_column: int
|
15
16
|
file_name: Optional[str] = pydantic.Field(default=None)
|
16
17
|
|
18
|
+
def __str__(self) -> str:
|
19
|
+
file_string = (
|
20
|
+
f"file {os.path.basename(self.file_name)} " if self.file_name else ""
|
21
|
+
)
|
22
|
+
start_character_string = (
|
23
|
+
f" character {self.start_column}" if self.start_column else ""
|
24
|
+
)
|
25
|
+
return f"{file_string}line {self.start_line}{start_character_string}"
|
17
26
|
|
18
|
-
|
27
|
+
|
28
|
+
class ASTNode(HashablePydanticBaseModel):
|
19
29
|
source_ref: Optional[SourceReference] = pydantic.Field(default=None)
|
20
30
|
|
21
31
|
|
@@ -4,7 +4,7 @@ from datetime import timedelta
|
|
4
4
|
from typing import Any, Dict, Iterable, List, Optional, Union
|
5
5
|
|
6
6
|
import pydantic
|
7
|
-
from pydantic import BaseModel, validator
|
7
|
+
from pydantic import BaseModel, PrivateAttr, validator
|
8
8
|
|
9
9
|
from classiq.interface.backend import pydantic_backend
|
10
10
|
from classiq.interface.backend.quantum_backend_providers import (
|
@@ -12,8 +12,8 @@ from classiq.interface.backend.quantum_backend_providers import (
|
|
12
12
|
AliceBobBackendNames,
|
13
13
|
AmazonBraketBackendNames,
|
14
14
|
AzureQuantumBackendNames,
|
15
|
-
ClassiqAerBackendNames,
|
16
15
|
ClassiqNvidiaBackendNames,
|
16
|
+
ClassiqSimulatorBackendNames,
|
17
17
|
IonqBackendNames,
|
18
18
|
OQCBackendNames,
|
19
19
|
ProviderTypeVendor,
|
@@ -56,14 +56,27 @@ class BackendPreferences(BaseModel):
|
|
56
56
|
return False
|
57
57
|
|
58
58
|
|
59
|
-
AWS_DEFAULT_JOB_TIMEOUT_SECONDS = int(timedelta(minutes=
|
59
|
+
AWS_DEFAULT_JOB_TIMEOUT_SECONDS = int(timedelta(minutes=240).total_seconds())
|
60
60
|
|
61
61
|
|
62
62
|
class AliceBobBackendPreferences(BackendPreferences):
|
63
63
|
backend_service_provider: ProviderTypeVendor.ALICE_BOB
|
64
|
+
distance: Optional[int] = pydantic.Field(
|
65
|
+
default=None, description="Repetition code distance"
|
66
|
+
)
|
67
|
+
kappa_1: Optional[float] = pydantic.Field(
|
68
|
+
default=None, description="One-photon dissipation rate (Hz)"
|
69
|
+
)
|
70
|
+
kappa_2: Optional[float] = pydantic.Field(
|
71
|
+
default=None, description="Two-photon dissipation rate (Hz)"
|
72
|
+
)
|
73
|
+
average_nb_photons: Optional[float] = pydantic.Field(
|
74
|
+
default=None, description="Average number of photons"
|
75
|
+
)
|
64
76
|
api_key: pydantic_backend.PydanticAliceBobApiKeyType = pydantic.Field(
|
65
77
|
..., description="AliceBob API key"
|
66
78
|
)
|
79
|
+
_parameters: Dict[str, Any] = PrivateAttr(default_factory=dict)
|
67
80
|
|
68
81
|
@pydantic.root_validator(pre=True)
|
69
82
|
def _set_backend_service_provider(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
@@ -71,6 +84,17 @@ class AliceBobBackendPreferences(BackendPreferences):
|
|
71
84
|
values, "backend_service_provider", ProviderVendor.ALICE_AND_BOB
|
72
85
|
)
|
73
86
|
|
87
|
+
@property
|
88
|
+
def parameters(self) -> Dict[str, Any]:
|
89
|
+
self._parameters = {
|
90
|
+
"distance": self.distance,
|
91
|
+
"kappa_1": self.kappa_1,
|
92
|
+
"kappa_2": self.kappa_2,
|
93
|
+
"average_nb_photons": self.average_nb_photons,
|
94
|
+
}
|
95
|
+
self._parameters = {k: v for k, v in self._parameters.items() if v is not None}
|
96
|
+
return self._parameters
|
97
|
+
|
74
98
|
|
75
99
|
class ClassiqBackendPreferences(BackendPreferences):
|
76
100
|
backend_service_provider: ProviderTypeVendor.CLASSIQ
|
@@ -221,13 +245,13 @@ def is_exact_simulator(backend_preferences: BackendPreferences) -> bool:
|
|
221
245
|
|
222
246
|
|
223
247
|
def default_backend_preferences(
|
224
|
-
backend_name: str =
|
248
|
+
backend_name: str = ClassiqSimulatorBackendNames.SIMULATOR,
|
225
249
|
) -> BackendPreferences:
|
226
250
|
return ClassiqBackendPreferences(backend_name=backend_name)
|
227
251
|
|
228
252
|
|
229
253
|
def backend_preferences_field(
|
230
|
-
backend_name: str =
|
254
|
+
backend_name: str = ClassiqSimulatorBackendNames.SIMULATOR,
|
231
255
|
) -> Any:
|
232
256
|
return pydantic.Field(
|
233
257
|
default_factory=lambda: default_backend_preferences(backend_name),
|
@@ -252,7 +276,7 @@ __all__ = [
|
|
252
276
|
"AzureCredential",
|
253
277
|
"AzureQuantumBackendNames",
|
254
278
|
"ClassiqBackendPreferences",
|
255
|
-
"
|
279
|
+
"ClassiqSimulatorBackendNames",
|
256
280
|
"IBMBackendPreferences",
|
257
281
|
"IBMBackendProvider",
|
258
282
|
"AwsBackendPreferences",
|
@@ -31,11 +31,11 @@ class ProviderTypeVendor:
|
|
31
31
|
OQC = Literal[ProviderVendor.OQC]
|
32
32
|
|
33
33
|
|
34
|
-
class
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
class ClassiqSimulatorBackendNames(StrEnum):
|
35
|
+
SIMULATOR = "simulator"
|
36
|
+
SIMULATOR_STATEVECTOR = "simulator_statevector"
|
37
|
+
SIMULATOR_DENSITY_MATRIX = "simulator_density_matrix"
|
38
|
+
SIMULATOR_MATRIX_PRODUCT_STATE = "simulator_matrix_product_state"
|
39
39
|
|
40
40
|
|
41
41
|
class IonqBackendNames(StrEnum):
|
@@ -141,7 +141,7 @@ class ClassiqNvidiaBackendNames(StrEnum):
|
|
141
141
|
SIMULATOR = "nvidia_state_vector_simulator"
|
142
142
|
|
143
143
|
|
144
|
-
AllClassiqBackendNames = Union[
|
144
|
+
AllClassiqBackendNames = Union[ClassiqSimulatorBackendNames, ClassiqNvidiaBackendNames]
|
145
145
|
|
146
146
|
|
147
147
|
class GoogleNvidiaBackendNames(StrEnum):
|
@@ -149,10 +149,10 @@ class GoogleNvidiaBackendNames(StrEnum):
|
|
149
149
|
|
150
150
|
|
151
151
|
class AliceBobBackendNames(StrEnum):
|
152
|
-
PERFECT_QUBITS = "
|
153
|
-
LOGICAL_TARGET = "
|
154
|
-
LOGICAL_EARLY = "
|
155
|
-
TRANSMONS = "
|
152
|
+
PERFECT_QUBITS = "PERFECT_QUBITS"
|
153
|
+
LOGICAL_TARGET = "LOGICAL_TARGET"
|
154
|
+
LOGICAL_EARLY = "LOGICAL_EARLY"
|
155
|
+
TRANSMONS = "TRANSMONS"
|
156
156
|
|
157
157
|
|
158
158
|
class OQCBackendNames(StrEnum):
|
@@ -166,7 +166,7 @@ EXACT_SIMULATORS = {
|
|
166
166
|
AmazonBraketBackendNames.AMAZON_BRAKET_SV1,
|
167
167
|
AmazonBraketBackendNames.AMAZON_BRAKET_TN1,
|
168
168
|
AmazonBraketBackendNames.AMAZON_BRAKET_DM1,
|
169
|
-
*
|
169
|
+
*ClassiqSimulatorBackendNames,
|
170
170
|
*ClassiqNvidiaBackendNames,
|
171
171
|
}
|
172
172
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from datetime import timedelta
|
2
|
-
from typing import Any, Dict, Optional
|
2
|
+
from typing import Any, Dict, Optional
|
3
3
|
|
4
4
|
import pydantic
|
5
5
|
|
@@ -10,12 +10,10 @@ from classiq.interface.backend.backend_preferences import (
|
|
10
10
|
backend_preferences_field,
|
11
11
|
)
|
12
12
|
from classiq.interface.backend.pydantic_backend import MAX_EXECUTION_TIMEOUT_SECONDS
|
13
|
-
from classiq.interface.backend.quantum_backend_providers import
|
14
|
-
|
15
|
-
from classiq.interface.executor.optimizer_preferences import (
|
16
|
-
OptimizerPreferences,
|
17
|
-
OptimizerType,
|
13
|
+
from classiq.interface.backend.quantum_backend_providers import (
|
14
|
+
ClassiqSimulatorBackendNames,
|
18
15
|
)
|
16
|
+
from classiq.interface.executor.optimizer_preferences import OptimizerType
|
19
17
|
from classiq.interface.generator.model.preferences.preferences import (
|
20
18
|
TranspilationOption,
|
21
19
|
)
|
@@ -47,24 +45,15 @@ class ExecutionPreferences(pydantic.BaseModel):
|
|
47
45
|
description="If set, limits the execution runtime. Value is in seconds. "
|
48
46
|
"Not supported on all platforms.",
|
49
47
|
)
|
50
|
-
optimizer_preferences: Optional[OptimizerPreferences] = pydantic.Field(
|
51
|
-
default_factory=None,
|
52
|
-
description="Settings related to VQE execution.",
|
53
|
-
)
|
54
|
-
error_mitigation_method: Optional[ErrorMitigationMethod] = pydantic.Field(
|
55
|
-
default=None,
|
56
|
-
description="Error mitigation method. Currently supports complete and tensored "
|
57
|
-
"measurement calibration.",
|
58
|
-
)
|
59
48
|
noise_properties: Optional[NoiseProperties] = pydantic.Field(
|
60
49
|
default=None, description="Properties of the noise in the circuit"
|
61
50
|
)
|
62
51
|
random_seed: int = pydantic.Field(
|
63
|
-
|
52
|
+
default_factory=create_random_seed,
|
64
53
|
description="The random seed used for the execution",
|
65
54
|
)
|
66
55
|
backend_preferences: BackendPreferencesTypes = backend_preferences_field(
|
67
|
-
backend_name=
|
56
|
+
backend_name=ClassiqSimulatorBackendNames.SIMULATOR
|
68
57
|
)
|
69
58
|
num_shots: Optional[pydantic.PositiveInt] = pydantic.Field(default=None)
|
70
59
|
transpile_to_hardware: TranspilationOption = pydantic.Field(
|
@@ -80,14 +69,6 @@ class ExecutionPreferences(pydantic.BaseModel):
|
|
80
69
|
def __init__(self, **kwargs: Any) -> None:
|
81
70
|
super().__init__(**kwargs)
|
82
71
|
|
83
|
-
@pydantic.validator("num_shots", always=True)
|
84
|
-
def validate_num_shots(
|
85
|
-
cls, original_num_shots: Optional[pydantic.PositiveInt], values: Dict[str, Any]
|
86
|
-
) -> Optional[pydantic.PositiveInt]:
|
87
|
-
return _choose_original_or_optimizer_attribute(
|
88
|
-
original_num_shots, "num_shots", None, values
|
89
|
-
)
|
90
|
-
|
91
72
|
@pydantic.validator("backend_preferences", always=True)
|
92
73
|
def validate_timeout_for_aws(
|
93
74
|
cls, backend_preferences: BackendPreferencesTypes, values: Dict[str, Any]
|
@@ -109,51 +90,10 @@ class ExecutionPreferences(pydantic.BaseModel):
|
|
109
90
|
backend_preferences.job_timeout = timeout
|
110
91
|
return backend_preferences
|
111
92
|
|
112
|
-
@pydantic.validator("random_seed", always=True)
|
113
|
-
def validate_random_seed(
|
114
|
-
cls, original_random_seed: Optional[int], values: Dict[str, Any]
|
115
|
-
) -> int:
|
116
|
-
return _choose_original_or_optimizer_attribute(
|
117
|
-
original_random_seed, "random_seed", create_random_seed(), values
|
118
|
-
)
|
119
|
-
|
120
|
-
|
121
|
-
T = TypeVar("T")
|
122
|
-
|
123
|
-
|
124
|
-
def _choose_original_or_optimizer_attribute(
|
125
|
-
original_attribute: Optional[T],
|
126
|
-
attribure_name: str,
|
127
|
-
default_value: T,
|
128
|
-
values: Dict[str, Any],
|
129
|
-
) -> T:
|
130
|
-
optimizer_preferences = values.get("optimizer_preferences", None)
|
131
|
-
optimizer_attribute = getattr(optimizer_preferences, attribure_name, None)
|
132
|
-
|
133
|
-
if original_attribute is None and optimizer_attribute is None:
|
134
|
-
return default_value
|
135
|
-
|
136
|
-
elif optimizer_attribute is None:
|
137
|
-
# mypy doesn't understand that original_attribute is not None
|
138
|
-
return original_attribute # type: ignore[return-value]
|
139
|
-
|
140
|
-
elif original_attribute is None:
|
141
|
-
return optimizer_attribute
|
142
|
-
|
143
|
-
elif original_attribute != optimizer_attribute:
|
144
|
-
raise ClassiqValueError(
|
145
|
-
f"Different {attribure_name} were given for ExecutionPreferences and OptimizerPreferences."
|
146
|
-
)
|
147
|
-
|
148
|
-
else: # This case is original_num_shots == optimizer_num_shots != None
|
149
|
-
return original_attribute
|
150
|
-
|
151
93
|
|
152
94
|
__all__ = [
|
153
95
|
"ExecutionPreferences",
|
154
|
-
"ErrorMitigationMethod",
|
155
|
-
"NoiseProperties",
|
156
|
-
"OptimizerPreferences",
|
157
96
|
"OptimizerType",
|
97
|
+
"NoiseProperties",
|
158
98
|
"QaeWithQpeEstimationMethod",
|
159
99
|
]
|
@@ -4,7 +4,12 @@ from pydantic import BaseModel, Field
|
|
4
4
|
from typing_extensions import Annotated, TypeAlias
|
5
5
|
|
6
6
|
from classiq.interface.executor.iqae_result import IQAEResult
|
7
|
-
from classiq.interface.executor.result import
|
7
|
+
from classiq.interface.executor.result import (
|
8
|
+
EstimationResult,
|
9
|
+
EstimationResults,
|
10
|
+
ExecutionDetails,
|
11
|
+
MultipleExecutionDetails,
|
12
|
+
)
|
8
13
|
from classiq.interface.executor.vqe_result import VQESolverResult
|
9
14
|
from classiq.interface.helpers.versioned_model import VersionedModel
|
10
15
|
|
@@ -17,7 +22,9 @@ class SavedResultValueType(StrEnum):
|
|
17
22
|
Boolean = "bool"
|
18
23
|
VQESolverResult = "VQESolverResult"
|
19
24
|
ExecutionDetails = "ExecutionDetails"
|
25
|
+
MultipleExecutionDetails = "MultipleExecutionDetails"
|
20
26
|
EstimationResult = "EstimationResult"
|
27
|
+
EstimationResults = "EstimationResults"
|
21
28
|
IQAEResult = "IQAEResult"
|
22
29
|
Unstructured = "Unstructured"
|
23
30
|
|
@@ -52,12 +59,24 @@ class TaggedExecutionDetails(BaseModel):
|
|
52
59
|
value: ExecutionDetails
|
53
60
|
|
54
61
|
|
62
|
+
class TaggedMultipleExecutionDetails(BaseModel):
|
63
|
+
value_type: Literal[SavedResultValueType.MultipleExecutionDetails]
|
64
|
+
name: str
|
65
|
+
value: MultipleExecutionDetails
|
66
|
+
|
67
|
+
|
55
68
|
class TaggedEstimationResult(BaseModel):
|
56
69
|
value_type: Literal[SavedResultValueType.EstimationResult]
|
57
70
|
name: str
|
58
71
|
value: EstimationResult
|
59
72
|
|
60
73
|
|
74
|
+
class TaggedEstimationResults(BaseModel):
|
75
|
+
value_type: Literal[SavedResultValueType.EstimationResults]
|
76
|
+
name: str
|
77
|
+
value: EstimationResults
|
78
|
+
|
79
|
+
|
61
80
|
class TaggedIQAEResult(BaseModel):
|
62
81
|
value_type: Literal[SavedResultValueType.IQAEResult]
|
63
82
|
name: str
|
@@ -77,7 +96,9 @@ SavedResult = Annotated[
|
|
77
96
|
TaggedBoolean,
|
78
97
|
TaggedVQESolverResult,
|
79
98
|
TaggedExecutionDetails,
|
99
|
+
TaggedMultipleExecutionDetails,
|
80
100
|
TaggedEstimationResult,
|
101
|
+
TaggedEstimationResults,
|
81
102
|
TaggedIQAEResult,
|
82
103
|
TaggedUnstructured,
|
83
104
|
],
|
@@ -24,9 +24,7 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
24
24
|
)
|
25
25
|
|
26
26
|
MOLECULE_PROBLEM_PARAM = {"molecule_problem": Struct(name="MoleculeProblem")}
|
27
|
-
MOLECULE_PROBLEM_SIZE = (
|
28
|
-
"len(get_field(molecule_problem_to_hamiltonian(molecule_problem)[0], 'pauli'))"
|
29
|
-
)
|
27
|
+
MOLECULE_PROBLEM_SIZE = "get_field(get_field(molecule_problem_to_hamiltonian(molecule_problem)[0], 'pauli'), 'len')"
|
30
28
|
MOLECULE_PROBLEM_PORT = {
|
31
29
|
"qbv": PortDeclaration(
|
32
30
|
name="qbv",
|
@@ -40,7 +38,7 @@ MOLECULE_PROBLEM_PORT = {
|
|
40
38
|
FOCK_HAMILTONIAN_PROBLEM_PARAM = {
|
41
39
|
"fock_hamiltonian_problem": Struct(name="FockHamiltonianProblem")
|
42
40
|
}
|
43
|
-
FOCK_HAMILTONIAN_SIZE = "
|
41
|
+
FOCK_HAMILTONIAN_SIZE = "get_field(get_field(fock_hamiltonian_problem_to_hamiltonian(fock_hamiltonian_problem)[0], 'pauli'), 'len')"
|
44
42
|
|
45
43
|
FOCK_HAMILTONIAN_PROBLEM_PORT = {
|
46
44
|
"qbv": PortDeclaration(
|
@@ -31,7 +31,7 @@ class FinanceModelType(Enum):
|
|
31
31
|
|
32
32
|
|
33
33
|
FINANCE_FUNCTION_PORT_SIZE_MAPPING: Mapping[FinanceModelType, str] = {
|
34
|
-
FinanceModelType.Gaussian: "get_field(finance_model, 'num_qubits') +
|
34
|
+
FinanceModelType.Gaussian: "get_field(finance_model, 'num_qubits') + get_field(get_field(finance_model, 'rhos'), 'len') + floor(log(sum(get_field(finance_model, 'loss')), 2)) + 1",
|
35
35
|
FinanceModelType.LogNormal: "get_field(finance_model, 'num_qubits')",
|
36
36
|
}
|
37
37
|
|