classiq 0.100.0__py3-none-any.whl → 0.104.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 (95) hide show
  1. classiq/__init__.py +3 -0
  2. classiq/_internals/api_wrapper.py +29 -4
  3. classiq/applications/chemistry/op_utils.py +63 -1
  4. classiq/applications/chemistry/problems.py +18 -6
  5. classiq/applications/chemistry/ucc.py +2 -2
  6. classiq/evaluators/parameter_types.py +1 -4
  7. classiq/evaluators/qmod_annotated_expression.py +1 -1
  8. classiq/evaluators/qmod_expression_visitors/qmod_expression_evaluator.py +1 -8
  9. classiq/evaluators/qmod_expression_visitors/qmod_expression_simplifier.py +1 -1
  10. classiq/evaluators/qmod_node_evaluators/attribute_evaluation.py +2 -2
  11. classiq/evaluators/qmod_node_evaluators/binary_op_evaluation.py +18 -29
  12. classiq/evaluators/qmod_node_evaluators/min_max_evaluation.py +1 -6
  13. classiq/evaluators/qmod_node_evaluators/numeric_attrs_utils.py +1 -7
  14. classiq/evaluators/qmod_node_evaluators/utils.py +6 -3
  15. classiq/evaluators/qmod_type_inference/quantum_type_comparison.py +52 -0
  16. classiq/execution/__init__.py +11 -1
  17. classiq/execution/execution_session.py +1 -1
  18. classiq/execution/functions/__init__.py +3 -0
  19. classiq/execution/functions/_logging.py +19 -0
  20. classiq/execution/functions/constants.py +9 -0
  21. classiq/execution/functions/parse_provider_backend.py +90 -0
  22. classiq/execution/functions/sample.py +257 -0
  23. classiq/execution/jobs.py +122 -5
  24. classiq/interface/_version.py +1 -1
  25. classiq/interface/backend/backend_preferences.py +15 -0
  26. classiq/interface/backend/provider_config/providers/aqt.py +1 -1
  27. classiq/interface/backend/provider_config/providers/azure.py +1 -2
  28. classiq/interface/backend/provider_config/providers/ibm.py +1 -1
  29. classiq/interface/backend/quantum_backend_providers.py +3 -0
  30. classiq/interface/exceptions.py +0 -42
  31. classiq/interface/executor/execution_request.py +1 -0
  32. classiq/interface/executor/quantum_code.py +0 -6
  33. classiq/interface/executor/result.py +9 -5
  34. classiq/interface/generator/arith/binary_ops.py +38 -2
  35. classiq/interface/generator/function_param_list.py +4 -2
  36. classiq/interface/generator/functions/builtins/internal_operators.py +5 -9
  37. classiq/interface/generator/functions/classical_type.py +45 -0
  38. classiq/interface/generator/functions/type_name.py +23 -0
  39. classiq/interface/generator/generated_circuit_data.py +0 -2
  40. classiq/interface/generator/generation_request.py +9 -4
  41. classiq/interface/generator/quantum_program.py +8 -36
  42. classiq/interface/generator/types/compilation_metadata.py +9 -0
  43. classiq/interface/hardware.py +1 -0
  44. classiq/interface/helpers/model_normalizer.py +62 -2
  45. classiq/interface/helpers/text_utils.py +17 -6
  46. classiq/interface/interface_version.py +1 -1
  47. classiq/interface/model/invert.py +15 -0
  48. classiq/interface/model/model.py +42 -3
  49. classiq/interface/model/model_visitor.py +4 -2
  50. classiq/interface/model/quantum_function_call.py +17 -5
  51. classiq/interface/model/quantum_type.py +21 -0
  52. classiq/interface/model/statement_block.py +0 -4
  53. classiq/model_expansions/capturing/captured_vars.py +16 -12
  54. classiq/model_expansions/function_builder.py +9 -1
  55. classiq/model_expansions/interpreters/base_interpreter.py +12 -10
  56. classiq/model_expansions/interpreters/generative_interpreter.py +9 -24
  57. classiq/model_expansions/quantum_operations/arithmetic/explicit_boolean_expressions.py +1 -0
  58. classiq/model_expansions/quantum_operations/assignment_result_processor.py +132 -28
  59. classiq/model_expansions/quantum_operations/bind.py +4 -0
  60. classiq/model_expansions/quantum_operations/call_emitter.py +5 -35
  61. classiq/model_expansions/quantum_operations/emitter.py +1 -4
  62. classiq/model_expansions/quantum_operations/expression_evaluator.py +0 -3
  63. classiq/model_expansions/visitors/uncomputation_signature_inference.py +15 -47
  64. classiq/open_library/functions/__init__.py +42 -27
  65. classiq/open_library/functions/bit_operations.py +30 -0
  66. classiq/open_library/functions/modular_arithmetics.py +597 -0
  67. classiq/open_library/functions/qft_space_arithmetics.py +81 -0
  68. classiq/open_library/functions/state_preparation.py +6 -3
  69. classiq/open_library/functions/utility_functions.py +22 -3
  70. classiq/qmod/builtins/functions/__init__.py +9 -0
  71. classiq/qmod/builtins/functions/arithmetic.py +131 -0
  72. classiq/qmod/builtins/functions/exponentiation.py +34 -4
  73. classiq/qmod/builtins/operations.py +30 -41
  74. classiq/qmod/native/pretty_printer.py +12 -12
  75. classiq/qmod/pretty_print/pretty_printer.py +11 -15
  76. classiq/qmod/qmod_parameter.py +4 -0
  77. classiq/qmod/qmod_variable.py +38 -63
  78. classiq/qmod/quantum_callable.py +8 -2
  79. classiq/qmod/quantum_expandable.py +3 -1
  80. classiq/qmod/quantum_function.py +45 -8
  81. classiq/qmod/semantics/validation/function_name_collisions_validation.py +7 -4
  82. classiq/qmod/semantics/validation/model_validation.py +7 -2
  83. classiq/qmod/symbolic_type.py +4 -2
  84. classiq/qmod/utilities.py +7 -4
  85. classiq/synthesis_action/__init__.py +20 -0
  86. classiq/synthesis_action/actions.py +106 -0
  87. {classiq-0.100.0.dist-info → classiq-0.104.0.dist-info}/METADATA +1 -1
  88. {classiq-0.100.0.dist-info → classiq-0.104.0.dist-info}/RECORD +90 -84
  89. classiq/interface/executor/register_initialization.py +0 -36
  90. classiq/interface/generator/amplitude_loading.py +0 -103
  91. classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +0 -77
  92. classiq/open_library/functions/modular_exponentiation.py +0 -272
  93. classiq/open_library/functions/qsvt_temp.py +0 -536
  94. {classiq-0.100.0.dist-info → classiq-0.104.0.dist-info}/WHEEL +0 -0
  95. {classiq-0.100.0.dist-info → classiq-0.104.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -35,14 +35,6 @@ class ClassiqMissingOutputFormatError(ClassiqError):
35
35
  super().__init__(message=msg)
36
36
 
37
37
 
38
- class ClassiqCombinatorialOptimizationError(ClassiqError):
39
- pass
40
-
41
-
42
- class ClassiqOracleError(ClassiqError):
43
- pass
44
-
45
-
46
38
  class ClassiqAnalyzerError(ClassiqError):
47
39
  pass
48
40
 
@@ -57,10 +49,6 @@ class ClassiqAPIError(ClassiqError):
57
49
  super().__init__(message)
58
50
 
59
51
 
60
- class ClassiqVersionError(ClassiqError):
61
- pass
62
-
63
-
64
52
  class ClassiqValueError(ClassiqError, ValueError):
65
53
  pass
66
54
 
@@ -77,10 +65,6 @@ class ClassiqIndexError(ClassiqError, IndexError):
77
65
  pass
78
66
 
79
67
 
80
- class ClassiqWiringError(ClassiqValueError):
81
- pass
82
-
83
-
84
68
  class ClassiqControlError(ClassiqError):
85
69
  def __init__(self) -> None:
86
70
  message = "Repeated control names, please rename the control states"
@@ -91,10 +75,6 @@ class ClassiqQRegError(ClassiqValueError):
91
75
  pass
92
76
 
93
77
 
94
- class ClassiqQFuncError(ClassiqValueError):
95
- pass
96
-
97
-
98
78
  class ClassiqQNNError(ClassiqValueError):
99
79
  pass
100
80
 
@@ -103,10 +83,6 @@ class ClassiqTorchError(ClassiqQNNError):
103
83
  pass
104
84
 
105
85
 
106
- class ClassiqChemistryError(ClassiqError):
107
- pass
108
-
109
-
110
86
  class ClassiqAuthenticationError(ClassiqError):
111
87
  pass
112
88
 
@@ -115,22 +91,10 @@ class ClassiqExpiredTokenError(ClassiqAuthenticationError):
115
91
  pass
116
92
 
117
93
 
118
- class ClassiqFileNotFoundError(FileNotFoundError):
119
- pass
120
-
121
-
122
- class ClassiqStateInitializationError(ClassiqError):
123
- pass
124
-
125
-
126
94
  class ClassiqPasswordManagerSelectionError(ClassiqError):
127
95
  pass
128
96
 
129
97
 
130
- class ClassiqMismatchIOsError(ClassiqError):
131
- pass
132
-
133
-
134
98
  class ClassiqNotImplementedError(ClassiqError, NotImplementedError):
135
99
  pass
136
100
 
@@ -171,12 +135,6 @@ class ClassiqCombOptNotSupportedProblemError(ClassiqCombOptError):
171
135
  pass
172
136
 
173
137
 
174
- class ClassiqExecutorInvalidHamiltonianError(ClassiqCombOptError):
175
-
176
- def __init__(self) -> None:
177
- super().__init__("Invalid hamiltonian")
178
-
179
-
180
138
  class ClassiqDeprecationWarning(FutureWarning):
181
139
  pass
182
140
 
@@ -58,6 +58,7 @@ class JobCost(BaseModel):
58
58
  class ExecutionJobDetails(VersionedModel):
59
59
  id: str
60
60
 
61
+ session_id: str | None = Field(default=None)
61
62
  name: str | None = Field(default=None)
62
63
  start_time: datetime
63
64
  end_time: datetime | None = Field(default=None)
@@ -11,7 +11,6 @@ from classiq.interface.backend.ionq.ionq_quantum_program import IonqQuantumCircu
11
11
  from classiq.interface.backend.pydantic_backend import PydanticArgumentNameType
12
12
  from classiq.interface.exceptions import ClassiqValueError
13
13
  from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
14
- from classiq.interface.executor.register_initialization import RegisterInitialization
15
14
  from classiq.interface.generator.synthesis_metadata.synthesis_execution_data import (
16
15
  ExecutionData,
17
16
  )
@@ -19,7 +18,6 @@ from classiq.interface.generator.synthesis_metadata.synthesis_execution_data imp
19
18
  Arguments = dict[PydanticArgumentNameType, Any]
20
19
  MultipleArguments = tuple[Arguments, ...]
21
20
  CodeType = str
22
- RegistersInitialization = dict[str, RegisterInitialization]
23
21
  Qubits = tuple[int, ...]
24
22
  OutputQubitsMap = dict[str, Qubits]
25
23
 
@@ -57,10 +55,6 @@ class QuantumCode(QuantumBaseCode):
57
55
  default_factory=dict,
58
56
  description="The map of outputs to their qubits in the circuit.",
59
57
  )
