classiq 0.39.0__py3-none-any.whl → 0.41.0__py3-none-any.whl

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