classiq 0.67.0__py3-none-any.whl → 0.69.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/_internals/api_wrapper.py +9 -9
- classiq/_internals/async_utils.py +1 -1
- classiq/_internals/authentication/password_manager.py +1 -1
- classiq/_internals/client.py +1 -1
- classiq/applications/combinatorial_optimization/combinatorial_problem.py +8 -11
- classiq/applications/qnn/gradients/quantum_gradient.py +1 -1
- classiq/applications/qnn/gradients/simple_quantum_gradient.py +1 -1
- classiq/applications/qnn/torch_utils.py +1 -1
- classiq/execution/execution_session.py +7 -3
- classiq/execution/jobs.py +2 -5
- classiq/executor.py +7 -2
- classiq/interface/_version.py +1 -1
- classiq/interface/ast_node.py +1 -1
- classiq/interface/backend/quantum_backend_providers.py +2 -3
- classiq/interface/chemistry/operator.py +12 -8
- classiq/interface/debug_info/back_ref_util.py +22 -0
- classiq/interface/debug_info/debug_info.py +26 -21
- classiq/interface/executor/optimizer_preferences.py +1 -0
- classiq/interface/generator/arith/arithmetic.py +96 -1
- classiq/interface/generator/arith/arithmetic_expression_parser.py +1 -1
- classiq/interface/generator/arith/arithmetic_param_getters.py +3 -3
- classiq/interface/generator/functions/classical_type.py +12 -1
- classiq/interface/generator/generated_circuit_data.py +64 -23
- classiq/interface/generator/quantum_program.py +18 -1
- classiq/interface/generator/types/builtin_enum_declarations.py +1 -0
- classiq/interface/generator/types/enum_declaration.py +45 -3
- classiq/interface/ide/visual_model.py +0 -2
- classiq/interface/model/classical_if.py +2 -2
- classiq/interface/model/control.py +2 -2
- classiq/interface/model/invert.py +2 -2
- classiq/interface/model/power.py +2 -2
- classiq/interface/model/quantum_function_call.py +4 -0
- classiq/interface/model/quantum_statement.py +1 -1
- classiq/interface/model/repeat.py +2 -2
- classiq/interface/model/statement_block.py +1 -1
- classiq/interface/model/within_apply_operation.py +2 -2
- classiq/interface/server/routes.py +0 -6
- classiq/model_expansions/generative_functions.py +4 -3
- classiq/model_expansions/interpreters/generative_interpreter.py +78 -18
- classiq/model_expansions/quantum_operations/allocate.py +3 -1
- classiq/model_expansions/quantum_operations/assignment_result_processor.py +52 -0
- classiq/model_expansions/quantum_operations/bind.py +2 -1
- classiq/model_expansions/quantum_operations/block_evaluator.py +76 -0
- classiq/model_expansions/quantum_operations/call_emitter.py +0 -13
- classiq/model_expansions/quantum_operations/classicalif.py +5 -4
- classiq/model_expansions/quantum_operations/composite_emitter.py +27 -0
- classiq/model_expansions/quantum_operations/emitter.py +16 -2
- classiq/model_expansions/quantum_operations/expression_evaluator.py +33 -0
- classiq/model_expansions/quantum_operations/handle_evaluator.py +28 -0
- classiq/model_expansions/quantum_operations/quantum_function_call.py +3 -2
- classiq/model_expansions/quantum_operations/repeat.py +2 -1
- classiq/model_expansions/quantum_operations/variable_decleration.py +2 -1
- classiq/model_expansions/scope_initialization.py +5 -19
- classiq/model_expansions/sympy_conversion/expression_to_sympy.py +1 -1
- classiq/open_library/functions/__init__.py +1 -2
- classiq/open_library/functions/amplitude_amplification.py +11 -12
- classiq/open_library/functions/discrete_sine_cosine_transform.py +17 -14
- classiq/open_library/functions/grover.py +7 -11
- classiq/open_library/functions/hea.py +3 -3
- classiq/open_library/functions/modular_exponentiation.py +17 -33
- classiq/open_library/functions/qft_functions.py +2 -2
- classiq/open_library/functions/qsvt.py +8 -8
- classiq/open_library/functions/state_preparation.py +16 -17
- classiq/open_library/functions/swap_test.py +1 -1
- classiq/open_library/functions/utility_functions.py +12 -4
- classiq/qmod/builtins/classical_functions.py +24 -7
- classiq/qmod/builtins/enums.py +1 -0
- classiq/qmod/builtins/functions/__init__.py +2 -0
- classiq/qmod/builtins/functions/chemistry.py +6 -38
- classiq/qmod/builtins/functions/exponentiation.py +24 -0
- classiq/qmod/builtins/operations.py +26 -11
- classiq/qmod/cparam.py +32 -5
- classiq/qmod/python_classical_type.py +10 -4
- classiq/qmod/quantum_callable.py +2 -1
- classiq/qmod/quantum_expandable.py +30 -6
- classiq/qmod/quantum_function.py +3 -2
- classiq/qmod/semantics/error_manager.py +1 -1
- classiq/qmod/semantics/validation/types_validation.py +1 -1
- classiq/qmod/symbolic.py +2 -1
- classiq/qmod/utilities.py +31 -2
- classiq/qmod/write_qmod.py +10 -7
- classiq/synthesis.py +25 -9
- {classiq-0.67.0.dist-info → classiq-0.69.0.dist-info}/METADATA +1 -1
- {classiq-0.67.0.dist-info → classiq-0.69.0.dist-info}/RECORD +85 -81
- classiq/interface/execution/jobs.py +0 -31
- classiq/model_expansions/quantum_operations/shallow_emitter.py +0 -166
- {classiq-0.67.0.dist-info → classiq-0.69.0.dist-info}/WHEEL +0 -0
classiq/qmod/cparam.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import sys
|
2
|
+
from abc import ABC, abstractmethod
|
2
3
|
from typing import ( # type: ignore[attr-defined]
|
3
4
|
TYPE_CHECKING,
|
4
5
|
Any,
|
@@ -9,6 +10,8 @@ from typing import ( # type: ignore[attr-defined]
|
|
9
10
|
|
10
11
|
from typing_extensions import ParamSpec
|
11
12
|
|
13
|
+
from classiq.interface.exceptions import ClassiqValueError
|
14
|
+
|
12
15
|
from classiq.qmod.symbolic_expr import Symbolic, SymbolicExpr
|
13
16
|
|
14
17
|
if TYPE_CHECKING:
|
@@ -21,18 +24,34 @@ else:
|
|
21
24
|
|
22
25
|
class CParam(SymbolicSuperclass):
|
23
26
|
def __init__(self, expr: str) -> None:
|
24
|
-
super().__init__(expr, False)
|
27
|
+
super().__init__(expr, is_quantum=False)
|
28
|
+
|
29
|
+
|
30
|
+
class CParamAbstract(ABC, CParam):
|
31
|
+
|
32
|
+
def __new__(cls, *args: Any, **kwargs: Any) -> "CParamAbstract":
|
33
|
+
raise ClassiqValueError(
|
34
|
+
f"{cls.__name__} is a Qmod type hint for a classical parameter and it cannot be instantiated. "
|
35
|
+
f"Use regular Pythonic values as arguments instead. "
|
36
|
+
f"Example:\n\n"
|
37
|
+
f"def foo(val: {cls.__name__}) -> None: ...\n\n"
|
38
|
+
f"foo({_EXAMPLE_VALUES[cls.__name__]}) # Correct\n"
|
39
|
+
)
|
25
40
|
|
41
|
+
@abstractmethod
|
42
|
+
def __init__(self) -> None:
|
43
|
+
pass
|
26
44
|
|
27
|
-
|
45
|
+
|
46
|
+
class CInt(CParamAbstract):
|
28
47
|
pass
|
29
48
|
|
30
49
|
|
31
|
-
class CReal(
|
50
|
+
class CReal(CParamAbstract):
|
32
51
|
pass
|
33
52
|
|
34
53
|
|
35
|
-
class CBool(
|
54
|
+
class CBool(CParamAbstract):
|
36
55
|
pass
|
37
56
|
|
38
57
|
|
@@ -47,7 +66,7 @@ class ArrayBase(Generic[_P]):
|
|
47
66
|
return _GenericAlias(cls, args)
|
48
67
|
|
49
68
|
|
50
|
-
class CArray(
|
69
|
+
class CArray(CParamAbstract, ArrayBase[_P]):
|
51
70
|
if TYPE_CHECKING:
|
52
71
|
|
53
72
|
@property
|
@@ -62,3 +81,11 @@ Array = CArray
|
|
62
81
|
class CParamScalar(CParam, SymbolicExpr):
|
63
82
|
def __hash__(self) -> int:
|
64
83
|
return hash(str(self))
|
84
|
+
|
85
|
+
|
86
|
+
_EXAMPLE_VALUES: dict[str, Any] = {
|
87
|
+
CInt.__name__: 1,
|
88
|
+
CReal.__name__: 1.0,
|
89
|
+
CBool.__name__: True,
|
90
|
+
CArray.__name__: [1, 2],
|
91
|
+
}
|
@@ -30,16 +30,22 @@ CARRAY_ERROR_MESSAGE = (
|
|
30
30
|
|
31
31
|
class PythonClassicalType:
|
32
32
|
def convert(self, py_type: type) -> Optional[ConcreteClassicalType]:
|
33
|
-
if py_type is int
|
33
|
+
if py_type is int:
|
34
|
+
return Integer().set_generative()
|
35
|
+
elif py_type is CInt:
|
34
36
|
return Integer()
|
35
|
-
elif py_type in (float, complex)
|
37
|
+
elif py_type in (float, complex):
|
38
|
+
return Real().set_generative()
|
39
|
+
elif py_type is CReal:
|
36
40
|
return Real()
|
37
|
-
elif py_type is bool
|
41
|
+
elif py_type is bool:
|
42
|
+
return Bool().set_generative()
|
43
|
+
elif py_type is CBool:
|
38
44
|
return Bool()
|
39
45
|
elif get_origin(py_type) is list:
|
40
46
|
element_type = self.convert(get_args(py_type)[0])
|
41
47
|
if element_type is not None:
|
42
|
-
return ClassicalList(element_type=element_type)
|
48
|
+
return ClassicalList(element_type=element_type).set_generative()
|
43
49
|
elif get_origin(py_type) is CArray:
|
44
50
|
array_args = version_portable_get_args(py_type)
|
45
51
|
if len(array_args) == 1:
|
classiq/qmod/quantum_callable.py
CHANGED
@@ -21,7 +21,7 @@ from classiq.interface.model.quantum_type import QuantumType
|
|
21
21
|
from classiq.interface.source_reference import SourceReference
|
22
22
|
|
23
23
|
from classiq.qmod.cparam import CInt
|
24
|
-
from classiq.qmod.utilities import get_source_ref
|
24
|
+
from classiq.qmod.utilities import get_source_ref, suppress_return_value
|
25
25
|
|
26
26
|
if TYPE_CHECKING:
|
27
27
|
from classiq.qmod.quantum_expandable import QTerminalCallable
|
@@ -48,6 +48,7 @@ class QCallable(Generic[P], ABC):
|
|
48
48
|
CURRENT_EXPANDABLE: ClassVar[Optional[QExpandableInterface]] = None
|
49
49
|
FRAME_DEPTH = 1
|
50
50
|
|
51
|
+
@suppress_return_value
|
51
52
|
def __call__(self, *args: Any, **kwargs: Any) -> None:
|
52
53
|
assert QCallable.CURRENT_EXPANDABLE is not None
|
53
54
|
source_ref = get_source_ref(sys._getframe(self.FRAME_DEPTH))
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import inspect
|
2
2
|
from abc import ABC
|
3
|
+
from collections.abc import Generator, Iterable
|
3
4
|
from dataclasses import is_dataclass
|
4
5
|
from enum import Enum as PythonEnum
|
5
6
|
from types import TracebackType
|
@@ -67,7 +68,10 @@ from classiq.qmod.qmod_variable import (
|
|
67
68
|
from classiq.qmod.quantum_callable import QCallable, QExpandableInterface
|
68
69
|
from classiq.qmod.symbolic_expr import SymbolicExpr
|
69
70
|
from classiq.qmod.type_attribute_remover import decl_without_type_attributes
|
70
|
-
from classiq.qmod.utilities import
|
71
|
+
from classiq.qmod.utilities import (
|
72
|
+
mangle_keyword,
|
73
|
+
qmod_val_to_expr_str,
|
74
|
+
)
|
71
75
|
|
72
76
|
ArgType = Union[CParam, QVar, QCallable]
|
73
77
|
|
@@ -371,11 +375,14 @@ def prepare_arg(
|
|
371
375
|
def _validate_classical_arg(
|
372
376
|
arg: Any, arg_decl: AnonClassicalParameterDeclaration, func_name: Optional[str]
|
373
377
|
) -> None:
|
374
|
-
is_native_or_compatible_type =
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
378
|
+
is_native_or_compatible_type = (
|
379
|
+
not isinstance(
|
380
|
+
arg,
|
381
|
+
(*NativePythonClassicalTypes, CParam, SymbolicExpr, Basic, PythonEnum),
|
382
|
+
)
|
383
|
+
and not _is_legal_iterable(arg)
|
384
|
+
and not is_dataclass(arg) # type: ignore[unreachable]
|
385
|
+
)
|
379
386
|
try:
|
380
387
|
is_pydantic_classical_type = isinstance(
|
381
388
|
arg, pydantic.BaseModel
|
@@ -481,3 +488,20 @@ def _create_quantum_function_call(
|
|
481
488
|
return QuantumFunctionCall(
|
482
489
|
function=function_ident, positional_args=prepared_args, source_ref=source_ref_
|
483
490
|
)
|
491
|
+
|
492
|
+
|
493
|
+
_FORBIDDEN_ITERABLES = (set, dict, str, Generator)
|
494
|
+
|
495
|
+
|
496
|
+
def _is_legal_iterable(arg: Any) -> bool:
|
497
|
+
if not isinstance(arg, Iterable) or isinstance(arg, _FORBIDDEN_ITERABLES):
|
498
|
+
return False
|
499
|
+
return all(_is_legal_iterable_element(e) for e in arg)
|
500
|
+
|
501
|
+
|
502
|
+
def _is_legal_iterable_element(arg: Any) -> bool:
|
503
|
+
if isinstance(arg, _FORBIDDEN_ITERABLES):
|
504
|
+
return False
|
505
|
+
if isinstance(arg, Iterable):
|
506
|
+
return all(_is_legal_iterable_element(e) for e in arg)
|
507
|
+
return True
|
classiq/qmod/quantum_function.py
CHANGED
@@ -24,10 +24,11 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
24
24
|
)
|
25
25
|
|
26
26
|
from classiq.qmod.classical_function import CFunc
|
27
|
+
from classiq.qmod.cparam import CParamAbstract
|
27
28
|
from classiq.qmod.declaration_inferrer import infer_func_decl
|
28
29
|
from classiq.qmod.generative import set_frontend_interpreter
|
29
30
|
from classiq.qmod.qmod_constant import QConstant
|
30
|
-
from classiq.qmod.qmod_parameter import CArray
|
31
|
+
from classiq.qmod.qmod_parameter import CArray
|
31
32
|
from classiq.qmod.qmod_variable import QVar
|
32
33
|
from classiq.qmod.quantum_callable import QCallable, QCallableList
|
33
34
|
from classiq.qmod.quantum_expandable import QExpandable, QTerminalCallable
|
@@ -308,7 +309,7 @@ def _validate_no_gen_params(annotations: dict[str, Any]) -> None:
|
|
308
309
|
for name, annotation in annotations.items()
|
309
310
|
if not (
|
310
311
|
name == "return"
|
311
|
-
or (isclass(annotation) and issubclass(annotation,
|
312
|
+
or (isclass(annotation) and issubclass(annotation, CParamAbstract))
|
312
313
|
or (isclass(annotation) and is_dataclass(annotation))
|
313
314
|
or (isclass(annotation) and isinstance(annotation, EnumMeta))
|
314
315
|
or get_origin(annotation) is CArray
|
@@ -16,7 +16,7 @@ TYPE_EXISTS_ERROR_MESSAGE = "Type {!r} already exists"
|
|
16
16
|
|
17
17
|
|
18
18
|
def check_duplicate_types(
|
19
|
-
types: Sequence[Union[EnumDeclaration, StructDeclaration, QStructDeclaration]]
|
19
|
+
types: Sequence[Union[EnumDeclaration, StructDeclaration, QStructDeclaration]],
|
20
20
|
) -> None:
|
21
21
|
known_types = {type_.name for type_ in BUILTIN_ENUM_DECLARATIONS.values()}
|
22
22
|
known_types |= {type_.name for type_ in BUILTIN_STRUCT_DECLARATIONS.values()}
|
classiq/qmod/symbolic.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import sys
|
2
|
+
from collections.abc import Sequence
|
2
3
|
from typing import (
|
3
4
|
TYPE_CHECKING,
|
4
5
|
Any,
|
@@ -296,7 +297,7 @@ def sum(arr: SymbolicTypes) -> CParamScalar:
|
|
296
297
|
|
297
298
|
|
298
299
|
def subscript(
|
299
|
-
amplitudes: Union[
|
300
|
+
amplitudes: Union[Sequence[Union[float, CReal, CParamScalar]], CArray[CReal]],
|
300
301
|
index: QNum,
|
301
302
|
) -> CParamScalar:
|
302
303
|
return CParamScalar(expr=f"{amplitudes}[{index}]")
|
classiq/qmod/utilities.py
CHANGED
@@ -3,15 +3,32 @@ import inspect
|
|
3
3
|
import itertools
|
4
4
|
import keyword
|
5
5
|
import sys
|
6
|
+
from collections.abc import Iterable
|
6
7
|
from enum import Enum as PythonEnum
|
7
8
|
from types import FrameType
|
8
|
-
from typing import
|
9
|
+
from typing import (
|
10
|
+
TYPE_CHECKING,
|
11
|
+
Any,
|
12
|
+
Callable,
|
13
|
+
ForwardRef,
|
14
|
+
Literal,
|
15
|
+
Optional,
|
16
|
+
Union,
|
17
|
+
get_args,
|
18
|
+
get_origin,
|
19
|
+
overload,
|
20
|
+
)
|
21
|
+
|
22
|
+
from typing_extensions import ParamSpec
|
9
23
|
|
10
24
|
from classiq.interface.generator.expressions.qmod_struct_instance import (
|
11
25
|
QmodStructInstance,
|
12
26
|
)
|
13
27
|
from classiq.interface.source_reference import SourceReference
|
14
28
|
|
29
|
+
if TYPE_CHECKING:
|
30
|
+
from classiq.qmod.qmod_variable import QVar
|
31
|
+
|
15
32
|
DEFAULT_DECIMAL_PRECISION = 4
|
16
33
|
|
17
34
|
|
@@ -101,7 +118,7 @@ def qmod_val_to_expr_str(val: Any) -> str:
|
|
101
118
|
)
|
102
119
|
return f"struct_literal({val.struct_declaration.name}, {kwargs_str})"
|
103
120
|
|
104
|
-
if isinstance(val,
|
121
|
+
if isinstance(val, Iterable):
|
105
122
|
elements_str = ", ".join([qmod_val_to_expr_str(elem) for elem in val])
|
106
123
|
return f"[{elements_str}]"
|
107
124
|
|
@@ -131,3 +148,15 @@ def varname(depth: int) -> Optional[str]:
|
|
131
148
|
if not var_name.isidentifier():
|
132
149
|
return None
|
133
150
|
return var_name
|
151
|
+
|
152
|
+
|
153
|
+
Params = ParamSpec("Params")
|
154
|
+
|
155
|
+
|
156
|
+
def suppress_return_value(func: Callable[Params, None]) -> Callable[Params, None]:
|
157
|
+
# An empty decorator suppresses mypy's func-returns-value error when assigning the
|
158
|
+
# return value of a None-returning function
|
159
|
+
return func
|
160
|
+
|
161
|
+
|
162
|
+
Statements = Union[None, list[Union[None, "QVar"]], tuple[Union[None, "QVar"], ...]]
|
classiq/qmod/write_qmod.py
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
import json
|
2
2
|
from pathlib import Path
|
3
|
-
from typing import Optional
|
3
|
+
from typing import Optional, Union
|
4
4
|
|
5
5
|
from classiq.interface.model.model import Model, SerializedModel
|
6
6
|
|
7
7
|
from classiq.qmod.native.pretty_printer import DSLPrettyPrinter
|
8
|
+
from classiq.qmod.quantum_function import GenerativeQFunc, QFunc
|
8
9
|
from classiq.qmod.utilities import DEFAULT_DECIMAL_PRECISION
|
9
10
|
|
10
11
|
_QMOD_SUFFIX = "qmod"
|
@@ -12,7 +13,7 @@ _SYNTHESIS_OPTIONS_SUFFIX = "synthesis_options.json"
|
|
12
13
|
|
13
14
|
|
14
15
|
def write_qmod(
|
15
|
-
|
16
|
+
model: Union[SerializedModel, QFunc, GenerativeQFunc],
|
16
17
|
name: str,
|
17
18
|
directory: Optional[Path] = None,
|
18
19
|
decimal_precision: int = DEFAULT_DECIMAL_PRECISION,
|
@@ -22,7 +23,7 @@ def write_qmod(
|
|
22
23
|
The native Qmod file may be uploaded to the Classiq IDE.
|
23
24
|
|
24
25
|
Args:
|
25
|
-
|
26
|
+
model: The entry point of the Qmod model - a qfunc named 'main' (or alternatively the output of 'create_model').
|
26
27
|
name: The name to save the file by.
|
27
28
|
directory: The directory to save the files in. If None, the current working directory is used.
|
28
29
|
decimal_precision: The number of decimal places to use for numbers, set to 4 by default.
|
@@ -30,13 +31,15 @@ def write_qmod(
|
|
30
31
|
Returns:
|
31
32
|
None
|
32
33
|
"""
|
33
|
-
|
34
|
-
|
34
|
+
if isinstance(model, (QFunc, GenerativeQFunc)):
|
35
|
+
model_obj = model.create_model()
|
36
|
+
else:
|
37
|
+
model_obj = Model.model_validate_json(model)
|
35
38
|
pretty_printed_model = DSLPrettyPrinter(decimal_precision=decimal_precision).visit(
|
36
|
-
|
39
|
+
model_obj
|
37
40
|
)
|
38
41
|
|
39
|
-
synthesis_options =
|
42
|
+
synthesis_options = model_obj.model_dump(
|
40
43
|
include={"constraints", "preferences"}, exclude_none=True
|
41
44
|
)
|
42
45
|
|
classiq/synthesis.py
CHANGED
@@ -1,17 +1,18 @@
|
|
1
|
-
from typing import Any, NewType, Optional
|
1
|
+
from typing import Any, NewType, Optional, Union
|
2
2
|
|
3
3
|
import pydantic
|
4
4
|
|
5
5
|
from classiq.interface.analyzer.result import QasmCode
|
6
|
-
from classiq.interface.exceptions import ClassiqValueError
|
6
|
+
from classiq.interface.exceptions import ClassiqError, ClassiqValueError
|
7
7
|
from classiq.interface.executor.execution_preferences import ExecutionPreferences
|
8
8
|
from classiq.interface.generator.model.constraints import Constraints
|
9
9
|
from classiq.interface.generator.model.preferences.preferences import Preferences
|
10
|
-
from classiq.interface.model.model import Model, SerializedModel
|
10
|
+
from classiq.interface.model.model import MAIN_FUNCTION_NAME, Model, SerializedModel
|
11
11
|
|
12
12
|
from classiq import QuantumProgram
|
13
13
|
from classiq._internals import async_utils
|
14
14
|
from classiq._internals.api_wrapper import ApiWrapper
|
15
|
+
from classiq.qmod.quantum_function import GenerativeQFunc, QFunc
|
15
16
|
|
16
17
|
SerializedQuantumProgram = NewType("SerializedQuantumProgram", str)
|
17
18
|
|
@@ -69,19 +70,34 @@ async def synthesize_async(
|
|
69
70
|
|
70
71
|
|
71
72
|
def synthesize(
|
72
|
-
|
73
|
+
model: Union[SerializedModel, QFunc, GenerativeQFunc],
|
74
|
+
auto_show: bool = False,
|
75
|
+
constraints: Optional[Constraints] = None,
|
76
|
+
preferences: Optional[Preferences] = None,
|
73
77
|
) -> SerializedQuantumProgram:
|
74
78
|
"""
|
75
79
|
Synthesize a model with the Classiq engine to receive a quantum program.
|
76
80
|
[More details](https://docs.classiq.io/latest/reference-manual/synthesis/)
|
77
81
|
|
78
82
|
Args:
|
79
|
-
|
80
|
-
auto_show:
|
83
|
+
model: The entry point of the Qmod model - a qfunc named 'main' (or alternatively the output of 'create_model').
|
84
|
+
auto_show: Whether to 'show' the synthesized model (False by default).
|
85
|
+
constraints: Constraints for the synthesis of the model. See Constraints (Optional).
|
86
|
+
preferences: Preferences for the synthesis of the model. See Preferences (Optional).
|
81
87
|
|
82
88
|
Returns:
|
83
89
|
SerializedQuantumProgram: Quantum program serialized as a string. (See: QuantumProgram)
|
84
90
|
"""
|
91
|
+
if isinstance(model, (QFunc, GenerativeQFunc)):
|
92
|
+
func_name = model._py_callable.__name__
|
93
|
+
if func_name != MAIN_FUNCTION_NAME:
|
94
|
+
raise ClassiqError(
|
95
|
+
f"The entry point function must be named 'main', got {func_name!r}"
|
96
|
+
)
|
97
|
+
model_obj = model.create_model(constraints=constraints, preferences=preferences)
|
98
|
+
serialized_model = model_obj.get_model()
|
99
|
+
else:
|
100
|
+
serialized_model = model
|
85
101
|
result = async_utils.run(synthesize_async(serialized_model))
|
86
102
|
if auto_show:
|
87
103
|
show(result)
|
@@ -91,7 +107,7 @@ def synthesize(
|
|
91
107
|
def set_preferences(
|
92
108
|
serialized_model: SerializedModel,
|
93
109
|
preferences: Optional[Preferences] = None,
|
94
|
-
**kwargs: Any
|
110
|
+
**kwargs: Any,
|
95
111
|
) -> SerializedModel:
|
96
112
|
"""
|
97
113
|
Overrides the preferences of a (serialized) model and returns the updated model.
|
@@ -139,7 +155,7 @@ def update_preferences(
|
|
139
155
|
def set_constraints(
|
140
156
|
serialized_model: SerializedModel,
|
141
157
|
constraints: Optional[Constraints] = None,
|
142
|
-
**kwargs: Any
|
158
|
+
**kwargs: Any,
|
143
159
|
) -> SerializedModel:
|
144
160
|
"""
|
145
161
|
Overrides the constraints of a (serialized) model and returns the updated model.
|
@@ -187,7 +203,7 @@ def update_constraints(
|
|
187
203
|
def set_execution_preferences(
|
188
204
|
serialized_model: SerializedModel,
|
189
205
|
execution_preferences: Optional[ExecutionPreferences] = None,
|
190
|
-
**kwargs: Any
|
206
|
+
**kwargs: Any,
|
191
207
|
) -> SerializedModel:
|
192
208
|
"""
|
193
209
|
Overrides the execution preferences of a (serialized) model and returns the updated model.
|