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
@@ -46,9 +46,15 @@ class QCallable(Generic[P], ABC):
46
46
  FRAME_DEPTH = 1
47
47
 
48
48
  @suppress_return_value
49
- def __call__(self, *args: Any, **kwargs: Any) -> None:
49
+ def __call__(
50
+ self, *args: Any, _source_ref: SourceReference | None = None, **kwargs: Any
51
+ ) -> None:
50
52
  assert QCallable.CURRENT_EXPANDABLE is not None
51
- source_ref = get_source_ref(sys._getframe(self.FRAME_DEPTH))
53
+ source_ref = (
54
+ get_source_ref(sys._getframe(self.FRAME_DEPTH))
55
+ if _source_ref is None
56
+ else _source_ref
57
+ )
52
58
  QCallable.CURRENT_EXPANDABLE.append_statement_to_body(
53
59
  self.create_quantum_function_call(source_ref, *args, **kwargs)
54
60
  )
@@ -388,7 +388,9 @@ def prepare_arg(
388
388
  qlambda.set_py_callable(val._py_callable)
389
389
  return qlambda
390
390
 
391
- if isinstance(val, QExpandable):
391
+ if isinstance(val, QExpandable) and (
392
+ get_global_declarative_switch() or not is_generative_mode()
393
+ ):
392
394
  val.expand()
393
395
  elif isinstance(val, QTerminalCallable):
394
396
  return val.get_arg()
@@ -1,5 +1,6 @@
1
1
  import ast
2
2
  import functools
3
+ import inspect
3
4
  import warnings
4
5
  from abc import abstractmethod
5
6
  from collections.abc import Callable
@@ -8,7 +9,11 @@ from enum import EnumMeta
8
9
  from inspect import isclass
9
10
  from typing import Any, get_origin
10
11
 
11
- from classiq.interface.exceptions import ClassiqDeprecationWarning, ClassiqError
12
+ from classiq.interface.exceptions import (
13
+ ClassiqDeprecationWarning,
14
+ ClassiqError,
15
+ ClassiqExpansionError,
16
+ )
12
17
  from classiq.interface.executor.execution_preferences import ExecutionPreferences
13
18
  from classiq.interface.generator.functions.port_declaration import (
14
19
  PortDeclarationDirection,
@@ -162,7 +167,8 @@ class QFunc(BaseQFunc):
162
167
  not get_global_declarative_switch()
163
168
  and len(self._qmodule.generative_functions) > 0
164
169
  ):
165
- return self._create_generative_model(model)
170
+ model = self._create_generative_model(model)
171
+ model.compress_debug_info()
166
172
  return model
167
173
 
168
174
  def _create_generative_model(self, model_stub: Model) -> Model:
@@ -275,10 +281,16 @@ class ExternalQFunc(QTerminalCallable):
275
281
  ClassiqDeprecationWarning,
276
282
  stacklevel=2,
277
283
  )
