classiq 0.51.0__py3-none-any.whl → 0.52.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/_internals/api_wrapper.py +41 -15
- classiq/_internals/authentication/auth0.py +20 -4
- classiq/_internals/authentication/password_manager.py +16 -4
- classiq/_internals/client.py +2 -2
- classiq/_internals/host_checker.py +5 -3
- classiq/_internals/jobs.py +3 -3
- classiq/analyzer/analyzer_utilities.py +1 -1
- classiq/applications/chemistry/ground_state_problem.py +1 -1
- classiq/applications/combinatorial_helpers/pyomo_utils.py +3 -1
- classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
- classiq/applications/qnn/qlayer.py +2 -2
- classiq/execution/__init__.py +3 -0
- classiq/execution/execution_session.py +2 -2
- classiq/execution/iqcc.py +63 -0
- classiq/execution/jobs.py +2 -2
- classiq/executor.py +2 -2
- classiq/interface/_version.py +1 -1
- classiq/interface/analyzer/analysis_params.py +19 -9
- classiq/interface/analyzer/cytoscape_graph.py +10 -3
- classiq/interface/analyzer/result.py +6 -5
- classiq/interface/applications/qsvm.py +13 -12
- classiq/interface/backend/backend_preferences.py +78 -105
- classiq/interface/backend/ionq/ionq_quantum_program.py +12 -19
- classiq/interface/backend/pydantic_backend.py +24 -12
- classiq/interface/backend/quantum_backend_providers.py +2 -0
- classiq/interface/chemistry/fermionic_operator.py +7 -7
- classiq/interface/chemistry/ground_state_problem.py +23 -18
- classiq/interface/chemistry/molecule.py +10 -5
- classiq/interface/chemistry/operator.py +71 -44
- classiq/interface/combinatorial_optimization/mht_qaoa_input.py +2 -1
- classiq/interface/debug_info/debug_info.py +3 -4
- classiq/interface/execution/iqcc.py +21 -0
- classiq/interface/execution/jobs.py +10 -10
- classiq/interface/executor/aws_execution_cost.py +37 -20
- classiq/interface/executor/execution_preferences.py +1 -2
- classiq/interface/executor/execution_request.py +2 -2
- classiq/interface/executor/execution_result.py +4 -2
- classiq/interface/executor/iqae_result.py +1 -1
- classiq/interface/executor/optimizer_preferences.py +14 -10
- classiq/interface/executor/quantum_code.py +21 -16
- classiq/interface/executor/register_initialization.py +10 -10
- classiq/interface/executor/result.py +19 -16
- classiq/interface/executor/vqe_result.py +1 -1
- classiq/interface/finance/function_input.py +27 -18
- classiq/interface/finance/log_normal_model_input.py +2 -2
- classiq/interface/finance/model_input.py +3 -2
- classiq/interface/generator/amplitude_loading.py +8 -6
- classiq/interface/generator/arith/argument_utils.py +24 -0
- classiq/interface/generator/arith/arithmetic.py +5 -3
- classiq/interface/generator/arith/arithmetic_expression_abc.py +36 -14
- classiq/interface/generator/arith/arithmetic_operations.py +6 -3
- classiq/interface/generator/arith/binary_ops.py +88 -63
- classiq/interface/generator/arith/extremum_operations.py +22 -13
- classiq/interface/generator/arith/logical_ops.py +6 -4
- classiq/interface/generator/arith/number_utils.py +3 -3
- classiq/interface/generator/arith/register_user_input.py +32 -17
- classiq/interface/generator/arith/unary_ops.py +5 -4
- classiq/interface/generator/chemistry_function_params.py +2 -1
- classiq/interface/generator/circuit_code/circuit_code.py +2 -1
- classiq/interface/generator/commuting_pauli_exponentiation.py +6 -5
- classiq/interface/generator/complex_type.py +14 -18
- classiq/interface/generator/control_state.py +32 -26
- classiq/interface/generator/expressions/expression.py +6 -5
- classiq/interface/generator/expressions/qmod_qscalar_proxy.py +3 -3
- classiq/interface/generator/function_params.py +22 -39
- classiq/interface/generator/functions/classical_function_declaration.py +1 -1
- classiq/interface/generator/functions/classical_type.py +32 -23
- classiq/interface/generator/functions/concrete_types.py +8 -7
- classiq/interface/generator/functions/function_declaration.py +4 -5
- classiq/interface/generator/functions/type_name.py +5 -4
- classiq/interface/generator/generated_circuit_data.py +9 -6
- classiq/interface/generator/grover_diffuser.py +26 -18
- classiq/interface/generator/grover_operator.py +32 -22
- classiq/interface/generator/hamiltonian_evolution/exponentiation.py +3 -4
- classiq/interface/generator/hamiltonian_evolution/qdrift.py +4 -4
- classiq/interface/generator/hamiltonian_evolution/suzuki_trotter.py +8 -7
- classiq/interface/generator/hardware/hardware_data.py +27 -26
- classiq/interface/generator/hardware_efficient_ansatz.py +11 -6
- classiq/interface/generator/hartree_fock.py +2 -1
- classiq/interface/generator/identity.py +7 -2
- classiq/interface/generator/linear_pauli_rotations.py +27 -14
- classiq/interface/generator/mcu.py +15 -12
- classiq/interface/generator/mcx.py +18 -10
- classiq/interface/generator/model/constraints.py +4 -2
- classiq/interface/generator/model/model.py +2 -1
- classiq/interface/generator/model/preferences/preferences.py +30 -32
- classiq/interface/generator/oracles/custom_oracle.py +13 -10
- classiq/interface/generator/piecewise_linear_amplitude_loading.py +37 -21
- classiq/interface/generator/qpe.py +38 -26
- classiq/interface/generator/qsvm.py +4 -4
- classiq/interface/generator/quantum_function_call.py +57 -44
- classiq/interface/generator/quantum_program.py +8 -6
- classiq/interface/generator/range_types.py +10 -11
- classiq/interface/generator/standard_gates/controlled_standard_gates.py +9 -5
- classiq/interface/generator/standard_gates/standard_angle_metaclass.py +2 -6
- classiq/interface/generator/standard_gates/u_gate.py +7 -10
- classiq/interface/generator/state_preparation/computational_basis_state_preparation.py +2 -1
- classiq/interface/generator/state_preparation/distributions.py +12 -12
- classiq/interface/generator/state_preparation/state_preparation.py +22 -16
- classiq/interface/generator/types/enum_declaration.py +2 -1
- classiq/interface/generator/ucc.py +2 -1
- classiq/interface/generator/unitary_gate.py +2 -1
- classiq/interface/generator/user_defined_function_params.py +3 -0
- classiq/interface/generator/visitor.py +1 -1
- classiq/interface/hardware.py +18 -3
- classiq/interface/helpers/custom_pydantic_types.py +38 -47
- classiq/interface/helpers/pydantic_model_helpers.py +3 -2
- classiq/interface/helpers/versioned_model.py +1 -4
- classiq/interface/ide/ide_data.py +5 -5
- classiq/interface/ide/visual_model.py +5 -5
- classiq/interface/interface_version.py +1 -1
- classiq/interface/jobs.py +12 -22
- classiq/interface/model/bind_operation.py +2 -1
- classiq/interface/model/classical_parameter_declaration.py +10 -4
- classiq/interface/model/handle_binding.py +20 -24
- classiq/interface/model/inplace_binary_operation.py +16 -9
- classiq/interface/model/model.py +21 -11
- classiq/interface/model/port_declaration.py +10 -7
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +6 -4
- classiq/interface/model/quantum_function_declaration.py +22 -11
- classiq/interface/model/quantum_statement.py +6 -7
- classiq/interface/model/quantum_type.py +22 -19
- classiq/interface/model/statement_block.py +9 -9
- classiq/interface/server/global_versions.py +4 -5
- classiq/interface/server/routes.py +8 -0
- classiq/model_expansions/evaluators/parameter_types.py +3 -3
- classiq/model_expansions/expression_renamer.py +1 -1
- classiq/model_expansions/quantum_operations/control.py +11 -12
- classiq/model_expansions/quantum_operations/emitter.py +22 -0
- classiq/model_expansions/quantum_operations/expression_operation.py +2 -20
- classiq/model_expansions/quantum_operations/inplace_binary_operation.py +65 -14
- classiq/model_expansions/quantum_operations/invert.py +1 -1
- classiq/model_expansions/quantum_operations/phase.py +4 -5
- classiq/model_expansions/quantum_operations/power.py +1 -1
- classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +50 -9
- classiq/model_expansions/quantum_operations/variable_decleration.py +2 -2
- classiq/model_expansions/quantum_operations/within_apply.py +1 -1
- classiq/qmod/builtins/__init__.py +1 -3
- classiq/qmod/builtins/functions/__init__.py +4 -0
- classiq/qmod/builtins/functions/arithmetic.py +10 -0
- classiq/qmod/create_model_function.py +14 -8
- classiq/qmod/quantum_expandable.py +22 -9
- classiq/qmod/quantum_function.py +1 -1
- classiq/qmod/semantics/static_semantics_visitor.py +3 -1
- classiq/qmod/type_attribute_remover.py +1 -1
- classiq/qmod/write_qmod.py +2 -4
- classiq/synthesis.py +11 -13
- {classiq-0.51.0.dist-info → classiq-0.52.0.dist-info}/METADATA +3 -2
- {classiq-0.51.0.dist-info → classiq-0.52.0.dist-info}/RECORD +150 -148
- {classiq-0.51.0.dist-info → classiq-0.52.0.dist-info}/WHEEL +0 -0
@@ -1,20 +1,18 @@
|
|
1
1
|
from collections.abc import Sequence
|
2
2
|
from typing import (
|
3
|
-
TYPE_CHECKING,
|
4
3
|
Any,
|
5
4
|
Iterable as IterableType,
|
6
5
|
List,
|
7
6
|
Optional,
|
8
7
|
Tuple,
|
8
|
+
Type,
|
9
9
|
Union,
|
10
10
|
)
|
11
11
|
|
12
12
|
import numpy as np
|
13
13
|
import pydantic
|
14
14
|
from numpy.typing import ArrayLike
|
15
|
-
|
16
|
-
if TYPE_CHECKING:
|
17
|
-
from pydantic.typing import AnyClassMethod
|
15
|
+
from pydantic import ConfigDict, field_validator
|
18
16
|
|
19
17
|
from classiq.interface.helpers.versioned_model import VersionedModel
|
20
18
|
|
@@ -33,8 +31,12 @@ def listify(obj: Union[IterableType, ArrayLike]) -> list:
|
|
33
31
|
return list(obj) # type: ignore[arg-type]
|
34
32
|
|
35
33
|
|
36
|
-
def validate_array_to_list(name: str) ->
|
37
|
-
|
34
|
+
def validate_array_to_list(name: str) -> Any:
|
35
|
+
@field_validator(name, mode="before")
|
36
|
+
def _listify(cls: Type[pydantic.BaseModel], value: Any) -> Any:
|
37
|
+
return listify(value)
|
38
|
+
|
39
|
+
return _listify
|
38
40
|
|
39
41
|
|
40
42
|
Shape = Tuple[int, ...]
|
@@ -89,16 +91,15 @@ class QSVMData(VersionedModel):
|
|
89
91
|
data: DataList
|
90
92
|
labels: Optional[LabelsInt] = None
|
91
93
|
internal_state: Optional[QSVMInternalState] = None
|
94
|
+
model_config = ConfigDict(extra="forbid")
|
92
95
|
|
93
|
-
|
94
|
-
|
95
|
-
extra = "forbid"
|
96
|
-
|
97
|
-
@pydantic.validator("data", pre=True)
|
96
|
+
@pydantic.field_validator("data", mode="before")
|
97
|
+
@classmethod
|
98
98
|
def set_data(cls, data: Union[IterableType, ArrayLike]) -> list:
|
99
99
|
return listify(data)
|
100
100
|
|
101
|
-
@pydantic.
|
101
|
+
@pydantic.field_validator("labels", mode="before")
|
102
|
+
@classmethod
|
102
103
|
def set_labels(
|
103
104
|
cls, labels: Optional[Union[IterableType, ArrayLike]]
|
104
105
|
) -> Optional[list]:
|
@@ -3,7 +3,8 @@ from __future__ import annotations
|
|
3
3
|
from typing import Any, Dict, Iterable, List, Optional, Union
|
4
4
|
|
5
5
|
import pydantic
|
6
|
-
from pydantic import BaseModel
|
6
|
+
from pydantic import BaseModel
|
7
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
7
8
|
|
8
9
|
from classiq.interface.backend import pydantic_backend
|
9
10
|
from classiq.interface.backend.quantum_backend_providers import (
|
@@ -21,7 +22,6 @@ from classiq.interface.backend.quantum_backend_providers import (
|
|
21
22
|
)
|
22
23
|
from classiq.interface.exceptions import ClassiqValueError
|
23
24
|
from classiq.interface.hardware import Provider
|
24
|
-
from classiq.interface.helpers.pydantic_model_helpers import values_with_discriminator
|
25
25
|
|
26
26
|
|
27
27
|
class BackendPreferences(BaseModel):
|
@@ -36,10 +36,7 @@ class BackendPreferences(BaseModel):
|
|
36
36
|
backend_name (str): Name of the requested backend or target.
|
37
37
|
"""
|
38
38
|
|
39
|
-
|
40
|
-
# in the subclass, it shouldn't be dumped with exclude_unset. This causes this field not to appear.
|
41
|
-
# For example: don't use obj.dict(exclude_unset=True).
|
42
|
-
backend_service_provider: str = pydantic.Field(
|
39
|
+
backend_service_provider: ProviderVendor = pydantic.Field(
|
43
40
|
..., description="Provider company or cloud for the requested backend."
|
44
41
|
)
|
45
42
|
backend_name: str = pydantic.Field(
|
@@ -50,12 +47,6 @@ class BackendPreferences(BaseModel):
|
|
50
47
|
def hw_provider(self) -> Provider:
|
51
48
|
return Provider(self.backend_service_provider)
|
52
49
|
|
53
|
-
@pydantic.validator("backend_service_provider", pre=True)
|
54
|
-
def validate_backend_service_provider(
|
55
|
-
cls, backend_service_provider: Any
|
56
|
-
) -> Provider:
|
57
|
-
return validate_backend_service_provider(backend_service_provider)
|
58
|
-
|
59
50
|
@classmethod
|
60
51
|
def batch_preferences(
|
61
52
|
cls, *, backend_names: Iterable[str], **kwargs: Any
|
@@ -110,7 +101,9 @@ class AliceBobBackendPreferences(BackendPreferences):
|
|
110
101
|
For more details, refer to the [Alice&Bob Backend Documentation](https://docs.classiq.io/latest/reference-manual/executor/cloud-providers/alice-and-bob-backends/).
|
111
102
|
"""
|
112
103
|
|
113
|
-
backend_service_provider: ProviderTypeVendor.ALICE_BOB
|
104
|
+
backend_service_provider: ProviderTypeVendor.ALICE_BOB = pydantic.Field(
|
105
|
+
default=ProviderVendor.ALICE_AND_BOB
|
106
|
+
)
|
114
107
|
distance: Optional[int] = pydantic.Field(
|
115
108
|
default=None, description="Repetition code distance"
|
116
109
|
)
|
@@ -127,12 +120,6 @@ class AliceBobBackendPreferences(BackendPreferences):
|
|
127
120
|
..., description="AliceBob API key"
|
128
121
|
)
|
129
122
|
|
130
|
-
@pydantic.root_validator(pre=True)
|
131
|
-
def _set_backend_service_provider(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
132
|
-
return values_with_discriminator(
|
133
|
-
values, "backend_service_provider", ProviderVendor.ALICE_AND_BOB
|
134
|
-
)
|
135
|
-
|
136
123
|
@property
|
137
124
|
def parameters(self) -> Dict[str, Any]:
|
138
125
|
parameters = {
|
@@ -154,13 +141,9 @@ class ClassiqBackendPreferences(BackendPreferences):
|
|
154
141
|
For more details, refer to the [Classiq Backend Documentation](https://docs.classiq.io/latest/reference-manual/executor/cloud-providers/classiq-backends/).
|
155
142
|
"""
|
156
143
|
|
157
|
-
backend_service_provider: ProviderTypeVendor.CLASSIQ
|
158
|
-
|
159
|
-
|
160
|
-
def _set_backend_service_provider(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
161
|
-
return values_with_discriminator(
|
162
|
-
values, "backend_service_provider", ProviderVendor.CLASSIQ
|
163
|
-
)
|
144
|
+
backend_service_provider: ProviderTypeVendor.CLASSIQ = pydantic.Field(
|
145
|
+
default=ProviderVendor.CLASSIQ
|
146
|
+
)
|
164
147
|
|
165
148
|
def is_nvidia_backend(self) -> bool:
|
166
149
|
return self.backend_name in list(ClassiqNvidiaBackendNames)
|
@@ -197,7 +180,9 @@ class AwsBackendPreferences(BackendPreferences):
|
|
197
180
|
[AwsBackendPreferences examples](https://docs.classiq.io/latest/reference-manual/executor/cloud-providers/amazon-backends/?h=awsbackend#usage)
|
198
181
|
"""
|
199
182
|
|
200
|
-
backend_service_provider: ProviderTypeVendor.AMAZON_BRAKET
|
183
|
+
backend_service_provider: ProviderTypeVendor.AMAZON_BRAKET = pydantic.Field(
|
184
|
+
default=ProviderVendor.AMAZON_BRAKET
|
185
|
+
)
|
201
186
|
aws_role_arn: pydantic_backend.PydanticAwsRoleArn = pydantic.Field(
|
202
187
|
description="ARN of the role to be assumed for execution on your Braket account."
|
203
188
|
)
|
@@ -206,21 +191,14 @@ class AwsBackendPreferences(BackendPreferences):
|
|
206
191
|
description="S3 Folder Path Within The S3 Bucket"
|
207
192
|
)
|
208
193
|
|
209
|
-
@
|
210
|
-
|
211
|
-
|
212
|
-
) -> str:
|
194
|
+
@pydantic.field_validator("s3_bucket_name", mode="before")
|
195
|
+
@classmethod
|
196
|
+
def _validate_s3_bucket_name(cls, s3_bucket_name: str) -> str:
|
213
197
|
s3_bucket_name = s3_bucket_name.strip()
|
214
198
|
if not s3_bucket_name.startswith("amazon-braket-"):
|
215
199
|
raise ClassiqValueError('S3 bucket name should start with "amazon-braket-"')
|
216
200
|
return s3_bucket_name
|
217
201
|
|
218
|
-
@pydantic.root_validator(pre=True)
|
219
|
-
def _set_backend_service_provider(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
220
|
-
return values_with_discriminator(
|
221
|
-
values, "backend_service_provider", ProviderVendor.AMAZON_BRAKET
|
222
|
-
)
|
223
|
-
|
224
202
|
|
225
203
|
class IBMBackendProvider(BaseModel):
|
226
204
|
"""
|
@@ -255,7 +233,9 @@ class IBMBackendPreferences(BackendPreferences):
|
|
255
233
|
See examples in the [IBM Quantum Backend Documentation](https://docs.classiq.io/latest/reference-manual/executor/cloud-providers/ibm-backends/?h=).
|
256
234
|
"""
|
257
235
|
|
258
|
-
backend_service_provider: ProviderTypeVendor.IBM_QUANTUM
|
236
|
+
backend_service_provider: ProviderTypeVendor.IBM_QUANTUM = pydantic.Field(
|
237
|
+
default=ProviderVendor.IBM_QUANTUM
|
238
|
+
)
|
259
239
|
access_token: Optional[str] = pydantic.Field(
|
260
240
|
default=None,
|
261
241
|
description="IBM Quantum access token to be used"
|
@@ -270,14 +250,8 @@ class IBMBackendPreferences(BackendPreferences):
|
|
270
250
|
description="QCTRL API key to access QCTRL optimization abilities",
|
271
251
|
)
|
272
252
|
|
273
|
-
@pydantic.root_validator(pre=True)
|
274
|
-
def _set_backend_service_provider(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
275
|
-
return values_with_discriminator(
|
276
|
-
values, "backend_service_provider", ProviderVendor.IBM_QUANTUM
|
277
|
-
)
|
278
253
|
|
279
|
-
|
280
|
-
class AzureCredential(pydantic.BaseSettings):
|
254
|
+
class AzureCredential(BaseSettings):
|
281
255
|
"""
|
282
256
|
Represents the credentials and configuration required to authenticate with Azure services.
|
283
257
|
|
@@ -296,11 +270,20 @@ class AzureCredential(pydantic.BaseSettings):
|
|
296
270
|
description="Azure Resource ID (including Azure subscription ID, resource "
|
297
271
|
"group and workspace), for personal resource",
|
298
272
|
)
|
273
|
+
model_config = SettingsConfigDict(
|
274
|
+
title="Azure Service Principal Credential",
|
275
|
+
env_prefix="AZURE_",
|
276
|
+
case_sensitive=False,
|
277
|
+
extra="allow",
|
278
|
+
)
|
299
279
|
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
280
|
+
def __init__(self, **data: Any) -> None:
|
281
|
+
initial_data = {
|
282
|
+
field: data[field] for field in data if field in self.model_fields
|
283
|
+
}
|
284
|
+
super().__init__(**data)
|
285
|
+
for field, value in initial_data.items():
|
286
|
+
setattr(self, field, value)
|
304
287
|
|
305
288
|
|
306
289
|
class AzureBackendPreferences(BackendPreferences):
|
@@ -317,7 +300,9 @@ class AzureBackendPreferences(BackendPreferences):
|
|
317
300
|
|
318
301
|
"""
|
319
302
|
|
320
|
-
backend_service_provider: ProviderTypeVendor.AZURE_QUANTUM
|
303
|
+
backend_service_provider: ProviderTypeVendor.AZURE_QUANTUM = pydantic.Field(
|
304
|
+
default=ProviderVendor.AZURE_QUANTUM
|
305
|
+
)
|
321
306
|
|
322
307
|
location: str = pydantic.Field(
|
323
308
|
default="East US", description="Azure personal resource region"
|
@@ -343,12 +328,6 @@ class AzureBackendPreferences(BackendPreferences):
|
|
343
328
|
"""
|
344
329
|
return self.credentials is None
|
345
330
|
|
346
|
-
@pydantic.root_validator(pre=True)
|
347
|
-
def _set_backend_service_provider(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
348
|
-
return values_with_discriminator(
|
349
|
-
values, "backend_service_provider", ProviderVendor.AZURE_QUANTUM
|
350
|
-
)
|
351
|
-
|
352
331
|
|
353
332
|
class IonqBackendPreferences(BackendPreferences):
|
354
333
|
"""
|
@@ -365,7 +344,9 @@ class IonqBackendPreferences(BackendPreferences):
|
|
365
344
|
See examples in the [IonQ Backend Documentation](https://docs.classiq.io/latest/reference-manual/executor/cloud-providers/ionq-backends/?h=).
|
366
345
|
"""
|
367
346
|
|
368
|
-
backend_service_provider: ProviderTypeVendor.IONQ
|
347
|
+
backend_service_provider: ProviderTypeVendor.IONQ = pydantic.Field(
|
348
|
+
default=ProviderVendor.IONQ
|
349
|
+
)
|
369
350
|
api_key: pydantic_backend.PydanticIonQApiKeyType = pydantic.Field(
|
370
351
|
..., description="IonQ API key"
|
371
352
|
)
|
@@ -374,12 +355,6 @@ class IonqBackendPreferences(BackendPreferences):
|
|
374
355
|
description="Error mitigation configuration.",
|
375
356
|
)
|
376
357
|
|
377
|
-
@pydantic.root_validator(pre=True)
|
378
|
-
def _set_backend_service_provider(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
379
|
-
return values_with_discriminator(
|
380
|
-
values, "backend_service_provider", ProviderVendor.IONQ
|
381
|
-
)
|
382
|
-
|
383
358
|
|
384
359
|
class GCPBackendPreferences(BackendPreferences):
|
385
360
|
"""
|
@@ -394,13 +369,9 @@ class GCPBackendPreferences(BackendPreferences):
|
|
394
369
|
See examples in the [Google Cloud Backend Documentation](https://docs.classiq.io/latest/reference-manual/executor/cloud-providers/google-backends/?h=).
|
395
370
|
"""
|
396
371
|
|
397
|
-
backend_service_provider: ProviderTypeVendor.GOOGLE
|
398
|
-
|
399
|
-
|
400
|
-
def _set_backend_service_provider(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
401
|
-
return values_with_discriminator(
|
402
|
-
values, "backend_service_provider", ProviderVendor.GOOGLE
|
403
|
-
)
|
372
|
+
backend_service_provider: ProviderTypeVendor.GOOGLE = pydantic.Field(
|
373
|
+
default=ProviderVendor.GOOGLE
|
374
|
+
)
|
404
375
|
|
405
376
|
def is_nvidia_backend(self) -> bool:
|
406
377
|
return True
|
@@ -417,16 +388,12 @@ class OQCBackendPreferences(BackendPreferences):
|
|
417
388
|
password (str): OQC password
|
418
389
|
"""
|
419
390
|
|
420
|
-
backend_service_provider: ProviderTypeVendor.OQC
|
391
|
+
backend_service_provider: ProviderTypeVendor.OQC = pydantic.Field(
|
392
|
+
default=ProviderVendor.OQC
|
393
|
+
)
|
421
394
|
username: str = pydantic.Field(description="OQC username")
|
422
395
|
password: str = pydantic.Field(description="OQC password")
|
423
396
|
|
424
|
-
@pydantic.root_validator(pre=True)
|
425
|
-
def _set_backend_service_provider(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
426
|
-
return values_with_discriminator(
|
427
|
-
values, "backend_service_provider", ProviderVendor.OQC
|
428
|
-
)
|
429
|
-
|
430
397
|
|
431
398
|
class IntelBackendPreferences(BackendPreferences):
|
432
399
|
"""
|
@@ -438,13 +405,9 @@ class IntelBackendPreferences(BackendPreferences):
|
|
438
405
|
For more details, refer to the [Classiq Backend Documentation](https://docs.classiq.io/latest/reference-manual/executor/cloud-providers/classiq-backends/).
|
439
406
|
"""
|
440
407
|
|
441
|
-
backend_service_provider: ProviderTypeVendor.INTEL
|
442
|
-
|
443
|
-
|
444
|
-
def _set_backend_service_provider(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
445
|
-
return values_with_discriminator(
|
446
|
-
values, "backend_service_provider", ProviderVendor.INTEL
|
447
|
-
)
|
408
|
+
backend_service_provider: ProviderTypeVendor.INTEL = pydantic.Field(
|
409
|
+
default=ProviderVendor.INTEL
|
410
|
+
)
|
448
411
|
|
449
412
|
|
450
413
|
class AQTBackendPreferences(BackendPreferences):
|
@@ -458,17 +421,38 @@ class AQTBackendPreferences(BackendPreferences):
|
|
458
421
|
workspace: The AQT workspace where the simulator/hardware is located.
|
459
422
|
"""
|
460
423
|
|
461
|
-
|
462
|
-
|
424
|
+
backend_service_provider: ProviderTypeVendor.AQT = pydantic.Field(
|
425
|
+
default=ProviderVendor.AQT
|
426
|
+
)
|
463
427
|
api_key: str = pydantic.Field(description="AQT API key")
|
464
428
|
workspace: str = pydantic.Field(description="AQT workspace")
|
465
429
|
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
430
|
+
|
431
|
+
class IQCCBackendPreferences(BackendPreferences):
|
432
|
+
"""
|
433
|
+
NOTE: This is a work in progress and is subject to change.
|
434
|
+
|
435
|
+
Represents the backend preferences specific to IQCC (Israeli Quantum Computing
|
436
|
+
Center).
|
437
|
+
|
438
|
+
Attributes:
|
439
|
+
auth_token: The authorization token generated by calling `generate_iqcc_token`.
|
440
|
+
target_id: The target ID of the login node.
|
441
|
+
target_scope_id: The scope ID of the specified target.
|
442
|
+
ssh_user_name: The user name to use when connecting to the SSH server on the login node.
|
443
|
+
ssh_key: The private key to use when connecting to the SSH server on the login node.
|
444
|
+
slurm_account: The account to use when initiating SLURM jobs.
|
445
|
+
"""
|
446
|
+
|
447
|
+
backend_service_provider: ProviderTypeVendor.IQCC = pydantic.Field(
|
448
|
+
default=ProviderVendor.IQCC
|
449
|
+
)
|
450
|
+
auth_token: str
|
451
|
+
target_id: str
|
452
|
+
target_scope_id: str
|
453
|
+
ssh_user_name: str
|
454
|
+
ssh_key: str
|
455
|
+
slurm_account: str
|
472
456
|
|
473
457
|
|
474
458
|
def is_exact_simulator(backend_preferences: BackendPreferences) -> bool:
|
@@ -502,6 +486,7 @@ BackendPreferencesTypes = Union[
|
|
502
486
|
OQCBackendPreferences,
|
503
487
|
IntelBackendPreferences,
|
504
488
|
AQTBackendPreferences,
|
489
|
+
IQCCBackendPreferences,
|
505
490
|
]
|
506
491
|
|
507
492
|
__all__ = [
|
@@ -525,17 +510,5 @@ __all__ = [
|
|
525
510
|
"OQCBackendNames",
|
526
511
|
"IntelBackendPreferences",
|
527
512
|
"AQTBackendPreferences",
|
513
|
+
"IQCCBackendPreferences",
|
528
514
|
]
|
529
|
-
|
530
|
-
|
531
|
-
def validate_backend_service_provider(backend_service_provider: Any) -> Provider:
|
532
|
-
if isinstance(backend_service_provider, Provider):
|
533
|
-
return backend_service_provider
|
534
|
-
if isinstance(backend_service_provider, str):
|
535
|
-
for member in Provider:
|
536
|
-
if member.lower() == backend_service_provider.lower():
|
537
|
-
return Provider(member)
|
538
|
-
raise ClassiqValueError(
|
539
|
-
f"""Vendor {backend_service_provider} is not supported.
|
540
|
-
The supported providers are {', '.join(Provider)}."""
|
541
|
-
)
|
@@ -2,8 +2,8 @@ from __future__ import annotations
|
|
2
2
|
|
3
3
|
from typing import TYPE_CHECKING, List, Optional
|
4
4
|
|
5
|
-
import
|
6
|
-
from
|
5
|
+
from pydantic import BaseModel, ConfigDict, Field
|
6
|
+
from typing_extensions import Annotated
|
7
7
|
|
8
8
|
# This file is based on autogenerated code from: https://static.ionq.co/schemas/circuit-v0.json using
|
9
9
|
# https://pydantic-docs.helpmanual.io/datamodel_code_generator/
|
@@ -12,10 +12,13 @@ from pydantic import BaseModel
|
|
12
12
|
if TYPE_CHECKING:
|
13
13
|
PydanticGateName = str
|
14
14
|
else:
|
15
|
-
PydanticGateName =
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
PydanticGateName = Annotated[
|
16
|
+
str,
|
17
|
+
Field(
|
18
|
+
pattern=r"^\w+$",
|
19
|
+
min_length=1,
|
20
|
+
),
|
21
|
+
]
|
19
22
|
|
20
23
|
|
21
24
|
class Gate(BaseModel):
|
@@ -24,23 +27,13 @@ class Gate(BaseModel):
|
|
24
27
|
control: Optional[int] = None
|
25
28
|
targets: Optional[List[int]] = None
|
26
29
|
controls: Optional[List[int]] = None
|
27
|
-
|
28
|
-
# Ionq changes format sometimes.
|
29
|
-
# One example is that `IonqQauntumCircuit` got a field name "gateset" with the value "qis"
|
30
|
-
# Another is that `Gate` got a field named "rotation"
|
31
|
-
class Config:
|
32
|
-
extra = pydantic.Extra.allow
|
30
|
+
model_config = ConfigDict(extra="allow")
|
33
31
|
|
34
32
|
|
35
33
|
class IonqQuantumCircuit(BaseModel):
|
36
34
|
qubits: int
|
37
35
|
circuit: List[Gate]
|
38
|
-
|
39
|
-
# Ionq changes format sometimes.
|
40
|
-
# One example is that `IonqQuantumCircuit` got a field name "gateset" with the value "qis"
|
41
|
-
# Another is that `Gate` got a field named "rotation"
|
42
|
-
class Config:
|
43
|
-
extra = pydantic.Extra.allow
|
36
|
+
model_config = ConfigDict(extra="allow")
|
44
37
|
|
45
38
|
@classmethod
|
46
39
|
def from_string(cls, code: str) -> IonqQuantumCircuit:
|
@@ -48,4 +41,4 @@ class IonqQuantumCircuit(BaseModel):
|
|
48
41
|
commentless_code = "\n".join(
|
49
42
|
line for line in code_lines if not line.startswith("//")
|
50
43
|
)
|
51
|
-
return cls.
|
44
|
+
return cls.model_validate_json(commentless_code)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from typing import TYPE_CHECKING
|
2
2
|
|
3
|
-
import
|
3
|
+
from pydantic import Field, StrictStr, constr
|
4
|
+
from typing_extensions import Annotated
|
4
5
|
|
5
6
|
AZURE_QUANTUM_RESOURCE_ID_REGEX = r"^/subscriptions/([a-fA-F0-9-]*)/resourceGroups/([^\s/]*)/providers/Microsoft\.Quantum/Workspaces/([^\s/]*)$"
|
6
7
|
|
@@ -25,20 +26,31 @@ if TYPE_CHECKING:
|
|
25
26
|
else:
|
26
27
|
# TODO Simplify regular expressions in this file
|
27
28
|
|
28
|
-
PydanticAwsRoleArn =
|
29
|
-
|
30
|
-
|
29
|
+
PydanticAwsRoleArn = Annotated[
|
30
|
+
StrictStr,
|
31
|
+
constr(
|
32
|
+
strip_whitespace=True,
|
33
|
+
),
|
34
|
+
]
|
31
35
|
|
32
|
-
PydanticS3BucketKey =
|
36
|
+
PydanticS3BucketKey = Annotated[
|
37
|
+
StrictStr, constr(strip_whitespace=True, min_length=1)
|
38
|
+
]
|
33
39
|
|
34
|
-
PydanticAzureResourceIDType =
|
40
|
+
PydanticAzureResourceIDType = Annotated[
|
41
|
+
str, Field(pattern=AZURE_QUANTUM_RESOURCE_ID_REGEX)
|
42
|
+
]
|
35
43
|
|
36
|
-
PydanticIonQApiKeyType =
|
37
|
-
|
38
|
-
|
44
|
+
PydanticIonQApiKeyType = Annotated[
|
45
|
+
str, Field(pattern=f"[A-Za-z0-9]{{{_IONQ_API_KEY_LENGTH}}}")
|
46
|
+
]
|
39
47
|
|
40
|
-
PydanticAliceBobApiKeyType =
|
48
|
+
PydanticAliceBobApiKeyType = Annotated[
|
49
|
+
StrictStr, constr(min_length=1, strip_whitespace=True)
|
50
|
+
]
|
41
51
|
|
42
|
-
PydanticArgumentNameType =
|
52
|
+
PydanticArgumentNameType = Annotated[str, Field(pattern="[_a-zA-Z][_a-zA-Z0-9]*")]
|
43
53
|
|
44
|
-
PydanticExecutionParameter =
|
54
|
+
PydanticExecutionParameter = Annotated[
|
55
|
+
str, Field(pattern=EXECUTION_PARAMETER_PATTERN)
|
56
|
+
]
|
@@ -20,6 +20,7 @@ class ProviderVendor(StrEnum):
|
|
20
20
|
OQC = "OQC"
|
21
21
|
INTEL = "Intel"
|
22
22
|
AQT = "AQT"
|
23
|
+
IQCC = "IQCC"
|
23
24
|
|
24
25
|
|
25
26
|
class ProviderTypeVendor:
|
@@ -33,6 +34,7 @@ class ProviderTypeVendor:
|
|
33
34
|
OQC = Literal[ProviderVendor.OQC]
|
34
35
|
INTEL = Literal[ProviderVendor.INTEL]
|
35
36
|
AQT = Literal[ProviderVendor.AQT]
|
37
|
+
IQCC = Literal[ProviderVendor.IQCC]
|
36
38
|
|
37
39
|
|
38
40
|
class ClassiqSimulatorBackendNames(StrEnum):
|
@@ -5,6 +5,7 @@ from typing import Set, Tuple, Union
|
|
5
5
|
|
6
6
|
import numpy as np
|
7
7
|
import pydantic
|
8
|
+
from pydantic import ConfigDict
|
8
9
|
|
9
10
|
from classiq.interface.exceptions import ClassiqValueError
|
10
11
|
from classiq.interface.helpers.hashable_pydantic_base_model import (
|
@@ -75,7 +76,8 @@ class FermionicOperator(HashablePydanticBaseModel):
|
|
75
76
|
|
76
77
|
return (op_symbol, op_index)
|
77
78
|
|
78
|
-
@pydantic.
|
79
|
+
@pydantic.field_validator("op_list")
|
80
|
+
@classmethod
|
79
81
|
def _validate_op_list(cls, op_list: list) -> list:
|
80
82
|
return list(map(cls._validate_single_op, op_list))
|
81
83
|
|
@@ -99,8 +101,7 @@ class FermionicOperator(HashablePydanticBaseModel):
|
|
99
101
|
"FermionicOperator can be summed together only with type FermionicOperator or SummedFermionicOperator"
|
100
102
|
)
|
101
103
|
|
102
|
-
|
103
|
-
frozen = True
|
104
|
+
model_config = ConfigDict(frozen=True)
|
104
105
|
|
105
106
|
@staticmethod
|
106
107
|
def _to_ladder_op(char: str) -> str:
|
@@ -135,9 +136,7 @@ class SummedFermionicOperator(HashablePydanticBaseModel):
|
|
135
136
|
op_list: list = pydantic.Field(
|
136
137
|
description="A list of tuples each containing a FermionicOperator and a coefficient.",
|
137
138
|
)
|
138
|
-
|
139
|
-
class Config:
|
140
|
-
frozen = True
|
139
|
+
model_config = ConfigDict(frozen=True)
|
141
140
|
|
142
141
|
@staticmethod
|
143
142
|
def _validate_single_op(op: tuple) -> FermionicOperatorTuple:
|
@@ -166,7 +165,8 @@ class SummedFermionicOperator(HashablePydanticBaseModel):
|
|
166
165
|
|
167
166
|
return op # type: ignore[return-value] # mypy thinks that it is `Tuple[Any, ...]`, though the asserts here tell otherwise..
|
168
167
|
|
169
|
-
@pydantic.
|
168
|
+
@pydantic.field_validator("op_list")
|
169
|
+
@classmethod
|
170
170
|
def _validate_op_list(cls, op_list: list) -> list:
|
171
171
|
return list(map(cls._validate_single_op, op_list))
|
172
172
|
|
@@ -1,7 +1,8 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import List, Literal, Optional, Tuple, Union, cast
|
2
2
|
|
3
3
|
import pydantic
|
4
|
-
from pydantic import Field
|
4
|
+
from pydantic import ConfigDict, Field
|
5
|
+
from pydantic_core.core_schema import ValidationInfo
|
5
6
|
from typing_extensions import Annotated
|
6
7
|
|
7
8
|
from classiq.interface.chemistry.fermionic_operator import SummedFermionicOperator
|
@@ -52,18 +53,19 @@ class GroundStateProblem(HashablePydanticBaseModel):
|
|
52
53
|
)
|
53
54
|
num_qubits: Optional[int] = pydantic.Field(default=None)
|
54
55
|
|
55
|
-
@pydantic.
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
@pydantic.field_validator("z2_symmetries")
|
57
|
+
@classmethod
|
58
|
+
def _validate_z2_symmetries(cls, z2_symmetries: bool, info: ValidationInfo) -> bool:
|
59
|
+
if (
|
60
|
+
z2_symmetries
|
61
|
+
and info.data.get("mapping") == FermionMapping.FAST_BRAVYI_KITAEV
|
62
|
+
):
|
60
63
|
raise ClassiqValueError(
|
61
64
|
"z2 symmetries reduction can not be used for fast_bravyi_kitaev mapping"
|
62
65
|
)
|
63
66
|
return z2_symmetries
|
64
67
|
|
65
|
-
|
66
|
-
frozen = True
|
68
|
+
model_config = ConfigDict(frozen=True)
|
67
69
|
|
68
70
|
|
69
71
|
class MoleculeProblem(GroundStateProblem):
|
@@ -87,20 +89,23 @@ class HamiltonianProblem(GroundStateProblem):
|
|
87
89
|
description="Tuple containing the numbers of alpha particles and beta particles"
|
88
90
|
)
|
89
91
|
|
90
|
-
@pydantic.
|
91
|
-
|
92
|
-
|
92
|
+
@pydantic.field_validator("num_particles", mode="before")
|
93
|
+
@classmethod
|
94
|
+
def _validate_num_particles(
|
95
|
+
cls,
|
96
|
+
num_particles: Union[
|
97
|
+
List[Union[int, float]], Tuple[Union[int, float], Union[int, float]]
|
98
|
+
],
|
99
|
+
) -> List[int]:
|
100
|
+
assert isinstance(num_particles, (list, tuple))
|
93
101
|
assert len(num_particles) == 2
|
94
102
|
|
95
|
-
|
96
|
-
# floats to ints
|
97
|
-
assert isinstance(num_particles[0], int)
|
98
|
-
assert num_particles[0] >= 1
|
103
|
+
num_particles = [int(x) for x in num_particles]
|
99
104
|
|
100
|
-
assert
|
105
|
+
assert num_particles[0] >= 1
|
101
106
|
assert num_particles[1] >= 1
|
102
107
|
|
103
|
-
return num_particles
|
108
|
+
return cast(List[int], num_particles)
|
104
109
|
|
105
110
|
|
106
111
|
CHEMISTRY_PROBLEMS = (MoleculeProblem, HamiltonianProblem)
|