classiq 0.99.0__py3-none-any.whl → 0.102.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 (54) hide show
  1. classiq/__init__.py +3 -0
  2. classiq/_internals/api_wrapper.py +29 -4
  3. classiq/applications/chemistry/op_utils.py +31 -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_node_evaluators/utils.py +6 -3
  8. classiq/execution/__init__.py +11 -1
  9. classiq/execution/jobs.py +122 -5
  10. classiq/interface/_version.py +1 -1
  11. classiq/interface/exceptions.py +0 -42
  12. classiq/interface/executor/execution_request.py +1 -0
  13. classiq/interface/executor/quantum_code.py +0 -6
  14. classiq/interface/executor/user_budget.py +2 -6
  15. classiq/interface/generator/generation_request.py +40 -0
  16. classiq/interface/generator/quantum_program.py +8 -36
  17. classiq/interface/generator/transpiler_basis_gates.py +1 -3
  18. classiq/interface/generator/types/compilation_metadata.py +1 -1
  19. classiq/interface/helpers/model_normalizer.py +24 -0
  20. classiq/interface/helpers/text_utils.py +20 -5
  21. classiq/interface/model/bind_operation.py +3 -0
  22. classiq/interface/model/invert.py +7 -0
  23. classiq/interface/model/model.py +42 -3
  24. classiq/interface/model/quantum_function_call.py +17 -5
  25. classiq/model_expansions/arithmetic_compute_result_attrs.py +10 -1
  26. classiq/model_expansions/interpreters/base_interpreter.py +3 -2
  27. classiq/model_expansions/quantum_operations/call_emitter.py +0 -3
  28. classiq/model_expansions/visitors/uncomputation_signature_inference.py +15 -38
  29. classiq/open_library/functions/__init__.py +55 -27
  30. classiq/open_library/functions/bit_operations.py +30 -0
  31. classiq/open_library/functions/encodings.py +182 -0
  32. classiq/open_library/functions/modular_arithmetics.py +597 -0
  33. classiq/open_library/functions/qft_space_arithmetics.py +81 -0
  34. classiq/open_library/functions/state_preparation.py +13 -7
  35. classiq/open_library/functions/utility_functions.py +22 -3
  36. classiq/qmod/builtins/functions/exponentiation.py +2 -2
  37. classiq/qmod/builtins/operations.py +29 -4
  38. classiq/qmod/native/pretty_printer.py +15 -4
  39. classiq/qmod/pretty_print/pretty_printer.py +14 -2
  40. classiq/qmod/qmod_variable.py +1 -1
  41. classiq/qmod/quantum_callable.py +8 -2
  42. classiq/qmod/quantum_expandable.py +3 -1
  43. classiq/qmod/quantum_function.py +2 -1
  44. classiq/qmod/semantics/error_manager.py +11 -1
  45. classiq/qmod/utilities.py +7 -4
  46. classiq/synthesis_action/__init__.py +20 -0
  47. classiq/synthesis_action/actions.py +106 -0
  48. {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/METADATA +1 -1
  49. {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/RECORD +51 -47
  50. classiq/interface/executor/register_initialization.py +0 -36
  51. classiq/open_library/functions/modular_exponentiation.py +0 -272
  52. classiq/open_library/functions/qsvt_temp.py +0 -536
  53. {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/WHEEL +0 -0
  54. {classiq-0.99.0.dist-info → classiq-0.102.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -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
  )
@@ -71,9 +71,7 @@ DEFAULT_BASIS_GATES: BasisGates = SINGLE_QUBIT_GATES | BASIC_TWO_QUBIT_GATES
71
71
  ALL_GATES: BasisGates = (
72
72
  SINGLE_QUBIT_GATES | TWO_QUBIT_GATES | THREE_QUBIT_GATES | NON_UNITARY_GATES
73
73
  )
74
- ALL_NON_3_QBIT_GATES: BasisGates = (
75
- SINGLE_QUBIT_GATES | TWO_QUBIT_GATES | NON_UNITARY_GATES
76
- )
74
+ ALL_NON_3_QBIT_GATES: BasisGates = ALL_GATES - THREE_QUBIT_GATES
77
75
 
78
76
  ROUTING_TWO_QUBIT_BASIS_GATES: BasisGates = frozenset(
79
77
  ("cx", "ecr", "rzx", "ryy", "rxx", "rzz", "cy", "cz", "cp", "swap")
@@ -3,7 +3,7 @@ from pydantic import BaseModel, Field, NonNegativeInt, PrivateAttr
3
3
 
4
4
  class CompilationMetadata(BaseModel):
5
5
  should_synthesize_separately: bool = Field(default=False)
6
- occurrences_number: NonNegativeInt = Field(default=1)
6
+ occurrences_number: NonNegativeInt = Field(default=0)
7
7
  _occupation_number: NonNegativeInt = PrivateAttr(default=0)
8
8
  disable_perm_check: bool = Field(default=False)
9
9
  disable_const_checks: list[str] | bool = Field(default=False)
@@ -7,10 +7,16 @@ from classiq.interface.generator.functions.classical_type import ClassicalType
7
7
  from classiq.interface.generator.functions.type_modifier import TypeModifier
8
8
  from classiq.interface.generator.visitor import Transformer, Visitor
9
9
  from classiq.interface.model.model import Model
10
+ from classiq.interface.model.native_function_definition import NativeFunctionDefinition
10
11
  from classiq.interface.model.port_declaration import AnonPortDeclaration
12
+ from classiq.interface.model.quantum_function_call import QuantumFunctionCall
11
13
 
12
14
 
13
15
  class ModelNormalizer(Visitor):
16
+ def __init__(self, normalize_names: bool = False) -> None:
17
+ self._normalize_names = normalize_names
18
+ self._funcs_renames: dict[str, str] = {}
19
+
14
20
  def visit(self, node: Any) -> None:
15
21
  if isinstance(node, ASTNode):
16
22
  node.model_config["frozen"] = False
@@ -23,8 +29,26 @@ class ModelNormalizer(Visitor):
23
29
  def visit_Model(self, model: Model) -> None:
24
30
  model.debug_info = DebugInfoCollection()
25
31
  model.functions.sort(key=lambda x: x.name)
32
+ self._funcs_renames = {
33
+ func.name: f"___func_{index}" for index, func in enumerate(model.functions)
34
+ }
26
35
  self.generic_visit(model)
27
36
 
37
+ def visit_NativeFunctionDefinition(self, func: NativeFunctionDefinition) -> None:
38
+ if self._normalize_names:
39
+ func.name = self._funcs_renames[func.name]
40
+ self.generic_visit(func)
41
+
42
+ def visit_QuantumFunctionCall(self, call: QuantumFunctionCall) -> None:
43
+ if self._normalize_names:
44
+ if isinstance(call.function, str):
45
+ if call.function in self._funcs_renames:
46
+ call.function = self._funcs_renames[call.function]
47
+ else:
48
+ if call.function.name in self._funcs_renames:
49
+ call.function.name = self._funcs_renames[call.function.name]
50
+ self.generic_visit(call)
51
+
28
52
  def visit_AnonPortDeclaration(self, decl: AnonPortDeclaration) -> None:
29
53
  decl.type_modifier = TypeModifier.Mutable
30
54
 
@@ -1,18 +1,33 @@
1
- def s(items: list | int) -> str:
2
- if isinstance(items, list):
1
+ from collections.abc import Sequence, Sized
2
+
3
+
4
+ def s(items: Sized | int) -> str:
5
+ if isinstance(items, Sized):
3
6
  items = len(items)
4
7
  return "" if items == 1 else "s"
5
8
 
6
9
 
7
- def are(items: list) -> str:
10
+ def are(items: Sized) -> str:
8
11
  return "is" if len(items) == 1 else "are"
9
12
 
10
13
 
11
- def they(items: list) -> str:
14
+ def were(items: Sized) -> str:
15
+ return "was" if len(items) == 1 else "were"
16
+
17
+
18
+ def an(items: Sized) -> str:
19
+ return "an " if len(items) == 1 else ""
20
+
21
+
22
+ def they(items: Sized) -> str:
12
23
  return "it" if len(items) == 1 else "they"
13
24
 
14
25
 
15
- def readable_list(items: list, quote: bool = False) -> str:
26
+ def conj(items: Sized) -> str:
27
+ return "s" if len(items) == 1 else ""
28
+
29
+
30
+ def readable_list(items: Sequence, quote: bool = False) -> str:
16
31
  if quote:
17
32
  items = [repr(str(item)) for item in items]
18
33
  if len(items) == 1:
@@ -46,3 +46,6 @@ class BindOperation(QuantumOperation):
46
46
  )
47
47
  for handle in self.out_handles
48
48
  ]
49
+
50
+ def inverse(self) -> "BindOperation":
51
+ return BindOperation(in_handles=self.out_handles, out_handles=self.in_handles)
@@ -1,16 +1,23 @@
1
1
  from typing import TYPE_CHECKING, Literal
2
2
 
3
3
  from classiq.interface.ast_node import ASTNodeType, reset_lists
4
+ from classiq.interface.enum_utils import StrEnum
4
5
  from classiq.interface.model.quantum_statement import QuantumOperation
5
6
 
6
7
  if TYPE_CHECKING:
7
8
  from classiq.interface.model.statement_block import StatementBlock
8
9
 
9
10
 
11
+ class BlockKind(StrEnum):
12
+ SingleCall = "single_call"
13
+ Compound = "compound"
14
+
15
+
10
16
  class Invert(QuantumOperation):
11
17
  kind: Literal["Invert"]
12
18
 
13
19
  body: "StatementBlock"
20
+ block_kind: BlockKind = BlockKind.Compound
14
21
 
15
22
  def _as_back_ref(self: ASTNodeType) -> ASTNodeType:
16
23
  return reset_lists(self, ["body"])
@@ -5,6 +5,7 @@ from typing import Annotated, Any, Literal, NewType
5
5
  import pydantic
6
6
 
7
7
  from classiq.interface.ast_node import ASTNode
8
+ from classiq.interface.compression_utils import compress_pydantic, decompress
8
9
  from classiq.interface.debug_info.debug_info import DebugInfoCollection
9
10
  from classiq.interface.exceptions import ClassiqValueError
10
11
  from classiq.interface.executor.execution_preferences import ExecutionPreferences
@@ -96,9 +97,9 @@ class Model(VersionedModel, ASTNode):
96
97
  )
97
98
  preferences: Preferences = pydantic.Field(default_factory=Preferences)
98
99
 
99
- debug_info: DebugInfoCollection = pydantic.Field(
100
- default_factory=DebugInfoCollection
101
- )
100
+ _debug_info: DebugInfoCollection | None = pydantic.PrivateAttr(default=None)
101
+ compressed_debug_info: bytes | None = pydantic.Field(default=None)
102
+
102
103
  functions_compilation_metadata: defaultdict[
103
104
  str,
104
105
  Annotated[
@@ -198,3 +199,41 @@ class Model(VersionedModel, ASTNode):
198
199
  return model.model_dump(
199
200
  exclude={"constraints", "execution_preferences", "preferences"},
200
201
  )
202
+
203
+ # TODO (CLS-4966): remove
204
+ @pydantic.model_validator(mode="wrap")
205
+ @classmethod
206
+ def get_deprecated_debug_info(
207
+ cls, data: Any, handler: pydantic.ModelWrapValidatorHandler
208
+ ) -> "Model":
209
+ model = handler(data)
210
+ if isinstance(data, dict) and "debug_info" in data:
211
+ model._debug_info = DebugInfoCollection.model_validate(data["debug_info"])
212
+ return model
213
+
214
+ @property
215
+ def debug_info(self) -> DebugInfoCollection:
216
+ if self._debug_info is None:
217
+ if self.compressed_debug_info is None:
218
+ self._debug_info = DebugInfoCollection()
219
+ else:
220
+ self._debug_info = DebugInfoCollection.model_validate(
221
+ decompress(self.compressed_debug_info)
222
+ )
223
+
224
+ return self._debug_info
225
+
226
+ @debug_info.setter
227
+ def debug_info(self, value: DebugInfoCollection) -> None:
228
+ self._debug_info = value
229
+ self.compressed_debug_info = None
230
+
231
+ def clear_debug_info(self) -> None:
232
+ self._debug_info = None
233
+ self.compressed_debug_info = None
234
+
235
+ def compress_debug_info(self) -> None:
236
+ if self._debug_info is None:
237
+ self.compressed_debug_info = None
238
+ else:
239
+ self.compressed_debug_info = compress_pydantic(self._debug_info)
@@ -29,6 +29,13 @@ from classiq.interface.model.quantum_lambda_function import (
29
29
  )
30
30
  from classiq.interface.model.quantum_statement import HandleMetadata, QuantumOperation
31
31
 
32
+
33
+ def _split_concatenation(var: HandleBinding | HandlesList) -> list[HandleBinding]:
34
+ if isinstance(var, HandleBinding):
35
+ return [var]
36
+ return list(chain.from_iterable(_split_concatenation(item) for item in var.handles))
37
+
38
+
32
39
  ArgValue = Union[
33
40
  Expression,
34
41
  QuantumOperand,
@@ -221,18 +228,23 @@ class QuantumFunctionCall(QuantumOperation):
221
228
  def _get_handles_with_declarations(
222
229
  self,
223
230
  ) -> Iterable[tuple[int, AnonPortDeclaration, HandleBinding]]:
231
+ """
232
+ Get variable arguments attached to their position and parameter declaration.
233
+ Splits concatenations into variables.
234
+ """
224
235
  return [
225
- (idx, port, handle)
226
- for idx, (port, handle) in enumerate(
236
+ (positional_idx, port, var)
237
+ for positional_idx, (port, var_or_concatenation) in enumerate(
227
238
  zip(
228
239
  (port_decl for port_decl in self.func_decl.port_declarations),
229
240
  (
230
- param
231
- for param in self.positional_args
232
- if isinstance(param, HandleBinding)
241
+ arg
242
+ for arg in self.positional_args
243
+ if isinstance(arg, (HandleBinding, HandlesList))
233
244
  ),
234
245
  )
235
246
  )
247
+ for var in _split_concatenation(var_or_concatenation)
236
248
  ]
237
249
 
238
250
  def _get_readable_location(
@@ -64,11 +64,20 @@ def compute_result_attrs_bitwise_and(
64
64
  if left.fraction_digits > 0 or right.fraction_digits > 0:
65
65
  raise ClassiqValueError("Bitwise AND is only defined for integers")
66
66
 
67
+ if left.is_signed and not right.is_signed:
68
+ size = right.size
69
+ elif not left.is_signed and right.is_signed:
70
+ size = left.size
71
+ elif not left.is_signed and not right.is_signed:
72
+ size = min(left.size, right.size)
73
+ else:
74
+ size = max(left.size, right.size)
75
+
67
76
  # we comply with python, which uses arbitrary precision, so a positive number can
68
77
  # always be represented by "0..." and a negative number by "1...", thus their
69
78
  # bitwise AND is always non-negative
70
79
  return NumericAttributes(
71
- size=max(left.size, right.size),
80
+ size=size,
72
81
  is_signed=left.is_signed and right.is_signed,
73
82
  fraction_digits=0,
74
83
  )
@@ -159,7 +159,7 @@ class BaseInterpreter:
159
159
  finally:
160
160
  self._error_manager.report_errors(ClassiqExpansionError)
161
161
 
162
- return Model(
162
+ model = Model(
163
163
  constraints=self._model.constraints,
164
164
  preferences=self._model.preferences,
165
165
  classical_execution_code=self._model.classical_execution_code,
@@ -181,9 +181,10 @@ class BaseInterpreter:
181
181
  if name not in BUILTIN_STRUCT_DECLARATIONS
182
182
  ],
183
183
  qstructs=list(QMODULE.qstruct_decls.values()),
184
- debug_info=self._model.debug_info,
185
184
  functions_compilation_metadata=self._expanded_functions_compilation_metadata,
186
185
  )
186
+ model.debug_info = self._model.debug_info
187
+ return model
187
188
 
188
189
  def process_exception(self, e: Exception) -> None:
189
190
  if not isinstance(e, (ClassiqError, ValidationError)):
@@ -286,9 +286,6 @@ class CallEmitter(Generic[QuantumStatementT], Emitter[QuantumStatementT], ModelR
286
286
  if cache_key in self._expanded_functions:
287
287
  function_def = self._expanded_functions[cache_key]
288
288
  self._expand_cached_function(function, function_def)
289
- self._expanded_functions_compilation_metadata[
290
- function_def.name
291
- ].occurrences_number += 1
292
289
  return function_def
293
290
 
294
291
  context = self._expand_operation(function)
@@ -1,4 +1,3 @@
1
- import warnings
2
1
  from collections import defaultdict
3
2
  from collections.abc import Iterator
4
3
  from contextlib import contextmanager
@@ -6,10 +5,8 @@ from typing import NamedTuple
6
5
 
7
6
  from classiq.interface.ast_node import ASTNode
8
7
  from classiq.interface.exceptions import (
9
- ClassiqDeprecationWarning,
10
8
  ClassiqInternalExpansionError,
11
9
  )
12
- from classiq.interface.generator.compiler_keywords import EXPANDED_KEYWORD
13
10
  from classiq.interface.generator.functions.port_declaration import (
14
11
  PortDeclarationDirection,
15
12
  )
@@ -35,6 +32,8 @@ from classiq.interface.model.skip_control import SkipControl
35
32
  from classiq.interface.model.within_apply_operation import WithinApply
36
33
  from classiq.interface.source_reference import SourceReference
37
34
 
35
+ from classiq.qmod.semantics.error_manager import ErrorManager
36
+
38
37
 
39
38
  class _BoundVars(NamedTuple):
40
39
  in_identifiers: list[str]
@@ -243,11 +242,7 @@ def infer_and_validate_uncomputation_signature(
243
242
  PortDeclarationDirection.Input,
244
243
  PortDeclarationDirection.Output,
245
244
  ):
246
- warnings.warn(
247
- _input_output_const(port.name, port.direction, func_def.name),
248
- ClassiqDeprecationWarning,
249
- stacklevel=1,
250
- )
245
+ ErrorManager().add_error(_input_output_const(port.name, port.direction))
251
246
 
252
247
  if disable_perm_check and (disable_const_checks is True) and not tighten_signature:
253
248
  return
@@ -257,10 +252,9 @@ def infer_and_validate_uncomputation_signature(
257
252
 
258
253
  if not disable_perm_check and func_def.permutation and not visitor.is_permutation():
259
254
  for source_ref in visitor.non_permutation_reasons():
260
- warnings.warn(
261
- _non_permutation_usage(func_def.name, source_ref),
262
- ClassiqDeprecationWarning,
263
- stacklevel=1,
255
+ ErrorManager().add_error(
256
+ _non_permutation_usage(),
257
+ source_ref=source_ref,
264
258
  )
265
259
 
266
260
  if tighten_signature and not func_def.permutation and visitor.is_permutation():
@@ -276,10 +270,8 @@ def infer_and_validate_uncomputation_signature(
276
270
  and not visitor.is_const(port.name)
277
271
  ):
278
272
  for source_ref in visitor.non_const_reasons(port.name):
279
- warnings.warn(
280
- _non_const_usage(port.name, source_ref),
281
- ClassiqDeprecationWarning,
282
- stacklevel=1,
273
+ ErrorManager().add_error(
274
+ _non_const_usage(port.name), source_ref=source_ref
283
275
  )
284
276
 
285
277
  if (
@@ -293,36 +285,21 @@ def infer_and_validate_uncomputation_signature(
293
285
  def _input_output_const(
294
286
  port_name: str,
295
287
  direction: PortDeclarationDirection,
296
- function_name: str,
297
288
  ) -> str:
298
- return (
299
- f"{direction.capitalize()} parameters cannot be defined as constants"
300
- f" (parameter {port_name!r} in function {function_name.split('_' + EXPANDED_KEYWORD)[0]!r}).\n"
301
- "The deprecation warning will be elevated to an error starting 2025-12-03, at the earliest."
302
- )
289
+ return f"{direction.capitalize()} parameter {port_name!r} cannot be defined as constant."
303
290
 
304
291
 
305
- def _non_const_usage(
306
- port_name: str,
307
- source_ref: SourceReference | None = None,
308
- ) -> str:
309
- source_ref_str = f"\n\tat {source_ref}" if source_ref else ""
292
+ def _non_const_usage(port_name: str) -> str:
310
293
  return (
311
- f"Non-constant usage of a constant parameter {port_name!r}.{source_ref_str}\n"
294
+ f"Non-constant usage of a constant parameter {port_name!r}.\n"
312
295
  "Tip: if the commulative use of the parameter in the function is constant, "
313
- "use the `disable_const_checks` flag to instruct the compiler to disregard individual operations.\n"
314
- "The deprecation warning will be elevated to an error starting 2025-12-03, at the earliest."
296
+ "use the `disable_const_checks` flag to instruct the compiler to disregard individual operations."
315
297
  )
316
298
 
317
299
 
318
- def _non_permutation_usage(
319
- function_name: str,
320
- source_ref: SourceReference | None = None,
321
- ) -> str:
322
- source_ref_str = f"\n\tat {source_ref}" if source_ref else ""
300
+ def _non_permutation_usage() -> str:
323
301
  return (
324
- f"Non-permutation operation used in a permutation function {function_name.split('_' + EXPANDED_KEYWORD)[0]!r}.{source_ref_str}\n"
302
+ "Non-permutation operation used in a permutation function.\n"
325
303
  "Tip: if the commulative effect of the function is a permutation, "
326
- "use the `disable_perm_check` flag to instruct the compiler to disregard individual operations.\n"
327
- "The deprecation warning will be elevated to an error starting 2025-12-03, at the earliest."
304
+ "use the `disable_perm_check` flag to instruct the compiler to disregard individual operations."
328
305
  )
@@ -8,19 +8,20 @@ from .amplitude_estimation import *
8
8
  from .amplitude_loading import assign_amplitude_table
9
9
  from .discrete_sine_cosine_transform import *
10
10
  from .discrete_sine_cosine_transform import _qct_d_operator, _qct_pi_operator
11
+ from .encodings import *
11
12
  from .grover import *
12
13
  from .grover import _cond_phase_flip
13
14
  from .hea import *
14
15
  from .lcu import *
15
16
  from .linear_pauli_rotation import *
16
17
  from .linear_pauli_rotation import _single_pauli
17
- from .modular_exponentiation import *
18
- from .modular_exponentiation import _check_msb
18
+ from .modular_arithmetics import *
19
19
  from .qaoa_penalty import *
20
20
  from .qft_functions import *
21
+ from .qft_space_arithmetics import *
22
+ from .qft_space_arithmetics import _check_msb
21
23
  from .qpe import *
22
- from .qsvt import gqsp
23
- from .qsvt_temp import * # change to .qsvt after deprecation
24
+ from .qsvt import * # change to .qsvt after deprecation
24
25
  from .state_preparation import *
25
26
  from .state_preparation import _prepare_uniform_trimmed_state_step
26
27
  from .swap_test import *
@@ -30,6 +31,7 @@ from .variational import *
30
31
  OPEN_LIBRARY_FUNCTIONS: list[BaseQFunc] = [
31
32
  qpe_flexible,
32
33
  qpe,
34
+ _check_msb,
33
35
  _single_pauli,
34
36
  linear_pauli_rotations,
35
37
  amplitude_estimation,
@@ -44,25 +46,14 @@ OPEN_LIBRARY_FUNCTIONS: list[BaseQFunc] = [
44
46
  apply_to_all,
45
47
  qft_no_swap,
46
48
  qft_space_add_const,
47
- cc_modular_add,
48
- c_modular_multiply,
49
49
  multiswap,
50
- inplace_c_modular_multiply,
51
- modular_exp,
52
- qsvt_step_old,
53
- qsvt_step_new,
54
- qsvt_old,
55
- qsvt_new,
56
- projector_controlled_double_phase_old,
57
- projector_controlled_double_phase_new,
58
- projector_controlled_phase_old,
59
- projector_controlled_phase_new,
60
- qsvt_inversion_old,
61
- qsvt_inversion_new,
62
- qsvt_lcu_old,
63
- qsvt_lcu_new,
64
- qsvt_lcu_step_old,
65
- qsvt_lcu_step_new,
50
+ qsvt_step,
51
+ qsvt,
52
+ projector_controlled_double_phase,
53
+ projector_controlled_phase,
54
+ qsvt_inversion,
55
+ qsvt_lcu,
56
+ qsvt_lcu_step,
66
57
  gqsp,
67
58
  qaoa_mixer_layer,
68
59
  qaoa_cost_layer,
@@ -88,13 +79,31 @@ OPEN_LIBRARY_FUNCTIONS: list[BaseQFunc] = [
88
79
  _prepare_uniform_trimmed_state_step,
89
80
  _qct_d_operator,
90
81
  _qct_pi_operator,
91
- _check_msb,
92
82
  encode_in_angle,
93
83
  encode_on_bloch,
94
84
  _cond_phase_flip,
95
85
  inplace_modular_multiply,
96
86
  modular_multiply,
97
87
  modular_add_qft_space,
88
+ one_hot_to_unary,
89
+ inplace_one_hot_to_unary,
90
+ unary_to_one_hot,
91
+ modular_negate_inplace,
92
+ modular_subtract_inplace,
93
+ modular_double_inplace,
94
+ modular_add_constant_inplace,
95
+ modular_add_inplace,
96
+ modular_multiply,
97
+ modular_square,
98
+ modular_multiply_constant,
99
+ modular_multiply_constant_inplace,
100
+ modular_to_montgomery_inplace,
101
+ modular_montgomery_to_standard_inplace,
102
+ modular_inverse_inplace,
103
+ kaliski_iteration,
104
+ modular_rsub_inplace,
105
+ modular_exp, # TODO: deprecate when ready
106
+ modular_exponentiate,
98
107
  ]
99
108
 
100
109
  __all__ = [
@@ -103,8 +112,8 @@ __all__ = [
103
112
  "amplitude_estimation",
104
113
  "apply_to_all",
105
114
  "assign_amplitude_table",
106
- "c_modular_multiply",
107
- "cc_modular_add",
115
+ "binary_to_one_hot",
116
+ "binary_to_unary",
108
117
  "encode_in_angle",
109
118
  "encode_on_bloch",
110
119
  "exact_amplitude_amplification",
@@ -114,19 +123,36 @@ __all__ = [
114
123
  "grover_operator",
115
124
  "grover_search",
116
125
  "hadamard_transform",
117
- "inplace_c_modular_multiply",
126
+ "inplace_binary_to_one_hot",
118
127
  "inplace_modular_multiply",
128
+ "inplace_one_hot_to_unary",
119
129
  "inplace_prepare_complex_amplitudes",
120
130
  "inplace_prepare_int",
121
131
  "inplace_prepare_sparse_amplitudes",
132
+ "kaliski_iteration",
122
133
  "lcu",
123
134
  "lcu_pauli",
124
135
  "linear_pauli_rotations",
136
+ "modular_add_constant_inplace",
137
+ "modular_add_inplace",
125
138
  "modular_add_qft_space",
139
+ "modular_double_inplace",
126
140
  "modular_exp",
127
- "modular_increment",
141
+ "modular_exponentiate",
142
+ "modular_inverse_inplace",
143
+ "modular_montgomery_to_standard_inplace",
128
144
  "modular_multiply",
145
+ "modular_multiply_constant",
146
+ "modular_multiply_constant_inplace",
147
+ "modular_negate_inplace",
148
+ "modular_rsub_inplace",
149
+ "modular_square",
150
+ "modular_subtract_inplace",
151
+ "modular_to_montgomery_inplace",
129
152
  "multiswap",
153
+ "one_hot_to_binary",
154
+ "one_hot_to_unary",
155
+ "pad_zeros",
130
156
  "phase_oracle",
131
157
  "prepare_basis_state",
132
158
  "prepare_bell_state",
@@ -166,4 +192,6 @@ __all__ = [
166
192
  "suzuki_trotter",
167
193
  "swap_test",
168
194
  "switch",
195
+ "unary_to_binary",
196
+ "unary_to_one_hot",
169
197
  ]