60
- registers_initialization: RegistersInitialization | None = pydantic.Field(
61
- default=None,
62
- description="Initial conditions for the different registers in the circuit.",
63
- )
64
58
  synthesis_execution_data: ExecutionData | None = pydantic.Field(default=None)
65
59
  synthesis_execution_arguments: Arguments = pydantic.Field(default_factory=dict)
66
60
  model_config = ConfigDict(validate_assignment=True)
@@ -47,7 +47,7 @@ StateVector: TypeAlias = Optional[dict[str, Complex]]
47
47
  BITSTRING = "bitstring"
48
48
  PROBABILITY = "probability"
49
49
  AMPLITUDE = "amplitude"
50
- COUNT = "count"
50
+ COUNTS = "counts"
51
51
  MAGNITUDE = "magnitude"
52
52
  PHASE = "phase"
53
53
 
@@ -374,7 +374,9 @@ class ExecutionDetails(BaseModel, QmodPyObject):
374
374
 
375
375
  for bitstring, count in self.counts.items():
376
376
  data[BITSTRING].append(bitstring)
377
- data[COUNT].append(count)
377
+ # TODO CLS-4767: delete "count"
378
+ data["count"].append(count)
379
+ data[COUNTS].append(count)
378
380
  if self.probabilities:
379
381
  data[PROBABILITY].append(self.probabilities[bitstring])
