classiq 0.37.1__py3-none-any.whl → 0.39.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 +23 -24
- classiq/_analyzer_extras/_ipywidgets_async_extension.py +1 -1
- classiq/_analyzer_extras/interactive_hardware.py +3 -3
- classiq/_internals/api_wrapper.py +37 -17
- 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 +24 -6
- classiq/_internals/jobs.py +10 -7
- classiq/analyzer/analyzer.py +29 -29
- classiq/analyzer/analyzer_utilities.py +5 -5
- classiq/analyzer/rb.py +4 -5
- classiq/analyzer/show_interactive_hack.py +6 -6
- classiq/applications/__init__.py +1 -8
- classiq/applications/chemistry/__init__.py +6 -0
- classiq/{applications_model_constructors → applications/chemistry}/chemistry_model_constructor.py +9 -16
- classiq/applications/combinatorial_helpers/allowed_constraints.py +20 -0
- classiq/applications/combinatorial_helpers/arithmetic/arithmetic_expression.py +35 -0
- classiq/applications/combinatorial_helpers/arithmetic/isolation.py +42 -0
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +150 -0
- classiq/applications/combinatorial_helpers/encoding_mapping.py +107 -0
- classiq/applications/combinatorial_helpers/encoding_utils.py +122 -0
- classiq/applications/combinatorial_helpers/memory.py +77 -0
- classiq/applications/combinatorial_helpers/optimization_model.py +162 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_sparsing.py +31 -0
- classiq/applications/combinatorial_helpers/pauli_helpers/pauli_utils.py +75 -0
- classiq/applications/combinatorial_helpers/py.typed +0 -0
- classiq/applications/combinatorial_helpers/pyomo_utils.py +245 -0
- classiq/applications/combinatorial_helpers/solvers/__init__.py +0 -0
- classiq/applications/combinatorial_helpers/sympy_utils.py +22 -0
- classiq/applications/combinatorial_helpers/transformations/__init__.py +0 -0
- classiq/applications/combinatorial_helpers/transformations/encoding.py +187 -0
- classiq/applications/combinatorial_helpers/transformations/fixed_variables.py +142 -0
- classiq/applications/combinatorial_helpers/transformations/ising_converter.py +122 -0
- classiq/applications/combinatorial_helpers/transformations/penalty.py +32 -0
- classiq/applications/combinatorial_helpers/transformations/penalty_support.py +37 -0
- classiq/applications/combinatorial_helpers/transformations/sign_seperation.py +75 -0
- classiq/applications/combinatorial_helpers/transformations/slack_variables.py +88 -0
- classiq/applications/combinatorial_optimization/__init__.py +13 -2
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +134 -0
- classiq/applications/finance/__init__.py +3 -2
- classiq/{applications_model_constructors → applications/finance}/finance_model_constructor.py +27 -30
- classiq/applications/grover/__init__.py +11 -0
- classiq/{applications_model_constructors → applications/grover}/grover_model_constructor.py +20 -91
- classiq/applications/libraries/__init__.py +0 -0
- classiq/applications/libraries/qmci_library.py +35 -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/__init__.py +5 -1
- classiq/applications/qsvm/qsvm.py +4 -7
- classiq/applications/qsvm/qsvm_data_generation.py +2 -5
- classiq/exceptions.py +43 -1
- classiq/execution/all_hardware_devices.py +13 -0
- classiq/executor.py +12 -10
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +6 -3
- classiq/interface/analyzer/result.py +12 -8
- classiq/interface/applications/qsvm.py +17 -3
- classiq/interface/ast_node.py +23 -0
- 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 +8 -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 +15 -48
- 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 +2 -2
- 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/builtin_api_builder.py +0 -5
- 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/constant.py +2 -3
- 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 +3 -5
- 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 +2 -2
- classiq/interface/generator/functions/builtins/__init__.py +15 -0
- classiq/interface/generator/functions/builtins/core_library/__init__.py +14 -0
- classiq/interface/generator/functions/builtins/core_library/chemistry_functions.py +0 -0
- classiq/interface/generator/functions/builtins/internal_operators.py +62 -0
- classiq/interface/generator/functions/{core_lib_declarations/quantum_functions/std_lib_functions.py → builtins/open_lib_functions.py} +612 -219
- classiq/interface/generator/functions/builtins/quantum_operators.py +37 -0
- classiq/interface/generator/functions/classical_type.py +2 -4
- classiq/interface/generator/functions/foreign_function_definition.py +12 -4
- classiq/interface/generator/functions/function_declaration.py +2 -2
- 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 +13 -3
- 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/classical_main_validator.py +1 -1
- classiq/interface/generator/model/constraints.py +2 -1
- classiq/interface/generator/model/model.py +12 -20
- 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 +10 -7
- 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/classical_if.py +13 -0
- classiq/interface/model/classical_parameter_declaration.py +2 -3
- classiq/interface/model/control.py +16 -0
- classiq/interface/model/handle_binding.py +3 -2
- classiq/interface/model/inplace_binary_operation.py +2 -2
- classiq/interface/model/invert.py +10 -0
- classiq/interface/model/model.py +29 -22
- classiq/interface/model/native_function_definition.py +3 -5
- classiq/interface/model/power.py +12 -0
- 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 +33 -142
- classiq/interface/model/quantum_function_declaration.py +8 -0
- classiq/interface/model/quantum_if_operation.py +4 -5
- classiq/interface/model/quantum_lambda_function.py +58 -0
- classiq/{quantum_register.py → interface/model/quantum_register.py} +17 -9
- classiq/interface/model/quantum_statement.py +3 -2
- classiq/interface/model/quantum_type.py +58 -59
- classiq/interface/model/quantum_variable_declaration.py +3 -3
- classiq/interface/model/repeat.py +13 -0
- classiq/interface/model/resolvers/function_call_resolver.py +26 -0
- classiq/interface/model/statement_block.py +49 -0
- classiq/interface/model/validations/handles_validator.py +16 -18
- 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 -4
- classiq/qmod/__init__.py +13 -6
- classiq/qmod/builtins/classical_execution_primitives.py +27 -36
- classiq/qmod/builtins/classical_functions.py +22 -12
- classiq/qmod/builtins/functions.py +272 -328
- classiq/qmod/builtins/operations.py +171 -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 +340 -0
- classiq/qmod/qfunc.py +27 -0
- classiq/qmod/qmod_constant.py +100 -0
- classiq/qmod/qmod_parameter.py +36 -13
- classiq/qmod/qmod_struct.py +3 -3
- classiq/qmod/qmod_variable.py +148 -31
- classiq/qmod/quantum_callable.py +1 -0
- classiq/qmod/quantum_expandable.py +18 -19
- classiq/qmod/quantum_function.py +41 -8
- classiq/qmod/symbolic.py +48 -5
- classiq/qmod/symbolic_expr.py +9 -0
- classiq/qmod/utilities.py +13 -0
- classiq/qmod/write_qmod.py +39 -0
- {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/METADATA +2 -1
- {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/RECORD +244 -225
- {classiq-0.37.1.dist-info → classiq-0.39.0.dist-info}/WHEEL +1 -1
- classiq/applications/benchmarking/__init__.py +0 -9
- classiq/applications/benchmarking/mirror_benchmarking.py +0 -67
- classiq/applications/numpy_utils.py +0 -37
- classiq/applications_model_constructors/__init__.py +0 -17
- classiq/applications_model_constructors/combinatorial_optimization_model_constructor.py +0 -178
- classiq/applications_model_constructors/libraries/qmci_library.py +0 -109
- classiq/builtin_functions/__init__.py +0 -43
- classiq/builtin_functions/amplitude_loading.py +0 -3
- classiq/builtin_functions/binary_ops.py +0 -1
- classiq/builtin_functions/exponentiation.py +0 -5
- classiq/builtin_functions/qpe.py +0 -4
- classiq/builtin_functions/qsvm.py +0 -7
- classiq/builtin_functions/range_types.py +0 -5
- classiq/builtin_functions/standard_gates.py +0 -1
- classiq/builtin_functions/state_preparation.py +0 -6
- classiq/builtin_functions/suzuki_trotter.py +0 -3
- classiq/interface/generator/expressions/qmod_qnum_proxy.py +0 -22
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/__init__.py +0 -18
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +0 -169
- 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/__init__.py +0 -14
- classiq/model/composite_function_generator.py +0 -33
- classiq/model/function_handler.py +0 -466
- classiq/model/function_handler.pyi +0 -152
- classiq/model/logic_flow.py +0 -149
- classiq/model/logic_flow_change_handler.py +0 -71
- classiq/model/model.py +0 -246
- classiq/quantum_functions/__init__.py +0 -17
- classiq/quantum_functions/annotation_parser.py +0 -207
- classiq/quantum_functions/decorators.py +0 -22
- classiq/quantum_functions/function_library.py +0 -181
- classiq/quantum_functions/function_parser.py +0 -74
- classiq/quantum_functions/quantum_function.py +0 -236
- /classiq/{applications_model_constructors/libraries → applications/combinatorial_helpers}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations → applications/combinatorial_helpers/arithmetic}/__init__.py +0 -0
- /classiq/{interface/generator/functions/core_lib_declarations/quantum_functions/chemistry_functions.py → applications/combinatorial_helpers/pauli_helpers/__init__.py} +0 -0
- /classiq/{applications_model_constructors → applications}/libraries/ampltitude_estimation_library.py +0 -0
- /classiq/{applications_model_constructors → applications/qsvm}/qsvm_model_constructor.py +0 -0
- /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/atomic_quantum_functions.py +0 -0
- /classiq/interface/generator/functions/{core_lib_declarations/quantum_functions → builtins/core_library}/exponentiation_functions.py +0 -0
@@ -0,0 +1,37 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
from classiq.interface.model.quantum_function_declaration import (
|
4
|
+
QuantumFunctionDeclaration,
|
5
|
+
QuantumOperandDeclaration,
|
6
|
+
)
|
7
|
+
|
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(
|
23
|
+
name="permute",
|
24
|
+
operand_declarations={
|
25
|
+
"functions": QuantumOperandDeclaration(
|
26
|
+
name="functions",
|
27
|
+
is_list=True,
|
28
|
+
)
|
29
|
+
},
|
30
|
+
)
|
31
|
+
|
32
|
+
APPLY_OPERATOR = get_single_empty_operand_operator(operator_name="apply")
|
33
|
+
|
34
|
+
STD_QMOD_OPERATORS = [
|
35
|
+
PERMUTE_OPERATOR,
|
36
|
+
APPLY_OPERATOR,
|
37
|
+
]
|
@@ -6,20 +6,18 @@ from pydantic import Extra, Field
|
|
6
6
|
from sympy import IndexedBase, Symbol
|
7
7
|
from typing_extensions import Annotated
|
8
8
|
|
9
|
+
from classiq.interface.ast_node import HashableASTNode
|
9
10
|
from classiq.interface.generator.expressions.enums.ladder_operator import (
|
10
11
|
LadderOperator as LadderOperatorEnum,
|
11
12
|
)
|
12
13
|
from classiq.interface.generator.expressions.enums.pauli import Pauli as PauliEnum
|
13
14
|
from classiq.interface.generator.expressions.expression_types import RuntimeExpression
|
14
|
-
from classiq.interface.helpers.hashable_pydantic_base_model import (
|
15
|
-
HashablePydanticBaseModel,
|
16
|
-
)
|
17
15
|
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
18
16
|
|
19
17
|
NamedSymbol = Union[IndexedBase, Symbol]
|
20
18
|
|
21
19
|
|
22
|
-
class ClassicalType(
|
20
|
+
class ClassicalType(HashableASTNode):
|
23
21
|
def as_symbolic(self, name: str) -> Union[NamedSymbol, List[NamedSymbol]]:
|
24
22
|
return Symbol(name)
|
25
23
|
|
@@ -20,6 +20,8 @@ from classiq.interface.generator.functions.register_mapping_data import (
|
|
20
20
|
RegisterMappingData,
|
21
21
|
)
|
22
22
|
|
23
|
+
from classiq.exceptions import ClassiqValueError
|
24
|
+
|
23
25
|
ImplementationsType = Tuple[FunctionImplementation, ...]
|
24
26
|
|
25
27
|
|
@@ -44,7 +46,9 @@ class SynthesisForeignFunctionDefinition(SynthesisQuantumFunctionDeclaration):
|
|
44
46
|
cls, register_mapping: RegisterMappingData
|
45
47
|
) -> RegisterMappingData:
|
46
48
|
if not register_mapping.output_registers:
|
47
|
-
raise
|
49
|
+
raise ClassiqValueError(
|
50
|
+
"The outputs of a custom function must be non-empty"
|
51
|
+
)
|
48
52
|
return register_mapping
|
49
53
|
|
50
54
|
@pydantic.validator("implementations", pre=True)
|
@@ -64,7 +68,7 @@ class SynthesisForeignFunctionDefinition(SynthesisQuantumFunctionDeclaration):
|
|
64
68
|
values: Dict[str, Any],
|
65
69
|
) -> Optional[ImplementationsType]:
|
66
70
|
if not implementations:
|
67
|
-
raise
|
71
|
+
raise ClassiqValueError(
|
68
72
|
"The implementations of a custom function must be non-empty."
|
69
73
|
)
|
70
74
|
|
@@ -92,11 +96,15 @@ class SynthesisForeignFunctionDefinition(SynthesisQuantumFunctionDeclaration):
|
|
92
96
|
|
93
97
|
@property
|
94
98
|
def port_declarations(self) -> Dict[IOName, SynthesisPortDeclaration]:
|
95
|
-
raise
|
99
|
+
raise ClassiqValueError(
|
100
|
+
"Bad usage of foreign function definition: port_declarations"
|
101
|
+
)
|
96
102
|
|
97
103
|
@port_declarations.setter
|
98
104
|
def port_declarations(self, value: Any) -> NoReturn:
|
99
|
-
raise
|
105
|
+
raise ClassiqValueError(
|
106
|
+
"Bad usage of foreign function definition: port_declarations"
|
107
|
+
)
|
100
108
|
|
101
109
|
|
102
110
|
def _map_reg_user_input(registers: List[Register]) -> ArithmeticIODict:
|
@@ -2,12 +2,12 @@ import abc
|
|
2
2
|
from typing import Dict
|
3
3
|
|
4
4
|
import pydantic
|
5
|
-
from pydantic.main import BaseModel
|
6
5
|
|
6
|
+
from classiq.interface.ast_node import ASTNode
|
7
7
|
from classiq.interface.generator.functions.classical_type import ConcreteClassicalType
|
8
8
|
|
9
9
|
|
10
|
-
class FunctionDeclaration(
|
10
|
+
class FunctionDeclaration(ASTNode, abc.ABC):
|
11
11
|
"""
|
12
12
|
Facilitates the creation of a common function interface object.
|
13
13
|
"""
|
@@ -10,6 +10,8 @@ from classiq.interface.generator.functions.register_mapping_data import (
|
|
10
10
|
)
|
11
11
|
from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
|
12
12
|
|
13
|
+
from classiq.exceptions import ClassiqValueError
|
14
|
+
|
13
15
|
RegistersStrictType = Tuple[Register, ...]
|
14
16
|
RegistersType = Union[Register, RegistersStrictType]
|
15
17
|
|
@@ -85,9 +87,9 @@ class FunctionImplementation(BaseModel):
|
|
85
87
|
num_qubits = len(input_qubits)
|
86
88
|
all_qubits = set(range(num_qubits))
|
87
89
|
if num_qubits != sum(register.width for register in all_input_registers):
|
88
|
-
raise
|
90
|
+
raise ClassiqValueError("The input registers must not overlap.")
|
89
91
|
if input_qubits != all_qubits:
|
90
|
-
raise
|
92
|
+
raise ClassiqValueError(
|
91
93
|
"The set of qubits contained in all registers must be consecutive."
|
92
94
|
)
|
93
95
|
|
@@ -98,6 +100,8 @@ class FunctionImplementation(BaseModel):
|
|
98
100
|
if len(output_qubits) != sum(
|
99
101
|
register.width for register in all_output_registers
|
100
102
|
):
|
101
|
-
raise
|
103
|
+
raise ClassiqValueError("The output registers must not overlap.")
|
102
104
|
if not output_qubits == all_qubits:
|
103
|
-
raise
|
105
|
+
raise ClassiqValueError(
|
106
|
+
"The input and output qubits must be mutually consistent."
|
107
|
+
)
|
@@ -17,6 +17,8 @@ from classiq.interface.generator.quantum_function_call import (
|
|
17
17
|
)
|
18
18
|
from classiq.interface.generator.validations import flow_graph
|
19
19
|
|
20
|
+
from classiq.exceptions import ClassiqValueError
|
21
|
+
|
20
22
|
LOGIC_FLOW_DUPLICATE_NAME_ERROR_MSG = (
|
21
23
|
"Cannot have multiple function calls with the same name"
|
22
24
|
)
|
@@ -59,7 +61,7 @@ class SynthesisNativeFunctionDefinition(SynthesisQuantumFunctionDeclaration):
|
|
59
61
|
def validate_body(self) -> None:
|
60
62
|
function_call_names = {call.name for call in self.body}
|
61
63
|
if len(function_call_names) != len(self.body):
|
62
|
-
raise
|
64
|
+
raise ClassiqValueError(LOGIC_FLOW_DUPLICATE_NAME_ERROR_MSG)
|
63
65
|
flow_graph.validate_legal_wiring(
|
64
66
|
self.body,
|
65
67
|
flow_input_names=list(self.input_ports_wiring.values()),
|
@@ -83,7 +85,7 @@ class SynthesisNativeFunctionDefinition(SynthesisQuantumFunctionDeclaration):
|
|
83
85
|
io_name not in port_declarations
|
84
86
|
or not port_declarations[io_name].direction == direction
|
85
87
|
):
|
86
|
-
raise
|
88
|
+
raise ClassiqValueError(
|
87
89
|
f"The wired {direction} port {io_name!r} is not declared."
|
88
90
|
)
|
89
91
|
|
@@ -8,6 +8,8 @@ from pydantic import BaseModel
|
|
8
8
|
|
9
9
|
from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
|
10
10
|
|
11
|
+
from classiq.exceptions import ClassiqValueError
|
12
|
+
|
11
13
|
QubitsType = Tuple[pydantic.NonNegativeInt, ...]
|
12
14
|
|
13
15
|
|
@@ -32,9 +34,9 @@ class Register(BaseModel):
|
|
32
34
|
@pydantic.validator("qubits")
|
33
35
|
def validate_qubits(cls, qubits: QubitsType) -> QubitsType:
|
34
36
|
if len(qubits) == 0:
|
35
|
-
raise
|
37
|
+
raise ClassiqValueError("qubits field must be non-empty.")
|
36
38
|
if len(set(qubits)) != len(qubits):
|
37
|
-
raise
|
39
|
+
raise ClassiqValueError("All qubits of a register must be distinct.")
|
38
40
|
return qubits
|
39
41
|
|
40
42
|
|
@@ -9,6 +9,8 @@ from classiq.interface.generator.functions.register import Register, get_registe
|
|
9
9
|
from classiq.interface.generator.register_role import RegisterRole as Role
|
10
10
|
from classiq.interface.helpers.custom_pydantic_types import PydanticNonEmptyString
|
11
11
|
|
12
|
+
from classiq.exceptions import ClassiqValueError
|
13
|
+
|
12
14
|
REGISTER_NOT_FOUND_ERROR = "Register name not found"
|
13
15
|
|
14
16
|
|
@@ -29,12 +31,12 @@ class RegisterMappingData(pydantic.BaseModel):
|
|
29
31
|
|
30
32
|
all_input_qubits = sorted(input_qubits + zero_input_qubits)
|
31
33
|
if not cls._validate_no_overlap(all_input_qubits):
|
32
|
-
raise
|
34
|
+
raise ClassiqValueError("overlapping input qubits are not allowed")
|
33
35
|
if not cls._validate_no_overlap(output_qubits):
|
34
|
-
raise
|
36
|
+
raise ClassiqValueError("overlapping output qubits are not allowed")
|
35
37
|
|
36
38
|
if not output_qubits == all_input_qubits:
|
37
|
-
raise
|
39
|
+
raise ClassiqValueError(
|
38
40
|
"output registers should be included within the input / zero input registers"
|
39
41
|
)
|
40
42
|
|
@@ -45,7 +47,9 @@ class RegisterMappingData(pydantic.BaseModel):
|
|
45
47
|
cls, field_value: List[Register]
|
46
48
|
) -> List[Register]:
|
47
49
|
if len(field_value) != len({io_register.name for io_register in field_value}):
|
48
|
-
raise
|
50
|
+
raise ClassiqValueError(
|
51
|
+
"The names of PortDirection registers must be distinct."
|
52
|
+
)
|
49
53
|
return field_value
|
50
54
|
|
51
55
|
@staticmethod
|
@@ -54,9 +58,7 @@ class RegisterMappingData(pydantic.BaseModel):
|
|
54
58
|
|
55
59
|
@staticmethod
|
56
60
|
def _get_qubit_range(registers: Iterable[Register]) -> List[int]:
|
57
|
-
return sorted(
|
58
|
-
list(itertools.chain.from_iterable(reg.qubits for reg in registers))
|
59
|
-
)
|
61
|
+
return sorted(itertools.chain.from_iterable(reg.qubits for reg in registers))
|
60
62
|
|
61
63
|
@property
|
62
64
|
def input_names(self) -> Iterable[str]:
|
@@ -74,19 +76,21 @@ class RegisterMappingData(pydantic.BaseModel):
|
|
74
76
|
self.zero_input_registers != other.zero_input_registers,
|
75
77
|
]
|
76
78
|
):
|
77
|
-
raise
|
79
|
+
raise ClassiqValueError(
|
80
|
+
"Interface should be identical in all implementations"
|
81
|
+
)
|
78
82
|
|
79
83
|
def get_input_register(self, name: PydanticNonEmptyString) -> Register:
|
80
84
|
for reg in self.input_registers:
|
81
85
|
if reg.name == name:
|
82
86
|
return reg
|
83
|
-
raise
|
87
|
+
raise ClassiqValueError(REGISTER_NOT_FOUND_ERROR)
|
84
88
|
|
85
89
|
def get_output_register(self, name: PydanticNonEmptyString) -> Register:
|
86
90
|
for reg in self.output_registers:
|
87
91
|
if reg.name == name:
|
88
92
|
return reg
|
89
|
-
raise
|
93
|
+
raise ClassiqValueError(REGISTER_NOT_FOUND_ERROR)
|
90
94
|
|
91
95
|
@staticmethod
|
92
96
|
def from_registers_dict(
|
@@ -61,9 +61,9 @@ class GeneratedFunction(pydantic.BaseModel):
|
|
61
61
|
dangling_outputs: Dict[str, GeneratedRegister] = dict()
|
62
62
|
|
63
63
|
def __getitem__(self, key: Union[int, str]) -> GeneratedRegister:
|
64
|
-
if
|
64
|
+
if isinstance(key, int):
|
65
65
|
return self.registers[key]
|
66
|
-
if
|
66
|
+
if isinstance(key, str):
|
67
67
|
for register in self.registers:
|
68
68
|
if key == register.name:
|
69
69
|
return register
|
@@ -18,6 +18,8 @@ from classiq.interface.generator.oracles.oracle_function_param_list import (
|
|
18
18
|
from classiq.interface.generator.range_types import NonNegativeFloatRange
|
19
19
|
from classiq.interface.generator.state_preparation import Metrics, StatePreparation
|
20
20
|
|
21
|
+
from classiq.exceptions import ClassiqValueError
|
22
|
+
|
21
23
|
_DEFAULT_ORACLE_DISCRIMINATOR: FunctionParamsDiscriminator = (
|
22
24
|
ArithmeticOracle.discriminator()
|
23
25
|
)
|
@@ -47,13 +49,13 @@ class GroverOperator(FunctionParams):
|
|
47
49
|
params=oracle_params,
|
48
50
|
discriminator=values.get("oracle", _DEFAULT_ORACLE_DISCRIMINATOR),
|
49
51
|
param_classes=oracle_function_param_library.param_list,
|
50
|
-
no_discriminator_error=
|
51
|
-
bad_function_error=
|
52
|
+
no_discriminator_error=ClassiqValueError("Invalid oracle name"),
|
53
|
+
bad_function_error=ClassiqValueError("Invalid oracle params"),
|
52
54
|
)
|
53
55
|
elif isinstance(oracle_params, FunctionParams):
|
54
56
|
values["oracle"] = oracle_params.discriminator()
|
55
57
|
else:
|
56
|
-
raise
|
58
|
+
raise ClassiqValueError("Invalid oracle params")
|
57
59
|
return values
|
58
60
|
|
59
61
|
@pydantic.validator("state_preparation_params", always=True)
|
@@ -7,6 +7,8 @@ from classiq.interface.generator.hamiltonian_evolution.hamiltonian_evolution imp
|
|
7
7
|
)
|
8
8
|
from classiq.interface.generator.parameters import ParameterFloatType
|
9
9
|
|
10
|
+
from classiq.exceptions import ClassiqValueError
|
11
|
+
|
10
12
|
|
11
13
|
class SuzukiParameters(pydantic.BaseModel):
|
12
14
|
order: pydantic.PositiveInt = pydantic.Field(
|
@@ -20,7 +22,9 @@ class SuzukiParameters(pydantic.BaseModel):
|
|
20
22
|
@pydantic.validator("order")
|
21
23
|
def _validate_order(cls, order: int) -> int:
|
22
24
|
if order != 1 and order % 2:
|
23
|
-
raise
|
25
|
+
raise ClassiqValueError(
|
26
|
+
f"Odd order greater than 1 is not supported. Got {order}"
|
27
|
+
)
|
24
28
|
return order
|
25
29
|
|
26
30
|
class Config:
|
@@ -14,6 +14,8 @@ from classiq.interface.generator.transpiler_basis_gates import (
|
|
14
14
|
)
|
15
15
|
from classiq.interface.helpers.custom_pydantic_types import PydanticNonNegIntTuple
|
16
16
|
|
17
|
+
from classiq.exceptions import ClassiqValueError
|
18
|
+
|
17
19
|
ConnectivityMap = List[PydanticNonNegIntTuple]
|
18
20
|
BACKEND_VALIDATION_ERROR_MESSAGE = (
|
19
21
|
"Backend service provider and backend name should be specified together."
|
@@ -48,7 +50,7 @@ class HardwareData(pydantic.BaseModel):
|
|
48
50
|
if connectivity_map is None:
|
49
51
|
return connectivity_map
|
50
52
|
if not connectivity_map:
|
51
|
-
raise
|
53
|
+
raise ClassiqValueError("Connectivity map cannot be empty")
|
52
54
|
connectivity_map = _reindex_qubits(connectivity_map)
|
53
55
|
return connectivity_map
|
54
56
|
|
@@ -64,7 +66,7 @@ class HardwareData(pydantic.BaseModel):
|
|
64
66
|
values["connectivity_map"] = connectivity_map
|
65
67
|
|
66
68
|
if not _is_connected_map(connectivity_map):
|
67
|
-
raise
|
69
|
+
raise ClassiqValueError(
|
68
70
|
f"Connectivity map must be connected: {connectivity_map} is not connected."
|
69
71
|
)
|
70
72
|
return values
|
@@ -91,7 +93,7 @@ class HardwareData(pydantic.BaseModel):
|
|
91
93
|
if gate in TWO_QUBIT_GATES and gate not in ROUTING_TWO_QUBIT_BASIS_GATES
|
92
94
|
]
|
93
95
|
if invalid_gates:
|
94
|
-
raise
|
96
|
+
raise ClassiqValueError(
|
95
97
|
"Connectivity-aware synthesis with non-symmetric coupling map "
|
96
98
|
"is currently supported for the following two-qubit gates only: cx, ecr, rzx."
|
97
99
|
)
|
@@ -107,7 +109,7 @@ class CustomHardwareSettings(HardwareData):
|
|
107
109
|
valid_gates = list(TranspilerBasisGates)
|
108
110
|
invalid_gates = [gate for gate in basis_gates if gate not in valid_gates]
|
109
111
|
if invalid_gates:
|
110
|
-
raise
|
112
|
+
raise ClassiqValueError(
|
111
113
|
"Invalid gates for hardware-aware synthesis: " + str(invalid_gates)
|
112
114
|
)
|
113
115
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import itertools
|
2
|
-
from typing import List, Union
|
2
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union
|
3
3
|
|
4
4
|
import pydantic
|
5
5
|
|
@@ -16,6 +16,7 @@ from classiq.interface.generator.transpiler_basis_gates import (
|
|
16
16
|
from classiq.interface.helpers.custom_pydantic_types import PydanticNonNegIntTuple
|
17
17
|
|
18
18
|
from classiq._internals.enum_utils import StrEnum
|
19
|
+
from classiq.exceptions import ClassiqValueError
|
19
20
|
|
20
21
|
ConnectivityMap = List[PydanticNonNegIntTuple]
|
21
22
|
|
@@ -63,7 +64,9 @@ class HardwareEfficientAnsatz(function_params.FunctionParams):
|
|
63
64
|
)
|
64
65
|
|
65
66
|
@pydantic.validator("num_qubits", pre=True, always=True)
|
66
|
-
def validate_num_qubits(
|
67
|
+
def validate_num_qubits(
|
68
|
+
cls, num_qubits: Optional[pydantic.PositiveInt], values: Dict[str, Any]
|
69
|
+
) -> pydantic.PositiveInt:
|
67
70
|
connectivity_map = values.get("connectivity_map")
|
68
71
|
conn_map_is_not_list = (
|
69
72
|
isinstance(connectivity_map, SupportedConnectivityMaps)
|
@@ -71,42 +74,56 @@ class HardwareEfficientAnsatz(function_params.FunctionParams):
|
|
71
74
|
)
|
72
75
|
|
73
76
|
if num_qubits is None and conn_map_is_not_list:
|
74
|
-
raise
|
77
|
+
raise ClassiqValueError(_NUM_QUBITS_NOT_PROVIDED_ERROR)
|
75
78
|
if num_qubits is None:
|
79
|
+
if conn_map_is_not_list:
|
80
|
+
raise ValueError(_NUM_QUBITS_NOT_PROVIDED_ERROR)
|
81
|
+
|
82
|
+
if TYPE_CHECKING:
|
83
|
+
assert connectivity_map is not None
|
84
|
+
|
76
85
|
return len(set(itertools.chain.from_iterable(connectivity_map)))
|
86
|
+
|
77
87
|
if conn_map_is_not_list:
|
78
88
|
return num_qubits
|
79
89
|
|
90
|
+
if TYPE_CHECKING:
|
91
|
+
assert connectivity_map is not None
|
92
|
+
|
80
93
|
invalid_qubits = {
|
81
94
|
qubit
|
82
95
|
for qubit in itertools.chain.from_iterable(connectivity_map)
|
83
96
|
if qubit >= num_qubits
|
84
97
|
}
|
85
98
|
if invalid_qubits:
|
86
|
-
raise
|
99
|
+
raise ClassiqValueError(
|
87
100
|
f"Invalid qubits: {invalid_qubits} "
|
88
101
|
f"out of range specified by num_qubits: [0, {num_qubits - 1}]"
|
89
102
|
)
|
90
103
|
return num_qubits
|
91
104
|
|
92
105
|
@pydantic.validator("one_qubit_gates")
|
93
|
-
def validate_one_qubit_gates(
|
106
|
+
def validate_one_qubit_gates(
|
107
|
+
cls, one_qubit_gates: Union[str, List[str]]
|
108
|
+
) -> Union[str, List[str]]:
|
94
109
|
one_qubit_gates_list = (
|
95
110
|
[one_qubit_gates] if isinstance(one_qubit_gates, str) else one_qubit_gates
|
96
111
|
)
|
97
112
|
for one_qubit_gate in one_qubit_gates_list:
|
98
113
|
if one_qubit_gate not in SINGLE_QUBIT_GATES:
|
99
|
-
raise
|
114
|
+
raise ClassiqValueError(f"Invalid one qubit gate: {one_qubit_gate}")
|
100
115
|
return one_qubit_gates
|
101
116
|
|
102
117
|
@pydantic.validator("two_qubit_gates")
|
103
|
-
def validate_two_qubit_gates(
|
118
|
+
def validate_two_qubit_gates(
|
119
|
+
cls, two_qubit_gates: Union[str, List[str]]
|
120
|
+
) -> Union[str, List[str]]:
|
104
121
|
two_qubit_gates_list = (
|
105
122
|
[two_qubit_gates] if isinstance(two_qubit_gates, str) else two_qubit_gates
|
106
123
|
)
|
107
124
|
for two_qubit_gate in two_qubit_gates_list:
|
108
125
|
if two_qubit_gate not in TWO_QUBIT_GATES:
|
109
|
-
raise
|
126
|
+
raise ClassiqValueError(f"Invalid two qubit gate: {two_qubit_gate}")
|
110
127
|
return two_qubit_gates
|
111
128
|
|
112
129
|
def _create_ios(self) -> None:
|
@@ -1,16 +1,26 @@
|
|
1
|
+
from typing import Any, Union
|
2
|
+
|
1
3
|
import pydantic
|
2
4
|
|
3
|
-
from classiq.interface.chemistry.ground_state_problem import
|
5
|
+
from classiq.interface.chemistry.ground_state_problem import (
|
6
|
+
CHEMISTRY_PROBLEMS,
|
7
|
+
HamiltonianProblem,
|
8
|
+
MoleculeProblem,
|
9
|
+
)
|
4
10
|
from classiq.interface.generator.chemistry_function_params import (
|
5
11
|
ChemistryFunctionParams,
|
6
12
|
)
|
7
13
|
|
14
|
+
from classiq.exceptions import ClassiqValueError
|
15
|
+
|
8
16
|
|
9
17
|
class HartreeFock(ChemistryFunctionParams):
|
10
18
|
@pydantic.validator("gs_problem")
|
11
|
-
def validate_gs_problem(
|
19
|
+
def validate_gs_problem(
|
20
|
+
cls, gs_problem: Any
|
21
|
+
) -> Union[MoleculeProblem, HamiltonianProblem]:
|
12
22
|
if not isinstance(gs_problem, CHEMISTRY_PROBLEMS):
|
13
|
-
raise
|
23
|
+
raise ClassiqValueError(
|
14
24
|
f"ground state problem must be of type {CHEMISTRY_PROBLEMS}"
|
15
25
|
)
|
16
26
|
return gs_problem
|
@@ -5,6 +5,8 @@ import pydantic
|
|
5
5
|
from classiq.interface.generator import function_params
|
6
6
|
from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
|
7
7
|
|
8
|
+
from classiq.exceptions import ClassiqValueError
|
9
|
+
|
8
10
|
STATE = "state"
|
9
11
|
TARGET = "target"
|
10
12
|
|
@@ -68,7 +70,7 @@ class LinearPauliRotations(function_params.FunctionParams):
|
|
68
70
|
slopes = values.get("slopes", list())
|
69
71
|
if len(slopes) == len(offsets) and len(offsets) == len(bases):
|
70
72
|
return values
|
71
|
-
raise
|
73
|
+
raise ClassiqValueError(LENGTH_ERROR_MESSAGE)
|
72
74
|
|
73
75
|
def _create_ios(self) -> None:
|
74
76
|
self._inputs = {
|
@@ -7,6 +7,8 @@ from classiq.interface.generator.control_state import ControlState
|
|
7
7
|
from classiq.interface.generator.function_params import FunctionParams
|
8
8
|
from classiq.interface.generator.parameters import ParameterFloatType
|
9
9
|
|
10
|
+
from classiq.exceptions import ClassiqValueError
|
11
|
+
|
10
12
|
CTRL = "CTRL"
|
11
13
|
TARGET = "TARGET"
|
12
14
|
|
@@ -58,7 +60,7 @@ class Mcu(FunctionParams):
|
|
58
60
|
ControlState.validate_control_string(ctrl_state)
|
59
61
|
|
60
62
|
if ctrl_state is None and num_ctrl_qubits is None:
|
61
|
-
raise
|
63
|
+
raise ClassiqValueError("num_ctrl_qubits or ctrl_state must exist.")
|
62
64
|
|
63
65
|
if ctrl_state is None and num_ctrl_qubits is not None:
|
64
66
|
values["ctrl_state"] = "1" * num_ctrl_qubits
|
@@ -69,7 +71,7 @@ class Mcu(FunctionParams):
|
|
69
71
|
values["num_ctrl_qubits"] = num_ctrl_qubits
|
70
72
|
|
71
73
|
if len(ctrl_state) != num_ctrl_qubits:
|
72
|
-
raise
|
74
|
+
raise ClassiqValueError(
|
73
75
|
"control state length should be equal to the number of control qubits"
|
74
76
|
)
|
75
77
|
|
@@ -77,7 +79,7 @@ class Mcu(FunctionParams):
|
|
77
79
|
|
78
80
|
def _create_ios(self) -> None:
|
79
81
|
if self.num_ctrl_qubits is None:
|
80
|
-
raise
|
82
|
+
raise ClassiqValueError("num_ctrl_qubits must have a valid value.")
|
81
83
|
ctrl_register = RegisterUserInput(size=self.num_ctrl_qubits, name=CTRL)
|
82
84
|
target_register = RegisterUserInput(size=1, name=TARGET)
|
83
85
|
self._inputs = {reg.name: reg for reg in (ctrl_register, target_register)}
|
@@ -6,6 +6,8 @@ from classiq.interface.generator.arith.register_user_input import RegisterUserIn
|
|
6
6
|
from classiq.interface.generator.control_state import ControlState
|
7
7
|
from classiq.interface.generator.function_params import FunctionParams
|
8
8
|
|
9
|
+
from classiq.exceptions import ClassiqValueError
|
10
|
+
|
9
11
|
CTRL = "CTRL_IN"
|
10
12
|
TARGET_QUBIT = "TARGET_QUBIT"
|
11
13
|
|
@@ -29,9 +31,9 @@ class Mcx(FunctionParams):
|
|
29
31
|
) -> List[RegisterUserInput]:
|
30
32
|
register_name_list: List[Optional[str]] = [arg.name for arg in arguments]
|
31
33
|
if None in register_name_list:
|
32
|
-
raise
|
34
|
+
raise ClassiqValueError("All registers must be named")
|
33
35
|
if len(set(register_name_list)) != len(register_name_list):
|
34
|
-
raise
|
36
|
+
raise ClassiqValueError("Registers must have distinct names")
|
35
37
|
return arguments
|
36
38
|
|
37
39
|
@pydantic.validator("num_ctrl_qubits", always=True)
|
@@ -42,14 +44,14 @@ class Mcx(FunctionParams):
|
|
42
44
|
num_ctrl_qubits = arguments_size - 1
|
43
45
|
|
44
46
|
if num_ctrl_qubits < 1:
|
45
|
-
raise
|
47
|
+
raise ClassiqValueError("Must have control qubits")
|
46
48
|
|
47
49
|
if arguments_size == 0:
|
48
50
|
ctrl_register = RegisterUserInput(size=num_ctrl_qubits, name=CTRL)
|
49
51
|
target_register = RegisterUserInput(size=1, name=TARGET_QUBIT)
|
50
52
|
values["arguments"] = [ctrl_register, target_register]
|
51
53
|
elif num_ctrl_qubits != arguments_size - 1:
|
52
|
-
raise
|
54
|
+
raise ClassiqValueError("Given sizes do not match")
|
53
55
|
return num_ctrl_qubits
|
54
56
|
|
55
57
|
@pydantic.validator("ctrl_state", always=True)
|
@@ -58,7 +60,7 @@ class Mcx(FunctionParams):
|
|
58
60
|
if not ctrl_state:
|
59
61
|
return "1" * num_ctrl_qubits
|
60
62
|
if len(ctrl_state) != num_ctrl_qubits:
|
61
|
-
raise
|
63
|
+
raise ClassiqValueError(
|
62
64
|
"control state length should be equal to the number of control qubits"
|
63
65
|
)
|
64
66
|
ControlState.validate_control_string(ctrl_state)
|
@@ -7,6 +7,7 @@ from pydantic import BaseModel, Extra
|
|
7
7
|
from classiq.interface.generator.transpiler_basis_gates import TranspilerBasisGates
|
8
8
|
|
9
9
|
from classiq._internals.enum_utils import StrEnum
|
10
|
+
from classiq.exceptions import ClassiqValueError
|
10
11
|
|
11
12
|
UNCONSTRAINED = -1
|
12
13
|
|
@@ -26,7 +27,7 @@ def optimization_parameter_type_from_string(param: str) -> OptimizationParameter
|
|
26
27
|
return enum_(param) # type: ignore[return-value]
|
27
28
|
except ValueError:
|
28
29
|
pass
|
29
|
-
raise
|
30
|
+
raise ClassiqValueError(f"Invalid OptimizationParameterType {param}")
|
30
31
|
|
31
32
|
|
32
33
|
class Constraints(BaseModel, extra=Extra.forbid):
|