classiq 0.36.0__py3-none-any.whl → 0.37.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 +1 -0
- classiq/_internals/api_wrapper.py +24 -6
- classiq/_internals/authentication/device.py +6 -3
- classiq/_internals/authentication/token_manager.py +21 -5
- classiq/_internals/client.py +7 -2
- classiq/_internals/config.py +12 -0
- classiq/_internals/host_checker.py +1 -1
- classiq/_internals/jobs.py +3 -1
- classiq/_internals/type_validation.py +3 -6
- classiq/analyzer/analyzer.py +1 -0
- classiq/analyzer/rb.py +3 -5
- classiq/applications_model_constructors/chemistry_model_constructor.py +42 -67
- classiq/applications_model_constructors/grover_model_constructor.py +27 -18
- classiq/exceptions.py +5 -0
- classiq/execution/jobs.py +13 -4
- classiq/executor.py +3 -2
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +0 -6
- classiq/interface/analyzer/result.py +0 -4
- classiq/interface/backend/backend_preferences.py +2 -2
- classiq/interface/backend/quantum_backend_providers.py +1 -1
- classiq/interface/execution/resource_estimator.py +7 -0
- classiq/interface/execution/result.py +5 -0
- classiq/interface/executor/register_initialization.py +3 -1
- classiq/interface/executor/vqe_result.py +1 -0
- classiq/interface/generator/ansatz_library.py +3 -3
- classiq/interface/generator/arith/argument_utils.py +4 -4
- classiq/interface/generator/arith/arithmetic.py +4 -2
- classiq/interface/generator/arith/arithmetic_arg_type_validator.py +11 -5
- classiq/interface/generator/arith/arithmetic_expression_parser.py +8 -7
- classiq/interface/generator/arith/arithmetic_operations.py +7 -0
- classiq/interface/generator/arith/arithmetic_param_getters.py +97 -16
- classiq/interface/generator/arith/arithmetic_result_builder.py +13 -3
- classiq/interface/generator/arith/binary_ops.py +8 -10
- classiq/interface/generator/arith/extremum_operations.py +2 -2
- classiq/interface/generator/arith/number_utils.py +20 -23
- classiq/interface/generator/arith/register_user_input.py +3 -1
- classiq/interface/generator/arith/unary_ops.py +9 -13
- classiq/interface/generator/expressions/atomic_expression_functions.py +2 -0
- classiq/interface/generator/expressions/expression.py +7 -2
- classiq/interface/generator/expressions/qmod_qnum_proxy.py +22 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +2 -12
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +63 -3
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +143 -17
- classiq/interface/generator/functions/core_lib_declarations/quantum_operators.py +41 -16
- classiq/interface/generator/functions/native_function_definition.py +3 -3
- classiq/interface/generator/model/constraints.py +3 -3
- classiq/interface/generator/model/preferences/preferences.py +13 -9
- classiq/interface/generator/noise_properties.py +5 -5
- classiq/interface/generator/qpe.py +5 -5
- classiq/interface/generator/quantum_function_call.py +5 -3
- classiq/interface/generator/randomized_benchmarking.py +5 -3
- classiq/interface/generator/visitor.py +1 -2
- classiq/interface/hardware.py +1 -1
- classiq/interface/helpers/custom_pydantic_types.py +6 -0
- classiq/interface/model/{modular_addition_operation.py → inplace_binary_operation.py} +16 -2
- classiq/interface/model/native_function_definition.py +2 -24
- classiq/interface/model/operator_synthesis_data.py +6 -0
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +8 -4
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +9 -5
- classiq/interface/model/quantum_expressions/control_state.py +38 -0
- classiq/interface/model/quantum_expressions/quantum_expression.py +21 -11
- classiq/interface/model/quantum_function_call.py +81 -6
- classiq/interface/model/quantum_function_declaration.py +3 -3
- classiq/interface/model/quantum_if_operation.py +95 -0
- classiq/interface/model/resolvers/function_call_resolver.py +1 -1
- classiq/interface/model/validations/handles_validator.py +42 -15
- classiq/interface/server/routes.py +10 -6
- classiq/model/function_handler.pyi +86 -86
- classiq/model/model.py +1 -0
- classiq/qmod/__init__.py +6 -1
- classiq/qmod/builtins/__init__.py +13 -1
- classiq/qmod/builtins/classical_execution_primitives.py +109 -0
- classiq/qmod/builtins/classical_functions.py +68 -0
- classiq/qmod/builtins/functions.py +88 -18
- classiq/qmod/builtins/operations.py +60 -35
- classiq/qmod/classical_function.py +40 -0
- classiq/qmod/declaration_inferrer.py +5 -2
- classiq/qmod/qmod_variable.py +17 -10
- classiq/qmod/quantum_callable.py +24 -3
- classiq/qmod/quantum_expandable.py +131 -21
- classiq/qmod/quantum_function.py +12 -2
- classiq/qmod/symbolic.py +182 -107
- classiq/qmod/symbolic_expr.py +11 -10
- classiq/qmod/symbolic_type.py +8 -0
- classiq/quantum_functions/decorators.py +2 -4
- classiq/quantum_functions/function_library.py +1 -0
- {classiq-0.36.0.dist-info → classiq-0.37.0.dist-info}/METADATA +1 -1
- {classiq-0.36.0.dist-info → classiq-0.37.0.dist-info}/RECORD +90 -82
- classiq/interface/model/local_variable_declaration.py +0 -7
- {classiq-0.36.0.dist-info → classiq-0.37.0.dist-info}/WHEEL +0 -0
classiq/execution/jobs.py
CHANGED
@@ -7,9 +7,9 @@ from classiq.interface.execution.jobs import ExecutionJobDetailsV1
|
|
7
7
|
from classiq.interface.executor.execution_request import ExecutionJobDetails
|
8
8
|
from classiq.interface.executor.execution_result import ResultsCollection
|
9
9
|
from classiq.interface.jobs import JobStatus, JSONObject
|
10
|
-
from classiq.interface.server.routes import
|
10
|
+
from classiq.interface.server.routes import EXECUTION_JOBS_NON_VERSIONED_FULL_PATH
|
11
11
|
|
12
|
-
from classiq._internals.api_wrapper import ApiWrapper
|
12
|
+
from classiq._internals.api_wrapper import CLASSIQ_ACCEPT_HEADER, ApiWrapper
|
13
13
|
from classiq._internals.async_utils import syncify_function
|
14
14
|
from classiq._internals.client import client
|
15
15
|
from classiq._internals.jobs import JobID, JobPoller
|
@@ -17,6 +17,9 @@ from classiq.exceptions import ClassiqAPIError
|
|
17
17
|
|
18
18
|
_JobDetails = Union[ExecutionJobDetails, ExecutionJobDetailsV1]
|
19
19
|
|
20
|
+
_JOB_DETAILS_VERSION = "v1"
|
21
|
+
_JOB_RESULT_VERSION = "v1"
|
22
|
+
|
20
23
|
|
21
24
|
class ExecutionJob:
|
22
25
|
_details: _JobDetails
|
@@ -98,7 +101,9 @@ class ExecutionJob:
|
|
98
101
|
|
99
102
|
if self._result is None:
|
100
103
|
self._result = (
|
101
|
-
await ApiWrapper.call_get_execution_job_result(
|
104
|
+
await ApiWrapper.call_get_execution_job_result(
|
105
|
+
job_id=self._job_id, version=_JOB_RESULT_VERSION
|
106
|
+
)
|
102
107
|
).results
|
103
108
|
return self._result
|
104
109
|
|
@@ -117,7 +122,11 @@ class ExecutionJob:
|
|
117
122
|
return True
|
118
123
|
return None
|
119
124
|
|
120
|
-
poller = JobPoller(
|
125
|
+
poller = JobPoller(
|
126
|
+
base_url=EXECUTION_JOBS_NON_VERSIONED_FULL_PATH,
|
127
|
+
use_versioned_url=False,
|
128
|
+
additional_headers={CLASSIQ_ACCEPT_HEADER: _JOB_DETAILS_VERSION},
|
129
|
+
)
|
121
130
|
await poller.poll(
|
122
131
|
job_id=self._job_id,
|
123
132
|
response_parser=response_parser,
|
classiq/executor.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
"""Executor module, implementing facilities for executing quantum programs using Classiq platform."""
|
2
|
+
|
2
3
|
import functools
|
3
4
|
from typing import Optional, Tuple, Union
|
4
5
|
|
@@ -32,8 +33,8 @@ from classiq.synthesis import SerializedQuantumProgram
|
|
32
33
|
|
33
34
|
BatchExecutionResult: TypeAlias = Union[ExecutionDetails, BaseException]
|
34
35
|
ProgramAndResult: TypeAlias = Tuple[QuantumProgram, BatchExecutionResult]
|
35
|
-
|
36
|
-
BackendPreferencesTypes,
|
36
|
+
BackendPreferencesAndResult: TypeAlias = Tuple[
|
37
|
+
BackendPreferencesTypes, int, BatchExecutionResult
|
37
38
|
]
|
38
39
|
_MAX_ARGUMENTS_SIZE = 1024
|
39
40
|
|
classiq/interface/_version.py
CHANGED
@@ -51,12 +51,6 @@ class AnalysisHardwareListParams(AnalysisParams, HardwareListParams):
|
|
51
51
|
transpilation_params: AnalysisHardwareTranspilationParams
|
52
52
|
|
53
53
|
|
54
|
-
class ResourceEstimatorParams(pydantic.BaseModel):
|
55
|
-
circuit_id: str
|
56
|
-
error_budget: float
|
57
|
-
physical_error_rate: float
|
58
|
-
|
59
|
-
|
60
54
|
class HardwareParams(pydantic.BaseModel):
|
61
55
|
device: PydanticNonEmptyString = pydantic.Field(default=None, description="Devices")
|
62
56
|
provider: AnalyzerProviderVendor
|
@@ -136,10 +136,6 @@ class DevicesResult(VersionedModel):
|
|
136
136
|
status: GraphStatus
|
137
137
|
|
138
138
|
|
139
|
-
class ResourceEstimatorResult(VersionedModel):
|
140
|
-
report_json: str
|
141
|
-
|
142
|
-
|
143
139
|
class QuantumCircuitProperties(pydantic.BaseModel):
|
144
140
|
depth: pydantic.NonNegativeInt = pydantic.Field(
|
145
141
|
default=..., description="Circuit depth"
|
@@ -204,8 +204,8 @@ class GCPBackendPreferences(BackendPreferences):
|
|
204
204
|
|
205
205
|
class OQCBackendPreferences(BackendPreferences):
|
206
206
|
backend_service_provider: ProviderTypeVendor.OQC
|
207
|
-
|
208
|
-
|
207
|
+
username: str = pydantic.Field(description="OQC username")
|
208
|
+
password: str = pydantic.Field(description="OQC password")
|
209
209
|
|
210
210
|
@pydantic.root_validator(pre=True)
|
211
211
|
def _set_backend_service_provider(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
@@ -30,7 +30,9 @@ class RegisterInitialization(pydantic.BaseModel):
|
|
30
30
|
initial_condition: int = values.get("initial_condition", 0)
|
31
31
|
name: str = values.get("name", "")
|
32
32
|
|
33
|
-
initial_condition_length = number_utils.size(
|
33
|
+
initial_condition_length = number_utils.size(
|
34
|
+
initial_condition, machine_precision=number_utils.MAX_FRACTION_PLACES
|
35
|
+
)
|
34
36
|
register_length = len(qubits)
|
35
37
|
if initial_condition_length > register_length:
|
36
38
|
raise ClassiqStateInitializationError(
|
@@ -51,6 +51,7 @@ class VQEIntermediateData(BaseModel):
|
|
51
51
|
|
52
52
|
class VQESolverResult(SolverResult, QmodPyObject):
|
53
53
|
eigenstate: Dict[str, Complex]
|
54
|
+
reduced_probabilities: Optional[Dict[str, float]] = None
|
54
55
|
optimized_circuit_sample_results: ExecutionDetails
|
55
56
|
intermediate_results: List[VQEIntermediateData]
|
56
57
|
optimal_parameters: Dict[str, float]
|
@@ -52,9 +52,9 @@ class RandomTwoQubitGatesArgs(CustomAnsatzArgs):
|
|
52
52
|
|
53
53
|
|
54
54
|
class TwoLocalArgs(CustomAnsatzArgs):
|
55
|
-
rotation_blocks: Optional[
|
56
|
-
|
57
|
-
|
55
|
+
rotation_blocks: Optional[Union[RotationBlocksType, List[RotationBlocksType]]] = (
|
56
|
+
RotationBlocksType.ry
|
57
|
+
)
|
58
58
|
entanglement_blocks: Optional[
|
59
59
|
Union[EntanglementBlocksType, List[EntanglementBlocksType]]
|
60
60
|
] = EntanglementBlocksType.cx
|
@@ -6,10 +6,10 @@ from classiq.interface.generator.arith.register_user_input import RegisterArithm
|
|
6
6
|
RegisterOrConst = Union[RegisterArithmeticInfo, float]
|
7
7
|
|
8
8
|
|
9
|
-
def fraction_places(argument: RegisterOrConst) -> int:
|
9
|
+
def fraction_places(argument: RegisterOrConst, *, machine_precision: int) -> int:
|
10
10
|
if isinstance(argument, RegisterArithmeticInfo):
|
11
11
|
return argument.fraction_places
|
12
|
-
return number_utils.fraction_places(argument)
|
12
|
+
return number_utils.fraction_places(argument, machine_precision=machine_precision)
|
13
13
|
|
14
14
|
|
15
15
|
def integer_part_size(argument: RegisterOrConst) -> int:
|
@@ -18,10 +18,10 @@ def integer_part_size(argument: RegisterOrConst) -> int:
|
|
18
18
|
return number_utils.integer_part_size(argument)
|
19
19
|
|
20
20
|
|
21
|
-
def size(argument: RegisterOrConst) -> int:
|
21
|
+
def size(argument: RegisterOrConst, *, machine_precision: int) -> int:
|
22
22
|
if isinstance(argument, RegisterArithmeticInfo):
|
23
23
|
return argument.size
|
24
|
-
return number_utils.size(argument)
|
24
|
+
return number_utils.size(argument, machine_precision=machine_precision)
|
25
25
|
|
26
26
|
|
27
27
|
def is_signed(argument: RegisterOrConst) -> bool:
|
@@ -75,6 +75,7 @@ class Arithmetic(ArithmeticExpressionABC):
|
|
75
75
|
def get_arithmetic_params(
|
76
76
|
expr_str: str,
|
77
77
|
var_types: Dict[str, QuantumType],
|
78
|
+
machine_precision: int,
|
78
79
|
enable_target: bool = False,
|
79
80
|
) -> Arithmetic:
|
80
81
|
return Arithmetic(
|
@@ -86,13 +87,14 @@ def get_arithmetic_params(
|
|
86
87
|
inputs_to_save=set(var_types.keys()),
|
87
88
|
# FIXME: generalize inout target to multiple qubits
|
88
89
|
target=RegisterArithmeticInfo(size=1) if enable_target else None,
|
90
|
+
machine_precision=machine_precision,
|
89
91
|
)
|
90
92
|
|
91
93
|
|
92
94
|
def compute_arithmetic_result_type(
|
93
|
-
expr_str: str, var_types: Dict[str, QuantumType]
|
95
|
+
expr_str: str, var_types: Dict[str, QuantumType], machine_precision: int
|
94
96
|
) -> QuantumType:
|
95
|
-
arith_param = get_arithmetic_params(expr_str, var_types)
|
97
|
+
arith_param = get_arithmetic_params(expr_str, var_types, machine_precision)
|
96
98
|
return register_info_to_quantum_type(
|
97
99
|
arith_param.outputs[ARITHMETIC_EXPRESSION_RESULT_NAME]
|
98
100
|
)
|
@@ -10,11 +10,15 @@ from classiq.interface.generator.arith.binary_ops import BOOLEAN_OP_WITH_FRACTIO
|
|
10
10
|
|
11
11
|
from classiq.exceptions import ClassiqArithmeticError
|
12
12
|
|
13
|
-
ArgTypeValidator: TypeAlias = Callable[[List[RegisterOrConst]], None]
|
13
|
+
ArgTypeValidator: TypeAlias = Callable[[List[RegisterOrConst], int], None]
|
14
14
|
|
15
15
|
|
16
|
-
def _validate_bitwise_op_args(
|
17
|
-
|
16
|
+
def _validate_bitwise_op_args(
|
17
|
+
args: List[RegisterOrConst], machine_precision: int
|
18
|
+
) -> None:
|
19
|
+
if any(
|
20
|
+
fraction_places(arg, machine_precision=machine_precision) > 0 for arg in args
|
21
|
+
):
|
18
22
|
raise ClassiqArithmeticError(BOOLEAN_OP_WITH_FRACTIONS_ERROR)
|
19
23
|
|
20
24
|
|
@@ -25,7 +29,9 @@ arg_type_validator_map: Dict[str, ArgTypeValidator] = dict(
|
|
25
29
|
)
|
26
30
|
|
27
31
|
|
28
|
-
def validate_operation_arg_types(
|
32
|
+
def validate_operation_arg_types(
|
33
|
+
operation: str, args: List[RegisterOrConst], machine_precision: int
|
34
|
+
) -> None:
|
29
35
|
if operation not in arg_type_validator_map:
|
30
36
|
return
|
31
|
-
arg_type_validator_map[operation](args)
|
37
|
+
arg_type_validator_map[operation](args, machine_precision)
|
@@ -18,7 +18,8 @@ from classiq.interface.generator.arith.ast_node_rewrite import (
|
|
18
18
|
|
19
19
|
from classiq.exceptions import ClassiqArithmeticError
|
20
20
|
|
21
|
-
|
21
|
+
_MULTIPLE_RESULTS_ERROR_MESSAGE: str = "Expression cannot contain multiple result"
|
22
|
+
_TRIVIAL_ARITHMETIC_ERROR_MESSAGE: str = "Expression must be nontrivial"
|
22
23
|
_ALLOWED_MULTI_ARGUMENT_FUNCTIONS = ("min", "max")
|
23
24
|
Node = Union[str, float, int]
|
24
25
|
|
@@ -116,8 +117,12 @@ class InDegreeLimiter:
|
|
116
117
|
for node in list(graph.nodes):
|
117
118
|
if cls._condition(graph, node):
|
118
119
|
graph = cls._node_conversion(graph, node)
|
119
|
-
|
120
|
-
|
120
|
+
|
121
|
+
num_results = sum(int(graph.out_degree(node) == 0) for node in graph.nodes)
|
122
|
+
if num_results > 1:
|
123
|
+
raise ClassiqArithmeticError(_MULTIPLE_RESULTS_ERROR_MESSAGE)
|
124
|
+
elif num_results == 0:
|
125
|
+
raise ClassiqArithmeticError(_TRIVIAL_ARITHMETIC_ERROR_MESSAGE)
|
121
126
|
return graph
|
122
127
|
|
123
128
|
|
@@ -134,7 +139,3 @@ def parse_expression(
|
|
134
139
|
visitor.validate(expression)
|
135
140
|
InDegreeLimiter.graph_conversion(graph=visitor.graph)
|
136
141
|
return visitor.graph
|
137
|
-
|
138
|
-
|
139
|
-
def num_of_result_nodes(graph: nx.DiGraph) -> int:
|
140
|
-
return sum(int(graph.out_degree(node) == 0) for node in graph.nodes)
|
@@ -5,6 +5,7 @@ from typing import ClassVar, Iterable, Optional, Tuple
|
|
5
5
|
|
6
6
|
import pydantic
|
7
7
|
|
8
|
+
from classiq.interface.generator.arith import argument_utils, number_utils
|
8
9
|
from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
|
9
10
|
from classiq.interface.generator.function_params import FunctionParams
|
10
11
|
|
@@ -13,6 +14,7 @@ DEFAULT_GARBAGE_OUT_NAME: str = "extra_qubits"
|
|
13
14
|
|
14
15
|
class ArithmeticOperationParams(FunctionParams):
|
15
16
|
output_size: Optional[pydantic.PositiveInt]
|
17
|
+
machine_precision: pydantic.PositiveInt = number_utils.MAX_FRACTION_PLACES
|
16
18
|
output_name: ClassVar[str]
|
17
19
|
garbage_output_name: ClassVar[str] = DEFAULT_GARBAGE_OUT_NAME
|
18
20
|
_result_register: Optional[RegisterArithmeticInfo] = pydantic.PrivateAttr(
|
@@ -44,6 +46,11 @@ class ArithmeticOperationParams(FunctionParams):
|
|
44
46
|
return suggested_bounds
|
45
47
|
return None
|
46
48
|
|
49
|
+
def _compute_fraction_places(self, argument: argument_utils.RegisterOrConst) -> int:
|
50
|
+
return argument_utils.fraction_places(
|
51
|
+
argument, machine_precision=self.machine_precision
|
52
|
+
)
|
53
|
+
|
47
54
|
@abc.abstractmethod
|
48
55
|
def get_params_inplace_options(self) -> Iterable[ArithmeticOperationParams]:
|
49
56
|
pass
|