classiq 0.37.1__py3-none-any.whl → 0.38.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 +2 -2
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +1 -1
- classiq/_analyzer_extras/interactive_hardware.py +3 -3
- classiq/_internals/api_wrapper.py +24 -16
- classiq/_internals/async_utils.py +1 -74
- classiq/_internals/authentication/device.py +9 -4
- classiq/_internals/authentication/password_manager.py +25 -10
- classiq/_internals/authentication/token_manager.py +2 -2
- classiq/_internals/client.py +13 -5
- classiq/_internals/jobs.py +10 -7
- classiq/analyzer/analyzer.py +26 -28
- classiq/analyzer/analyzer_utilities.py +5 -5
- classiq/analyzer/rb.py +4 -5
- classiq/analyzer/show_interactive_hack.py +6 -6
- classiq/applications/benchmarking/mirror_benchmarking.py +9 -6
- classiq/applications/combinatorial_optimization/__init__.py +5 -0
- classiq/applications/qnn/circuit_utils.py +2 -2
- classiq/applications/qnn/gradients/quantum_gradient.py +2 -2
- classiq/applications/qnn/types.py +2 -2
- classiq/applications/qsvm/qsvm.py +4 -7
- classiq/applications/qsvm/qsvm_data_generation.py +2 -5
- classiq/applications_model_constructors/__init__.py +9 -1
- classiq/applications_model_constructors/chemistry_model_constructor.py +9 -16
- classiq/applications_model_constructors/combinatorial_helpers/__init__.py +0 -0
- classiq/applications_model_constructors/combinatorial_helpers/allowed_constraints.py +20 -0
- classiq/applications_model_constructors/combinatorial_helpers/arithmetic/__init__.py +0 -0
- classiq/applications_model_constructors/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
- classiq/applications_model_constructors/combinatorial_helpers/arithmetic/isolation.py +42 -0
- classiq/applications_model_constructors/combinatorial_helpers/combinatorial_problem_utils.py +130 -0
- classiq/applications_model_constructors/combinatorial_helpers/encoding_mapping.py +107 -0
- classiq/applications_model_constructors/combinatorial_helpers/encoding_utils.py +122 -0
- classiq/applications_model_constructors/combinatorial_helpers/memory.py +79 -0
- classiq/applications_model_constructors/combinatorial_helpers/multiple_comp_basis_sp.py +34 -0
- classiq/applications_model_constructors/combinatorial_helpers/optimization_model.py +166 -0
- classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/__init__.py +0 -0
- classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
- classiq/applications_model_constructors/combinatorial_helpers/pauli_helpers/pauli_utils.py +65 -0
- classiq/applications_model_constructors/combinatorial_helpers/py.typed +0 -0
- classiq/applications_model_constructors/combinatorial_helpers/pyomo_utils.py +243 -0
- classiq/applications_model_constructors/combinatorial_helpers/sympy_utils.py +22 -0
- classiq/applications_model_constructors/combinatorial_helpers/transformations/__init__.py +0 -0
- classiq/applications_model_constructors/combinatorial_helpers/transformations/encoding.py +194 -0
- classiq/applications_model_constructors/combinatorial_helpers/transformations/fixed_variables.py +144 -0
- classiq/applications_model_constructors/combinatorial_helpers/transformations/ising_converter.py +124 -0
- classiq/applications_model_constructors/combinatorial_helpers/transformations/penalty.py +32 -0
- classiq/applications_model_constructors/combinatorial_helpers/transformations/penalty_support.py +41 -0
- classiq/applications_model_constructors/combinatorial_helpers/transformations/sign_seperation.py +75 -0
- classiq/applications_model_constructors/combinatorial_helpers/transformations/slack_variables.py +90 -0
- classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +48 -91
- classiq/applications_model_constructors/finance_model_constructor.py +4 -17
- classiq/applications_model_constructors/grover_model_constructor.py +20 -91
- classiq/applications_model_constructors/libraries/qmci_library.py +17 -19
- classiq/builtin_functions/standard_gates.py +1 -1
- classiq/exceptions.py +43 -1
- classiq/executor.py +10 -9
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +6 -3
- classiq/interface/analyzer/result.py +12 -4
- classiq/interface/applications/qsvm.py +13 -1
- classiq/interface/backend/backend_preferences.py +4 -2
- classiq/interface/backend/pydantic_backend.py +3 -1
- classiq/interface/backend/quantum_backend_providers.py +1 -0
- classiq/interface/chemistry/fermionic_operator.py +15 -13
- classiq/interface/chemistry/ground_state_problem.py +18 -3
- classiq/interface/chemistry/molecule.py +8 -6
- classiq/interface/chemistry/operator.py +20 -14
- classiq/interface/combinatorial_optimization/examples/ascending_sequence.py +1 -1
- classiq/interface/combinatorial_optimization/examples/greater_than_ilp.py +1 -1
- classiq/interface/combinatorial_optimization/examples/ilp.py +2 -1
- classiq/interface/combinatorial_optimization/examples/integer_portfolio_optimization.py +2 -2
- classiq/interface/combinatorial_optimization/examples/mds.py +2 -1
- classiq/interface/combinatorial_optimization/examples/mht.py +3 -3
- classiq/interface/combinatorial_optimization/examples/mis.py +4 -1
- classiq/interface/combinatorial_optimization/examples/mvc.py +2 -1
- classiq/interface/combinatorial_optimization/examples/set_cover.py +2 -1
- classiq/interface/combinatorial_optimization/examples/tsp.py +4 -3
- classiq/interface/combinatorial_optimization/examples/tsp_digraph.py +6 -2
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +9 -3
- classiq/interface/executor/aws_execution_cost.py +4 -3
- classiq/interface/executor/estimation.py +2 -2
- classiq/interface/executor/execution_preferences.py +5 -34
- classiq/interface/executor/execution_request.py +19 -17
- classiq/interface/executor/optimizer_preferences.py +22 -13
- classiq/interface/executor/{quantum_program.py → quantum_code.py} +21 -15
- classiq/interface/executor/quantum_instruction_set.py +2 -1
- classiq/interface/executor/register_initialization.py +1 -3
- classiq/interface/executor/result.py +41 -10
- classiq/interface/executor/vqe_result.py +1 -1
- classiq/interface/finance/function_input.py +17 -4
- classiq/interface/finance/gaussian_model_input.py +3 -1
- classiq/interface/finance/log_normal_model_input.py +3 -1
- classiq/interface/finance/model_input.py +2 -0
- classiq/interface/generator/amplitude_loading.py +6 -3
- classiq/interface/generator/application_apis/__init__.py +1 -0
- classiq/interface/generator/application_apis/arithmetic_declarations.py +14 -0
- classiq/interface/generator/arith/argument_utils.py +14 -4
- classiq/interface/generator/arith/arithmetic.py +3 -1
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +12 -13
- classiq/interface/generator/arith/arithmetic_expression_abc.py +4 -1
- classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -2
- classiq/interface/generator/arith/arithmetic_expression_validator.py +16 -2
- classiq/interface/generator/arith/arithmetic_operations.py +5 -10
- classiq/interface/generator/arith/ast_node_rewrite.py +1 -1
- classiq/interface/generator/arith/binary_ops.py +202 -54
- classiq/interface/generator/arith/extremum_operations.py +5 -3
- classiq/interface/generator/arith/logical_ops.py +4 -2
- classiq/interface/generator/arith/machine_precision.py +3 -0
- classiq/interface/generator/arith/number_utils.py +34 -44
- classiq/interface/generator/arith/register_user_input.py +21 -1
- classiq/interface/generator/arith/unary_ops.py +16 -25
- classiq/interface/generator/chemistry_function_params.py +4 -4
- classiq/interface/generator/commuting_pauli_exponentiation.py +3 -1
- classiq/interface/generator/compiler_keywords.py +4 -0
- classiq/interface/generator/complex_type.py +3 -10
- classiq/interface/generator/control_state.py +5 -3
- classiq/interface/generator/credit_risk_example/linear_gci.py +10 -3
- classiq/interface/generator/credit_risk_example/weighted_adder.py +14 -4
- classiq/interface/generator/expressions/atomic_expression_functions.py +5 -3
- classiq/interface/generator/expressions/evaluated_expression.py +18 -4
- classiq/interface/generator/expressions/expression.py +1 -1
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +33 -0
- classiq/interface/generator/expressions/sympy_supported_expressions.py +2 -1
- classiq/interface/generator/finance.py +1 -1
- classiq/interface/generator/function_params.py +7 -6
- classiq/interface/generator/functions/__init__.py +1 -1
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +505 -138
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +25 -99
- classiq/interface/generator/functions/foreign_function_definition.py +12 -4
- classiq/interface/generator/functions/function_implementation.py +8 -4
- classiq/interface/generator/functions/native_function_definition.py +4 -2
- classiq/interface/generator/functions/register.py +4 -2
- classiq/interface/generator/functions/register_mapping_data.py +14 -10
- classiq/interface/generator/generated_circuit_data.py +2 -2
- classiq/interface/generator/grover_operator.py +5 -3
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +5 -1
- classiq/interface/generator/hardware/hardware_data.py +6 -4
- classiq/interface/generator/hardware_efficient_ansatz.py +25 -8
- classiq/interface/generator/hartree_fock.py +3 -1
- classiq/interface/generator/linear_pauli_rotations.py +3 -1
- classiq/interface/generator/mcu.py +5 -3
- classiq/interface/generator/mcx.py +7 -5
- classiq/interface/generator/model/constraints.py +2 -1
- classiq/interface/generator/model/model.py +11 -19
- classiq/interface/generator/model/preferences/preferences.py +4 -3
- classiq/interface/generator/oracles/custom_oracle.py +4 -2
- classiq/interface/generator/oracles/oracle_abc.py +2 -2
- classiq/interface/generator/qpe.py +6 -4
- classiq/interface/generator/qsvm.py +5 -8
- classiq/interface/generator/quantum_function_call.py +21 -16
- classiq/interface/generator/{generated_circuit.py → quantum_program.py} +10 -14
- classiq/interface/generator/range_types.py +3 -1
- classiq/interface/generator/slice_parsing_utils.py +8 -3
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +4 -2
- classiq/interface/generator/state_preparation/metrics.py +2 -1
- classiq/interface/generator/state_preparation/state_preparation.py +7 -5
- classiq/interface/generator/state_propagator.py +16 -5
- classiq/interface/generator/types/builtin_struct_declarations/__init__.py +0 -1
- classiq/interface/generator/types/struct_declaration.py +8 -3
- classiq/interface/generator/ucc.py +6 -4
- classiq/interface/generator/unitary_gate.py +7 -3
- classiq/interface/generator/validations/flow_graph.py +6 -4
- classiq/interface/generator/validations/validator_functions.py +6 -4
- classiq/interface/hardware.py +2 -2
- classiq/interface/helpers/custom_encoders.py +3 -0
- classiq/interface/helpers/pydantic_model_helpers.py +0 -6
- classiq/interface/helpers/validation_helpers.py +1 -1
- classiq/interface/helpers/versioned_model.py +4 -1
- classiq/interface/ide/show.py +2 -2
- classiq/interface/jobs.py +72 -3
- classiq/interface/model/bind_operation.py +18 -11
- classiq/interface/model/call_synthesis_data.py +68 -0
- classiq/interface/model/inplace_binary_operation.py +2 -2
- classiq/interface/model/model.py +27 -21
- classiq/interface/model/native_function_definition.py +3 -5
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +9 -4
- classiq/interface/model/quantum_expressions/control_state.py +2 -2
- classiq/interface/model/quantum_function_call.py +25 -139
- classiq/interface/model/quantum_function_declaration.py +8 -0
- classiq/interface/model/quantum_if_operation.py +2 -3
- classiq/interface/model/quantum_lambda_function.py +64 -0
- classiq/interface/model/quantum_type.py +57 -56
- classiq/interface/model/quantum_variable_declaration.py +1 -1
- classiq/interface/model/statement_block.py +32 -0
- classiq/interface/model/validations/handles_validator.py +14 -12
- classiq/interface/model/within_apply_operation.py +11 -0
- classiq/interface/pyomo_extension/pyomo_sympy_bimap.py +4 -1
- classiq/interface/server/routes.py +5 -0
- classiq/model/function_handler.py +5 -9
- classiq/model/model.py +2 -19
- classiq/qmod/__init__.py +13 -6
- classiq/qmod/builtins/classical_execution_primitives.py +27 -36
- classiq/qmod/builtins/classical_functions.py +24 -14
- classiq/qmod/builtins/functions.py +162 -145
- classiq/qmod/builtins/operations.py +24 -35
- classiq/qmod/builtins/structs.py +15 -15
- classiq/qmod/cfunc.py +42 -0
- classiq/qmod/classical_function.py +6 -14
- classiq/qmod/declaration_inferrer.py +12 -21
- classiq/qmod/expression_query.py +23 -0
- classiq/qmod/model_state_container.py +2 -0
- classiq/qmod/native/__init__.py +0 -0
- classiq/qmod/native/expression_to_qmod.py +189 -0
- classiq/qmod/native/pretty_printer.py +311 -0
- classiq/qmod/qfunc.py +27 -0
- classiq/qmod/qmod_constant.py +76 -0
- classiq/qmod/qmod_parameter.py +34 -12
- classiq/qmod/qmod_struct.py +3 -3
- classiq/qmod/qmod_variable.py +102 -18
- classiq/qmod/quantum_expandable.py +16 -16
- classiq/qmod/quantum_function.py +37 -8
- classiq/qmod/symbolic.py +47 -4
- classiq/qmod/symbolic_expr.py +9 -0
- classiq/qmod/utilities.py +13 -0
- classiq/qmod/write_qmod.py +39 -0
- classiq/quantum_functions/__init__.py +2 -2
- classiq/quantum_functions/annotation_parser.py +9 -11
- classiq/quantum_functions/function_parser.py +1 -1
- classiq/quantum_functions/quantum_function.py +3 -3
- classiq/quantum_register.py +17 -9
- {classiq-0.37.1.dist-info → classiq-0.38.0.dist-info}/METADATA +2 -1
- {classiq-0.37.1.dist-info → classiq-0.38.0.dist-info}/RECORD +222 -186
- {classiq-0.37.1.dist-info → classiq-0.38.0.dist-info}/WHEEL +1 -1
- classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
- classiq/interface/generator/types/builtin_struct_declarations/qaoa_declarations.py +0 -23
- classiq/interface/generator/types/combinatorial_problem.py +0 -26
- classiq/interface/model/numeric_reinterpretation.py +0 -25
- classiq/interface/model/operator_synthesis_data.py +0 -48
- classiq/model/function_handler.pyi +0 -152
@@ -1,6 +1,8 @@
|
|
1
|
-
from typing import Any, Dict, List, Optional, Tuple, Union
|
1
|
+
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
|
2
2
|
|
3
3
|
import pydantic
|
4
|
+
from pydantic import Field
|
5
|
+
from typing_extensions import Annotated
|
4
6
|
|
5
7
|
from classiq.interface.chemistry.fermionic_operator import SummedFermionicOperator
|
6
8
|
from classiq.interface.chemistry.molecule import Molecule
|
@@ -9,6 +11,7 @@ from classiq.interface.helpers.hashable_pydantic_base_model import (
|
|
9
11
|
)
|
10
12
|
|
11
13
|
from classiq._internals.enum_utils import StrEnum
|
14
|
+
from classiq.exceptions import ClassiqValueError
|
12
15
|
|
13
16
|
"""
|
14
17
|
The correct type hint is:
|
@@ -37,6 +40,8 @@ class FermionMapping(StrEnum):
|
|
37
40
|
|
38
41
|
|
39
42
|
class GroundStateProblem(HashablePydanticBaseModel):
|
43
|
+
kind: str
|
44
|
+
|
40
45
|
mapping: FermionMapping = pydantic.Field(
|
41
46
|
default=FermionMapping.JORDAN_WIGNER,
|
42
47
|
description="Fermionic mapping type",
|
@@ -53,7 +58,7 @@ class GroundStateProblem(HashablePydanticBaseModel):
|
|
53
58
|
cls, z2_symmetries: bool, values: Dict[str, Any]
|
54
59
|
) -> bool:
|
55
60
|
if z2_symmetries and values.get("mapping") == FermionMapping.FAST_BRAVYI_KITAEV:
|
56
|
-
raise
|
61
|
+
raise ClassiqValueError(
|
57
62
|
"z2 symmetries reduction can not be used for fast_bravyi_kitaev mapping"
|
58
63
|
)
|
59
64
|
return z2_symmetries
|
@@ -63,6 +68,8 @@ class GroundStateProblem(HashablePydanticBaseModel):
|
|
63
68
|
|
64
69
|
|
65
70
|
class MoleculeProblem(GroundStateProblem):
|
71
|
+
kind: Literal["molecule"] = pydantic.Field(default="molecule")
|
72
|
+
|
66
73
|
molecule: Molecule
|
67
74
|
basis: str = pydantic.Field(default="sto3g", description="Molecular basis set")
|
68
75
|
freeze_core: bool = pydantic.Field(default=False)
|
@@ -72,6 +79,8 @@ class MoleculeProblem(GroundStateProblem):
|
|
72
79
|
|
73
80
|
|
74
81
|
class HamiltonianProblem(GroundStateProblem):
|
82
|
+
kind: Literal["hamiltonian"] = pydantic.Field(default="hamiltonian")
|
83
|
+
|
75
84
|
hamiltonian: SummedFermionicOperator = pydantic.Field(
|
76
85
|
description="Hamiltonian as a fermionic operator"
|
77
86
|
)
|
@@ -96,5 +105,11 @@ class HamiltonianProblem(GroundStateProblem):
|
|
96
105
|
|
97
106
|
|
98
107
|
CHEMISTRY_PROBLEMS = (MoleculeProblem, HamiltonianProblem)
|
99
|
-
CHEMISTRY_PROBLEMS_TYPE =
|
108
|
+
CHEMISTRY_PROBLEMS_TYPE = Annotated[
|
109
|
+
Union[MoleculeProblem, HamiltonianProblem],
|
110
|
+
Field(
|
111
|
+
discriminator="kind",
|
112
|
+
description="Ground state problem object describing the system.",
|
113
|
+
),
|
114
|
+
]
|
100
115
|
CHEMISTRY_ANSATZ_NAMES = ["hw_efficient", "ucc", "hva"]
|
@@ -8,6 +8,8 @@ from classiq.interface.helpers.hashable_pydantic_base_model import (
|
|
8
8
|
HashablePydanticBaseModel,
|
9
9
|
)
|
10
10
|
|
11
|
+
from classiq.exceptions import ClassiqValueError
|
12
|
+
|
11
13
|
|
12
14
|
class Atom(HashablePydanticBaseModel):
|
13
15
|
symbol: Literal[tuple(ELEMENTS)] = pydantic.Field(description="The atom symbol") # type: ignore[valid-type]
|
@@ -41,20 +43,20 @@ class Molecule(HashablePydanticBaseModel):
|
|
41
43
|
@staticmethod
|
42
44
|
def _validate_old_atoms_type(atom: AtomType) -> Atom:
|
43
45
|
if len(atom) != 2:
|
44
|
-
raise
|
46
|
+
raise ClassiqValueError(
|
45
47
|
"each atom should be a list of two entries: 1) name pf the elemnt (str) 2) list of its (x,y,z) location"
|
46
48
|
)
|
47
|
-
if
|
48
|
-
raise
|
49
|
+
if not isinstance(atom[0], str):
|
50
|
+
raise ClassiqValueError(
|
49
51
|
f"atom name should be a string. unknown element: {atom[0]}."
|
50
52
|
)
|
51
53
|
if len(atom[1]) != 3:
|
52
|
-
raise
|
54
|
+
raise ClassiqValueError(
|
53
55
|
f"location of the atom is of length three, representing the (x,y,z) coordinates of the atom, error value: {atom[1]}"
|
54
56
|
)
|
55
57
|
for idx in atom[1]:
|
56
|
-
if
|
57
|
-
raise
|
58
|
+
if not isinstance(idx, (float, int)):
|
59
|
+
raise ClassiqValueError(
|
58
60
|
f"coordinates of the atom should be of type float. error value: {idx}"
|
59
61
|
)
|
60
62
|
symbol, coordinate = atom
|
@@ -71,7 +71,7 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
|
|
71
71
|
@pydantic.validator("pauli_list")
|
72
72
|
def _validate_pauli_list(cls, pauli_list: PydanticPauliList) -> PydanticPauliList:
|
73
73
|
if not all_equal(len(summand[0]) for summand in pauli_list):
|
74
|
-
raise
|
74
|
+
raise ClassiqValueError("Pauli strings have incompatible lengths.")
|
75
75
|
return pauli_list
|
76
76
|
|
77
77
|
@pydantic.root_validator
|
@@ -172,16 +172,18 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
|
|
172
172
|
num_extra_qubits: int,
|
173
173
|
) -> None:
|
174
174
|
if num_extra_qubits < 0:
|
175
|
-
raise
|
175
|
+
raise ClassiqValueError("Number of extra qubits cannot be negative")
|
176
176
|
|
177
177
|
if len(order) != num_qubits:
|
178
|
-
raise
|
178
|
+
raise ClassiqValueError("The qubits order doesn't match the Pauli operator")
|
179
179
|
|
180
180
|
if len(order) != len(set(order)):
|
181
|
-
raise
|
181
|
+
raise ClassiqValueError("The qubits order is not one-to-one")
|
182
182
|
|
183
183
|
if not all(pos < num_qubits + num_extra_qubits for pos in order):
|
184
|
-
raise
|
184
|
+
raise ClassiqValueError(
|
185
|
+
"The qubits order contains qubits which do no exist"
|
186
|
+
)
|
185
187
|
|
186
188
|
@classmethod
|
187
189
|
def reorder(
|
@@ -209,7 +211,7 @@ class PauliOperator(HashablePydanticBaseModel, VersionedModel):
|
|
209
211
|
coefficients = [1] * len(operators)
|
210
212
|
|
211
213
|
if len(operators) != len(coefficients):
|
212
|
-
raise
|
214
|
+
raise ClassiqValueError(
|
213
215
|
f"The number of coefficients ({len(coefficients)}) must be equal to the number of pauli operators ({len(operators)})"
|
214
216
|
)
|
215
217
|
|
@@ -269,7 +271,7 @@ class PauliOperatorV1(HashablePydanticBaseModel):
|
|
269
271
|
@pydantic.validator("pauli_list")
|
270
272
|
def _validate_pauli_list(cls, pauli_list: PydanticPauliList) -> PydanticPauliList:
|
271
273
|
if not all_equal(len(summand[0]) for summand in pauli_list):
|
272
|
-
raise
|
274
|
+
raise ClassiqValueError("Pauli strings have incompatible lengths.")
|
273
275
|
return pauli_list
|
274
276
|
|
275
277
|
@pydantic.root_validator
|
@@ -370,16 +372,18 @@ class PauliOperatorV1(HashablePydanticBaseModel):
|
|
370
372
|
num_extra_qubits: int,
|
371
373
|
) -> None:
|
372
374
|
if num_extra_qubits < 0:
|
373
|
-
raise
|
375
|
+
raise ClassiqValueError("Number of extra qubits cannot be negative")
|
374
376
|
|
375
377
|
if len(order) != num_qubits:
|
376
|
-
raise
|
378
|
+
raise ClassiqValueError("The qubits order doesn't match the Pauli operator")
|
377
379
|
|
378
380
|
if len(order) != len(set(order)):
|
379
|
-
raise
|
381
|
+
raise ClassiqValueError("The qubits order is not one-to-one")
|
380
382
|
|
381
383
|
if not all(pos < num_qubits + num_extra_qubits for pos in order):
|
382
|
-
raise
|
384
|
+
raise ClassiqValueError(
|
385
|
+
"The qubits order contains qubits which do no exist"
|
386
|
+
)
|
383
387
|
|
384
388
|
@classmethod
|
385
389
|
def reorder(
|
@@ -407,7 +411,7 @@ class PauliOperatorV1(HashablePydanticBaseModel):
|
|
407
411
|
coefficients = [1] * len(operators)
|
408
412
|
|
409
413
|
if len(operators) != len(coefficients):
|
410
|
-
raise
|
414
|
+
raise ClassiqValueError(
|
411
415
|
f"The number of coefficients ({len(coefficients)}) must be equal to the number of pauli operators ({len(operators)})"
|
412
416
|
)
|
413
417
|
|
@@ -448,7 +452,7 @@ def to_pauli_matrix(pauli_op: PydanticPauliMonomialStr) -> np.ndarray:
|
|
448
452
|
|
449
453
|
def validate_operator_is_hermitian(pauli_operator: PauliOperator) -> PauliOperator:
|
450
454
|
if not pauli_operator.is_hermitian:
|
451
|
-
raise
|
455
|
+
raise ClassiqValueError("Coefficients of the Hamiltonian must be real numbers")
|
452
456
|
return pauli_operator
|
453
457
|
|
454
458
|
|
@@ -456,7 +460,9 @@ def validate_operator_has_no_complex_coefficients(
|
|
456
460
|
pauli_operator: PauliOperator,
|
457
461
|
) -> PauliOperator:
|
458
462
|
if pauli_operator.has_complex_coefficients:
|
459
|
-
raise
|
463
|
+
raise ClassiqValueError(
|
464
|
+
"Coefficients of the Hamiltonian mustn't be complex numbers"
|
465
|
+
)
|
460
466
|
return pauli_operator
|
461
467
|
|
462
468
|
|
@@ -11,7 +11,7 @@ def ascending_sequence(coeffs: List[int], bound: int) -> pyo.ConcreteModel:
|
|
11
11
|
)
|
12
12
|
|
13
13
|
@model.Constraint(range(len(coeffs) - 1))
|
14
|
-
def monotone_rule(model, idx):
|
14
|
+
def monotone_rule(model: pyo.ConcreteModel, idx: int) -> pyo.ExpressionBase:
|
15
15
|
return model.x[idx] <= model.x[idx + 1]
|
16
16
|
|
17
17
|
model.cost = pyo.Objective(
|
@@ -19,7 +19,7 @@ def greater_than_ilp(
|
|
19
19
|
)
|
20
20
|
|
21
21
|
@model.Constraint(range(num_constraints))
|
22
|
-
def monotone_rule(model, idx):
|
22
|
+
def monotone_rule(model: pyo.ConcreteModel, idx: int) -> pyo.ExpressionBase:
|
23
23
|
return a[idx, :] @ list(model.x.values()) >= float(b[idx])
|
24
24
|
|
25
25
|
# model objective: max(c * x)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import numpy as np
|
2
2
|
import pyomo.core as pyo
|
3
|
+
import pyomo.core.expr.numeric_expr as pyo_expr
|
3
4
|
|
4
5
|
|
5
6
|
def ilp(a: np.ndarray, b: np.ndarray, c: np.ndarray, bound: int) -> pyo.ConcreteModel:
|
@@ -17,7 +18,7 @@ def ilp(a: np.ndarray, b: np.ndarray, c: np.ndarray, bound: int) -> pyo.Concrete
|
|
17
18
|
)
|
18
19
|
|
19
20
|
@model.Constraint(range(num_constraints))
|
20
|
-
def monotone_rule(model, idx):
|
21
|
+
def monotone_rule(model: pyo.ConcreteModel, idx: int) -> pyo_expr.ExpressionBase:
|
21
22
|
return a[idx, :] @ list(model.x.values()) <= float(b[idx])
|
22
23
|
|
23
24
|
# model objective: max(c * x)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import List
|
1
|
+
from typing import List, Tuple
|
2
2
|
|
3
3
|
import numpy as np
|
4
4
|
import pyomo.core as pyo
|
@@ -10,7 +10,7 @@ def integer_portfolio_optimization(
|
|
10
10
|
model = pyo.ConcreteModel()
|
11
11
|
num_assets = len(returns)
|
12
12
|
|
13
|
-
def bounds(
|
13
|
+
def bounds(model: pyo.ConcreteModel, i: int) -> Tuple[int, int]:
|
14
14
|
return 0, upper_bounds[i]
|
15
15
|
|
16
16
|
model.x = pyo.Var(range(num_assets), domain=pyo.NonNegativeIntegers, bounds=bounds)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import networkx as nx
|
2
2
|
import pyomo.core as pyo
|
3
|
+
import pyomo.core.expr.numeric_expr as pyo_expr
|
3
4
|
|
4
5
|
|
5
6
|
def mds(graph: nx.Graph) -> pyo.ConcreteModel:
|
@@ -7,7 +8,7 @@ def mds(graph: nx.Graph) -> pyo.ConcreteModel:
|
|
7
8
|
model.x = pyo.Var(graph.nodes, domain=pyo.Binary)
|
8
9
|
|
9
10
|
@model.Constraint(graph.nodes)
|
10
|
-
def dominating_rule(model, idx):
|
11
|
+
def dominating_rule(model: pyo.ConcreteModel, idx: int) -> pyo_expr.ExpressionBase:
|
11
12
|
sum_of_neighbors = sum(model.x[neighbor] for neighbor in graph.neighbors(idx))
|
12
13
|
return model.x[idx] + sum_of_neighbors >= 1
|
13
14
|
|
@@ -22,7 +22,7 @@ def build_mht_pyomo_model(
|
|
22
22
|
if has_constraints:
|
23
23
|
|
24
24
|
@model.Constraint(model.Nodes)
|
25
|
-
def out_edges_rule(model, idx):
|
25
|
+
def out_edges_rule(model: pyo.ConcreteModel, idx: int) -> pyo.ExpressionBase:
|
26
26
|
out_nodes = [
|
27
27
|
node_id for node_id in model.Nodes if [idx, node_id] in model.Arcs
|
28
28
|
]
|
@@ -32,7 +32,7 @@ def build_mht_pyomo_model(
|
|
32
32
|
return pyo.Constraint.Feasible
|
33
33
|
|
34
34
|
@model.Constraint(model.Nodes)
|
35
|
-
def in_edges_rule(model, idx):
|
35
|
+
def in_edges_rule(model: pyo.ConcreteModel, idx: int) -> pyo.ExpressionBase:
|
36
36
|
in_nodes = [
|
37
37
|
node_id for node_id in model.Nodes if [node_id, idx] in model.Arcs
|
38
38
|
]
|
@@ -41,7 +41,7 @@ def build_mht_pyomo_model(
|
|
41
41
|
else:
|
42
42
|
return pyo.Constraint.Feasible
|
43
43
|
|
44
|
-
def obj_expression(model):
|
44
|
+
def obj_expression(model: pyo.ConcreteModel) -> pyo.ExpressionBase:
|
45
45
|
return sum(
|
46
46
|
round(pubo_energy, _decimals)
|
47
47
|
* math.prod(model.x[edge] for edge in pubo_edges)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import networkx as nx
|
2
2
|
import pyomo.core as pyo
|
3
|
+
import pyomo.core.expr.numeric_expr as pyo_expr
|
3
4
|
|
4
5
|
|
5
6
|
def mis(graph: nx.Graph) -> pyo.ConcreteModel:
|
@@ -7,7 +8,9 @@ def mis(graph: nx.Graph) -> pyo.ConcreteModel:
|
|
7
8
|
model.x = pyo.Var(graph.nodes, domain=pyo.Binary)
|
8
9
|
|
9
10
|
@model.Constraint(graph.edges)
|
10
|
-
def independent_rule(
|
11
|
+
def independent_rule(
|
12
|
+
model: pyo.ConcreteModel, node1: int, node2: int
|
13
|
+
) -> pyo_expr.ExpressionBase:
|
11
14
|
return model.x[node1] + model.x[node2] <= 1
|
12
15
|
|
13
16
|
model.cost = pyo.Objective(expr=sum(model.x.values()), sense=pyo.maximize)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import networkx as nx
|
2
2
|
import pyomo.core as pyo
|
3
|
+
import pyomo.core.expr.numeric_expr as pyo_expr
|
3
4
|
|
4
5
|
|
5
6
|
def mvc(graph: nx.Graph, k: int) -> pyo.ConcreteModel:
|
@@ -7,7 +8,7 @@ def mvc(graph: nx.Graph, k: int) -> pyo.ConcreteModel:
|
|
7
8
|
model.x = pyo.Var(graph.nodes, domain=pyo.Binary)
|
8
9
|
model.amount_constraint = pyo.Constraint(expr=sum(model.x.values()) == k)
|
9
10
|
|
10
|
-
def obj_expression(model):
|
11
|
+
def obj_expression(model: pyo.ConcreteModel) -> pyo_expr.ExpressionBase:
|
11
12
|
# number of edges not covered
|
12
13
|
return sum((1 - model.x[i]) * (1 - model.x[j]) for i, j in graph.edges)
|
13
14
|
|
@@ -2,6 +2,7 @@ import itertools
|
|
2
2
|
from typing import List
|
3
3
|
|
4
4
|
import pyomo.core as pyo
|
5
|
+
import pyomo.core.expr.numeric_expr as pyo_expr
|
5
6
|
|
6
7
|
|
7
8
|
def set_cover(sub_sets: List[List[int]]) -> pyo.ConcreteModel:
|
@@ -16,7 +17,7 @@ def set_cover(sub_sets: List[List[int]]) -> pyo.ConcreteModel:
|
|
16
17
|
model.x = pyo.Var(range(num_sets), domain=pyo.Binary)
|
17
18
|
|
18
19
|
@model.Constraint(entire_set)
|
19
|
-
def independent_rule(model, num):
|
20
|
+
def independent_rule(model: pyo.ConcreteModel, num: int) -> pyo_expr.ExpressionBase:
|
20
21
|
return sum(model.x[idx] for idx in range(num_sets) if num in sub_sets[idx]) >= 1
|
21
22
|
|
22
23
|
model.cost = pyo.Objective(expr=sum(model.x.values()), sense=pyo.minimize)
|
@@ -2,6 +2,7 @@ import itertools
|
|
2
2
|
|
3
3
|
import numpy as np
|
4
4
|
import pyomo.core as pyo
|
5
|
+
import pyomo.core.expr.numeric_expr as pyo_expr
|
5
6
|
|
6
7
|
|
7
8
|
def tsp(distance_matrix: np.ndarray) -> pyo.ConcreteModel:
|
@@ -22,16 +23,16 @@ def tsp(distance_matrix: np.ndarray) -> pyo.ConcreteModel:
|
|
22
23
|
@model.Constraint(points)
|
23
24
|
def each_step_visits_one_point_rule(
|
24
25
|
model: pyo.ConcreteModel, ii: int
|
25
|
-
) ->
|
26
|
+
) -> pyo_expr.ExpressionBase:
|
26
27
|
return sum(model.x[ii, jj] for jj in range(num_points)) == 1
|
27
28
|
|
28
29
|
@model.Constraint(points)
|
29
30
|
def each_point_visited_once_rule(
|
30
31
|
model: pyo.ConcreteModel, jj: int
|
31
|
-
) ->
|
32
|
+
) -> pyo_expr.ExpressionBase:
|
32
33
|
return sum(model.x[ii, jj] for ii in range(num_points)) == 1
|
33
34
|
|
34
|
-
def is_travel_between_2_points(point1: int, point2: int) ->
|
35
|
+
def is_travel_between_2_points(point1: int, point2: int) -> pyo_expr.ExpressionBase:
|
35
36
|
return sum(model.x[point1, kk] * model.x[point2, kk + 1] for kk in points[:-1])
|
36
37
|
|
37
38
|
model.cost = pyo.Objective(
|
@@ -21,11 +21,15 @@ def tsp_digraph(
|
|
21
21
|
) # x[i, j] = 1 indicates that point i is visited at step j
|
22
22
|
|
23
23
|
@model.Constraint(points)
|
24
|
-
def each_step_visits_one_point_rule(
|
24
|
+
def each_step_visits_one_point_rule(
|
25
|
+
model: pyo.ConcreteModel, ii: int
|
26
|
+
) -> pyo.ExpressionBase:
|
25
27
|
return sum(model.x[ii, jj] for jj in steps) == 1
|
26
28
|
|
27
29
|
@model.Constraint(steps)
|
28
|
-
def each_point_visited_once_rule(
|
30
|
+
def each_point_visited_once_rule(
|
31
|
+
model: pyo.ConcreteModel, jj: int
|
32
|
+
) -> pyo.ExpressionBase:
|
29
33
|
return sum(model.x[ii, jj] for ii in points) == 1
|
30
34
|
|
31
35
|
def is_travel_between_2_points(point1: int, point2: int) -> pyo.ExpressionBase:
|
@@ -5,6 +5,8 @@ import numpy as np
|
|
5
5
|
import pydantic
|
6
6
|
from pydantic import BaseModel
|
7
7
|
|
8
|
+
from classiq.exceptions import ClassiqValueError
|
9
|
+
|
8
10
|
_TOLERANCE_DECIMALS = 6
|
9
11
|
|
10
12
|
|
@@ -52,7 +54,9 @@ class MhtQaoaInput(BaseModel):
|
|
52
54
|
return True
|
53
55
|
|
54
56
|
@pydantic.validator("plot_list")
|
55
|
-
def round_plot_list_times_and_validate(
|
57
|
+
def round_plot_list_times_and_validate(
|
58
|
+
cls, plot_list: List[PlotData]
|
59
|
+
) -> List[PlotData]:
|
56
60
|
MhtQaoaInput._check_all_ids_are_distinct(plot_list)
|
57
61
|
MhtQaoaInput._round_to_tolerance_decimals(plot_list)
|
58
62
|
|
@@ -63,7 +67,9 @@ class MhtQaoaInput(BaseModel):
|
|
63
67
|
}
|
64
68
|
|
65
69
|
if len(time_diff_set) != 1:
|
66
|
-
raise
|
70
|
+
raise ClassiqValueError(
|
71
|
+
"The time difference between each time stamp is not equal"
|
72
|
+
)
|
67
73
|
|
68
74
|
return plot_list
|
69
75
|
|
@@ -75,4 +81,4 @@ class MhtQaoaInput(BaseModel):
|
|
75
81
|
@staticmethod
|
76
82
|
def _check_all_ids_are_distinct(plot_list: List[PlotData]) -> None:
|
77
83
|
if not more_itertools.all_unique(plot.plot_id for plot in plot_list):
|
78
|
-
raise
|
84
|
+
raise ClassiqValueError("Plot IDs should be unique.")
|
@@ -1,10 +1,11 @@
|
|
1
1
|
from datetime import date
|
2
|
-
from typing import List, Optional
|
2
|
+
from typing import Any, Dict, List, Optional
|
3
3
|
|
4
4
|
import pydantic
|
5
5
|
from pydantic import validator
|
6
6
|
|
7
7
|
from classiq._internals.enum_utils import StrEnum
|
8
|
+
from classiq.exceptions import ClassiqValueError
|
8
9
|
|
9
10
|
|
10
11
|
class Granularity(StrEnum):
|
@@ -37,9 +38,9 @@ class ExecutionCostForTimePeriod(pydantic.BaseModel):
|
|
37
38
|
json_encoders = {date: lambda v: v.strftime("%Y-%m-%d")}
|
38
39
|
|
39
40
|
@validator("end")
|
40
|
-
def date_order(cls, v, values, **kwargs):
|
41
|
+
def date_order(cls, v: date, values: Dict[str, Any], **kwargs: Any) -> date:
|
41
42
|
if "start" in values and v <= values["start"]:
|
42
|
-
raise
|
43
|
+
raise ClassiqValueError('"end" date should be after "start" date')
|
43
44
|
return v
|
44
45
|
|
45
46
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import pydantic
|
2
2
|
|
3
3
|
from classiq.interface.chemistry.operator import PauliOperators
|
4
|
-
from classiq.interface.executor.
|
4
|
+
from classiq.interface.executor.quantum_code import QuantumCode
|
5
5
|
|
6
6
|
|
7
7
|
class OperatorsEstimation(pydantic.BaseModel):
|
@@ -10,5 +10,5 @@ class OperatorsEstimation(pydantic.BaseModel):
|
|
10
10
|
by a quantum program.
|
11
11
|
"""
|
12
12
|
|
13
|
-
quantum_program:
|
13
|
+
quantum_program: QuantumCode
|
14
14
|
operators: PauliOperators
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from datetime import timedelta
|
2
|
-
from typing import Any, Dict,
|
2
|
+
from typing import Any, Dict, Optional, TypeVar
|
3
3
|
|
4
4
|
import pydantic
|
5
5
|
|
@@ -23,6 +23,7 @@ from classiq.interface.generator.model.preferences.randomness import create_rand
|
|
23
23
|
from classiq.interface.generator.noise_properties import NoiseProperties
|
24
24
|
|
25
25
|
from classiq._internals.enum_utils import ReprEnum
|
26
|
+
from classiq.exceptions import ClassiqValueError
|
26
27
|
|
27
28
|
DIFFERENT_TIMEOUT_MSG = (
|
28
29
|
"Timeout is defined differently in the execution preferences and the "
|
@@ -40,41 +41,12 @@ class QaeWithQpeEstimationMethod(int, ReprEnum):
|
|
40
41
|
BEST_FIT = 1
|
41
42
|
|
42
43
|
|
43
|
-
class AmplitudeAmplification(pydantic.BaseModel):
|
44
|
-
iterations: List[int] = pydantic.Field(
|
45
|
-
default_factory=list,
|
46
|
-
description="Number or list of numbers of iteration to use",
|
47
|
-
)
|
48
|
-
growth_rate: float = pydantic.Field(
|
49
|
-
default=1.25,
|
50
|
-
description="Number of iteration used is set to round(growth_rate**iterations)",
|
51
|
-
)
|
52
|
-
sample_from_iterations: bool = pydantic.Field(
|
53
|
-
default=False,
|
54
|
-
description="If True, number of iterations used is picked randomly from "
|
55
|
-
"[1, iteration] range",
|
56
|
-
)
|
57
|
-
num_of_highest_probability_states_to_check: pydantic.PositiveInt = pydantic.Field(
|
58
|
-
default=1, description="Then number of highest probability states to check"
|
59
|
-
)
|
60
|
-
|
61
|
-
@pydantic.validator("iterations")
|
62
|
-
def _validate_iterations(cls, iterations: Union[List[int], int]) -> List[int]:
|
63
|
-
if isinstance(iterations, int):
|
64
|
-
return [iterations]
|
65
|
-
return iterations
|
66
|
-
|
67
|
-
|
68
44
|
class ExecutionPreferences(pydantic.BaseModel):
|
69
45
|
timeout_sec: Optional[pydantic.PositiveInt] = pydantic.Field(
|
70
46
|
default=None,
|
71
47
|
description="If set, limits the execution runtime. Value is in seconds. "
|
72
48
|
"Not supported on all platforms.",
|
73
49
|
)
|
74
|
-
amplitude_amplification: AmplitudeAmplification = pydantic.Field(
|
75
|
-
default_factory=AmplitudeAmplification,
|
76
|
-
description="Settings related to amplitude amplification execution, used during the grover execution.",
|
77
|
-
)
|
78
50
|
optimizer_preferences: Optional[OptimizerPreferences] = pydantic.Field(
|
79
51
|
default_factory=None,
|
80
52
|
description="Settings related to VQE execution.",
|
@@ -130,9 +102,9 @@ class ExecutionPreferences(pydantic.BaseModel):
|
|
130
102
|
timeout != backend_preferences.job_timeout
|
131
103
|
and backend_preferences.job_timeout != AWS_DEFAULT_JOB_TIMEOUT_SECONDS
|
132
104
|
):
|
133
|
-
raise
|
105
|
+
raise ClassiqValueError(DIFFERENT_TIMEOUT_MSG)
|
134
106
|
if timeout > MAX_EXECUTION_TIMEOUT_SECONDS:
|
135
|
-
raise
|
107
|
+
raise ClassiqValueError(TIMEOUT_LARGE_FOR_AWS_MSG)
|
136
108
|
|
137
109
|
backend_preferences.job_timeout = timeout
|
138
110
|
return backend_preferences
|
@@ -169,7 +141,7 @@ def _choose_original_or_optimizer_attribute(
|
|
169
141
|
return optimizer_attribute
|
170
142
|
|
171
143
|
elif original_attribute != optimizer_attribute:
|
172
|
-
raise
|
144
|
+
raise ClassiqValueError(
|
173
145
|
f"Different {attribure_name} were given for ExecutionPreferences and OptimizerPreferences."
|
174
146
|
)
|
175
147
|
|
@@ -179,7 +151,6 @@ def _choose_original_or_optimizer_attribute(
|
|
179
151
|
|
180
152
|
__all__ = [
|
181
153
|
"ExecutionPreferences",
|
182
|
-
"AmplitudeAmplification",
|
183
154
|
"ErrorMitigationMethod",
|
184
155
|
"NoiseProperties",
|
185
156
|
"OptimizerPreferences",
|
@@ -2,38 +2,40 @@ from datetime import datetime
|
|
2
2
|
from typing import Any, Dict, List, Literal, Optional, Union
|
3
3
|
|
4
4
|
import pydantic
|
5
|
-
from pydantic import BaseModel
|
5
|
+
from pydantic import BaseModel, Field
|
6
|
+
from typing_extensions import Annotated
|
6
7
|
|
7
8
|
from classiq.interface.backend.backend_preferences import IonqBackendPreferences
|
8
9
|
from classiq.interface.executor.estimation import OperatorsEstimation
|
9
10
|
from classiq.interface.executor.execution_preferences import ExecutionPreferences
|
10
|
-
from classiq.interface.executor.
|
11
|
-
|
12
|
-
|
13
|
-
)
|
14
|
-
from classiq.interface.generator.generated_circuit import GeneratedCircuit
|
11
|
+
from classiq.interface.executor.quantum_code import QuantumCode, QuantumInstructionSet
|
12
|
+
from classiq.interface.generator.quantum_program import QuantumProgram
|
13
|
+
from classiq.interface.helpers.custom_encoders import CUSTOM_ENCODERS
|
15
14
|
from classiq.interface.helpers.versioned_model import VersionedModel
|
16
15
|
from classiq.interface.jobs import JobStatus
|
17
16
|
|
18
|
-
|
19
|
-
class GeneratedCircuitExecution(GeneratedCircuit):
|
20
|
-
execution_type: Literal["generated_circuit"] = "generated_circuit"
|
17
|
+
from classiq.exceptions import ClassiqValueError
|
21
18
|
|
22
19
|
|
23
20
|
class QuantumProgramExecution(QuantumProgram):
|
24
|
-
execution_type: Literal["
|
21
|
+
execution_type: Literal["quantum_program2"] = "quantum_program2"
|
22
|
+
|
23
|
+
|
24
|
+
class QuantumCodeExecution(QuantumCode):
|
25
|
+
execution_type: Literal["quantum_code"] = "quantum_code"
|
25
26
|
|
26
27
|
|
27
28
|
class EstimateOperatorsExecution(OperatorsEstimation):
|
28
29
|
execution_type: Literal["estimate_operators"] = "estimate_operators"
|
29
30
|
|
30
31
|
|
31
|
-
ExecutionPayloads =
|
32
|
-
|
32
|
+
ExecutionPayloads = Annotated[
|
33
|
+
Union[QuantumProgramExecution, QuantumCodeExecution, EstimateOperatorsExecution],
|
34
|
+
Field(discriminator="execution_type"),
|
33
35
|
]
|
34
36
|
|
35
37
|
|
36
|
-
class ExecutionRequest(BaseModel):
|
38
|
+
class ExecutionRequest(BaseModel, json_encoders=CUSTOM_ENCODERS):
|
37
39
|
execution_payload: ExecutionPayloads
|
38
40
|
preferences: ExecutionPreferences = pydantic.Field(
|
39
41
|
default_factory=ExecutionPreferences,
|
@@ -58,23 +60,23 @@ class ExecutionRequest(BaseModel):
|
|
58
60
|
is_ionq_backend = isinstance(
|
59
61
|
preferences.backend_preferences, IonqBackendPreferences
|
60
62
|
)
|
61
|
-
if isinstance(quantum_program,
|
63
|
+
if isinstance(quantum_program, QuantumCode):
|
62
64
|
if (
|
63
65
|
quantum_program.syntax == QuantumInstructionSet.IONQ
|
64
66
|
and not is_ionq_backend
|
65
67
|
):
|
66
|
-
raise
|
68
|
+
raise ClassiqValueError("Can only execute IonQ code on IonQ backend.")
|
67
69
|
else:
|
68
70
|
# If we handle anything other than a program.
|
69
71
|
if is_ionq_backend:
|
70
|
-
raise
|
72
|
+
raise ClassiqValueError(
|
71
73
|
"IonQ backend supports only execution of QuantumPrograms"
|
72
74
|
)
|
73
75
|
return preferences
|
74
76
|
|
75
77
|
|
76
78
|
class QuantumProgramExecutionRequest(ExecutionRequest):
|
77
|
-
execution_payload:
|
79
|
+
execution_payload: QuantumCodeExecution
|
78
80
|
|
79
81
|
|
80
82
|
class ExecutionJobDetails(VersionedModel):
|