classiq 0.61.0__py3-none-any.whl → 0.63.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- classiq/__init__.py +3 -0
- classiq/_internals/api_wrapper.py +6 -26
- classiq/_internals/client.py +1 -9
- classiq/applications/chemistry/chemistry_model_constructor.py +1 -1
- classiq/applications/combinatorial_helpers/combinatorial_problem_utils.py +26 -8
- classiq/applications/combinatorial_helpers/optimization_model.py +13 -2
- classiq/applications/combinatorial_helpers/pyomo_utils.py +143 -13
- classiq/applications/combinatorial_optimization/combinatorial_optimization_model_constructor.py +1 -1
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +58 -23
- classiq/applications/grover/grover_model_constructor.py +1 -1
- classiq/applications/libraries/qmci_library.py +2 -1
- classiq/execution/execution_session.py +66 -96
- classiq/execution/jobs.py +12 -10
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/backend_preferences.py +26 -5
- classiq/interface/backend/pydantic_backend.py +1 -1
- classiq/interface/backend/quantum_backend_providers.py +3 -1
- classiq/interface/chemistry/operator.py +0 -204
- classiq/interface/execution/primitives.py +1 -0
- classiq/interface/generator/compiler_keywords.py +4 -0
- classiq/interface/generator/copy.py +47 -0
- classiq/interface/generator/function_param_list_without_self_reference.py +2 -0
- classiq/interface/generator/functions/type_name.py +6 -0
- classiq/interface/generator/generated_circuit_data.py +22 -7
- classiq/interface/generator/model/model.py +3 -0
- classiq/interface/generator/model/preferences/preferences.py +14 -1
- classiq/interface/generator/quantum_function_call.py +4 -2
- classiq/interface/generator/types/compilation_metadata.py +2 -1
- classiq/interface/model/handle_binding.py +50 -5
- classiq/interface/model/quantum_type.py +16 -0
- classiq/interface/server/routes.py +1 -3
- classiq/model_expansions/capturing/captured_vars.py +114 -28
- classiq/model_expansions/closure.py +25 -65
- classiq/model_expansions/function_builder.py +19 -9
- classiq/model_expansions/generative_functions.py +16 -2
- classiq/model_expansions/interpreter.py +110 -66
- classiq/model_expansions/model_tables.py +4 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +83 -20
- classiq/model_expansions/quantum_operations/classicalif.py +1 -1
- classiq/model_expansions/quantum_operations/control.py +3 -10
- classiq/model_expansions/quantum_operations/emitter.py +3 -4
- classiq/model_expansions/quantum_operations/quantum_assignment_operation.py +1 -2
- classiq/model_expansions/quantum_operations/quantum_function_call.py +1 -1
- classiq/model_expansions/quantum_operations/repeat.py +4 -3
- classiq/model_expansions/quantum_operations/shallow_emitter.py +9 -3
- classiq/model_expansions/scope.py +9 -13
- classiq/model_expansions/scope_initialization.py +34 -25
- classiq/model_expansions/transformers/var_splitter.py +57 -7
- classiq/open_library/__init__.py +4 -0
- classiq/open_library/functions/__init__.py +130 -0
- classiq/{qmod/builtins → open_library}/functions/amplitude_estimation.py +2 -2
- classiq/{qmod/builtins → open_library}/functions/discrete_sine_cosine_transform.py +6 -4
- classiq/{qmod/builtins → open_library}/functions/grover.py +2 -2
- classiq/{qmod/builtins → open_library}/functions/linear_pauli_rotation.py +1 -1
- classiq/{qmod/builtins → open_library}/functions/modular_exponentiation.py +2 -2
- classiq/{qmod/builtins → open_library}/functions/qpe.py +2 -2
- classiq/{qmod/builtins → open_library}/functions/state_preparation.py +6 -149
- classiq/{qmod/builtins → open_library}/functions/swap_test.py +1 -1
- classiq/open_library/functions/utility_functions.py +81 -0
- classiq/{qmod/builtins → open_library}/functions/variational.py +1 -1
- classiq/qmod/builtins/functions/__init__.py +4 -130
- classiq/qmod/builtins/functions/allocation.py +150 -0
- classiq/qmod/builtins/functions/arithmetic.py +0 -34
- classiq/qmod/builtins/functions/operators.py +0 -6
- classiq/qmod/builtins/operations.py +19 -80
- classiq/qmod/create_model_function.py +8 -162
- classiq/qmod/generative.py +0 -16
- classiq/qmod/model_state_container.py +7 -0
- classiq/qmod/native/pretty_printer.py +10 -11
- classiq/qmod/pretty_print/pretty_printer.py +1 -1
- classiq/qmod/python_classical_type.py +1 -5
- classiq/qmod/qfunc.py +11 -12
- classiq/qmod/qmod_variable.py +1 -3
- classiq/qmod/quantum_expandable.py +23 -1
- classiq/qmod/quantum_function.py +69 -7
- {classiq-0.61.0.dist-info → classiq-0.63.0.dist-info}/METADATA +2 -1
- {classiq-0.61.0.dist-info → classiq-0.63.0.dist-info}/RECORD +82 -78
- classiq/qmod/builtins/functions/utility_functions.py +0 -43
- /classiq/{qmod/builtins → open_library}/functions/hea.py +0 -0
- /classiq/{qmod/builtins → open_library}/functions/qaoa_penalty.py +0 -0
- /classiq/{qmod/builtins → open_library}/functions/qft_functions.py +0 -0
- /classiq/{qmod/builtins → open_library}/functions/qsvt.py +0 -0
- {classiq-0.61.0.dist-info → classiq-0.63.0.dist-info}/WHEEL +0 -0
@@ -412,7 +412,7 @@ class PythonPrettyPrinter(Visitor):
|
|
412
412
|
def visit_PhaseOperation(self, op: PhaseOperation) -> str:
|
413
413
|
self._imports["phase"] = 1
|
414
414
|
theta = f", {self.visit(op.theta)}" if op.theta is not None else ""
|
415
|
-
return f"{self._indent}phase({self.visit(op.expression)}
|
415
|
+
return f"{self._indent}phase({self.visit(op.expression)}{theta})\n"
|
416
416
|
|
417
417
|
def visit_ClassicalIf(self, op: ClassicalIf) -> str:
|
418
418
|
self._imports["if_"] = 1
|
@@ -1,6 +1,5 @@
|
|
1
1
|
import dataclasses
|
2
2
|
import inspect
|
3
|
-
import sys
|
4
3
|
from enum import EnumMeta
|
5
4
|
from typing import (
|
6
5
|
Optional,
|
@@ -16,16 +15,13 @@ from classiq.interface.generator.functions.classical_type import (
|
|
16
15
|
Integer,
|
17
16
|
Real,
|
18
17
|
)
|
18
|
+
from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
|
19
19
|
from classiq.interface.generator.functions.type_name import Enum, Struct
|
20
20
|
|
21
21
|
from classiq.qmod.cparam import CArray, CBool, CInt, CReal
|
22
22
|
from classiq.qmod.qmod_variable import get_type_hint_expr
|
23
23
|
from classiq.qmod.utilities import version_portable_get_args
|
24
24
|
|
25
|
-
if sys.version_info[0:2] >= (3, 9):
|
26
|
-
pass
|
27
|
-
from classiq.interface.generator.functions.concrete_types import ConcreteClassicalType
|
28
|
-
|
29
25
|
CARRAY_ERROR_MESSAGE = (
|
30
26
|
"CArray accepts one or two generic parameters in the form "
|
31
27
|
"`CArray[<element-type>]` or `CArray[<element-type>, <size>]`"
|
classiq/qmod/qfunc.py
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
from collections.abc import Iterator
|
2
|
+
from contextlib import contextmanager
|
1
3
|
from typing import Callable, Literal, Optional, Union, overload
|
2
4
|
|
3
5
|
from classiq.interface.exceptions import ClassiqInternalError
|
@@ -10,17 +12,16 @@ from classiq.qmod.quantum_function import (
|
|
10
12
|
QFunc,
|
11
13
|
)
|
12
14
|
|
13
|
-
|
14
|
-
DEC_QFUNCS: list[QFunc] = []
|
15
|
+
_GENERATIVE_SWITCH = False
|
15
16
|
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
@contextmanager
|
19
|
+
def set_global_generative_switch() -> Iterator[None]:
|
20
|
+
global _GENERATIVE_SWITCH
|
21
|
+
previous = _GENERATIVE_SWITCH
|
22
|
+
_GENERATIVE_SWITCH = True
|
23
|
+
yield
|
24
|
+
_GENERATIVE_SWITCH = previous
|
24
25
|
|
25
26
|
|
26
27
|
@overload
|
@@ -56,9 +57,8 @@ def qfunc(
|
|
56
57
|
) -> Union[Callable[[Callable], QCallable], QCallable]:
|
57
58
|
def wrapper(func: Callable) -> QCallable:
|
58
59
|
qfunc: BaseQFunc
|
59
|
-
if generative:
|
60
|
+
if generative or _GENERATIVE_SWITCH:
|
60
61
|
qfunc = GenerativeQFunc(func)
|
61
|
-
GEN_QFUNCS.append(qfunc)
|
62
62
|
elif external:
|
63
63
|
if synthesize_separately:
|
64
64
|
raise ClassiqInternalError(
|
@@ -67,7 +67,6 @@ def qfunc(
|
|
67
67
|
return ExternalQFunc(func)
|
68
68
|
else:
|
69
69
|
qfunc = QFunc(func)
|
70
|
-
DEC_QFUNCS.append(qfunc)
|
71
70
|
if synthesize_separately:
|
72
71
|
qfunc.update_compilation_metadata(should_synthesize_separately=True)
|
73
72
|
return qfunc
|
classiq/qmod/qmod_variable.py
CHANGED
@@ -285,7 +285,7 @@ class QNum(Generic[_P], QScalar):
|
|
285
285
|
def __init__(
|
286
286
|
self,
|
287
287
|
name: Union[str, HandleBinding],
|
288
|
-
size: Union[int, CInt, Expression, None] = None,
|
288
|
+
size: Union[int, CInt, Expression, SymbolicExpr, None] = None,
|
289
289
|
is_signed: Union[bool, Expression, SymbolicExpr, None] = None,
|
290
290
|
fraction_digits: Union[int, CInt, Expression, None] = None,
|
291
291
|
_expr_str: Optional[str] = None,
|
@@ -485,8 +485,6 @@ class QArray(ArrayBase[_P], QVar):
|
|
485
485
|
if is_generative_mode():
|
486
486
|
with generative_mode_context(False):
|
487
487
|
return interpret_expression(str(self.len))
|
488
|
-
if self._length is not None:
|
489
|
-
return CParamScalar(f"{self._length}")
|
490
488
|
return CParamScalar(f"get_field({self}, 'len')")
|
491
489
|
|
492
490
|
@classmethod
|
@@ -101,6 +101,10 @@ class QExpandable(QCallable, QExpandableInterface, ABC):
|
|
101
101
|
QExpandable.STACK[-1] if QExpandable.STACK else None
|
102
102
|
)
|
103
103
|
|
104
|
+
def __call__(self, *args: Any, **kwargs: Any) -> None:
|
105
|
+
super().__call__(*args, **kwargs)
|
106
|
+
self.add_function_dependencies()
|
107
|
+
|
104
108
|
def expand(self) -> None:
|
105
109
|
if self not in QExpandable.STACK:
|
106
110
|
with self, generative_mode_context(False):
|
@@ -161,6 +165,17 @@ class QExpandable(QCallable, QExpandableInterface, ABC):
|
|
161
165
|
func_decl, None, source_ref_, *args, **kwargs
|
162
166
|
)
|
163
167
|
|
168
|
+
def add_function_dependencies(self) -> None:
|
169
|
+
called_name = self.func_decl.name
|
170
|
+
if called_name is None:
|
171
|
+
return
|
172
|
+
for expandable in QExpandable.STACK:
|
173
|
+
caller_name = expandable.func_decl.name
|
174
|
+
if caller_name is not None:
|
175
|
+
caller_deps = self._qmodule.function_dependencies[caller_name]
|
176
|
+
if called_name not in caller_deps:
|
177
|
+
caller_deps.append(called_name)
|
178
|
+
|
164
179
|
|
165
180
|
class QLambdaFunction(QExpandable):
|
166
181
|
def __init__(
|
@@ -298,6 +313,12 @@ def prepare_arg(
|
|
298
313
|
def prepare_arg(
|
299
314
|
arg_decl: AnonPositionalArg, val: Any, func_name: Optional[str], param_name: str
|
300
315
|
) -> ArgValue:
|
316
|
+
from classiq.qmod.quantum_function import BaseQFunc, GenerativeQFunc
|
317
|
+
|
318
|
+
if isinstance(val, BaseQFunc):
|
319
|
+
val.add_function_dependencies()
|
320
|
+
if isinstance(val, GenerativeQFunc):
|
321
|
+
QMODULE.generative_functions[val.func_decl.name] = val
|
301
322
|
if isinstance(val, QConstant):
|
302
323
|
val.add_to_model()
|
303
324
|
return Expression(expr=str(val.name))
|
@@ -336,7 +357,8 @@ def prepare_arg(
|
|
336
357
|
pos_rename_params=val.infer_rename_params(),
|
337
358
|
body=val.body,
|
338
359
|
)
|
339
|
-
|
360
|
+
if is_generative_mode():
|
361
|
+
qlambda.set_py_callable(val._py_callable)
|
340
362
|
return qlambda
|
341
363
|
|
342
364
|
if isinstance(val, QExpandable):
|
classiq/qmod/quantum_function.py
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
import ast
|
2
2
|
import functools
|
3
|
+
from abc import abstractmethod
|
4
|
+
from collections import defaultdict
|
3
5
|
from dataclasses import is_dataclass
|
4
6
|
from enum import EnumMeta
|
5
7
|
from inspect import isclass
|
@@ -23,6 +25,7 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
23
25
|
|
24
26
|
from classiq.qmod.classical_function import CFunc
|
25
27
|
from classiq.qmod.declaration_inferrer import infer_func_decl
|
28
|
+
from classiq.qmod.generative import set_frontend_interpreter
|
26
29
|
from classiq.qmod.qmod_constant import QConstant
|
27
30
|
from classiq.qmod.qmod_parameter import CArray, CParam
|
28
31
|
from classiq.qmod.qmod_variable import QVar
|
@@ -62,9 +65,19 @@ class BaseQFunc(QExpandable):
|
|
62
65
|
return CompilationMetadata()
|
63
66
|
return self.compilation_metadata
|
64
67
|
|
68
|
+
@abstractmethod
|
69
|
+
def create_model(
|
70
|
+
self,
|
71
|
+
constraints: Optional[Constraints] = None,
|
72
|
+
execution_preferences: Optional[ExecutionPreferences] = None,
|
73
|
+
preferences: Optional[Preferences] = None,
|
74
|
+
classical_execution_function: Optional[CFunc] = None,
|
75
|
+
) -> Model:
|
76
|
+
pass
|
77
|
+
|
65
78
|
|
66
79
|
class QFunc(BaseQFunc):
|
67
|
-
FRAME_DEPTH =
|
80
|
+
FRAME_DEPTH = 3
|
68
81
|
|
69
82
|
def __init__(
|
70
83
|
self,
|
@@ -90,14 +103,14 @@ class QFunc(BaseQFunc):
|
|
90
103
|
|
91
104
|
@property
|
92
105
|
def func_decl(self) -> NamedParamsQuantumFunctionDeclaration:
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
)
|
106
|
+
name = self._py_callable.__name__
|
107
|
+
if hasattr(self._qmodule, "native_defs") and name in self._qmodule.native_defs:
|
108
|
+
return self._qmodule.native_defs[name]
|
109
|
+
return infer_func_decl(self._py_callable, qmodule=self._qmodule)
|
97
110
|
|
98
111
|
def __call__(self, *args: Any, **kwargs: Any) -> None:
|
99
|
-
super().__call__(*args, **kwargs)
|
100
112
|
self.expand()
|
113
|
+
super().__call__(*args, **kwargs)
|
101
114
|
|
102
115
|
def create_model(
|
103
116
|
self,
|
@@ -112,6 +125,8 @@ class QFunc(BaseQFunc):
|
|
112
125
|
self._qmodule.native_defs = dict()
|
113
126
|
self._qmodule.constants = dict()
|
114
127
|
self._qmodule.functions_compilation_metadata = dict()
|
128
|
+
self._qmodule.generative_functions = dict()
|
129
|
+
self._qmodule.function_dependencies = defaultdict(list)
|
115
130
|
QConstant.set_current_model(self._qmodule)
|
116
131
|
self.expand()
|
117
132
|
model_extra_settings: list[tuple[str, Any]] = [
|
@@ -124,7 +139,7 @@ class QFunc(BaseQFunc):
|
|
124
139
|
model_extra_settings.append(
|
125
140
|
("classical_execution_code", classical_execution_function.code)
|
126
141
|
)
|
127
|
-
|
142
|
+
model = Model(
|
128
143
|
constants=list(self._qmodule.constants.values()),
|
129
144
|
functions=list(self._qmodule.native_defs.values()),
|
130
145
|
enums=list(self._qmodule.enum_decls.values()),
|
@@ -133,6 +148,30 @@ class QFunc(BaseQFunc):
|
|
133
148
|
functions_compilation_metadata=self._qmodule.functions_compilation_metadata,
|
134
149
|
**{key: value for key, value in model_extra_settings if value},
|
135
150
|
)
|
151
|
+
if len(self._qmodule.generative_functions) > 0:
|
152
|
+
return self._create_generative_model(model)
|
153
|
+
return model
|
154
|
+
|
155
|
+
def _create_generative_model(self, model_stub: Model) -> Model:
|
156
|
+
from classiq.model_expansions.interpreter import Interpreter
|
157
|
+
from classiq.qmod.semantics.static_semantics_visitor import (
|
158
|
+
resolve_function_calls,
|
159
|
+
)
|
160
|
+
|
161
|
+
generative_functions = list(self._qmodule.generative_functions.values())
|
162
|
+
resolve_function_calls(
|
163
|
+
model_stub,
|
164
|
+
dict(model_stub.function_dict)
|
165
|
+
| {
|
166
|
+
gen_func.func_decl.name: gen_func.func_decl
|
167
|
+
for gen_func in generative_functions
|
168
|
+
},
|
169
|
+
)
|
170
|
+
interpreter = Interpreter(
|
171
|
+
model_stub, generative_functions, is_normalizer=True, is_shallow=True
|
172
|
+
)
|
173
|
+
set_frontend_interpreter(interpreter)
|
174
|
+
return interpreter.expand()
|
136
175
|
|
137
176
|
def expand(self) -> None:
|
138
177
|
if self.func_decl.name in self._qmodule.native_defs:
|
@@ -220,6 +259,29 @@ class GenerativeQFunc(BaseQFunc):
|
|
220
259
|
self._func_decl = infer_func_decl(self._py_callable, self._qmodule)
|
221
260
|
return self._func_decl
|
222
261
|
|
262
|
+
def __call__(self, *args: Any, **kwargs: Any) -> None:
|
263
|
+
self._qmodule.generative_functions[self.func_decl.name] = self
|
264
|
+
super().__call__(*args, **kwargs)
|
265
|
+
|
266
|
+
def create_model(
|
267
|
+
self,
|
268
|
+
constraints: Optional[Constraints] = None,
|
269
|
+
execution_preferences: Optional[ExecutionPreferences] = None,
|
270
|
+
preferences: Optional[Preferences] = None,
|
271
|
+
classical_execution_function: Optional[CFunc] = None,
|
272
|
+
) -> Model:
|
273
|
+
def _dec_main(*args: Any, **kwargs: Any) -> None:
|
274
|
+
self(*args, **kwargs)
|
275
|
+
|
276
|
+
_dec_main.__annotations__ = self._py_callable.__annotations__
|
277
|
+
|
278
|
+
return QFunc(_dec_main).create_model(
|
279
|
+
constraints=constraints,
|
280
|
+
execution_preferences=execution_preferences,
|
281
|
+
preferences=preferences,
|
282
|
+
classical_execution_function=classical_execution_function,
|
283
|
+
)
|
284
|
+
|
223
285
|
|
224
286
|
ILLEGAL_PARAM_ERROR = "Unsupported type hint '{annotation}' for argument '{name}'."
|
225
287
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: classiq
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.63.0
|
4
4
|
Summary: Classiq's Python SDK for quantum computing
|
5
5
|
Home-page: https://classiq.io
|
6
6
|
License: Proprietary
|
@@ -53,6 +53,7 @@ Requires-Dist: sympy (>=1.13.0,<2.0.0)
|
|
53
53
|
Requires-Dist: tabulate (>=0.8.9,<1)
|
54
54
|
Requires-Dist: torch (>=2.0,<3.0) ; extra == "qml"
|
55
55
|
Requires-Dist: torchvision (>=0.15,<1.0) ; extra == "qml"
|
56
|
+
Requires-Dist: tqdm (>=4.67.1,<5.0.0)
|
56
57
|
Project-URL: Documentation, https://docs.classiq.io/
|
57
58
|
Description-Content-Type: text/markdown
|
58
59
|
|