278
- if (
279
- self._py_callable.__name__ == "suzuki_trotter"
280
- and len(args) > 0
281
- and isinstance(args[0], (list, CParamList))
284
+ if self._py_callable.__name__ == "suzuki_trotter" and (
285
+ (
286
+ "pauli_operator" not in kwargs
287
+ and len(args) > 0
288
+ and isinstance(args[0], (list, CParamList))
289
+ )
290
+ or (
291
+ "pauli_operator" in kwargs
292
+ and isinstance(kwargs["pauli_operator"], (list, CParamList))
293
+ )
282
294
  ):
283
295
  warnings.warn(
284
296
  (
@@ -319,6 +331,19 @@ class ExternalQFunc(QTerminalCallable):
319
331
  ClassiqDeprecationWarning,
320
332
  stacklevel=2,
321
333
  )
334
+ if (
335
+ self._py_callable.__name__ == "unscheduled_suzuki_trotter"
336
+ ): # FIXME: remove (CLS-5391)
337
+ warnings.warn(
338
+ (
339
+ "Function 'unscheduled_suzuki_trotter' was renamed to "
340
+ "'sequential_suzuki_trotter'. 'unscheduled_suzuki_trotter' is "
341
+ "deprecated and will no longer be supported starting on 2026-02-02 "
342
+ "at the earliest."
343
+ ),
344
+ ClassiqDeprecationWarning,
345
+ stacklevel=2,
346
+ )
322
347
  super().__call__(*args, **kwargs)
323
348
 
324
349
 
@@ -347,14 +372,26 @@ class GenerativeQFunc(BaseQFunc):
347
372
  return self._inferred_func_decl
348
373
 
349
374
  def __call__(self, *args: Any, **kwargs: Any) -> None:
375
+ from classiq.qmod.builtins.functions import BUILTIN_FUNCTION_DECLARATIONS
376
+
350
377
  if get_global_declarative_switch():
351
378
  return QFunc(
352
379
  self._py_callable,
353
380
  self.compilation_metadata,
354
381
  permutation=self.permutation,
355
382
  )(*args, **kwargs)
356
- if self.func_decl.name not in self._qmodule.generative_functions:
357
- self._qmodule.generative_functions[self.func_decl.name] = self
383
+ frame = inspect.currentframe()
384
+ caller_frame = frame.f_back if frame is not None else None
385
+ module = inspect.getmodule(caller_frame)
386
+ func_name = self.func_decl.name
387
+ if func_name in BUILTIN_FUNCTION_DECLARATIONS and (
388
+ module is None or not module.__name__.startswith("model.function_library")
389
+ ):
390
+ raise ClassiqExpansionError(
391
+ f"Cannot redefine built-in function {func_name!r}"
392
+ )
393
+ if func_name not in self._qmodule.generative_functions:
394
+ self._qmodule.generative_functions[func_name] = self
358
395
  if self._func_decl is None:
359
396
  self._inferred_func_decl = infer_func_decl(
360
397
  self._py_callable, self._qmodule, permutation=self.permutation
@@ -1,13 +1,16 @@
1
1
  from classiq.interface.exceptions import ClassiqExpansionError
2
2
  from classiq.interface.model.model import Model
3
+ from classiq.interface.model.quantum_function_declaration import (
4
+ NamedParamsQuantumFunctionDeclaration,
5
+ )
3
6
 
4
- from classiq.qmod.builtins.functions import CORE_LIB_DECLS
5
7
 
6
-
7
- def check_function_name_collisions(model: Model) -> None:
8
+ def check_function_name_collisions(
9
+ model: Model, builtin_functions: list[NamedParamsQuantumFunctionDeclaration]
10
+ ) -> None:
8
11
  redefined_functions = [
9
12
  function.name
10
- for function in CORE_LIB_DECLS
13
+ for function in builtin_functions
11
14
  if function.name in model.function_dict
12
15
  ]
13
16
  if len(redefined_functions) == 1:
@@ -1,4 +1,7 @@
1
1
  from classiq.interface.model.model import Model
2
+ from classiq.interface.model.quantum_function_declaration import (
3
+ NamedParamsQuantumFunctionDeclaration,
4
+ )
2
5
 
3
6
  from classiq.qmod.semantics.validation.constants_validation import (
4
7
  check_duplicate_constants,
@@ -14,7 +17,9 @@ from classiq.qmod.semantics.validation.types_validation import (
14
17
  )
15
18
 
16
19
 
17
- def validate_model(model: Model) -> None:
20
+ def validate_model(
21
+ model: Model, builtin_functions: list[NamedParamsQuantumFunctionDeclaration]
22
+ ) -> None:
18
23
  check_duplicate_types([*model.enums, *model.types, *model.qstructs])
19
24
  check_duplicate_constants(model.constants)
20
25
  for qstruct in model.qstructs:
@@ -22,4 +27,4 @@ def validate_model(model: Model) -> None:
22
27
  for cstruct in model.types:
23
28
  validate_cstruct(cstruct)
24
29
  validate_main_function(model.main_func)
25
- check_function_name_collisions(model)
30
+ check_function_name_collisions(model, builtin_functions)
@@ -1,6 +1,8 @@
1
1
  from typing import Union, get_args, get_origin
2
2
 
3
- from classiq.qmod.symbolic_expr import SymbolicExpr
3
+ from classiq.qmod.symbolic_expr import Symbolic
4
4
 
5
- SymbolicTypes = Union[SymbolicExpr, int, float, bool, tuple["SymbolicTypes", ...]]
5
+ SymbolicTypes = Union[
6
+ Symbolic, int, float, bool, tuple["SymbolicTypes", ...], list["SymbolicTypes"]
7
+ ]
6
8
  SYMBOLIC_TYPES = tuple(get_origin(t) or t for t in get_args(SymbolicTypes))
classiq/qmod/utilities.py CHANGED
@@ -11,6 +11,7 @@ from typing import (
11
11
  Any,
12
12
  ForwardRef,
13
13
  Literal,
14
+ TypeVar,
14
15
  Union,
15
16
  get_args,
16
17
  get_origin,
@@ -156,18 +157,20 @@ def varname(depth: int) -> str | None:
156
157
  return var_name
157
158
 
158
159
 
160
+ ReturnType = TypeVar("ReturnType")
159
161
  Params = ParamSpec("Params")
160
162
 
161
163
 
162
- def suppress_return_value(func: Callable[Params, None]) -> Callable[Params, None]:
164
+ def suppress_return_value(
165
+ func: Callable[Params, ReturnType],
166
+ ) -> Callable[Params, ReturnType]:
163
167
  # An empty decorator suppresses mypy's func-returns-value error when assigning the
164
168
  # return value of a None-returning function
165
169
  return func
166
170
 
167
171
 
168
- Statements = Union[
169
- None, list[Union[None, "QVar", "CParam"]], tuple[Union[None, "QVar", "CParam"], ...]
170
- ]
172
+ Statement = Union[None, Callable, "QVar", "CParam"]
173
+ Statements = Union[Statement, list[Statement], tuple[Statement, ...]]
171
174
 
172
175
 
173
176
  def _eval_qnum(val: int, size: int, is_signed: bool, fraction_digits: int) -> float:
@@ -0,0 +1,20 @@
1
+ from classiq.interface.generator.generation_request import (
2
+ SynthesisActionDetails,
3
+ )
4
+
5
+ from .actions import (
6
+ SynthesisActionFilters,
7
+ get_synthesis_actions,
8
+ get_synthesis_actions_async,
9
+ )
10
+
11
+ __all__ = [
12
+ "SynthesisActionDetails",
13
+ "SynthesisActionFilters",
14
+ "get_synthesis_actions",
15
+ "get_synthesis_actions_async",
16
+ ]
17
+
18
+
19
+ def __dir__() -> list[str]:
20
+ return __all__
@@ -0,0 +1,106 @@
1
+ from dataclasses import asdict, dataclass
2
+ from datetime import datetime
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from classiq.interface.jobs import JobStatus
6
+
7
+ from classiq._internals.api_wrapper import ApiWrapper
8
+ from classiq._internals.async_utils import syncify_function
9
+
10
+ if TYPE_CHECKING:
11
+ import pandas as pd
12
+
13
+
14
+ @dataclass
15
+ class SynthesisActionFilters:
16
+ """
17
+ Filter parameters for querying synthesis actions.
18
+
19
+ All filters are combined using AND logic: only actions matching all specified filters are returned.
20
+ Range filters (with _min/_max suffixes) are inclusive.
21
+ Datetime filters are compared against the job's timestamps.
22
+ """
23
+
24
+ status: JobStatus | None = None
25
+ target_backend: str | None = None
26
+ optimization_level: str | None = None
27
+ program_id: str | None = None
28
+ backend_name: str | None = None
29
+ optimization_parameter: str | None = None
30
+ random_seed: int | None = None
31
+ max_width: int | None = None
32
+ max_gate_count: int | None = None
33
+ total_cost_min: float | None = None
34
+ total_cost_max: float | None = None
35
+ start_time_min: datetime | None = None
36
+ start_time_max: datetime | None = None
37
+ end_time_min: datetime | None = None
38
+ end_time_max: datetime | None = None
39
+
40
+ def format_filters(self) -> dict[str, Any]:
41
+ """Convert filter fields to API kwargs, excluding None values and converting datetimes."""
42
+ filter_dict = asdict(self)
43
+ return {
44
+ k: (v.isoformat() if isinstance(v, datetime) else v)
45
+ for k, v in filter_dict.items()
46
+ if v is not None
47
+ }
48
+
49
+
50
+ async def get_synthesis_actions_async(
51
+ offset: int = 0,
52
+ limit: int = 50,
53
+ filters: SynthesisActionFilters | None = None,
54
+ ) -> "pd.DataFrame":
55
+ """Query synthesis actions with optional filters.
56
+ Args:
57
+ offset: Number of results to skip (default: 0)
58
+ limit: Maximum number of results to return (default: 50)
59
+ filters: Optional SynthesisActionFilters object containing filter parameters.
60
+
61
+ Returns:
62
+ A pandas DataFrame containing synthesis actions matching the filters.
63
+ Each row represents a synthesis action with columns for all fields
64
+ from SynthesisActionDetails (id, name, start_time, end_time, status, etc.).
65
+ """
66
+ import pandas as pd
67
+
68
+ api_kwargs = filters.format_filters() if filters is not None else {}
69
+
70
+ result = await ApiWrapper().call_query_synthesis_actions(
71
+ offset, limit, http_client=None, **api_kwargs
72
+ )
73
+
74
+ if not result.results:
75
+ return pd.DataFrame()
76
+
77
+ return pd.DataFrame(action.model_dump() for action in result.results)
78
+
79
+
80
+ def get_synthesis_actions(
81
+ offset: int = 0,
82
+ limit: int = 50,
83
+ filters: SynthesisActionFilters | None = None,
84
+ ) -> "pd.DataFrame":
85
+ """Query synthesis actions with optional filters.
86
+
87
+ Args:
88
+ offset: Number of results to skip (default: 0)
89
+ limit: Maximum number of results to return (default: 50)
90
+ filters: Optional SynthesisActionFilters object containing filter parameters.
91
+
92
+ Returns:
93
+ A pandas DataFrame containing synthesis actions matching the filters.
94
+ Each row represents a synthesis action with columns for all fields
95
+ from SynthesisActionDetails (id, name, start_time, end_time, status, etc.).
96
+
97
+ Examples:
98
+ # Query all actions:
99
+ df = get_synthesis_actions(limit=10)
100
+
101
+ # Query with filters:
102
+ filters = SynthesisActionFilters(status="COMPLETED", target_backend="ibm")
103
+ df = get_synthesis_actions(filters=filters, limit=10)
104
+ """
105
+
106
+ return syncify_function(get_synthesis_actions_async)(offset, limit, filters)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: classiq
3
- Version: 0.100.0
3
+ Version: 0.104.0
4
4
  Summary: Classiq's Python SDK for quantum computing
5
5
  Keywords: quantum computing,quantum circuits,quantum algorithms,QAD,QDL
6
6
  Author: Classiq Technologies