380
382
  elif self.num_shots:
@@ -383,7 +385,8 @@ class ExecutionDetails(BaseModel, QmodPyObject):
383
385
  for name, value in self.parsed_states[bitstring].items():
384
386
  data[name].append(value)
385
387
 
386
- final_columns = [COUNT, PROBABILITY, BITSTRING]
388
+ # TODO CLS-4767: delete "count"
389
+ final_columns = [COUNTS, "count", PROBABILITY, BITSTRING]
387
390
  columns = [
388
391
  col for col in data.keys() if col not in final_columns
389
392
  ] + final_columns
@@ -419,8 +422,9 @@ class ExecutionDetails(BaseModel, QmodPyObject):
419
422
 
420
423
  @functools.cached_property
421
424
  def dataframe(self) -> "pd.DataFrame":
425
+ # TODO CLS-4767: remove "count"
422
426
  reserved_words = frozenset(
423
- [BITSTRING, PROBABILITY, COUNT, AMPLITUDE, PHASE, MAGNITUDE]
427
+ ["count", BITSTRING, PROBABILITY, COUNTS, AMPLITUDE, PHASE, MAGNITUDE]
424
428
  )
425
429
  _invalid_output_names = reserved_words.intersection(
426
430
  self.output_qubits_map.keys()
@@ -436,7 +440,7 @@ class ExecutionDetails(BaseModel, QmodPyObject):
436
440
  df = self._counts_df()
437
441
 
438
442
  df.sort_values(
439
- by=[AMPLITUDE if self.state_vector else COUNT, BITSTRING],
443
+ by=[AMPLITUDE if self.state_vector else COUNTS, BITSTRING],
440
444
  inplace=True,
441
445
  ascending=[False, True],
442
446
  ignore_index=True,
@@ -29,7 +29,10 @@ from classiq.interface.generator.arith.ast_node_rewrite import (
29
29
  )
30
30
  from classiq.interface.generator.arith.register_user_input import RegisterArithmeticInfo
31
31
  from classiq.interface.generator.arith.unary_ops import Negation
32
- from classiq.interface.generator.function_params import get_zero_input_name
32
+ from classiq.interface.generator.function_params import (
33
+ FunctionParams,
34
+ get_zero_input_name,
35
+ )
33
36
 
34
37
  from classiq.model_expansions.arithmetic import NumericAttributes
35
38
  from classiq.model_expansions.arithmetic_compute_result_attrs import (
@@ -533,10 +536,43 @@ class Multiplier(BinaryOpWithFloatInputs):
533
536
 
534
537
  def garbage_output_size(self) -> pydantic.NonNegativeInt:
535
538
  return max(
536
- 0, self.expected_fraction_places() - self.result_register.fraction_places
539
+ 0,
540
+ self.expected_fraction_places() - self.result_register.fraction_places - 1,
537
541
  )
538
542
 
539
543
 
544
+ class CanonicalMultiplier(FunctionParams):
545
+ left_size: pydantic.PositiveInt
546
+ extend_left: bool
547
+ right_size: pydantic.PositiveInt
548
+ extend_right: bool
549
+ result_size: pydantic.PositiveInt
550
+ trim_result_lsb: bool
551
+
552
+ def _create_ios(self) -> None:
553
+ self._inputs = {
554
+ "left": RegisterArithmeticInfo(size=self.left_size),
555
+ "right": RegisterArithmeticInfo(size=self.right_size),
556
+ "result": RegisterArithmeticInfo(size=self.result_size),
557
+ }
558
+ self._outputs = {**self._inputs}
559
+
560
+
561
+ class CanonicalConstantMultiplier(FunctionParams):
562
+ left: int
563
+ right_size: pydantic.PositiveInt
564
+ extend_right: bool
565
+ result_size: pydantic.PositiveInt
566
+ trim_result_lsb: bool
567
+
568
+ def _create_ios(self) -> None:
569
+ self._inputs = {
570
+ "right": RegisterArithmeticInfo(size=self.right_size),
571
+ "result": RegisterArithmeticInfo(size=self.result_size),
572
+ }
573
+ self._outputs = {**self._inputs}
574
+
575
+
540
576
  class Comparator(BinaryOpWithFloatInputs):
541
577
  output_size: Literal[1] = 1
542
578
 
@@ -1,12 +1,13 @@
1
1
  import itertools
2
2
 
3
- from classiq.interface.generator.amplitude_loading import AmplitudeLoading
4
3
  from classiq.interface.generator.arith.arithmetic import Arithmetic
5
4
  from classiq.interface.generator.arith.binary_ops import (
6
5
  Adder,
7
6
  BitwiseAnd,
8
7
  BitwiseOr,
9
8
  BitwiseXor,
9
+ CanonicalConstantMultiplier,
10
+ CanonicalMultiplier,
10
11
  Equal,
11
12
  GreaterEqual,
12
13
  GreaterThan,
@@ -79,6 +80,8 @@ function_param_library: FunctionParamLibrary = FunctionParamLibrary(
79
80
  HardwareEfficientAnsatz,
80
81
  UnitaryGate,
81
82
  Multiplier,
83
+ CanonicalMultiplier,
84
+ CanonicalConstantMultiplier,
82
85
  Power,
83
86
  Min,
84
87
  Max,
@@ -88,7 +91,6 @@ function_param_library: FunctionParamLibrary = FunctionParamLibrary(
88
91
  Identity,
89
92
  RandomizedBenchmarking,
90
93
  UGate,
91
- AmplitudeLoading,
92
94
  HadamardTransform,
93
95
  Copy,
94
96
  Reset,
@@ -1,7 +1,8 @@
1
1
  CTRL_VAR_PREFIX = "ctrl__"
2
2
  CONTROL_OPERATOR_NAME = "control"
3
3
  SKIP_CONTROL_OPERATOR_NAME = "skip_control"
4
- INVERT_OPERATOR_NAME = "invert"
4
+ COMPOUND_INVERT_OPERATOR_NAME = "compound_invert"
5
+ SINGLE_CALL_INVERT_OPERATOR_NAME = "single_call_invert"
5
6
  REPEAT_OPERATOR_NAME = "iteration"
6
7
  CLASSICAL_IF_OPERATOR_NAME = "classical_if"
7
8
  POWER_OPERATOR_NAME = "power"
@@ -9,12 +10,7 @@ UNCOMPUTE_OPERATOR_NAME = "uncompute"
9
10
  WITHIN_APPLY_NAME = "within_apply"
10
11
  BLOCK_OPERATOR_NAME = "block"
11
12
 
12
- All_BUILTINS_OPERATORS = {
13
- CONTROL_OPERATOR_NAME,
14
- INVERT_OPERATOR_NAME,
15
- REPEAT_OPERATOR_NAME,
16
- POWER_OPERATOR_NAME,
17
- UNCOMPUTE_OPERATOR_NAME,
18
- WITHIN_APPLY_NAME,
19
- BLOCK_OPERATOR_NAME,
13
+ INVERT_OPERATOR_NAMES = {
14
+ COMPOUND_INVERT_OPERATOR_NAME,
15
+ SINGLE_CALL_INVERT_OPERATOR_NAME,
20
16
  }
@@ -61,6 +61,10 @@ class ClassicalType(HashableASTNode):
61
61
  def raw_qmod_type_name(self) -> str:
62
62
  return self.qmod_type_name
63
63
 
64
+ @property
65
+ def python_type_name(self) -> str:
66
+ raise NotImplementedError
67
+
64
68
  @property
65
69
  def expressions(self) -> list[Expression]:
66
70
  return []
@@ -76,6 +80,9 @@ class ClassicalType(HashableASTNode):
76
80
  def without_symbolic_attributes(self) -> Self:
77
81
  return self
78
82
 
83
+ def get_compile_time_attributes(self, path_expr_prefix: str) -> dict[str, Any]:
84
+ return {}
85
+
79
86
 
80
87
  class Integer(ClassicalType):
81
88
  kind: Literal["int"]
@@ -89,6 +96,10 @@ class Integer(ClassicalType):
89
96
  def qmod_type_name(self) -> str:
90
97
  return "CInt"
91
98
 
99
+ @property
100
+ def python_type_name(self) -> str:
101
+ return "int"
102
+
92
103
 
93
104
  class Real(ClassicalType):
94
105
  kind: Literal["real"]
@@ -102,6 +113,10 @@ class Real(ClassicalType):
102
113
  def qmod_type_name(self) -> str:
103
114
  return "CReal"
104
115
 
116
+ @property
117
+ def python_type_name(self) -> str:
118
+ return "float"
119
+
105
120
 
106
121
  class Bool(ClassicalType):
107
122
  kind: Literal["bool"]
@@ -115,6 +130,10 @@ class Bool(ClassicalType):
115
130
  def qmod_type_name(self) -> str:
116
131
  return "CBool"
117
132
 
133
+ @property
134
+ def python_type_name(self) -> str:
135
+ return "bool"
136
+
118
137
 
119
138
  class StructMetaType(ClassicalType):
120
139
  kind: Literal["type_proxy"]
@@ -201,6 +220,10 @@ class ClassicalArray(ClassicalType):
201
220
  def raw_qmod_type_name(self) -> str:
202
221
  return "CArray"
203
222
 
223
+ @property
224
+ def python_type_name(self) -> str:
225
+ return f"list[{self.element_type.python_type_name}]"
226
+
204
227
  def without_symbolic_attributes(self) -> "ClassicalArray":
205
228
  length = (
206
229
  None
@@ -213,6 +236,14 @@ class ClassicalArray(ClassicalType):
213
236
  element_type=self.element_type.without_symbolic_attributes(), length=length
214
237
  )
215
238
 
239
+ def get_compile_time_attributes(self, path_expr_prefix: str) -> dict[str, Any]:
240
+ attrs: dict[str, Any] = {}
241
+ if self.has_constant_length:
242
+ attrs[f"{path_expr_prefix}.len"] = self.length_value
243
+ return attrs | self.element_type.get_compile_time_attributes(
244
+ f"{path_expr_prefix}[0]"
245
+ )
246
+
216
247
 
217
248
  class ClassicalTuple(ClassicalType):
218
249
  kind: Literal["tuple"]
@@ -283,6 +314,13 @@ class ClassicalTuple(ClassicalType):
283
314
  def raw_qmod_type_name(self) -> str:
284
315
  return "CArray"
285
316
 
317
+ @property
318
+ def python_type_name(self) -> str:
319
+ raw_type = self.get_raw_type(preserve_length=True)
320
+ if isinstance(raw_type, ClassicalTuple):
321
+ return "list"
322
+ return raw_type.python_type_name
323
+
286
324
  def without_symbolic_attributes(self) -> "ClassicalTuple":
287
325
  return ClassicalTuple(
288
326
  element_types=[
@@ -291,6 +329,13 @@ class ClassicalTuple(ClassicalType):
291
329
  ]
292
330
  )
293
331
 
332
+ def get_compile_time_attributes(self, path_expr_prefix: str) -> dict[str, Any]:
333
+ raw_type = self.get_raw_type(preserve_length=True)
334
+ attrs = {f"{path_expr_prefix}.len": len(self.element_types)}
335
+ if isinstance(raw_type, ClassicalTuple):
336
+ return attrs
337
+ return attrs | raw_type.get_compile_time_attributes(path_expr_prefix)
338
+
294
339
 
295
340
  class OpaqueHandle(ClassicalType):
296
341
  pass
@@ -60,6 +60,10 @@ class TypeName(ClassicalType, QuantumType):
60
60
  def qmod_type_name(self) -> str:
61
61
  return self.name
62
62
 
63
+ @property
64
+ def python_type_name(self) -> str:
65
+ return self.name
66
+
63
67
  @property
64
68
  def type_name(self) -> str:
65
69
  return self.name
@@ -202,6 +206,25 @@ class TypeName(ClassicalType, QuantumType):
202
206
  return type_name
203
207
  return self
204
208
 
209
+ def get_compile_time_attributes(self, path_expr_prefix: str) -> dict[str, Any]:
210
+ attrs: dict[str, Any] = {}
211
+ if self.has_fields:
212
+ for field_name, field_type in self.fields.items():
213
+ field_prefix = f"{path_expr_prefix}.{field_name}"
214
+ attrs[field_prefix] = field_type.get_compile_time_attributes(
215
+ field_prefix
216
+ )
217
+ elif self.has_classical_struct_decl:
218
+ for (
219
+ field_name,
220
+ classical_field_type,
221
+ ) in self.classical_struct_decl.variables.items():
222
+ field_prefix = f"{path_expr_prefix}.{field_name}"
223
+ attrs[field_prefix] = classical_field_type.get_compile_time_attributes(
224
+ field_prefix
225
+ )
226
+ return attrs
227
+
205
228
 
206
229
  class Enum(TypeName):
207
230
  pass
@@ -140,7 +140,6 @@ class StatementType(StrEnum):
140
140
  WITHIN = "within"
141
141
  APPLY = "apply"
142
142
  ASSIGN = "assign"
143
- ASSIGN_AMPLITUDE = "assign amplitude"
144
143
  PHASE = "phase"
145
144
  INPLACE_XOR = "inplace xor"
146
145
  INPLACE_ADD = "inplace add"
@@ -163,7 +162,6 @@ STATEMENTS_NAME: dict[str, StatementType] = {
163
162
  "Uncompute": StatementType.WITHIN,
164
163
  ArithmeticOperationKind.Assignment.value: StatementType.ASSIGN,
165
164
  "InplaceBinaryOperation": StatementType.ASSIGN,
166
- "AmplitudeLoadingOperation": StatementType.ASSIGN_AMPLITUDE,
167
165
  "PhaseOperation": StatementType.PHASE,
168
166
  ArithmeticOperationKind.InplaceXor.value: StatementType.INPLACE_XOR,
169
167
  ArithmeticOperationKind.InplaceAdd.value: StatementType.INPLACE_ADD,
@@ -1,12 +1,17 @@
1
1
  from datetime import datetime
2
2
 
3
- from pydantic import Field
3
+ from pydantic import ConfigDict, Field
4
4
 
5
5
  from classiq.interface.helpers.versioned_model import VersionedModel
6
6
  from classiq.interface.jobs import JobStatus
7
7
 
8
8
 
9
- class SynthesisJobDetails(VersionedModel):
9
+ class SynthesisActionDetails(VersionedModel):
10
+ """
11
+ Details of a synthesis user action.
12
+ """
13
+
14
+ model_config = ConfigDict(frozen=True)
10
15
  id: str
11
16
 
12
17
  name: str | None = Field(default=None)
@@ -31,5 +36,5 @@ class SynthesisJobDetails(VersionedModel):
31
36
  max_gate_count: int | None = Field(default=None)
32
37
 
33
38
 
34
- class SynthesisJobsQueryResults(VersionedModel):
35
- results: list[SynthesisJobDetails]
39
+ class SynthesisActionsQueryResults(VersionedModel):
40
+ results: list[SynthesisActionDetails]
@@ -10,12 +10,10 @@ from classiq.interface.compression_utils import decompress
10
10
  from classiq.interface.exceptions import (
11
11
  ClassiqDeprecationWarning,
12
12
  ClassiqMissingOutputFormatError,
13
- ClassiqStateInitializationError,
14
13
  )
15
14
  from classiq.interface.execution.primitives import PrimitivesInput
16
15
  from classiq.interface.executor import quantum_code
17
16
  from classiq.interface.executor.quantum_instruction_set import QuantumInstructionSet
18
- from classiq.interface.executor.register_initialization import RegisterInitialization
19
17
  from classiq.interface.generator.circuit_code.circuit_code import CircuitCodeInterface
20
18
  from classiq.interface.generator.circuit_code.types_and_constants import (
21
19
  INSTRUCTION_SET_TO_FORMAT,
@@ -29,9 +27,9 @@ from classiq.interface.generator.hardware.hardware_data import SynthesisHardware
29
27
  from classiq.interface.generator.model.model import ExecutionModel
30
28
  from classiq.interface.helpers.versioned_model import VersionedModel
31
29
  from classiq.interface.ide.visual_model import CircuitMetrics
30
+ from classiq.interface.model.model import Model
32
31
 
33
32
  RegisterName: TypeAlias = str
34
- InitialConditions: TypeAlias = dict[RegisterName, int]
35
33
 
36
34
 
37
35
  class TranspiledCircuitData(CircuitCodeInterface):
@@ -56,7 +54,6 @@ def _get_formatted_utc_current_time() -> str:
56
54
 
57
55
  class QuantumProgram(VersionedModel, CircuitCodeInterface):
58
56
  hardware_data: SynthesisHardwareData
59
- initial_values: InitialConditions | None = pydantic.Field(default=None)
60
57
  data: GeneratedCircuitData
61
58
  model: ExecutionModel
62
59
  transpiled_circuit: TranspiledCircuitData | None = pydantic.Field(default=None)
@@ -65,7 +62,7 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
65
62
  program_id: str = pydantic.Field(default_factory=get_uuid_as_str)
66
63
  execution_primitives_input: PrimitivesInput | None = pydantic.Field(default=None)
67
64
  synthesis_warnings: list[str] | None = pydantic.Field(default=None)
68
- should_warn: bool = pydantic.Field(default=False)
65
+ compiled_qmod: Model | None = pydantic.Field(default=None)
69
66
 
70
67
  def __str__(self) -> str:
71
68
  return self.model_dump_json(indent=2)
@@ -85,10 +82,8 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
85
82
 
86
83
  def to_program(
87
84
  self,
88
- initial_values: InitialConditions | None = None,
89
85
  instruction_set: QuantumInstructionSet | None = None,
90
86
  ) -> quantum_code.QuantumCode:
91
- initial_values = initial_values or self.initial_values
92
87
  if instruction_set is not None:
93
88
  code, syntax = (
94
89
  self.program_circuit.get_code(instruction_set),
@@ -97,40 +92,17 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
97
92
  else:
98
93
  code, syntax = self._default_program_code()
99
94
 
100
- if initial_values is not None:
101
- registers_initialization = self.get_registers_initialization(
102
- initial_values=initial_values
103
- )
104
- else:
105
- registers_initialization = None
106
95
  return quantum_code.QuantumCode(
107
96
  code=code,
108
97
  syntax=syntax,
109
- output_qubits_map=self.data.qubit_mapping.physical_outputs,
110
- registers_initialization=registers_initialization,
98
+ output_qubits_map=(
99
+ self.data.qubit_mapping.physical_outputs
100
+ if self._can_use_transpiled_code
101
+ else self.data.qubit_mapping.logical_outputs
102
+ ),
111
103
  synthesis_execution_data=self.data.execution_data,
112
104
  )
113
105
 
114
- def _get_initialization_qubits(self, name: str) -> tuple[int, ...]:
115
- qubits = self.data.qubit_mapping.logical_inputs.get(name)
116
- if qubits is None:
117
- raise ClassiqStateInitializationError(
118
- f"Cannot initialize register {name}, it does not appear in circuit inputs"
119
- )
120
- return qubits
121
-
122
- def get_registers_initialization(
123
- self, initial_values: InitialConditions
124
- ) -> dict[RegisterName, RegisterInitialization]:
125
- return {
126
- name: RegisterInitialization(
127
- name=name,
128
- qubits=list(self._get_initialization_qubits(name)),
129
- initial_condition=init_value,
130
- )
131
- for name, init_value in initial_values.items()
132
- }
133
-
134
106
  def save_results(self, filename: str | Path | None = None) -> None:
135
107
  """
136
108
  Saves quantum program results as json into a file.
@@ -148,7 +120,7 @@ class QuantumProgram(VersionedModel, CircuitCodeInterface):
148
120
 
149
121
  @property
150
122
  def _can_use_transpiled_code(self) -> bool:
151
- return (
123
+ return self.transpiled_circuit is not None and (
152
124
  self.data.execution_data is None
153
125
  or not self.data.execution_data.function_execution
154
126
  )
@@ -5,6 +5,7 @@ class CompilationMetadata(BaseModel):
5
5
  should_synthesize_separately: bool = Field(default=False)
6
6
  occurrences_number: NonNegativeInt = Field(default=0)
7
7
  _occupation_number: NonNegativeInt = PrivateAttr(default=0)
8
+ _required_clean_qubit: NonNegativeInt = PrivateAttr(default=0)
8
9
  disable_perm_check: bool = Field(default=False)
9
10
  disable_const_checks: list[str] | bool = Field(default=False)
10
11
 
@@ -16,6 +17,14 @@ class CompilationMetadata(BaseModel):
16
17
  def occupation_number(self, value: NonNegativeInt) -> None:
17
18
  self._occupation_number = value
18
19
 
20
+ @property
21
+ def required_clean_qubit(self) -> NonNegativeInt:
22
+ return self._required_clean_qubit
23
+
24
+ @required_clean_qubit.setter
25
+ def required_clean_qubit(self, value: NonNegativeInt) -> None:
26
+ self._required_clean_qubit = value
27
+
19
28
  @property
20
29
  def has_user_directives(self) -> bool:
21
30
  return bool(self.disable_perm_check or self.disable_const_checks)
@@ -33,6 +33,7 @@ class Provider(StrEnum):
33
33
  INTEL = "Intel"
34
34
  AQT = "AQT"
35
35
  CINECA = "CINECA"
36
+ SOFTBANK = "Softbank"
36
37
 
37
38
  @property
38
39
  def id(self) -> "ProviderIDEnum":