classiq 0.33.0__py3-none-any.whl → 0.35.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 +61 -23
- classiq/_internals/client.py +4 -1
- classiq/_internals/jobs.py +9 -2
- classiq/applications_model_constructors/grover_model_constructor.py +1 -1
- classiq/execution/__init__.py +9 -2
- classiq/execution/jobs.py +84 -11
- classiq/executor.py +3 -10
- classiq/interface/_version.py +1 -1
- classiq/interface/backend/backend_preferences.py +17 -0
- classiq/interface/backend/pydantic_backend.py +8 -0
- classiq/interface/backend/quantum_backend_providers.py +15 -1
- classiq/interface/chemistry/ground_state_problem.py +1 -1
- classiq/interface/chemistry/operator.py +198 -0
- classiq/interface/execution/jobs.py +28 -0
- classiq/interface/executor/execution_request.py +2 -12
- classiq/interface/generator/arith/arithmetic_expression_validator.py +1 -0
- classiq/interface/generator/arith/arithmetic_param_getters.py +12 -0
- classiq/interface/generator/arith/binary_ops.py +34 -0
- classiq/interface/generator/expressions/expression.py +3 -0
- classiq/interface/generator/expressions/qmod_sized_proxy.py +12 -2
- classiq/interface/generator/function_param_list_without_self_reference.py +2 -0
- classiq/interface/generator/function_params.py +4 -0
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/atomic_quantum_functions.py +2 -2
- classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py +42 -105
- classiq/interface/generator/generated_circuit.py +8 -44
- classiq/interface/generator/generated_circuit_data.py +2 -11
- classiq/interface/generator/model/preferences/preferences.py +4 -2
- classiq/interface/generator/quantum_function_call.py +1 -1
- classiq/interface/hardware.py +2 -0
- classiq/interface/ide/show.py +1 -14
- classiq/interface/model/bind_operation.py +10 -0
- classiq/interface/model/handle_binding.py +18 -0
- classiq/interface/model/model.py +12 -3
- classiq/interface/model/quantum_expressions/amplitude_loading_operation.py +2 -1
- classiq/interface/model/quantum_expressions/arithmetic_operation.py +3 -1
- classiq/interface/model/quantum_expressions/quantum_expression.py +9 -6
- classiq/interface/model/quantum_function_call.py +9 -339
- classiq/interface/model/quantum_statement.py +3 -2
- classiq/interface/server/routes.py +8 -6
- classiq/model/function_handler.pyi +86 -85
- classiq/qmod/__init__.py +2 -2
- classiq/qmod/builtins/__init__.py +8 -0
- classiq/{interface/model/clients/qmod/qmod_builtins.py → qmod/builtins/functions.py} +46 -165
- classiq/qmod/builtins/operations.py +19 -0
- classiq/qmod/builtins/structs.py +128 -0
- classiq/qmod/declaration_inferrer.py +34 -17
- classiq/qmod/model_state_container.py +6 -3
- classiq/qmod/qmod_parameter.py +24 -8
- classiq/qmod/qmod_variable.py +4 -4
- classiq/qmod/quantum_callable.py +2 -2
- classiq/qmod/quantum_expandable.py +7 -3
- classiq/qmod/quantum_function.py +9 -9
- {classiq-0.33.0.dist-info → classiq-0.35.0.dist-info}/METADATA +1 -1
- {classiq-0.33.0.dist-info → classiq-0.35.0.dist-info}/RECORD +56 -55
- classiq/interface/model/clients/qmod/__init__.py +0 -0
- classiq/interface/model/semantics.py +0 -15
- classiq/qmod/qmod_builtins.py +0 -4
- /classiq/interface/{model/clients → execution}/__init__.py +0 -0
- {classiq-0.33.0.dist-info → classiq-0.35.0.dist-info}/WHEEL +0 -0
classiq/interface/generator/functions/core_lib_declarations/quantum_functions/std_lib_functions.py
CHANGED
@@ -7,17 +7,10 @@ from classiq.interface.model.quantum_function_declaration import (
|
|
7
7
|
QFT_STEP = QuantumFunctionDeclaration.parse_raw(
|
8
8
|
"""{
|
9
9
|
"name": "qft_step",
|
10
|
-
"param_decls": {
|
11
|
-
"num_qbits": {
|
12
|
-
"kind": "int"
|
13
|
-
}
|
14
|
-
},
|
10
|
+
"param_decls": {},
|
15
11
|
"port_declarations": {
|
16
|
-
"
|
17
|
-
"name": "
|
18
|
-
"size": {
|
19
|
-
"expr": "num_qbits"
|
20
|
-
},
|
12
|
+
"target": {
|
13
|
+
"name": "target",
|
21
14
|
"direction": "inout"
|
22
15
|
}
|
23
16
|
},
|
@@ -29,21 +22,40 @@ QFT_STEP = QuantumFunctionDeclaration.parse_raw(
|
|
29
22
|
QFT = QuantumFunctionDeclaration.parse_raw(
|
30
23
|
"""{
|
31
24
|
"name": "qft",
|
25
|
+
"param_decls": {},
|
26
|
+
"port_declarations": {
|
27
|
+
"target": {
|
28
|
+
"name": "target",
|
29
|
+
"direction": "inout"
|
30
|
+
}
|
31
|
+
},
|
32
|
+
"operand_declarations": {},
|
33
|
+
"positional_arg_declarations": []
|
34
|
+
}"""
|
35
|
+
)
|
36
|
+
|
37
|
+
STANDARD_QPE = QuantumFunctionDeclaration.parse_raw(
|
38
|
+
"""{
|
39
|
+
"name": "standard_qpe",
|
32
40
|
"param_decls": {
|
33
|
-
"
|
41
|
+
"precision": {
|
34
42
|
"kind": "int"
|
35
43
|
}
|
36
44
|
},
|
37
45
|
"port_declarations": {
|
38
|
-
"
|
39
|
-
"name": "
|
46
|
+
"phase": {
|
47
|
+
"name": "phase",
|
40
48
|
"size": {
|
41
|
-
"expr": "
|
49
|
+
"expr": "precision"
|
42
50
|
},
|
43
51
|
"direction": "inout"
|
44
52
|
}
|
45
53
|
},
|
46
|
-
"operand_declarations": {
|
54
|
+
"operand_declarations": {
|
55
|
+
"unitary": {
|
56
|
+
"name": "unitary"
|
57
|
+
}
|
58
|
+
},
|
47
59
|
"positional_arg_declarations": []
|
48
60
|
}"""
|
49
61
|
)
|
@@ -52,41 +64,22 @@ QPE = QuantumFunctionDeclaration.parse_raw(
|
|
52
64
|
"""{
|
53
65
|
"name": "qpe",
|
54
66
|
"param_decls": {
|
55
|
-
"
|
56
|
-
"kind": "int"
|
57
|
-
},
|
58
|
-
"qpe_reg_size": {
|
67
|
+
"precision": {
|
59
68
|
"kind": "int"
|
60
69
|
}
|
61
70
|
},
|
62
71
|
"port_declarations": {
|
63
|
-
"
|
64
|
-
"name": "
|
65
|
-
"size": {
|
66
|
-
"expr": "reg_size"
|
67
|
-
},
|
68
|
-
"direction": "inout"
|
69
|
-
},
|
70
|
-
"q": {
|
71
|
-
"name": "q",
|
72
|
+
"phase": {
|
73
|
+
"name": "phase",
|
72
74
|
"size": {
|
73
|
-
"expr": "
|
75
|
+
"expr": "precision"
|
74
76
|
},
|
75
|
-
"direction": "
|
77
|
+
"direction": "output"
|
76
78
|
}
|
77
79
|
},
|
78
80
|
"operand_declarations": {
|
79
|
-
"
|
80
|
-
"name": "
|
81
|
-
"port_declarations": {
|
82
|
-
"target": {
|
83
|
-
"name": "target",
|
84
|
-
"size": {
|
85
|
-
"expr": "reg_size"
|
86
|
-
},
|
87
|
-
"direction": "inout"
|
88
|
-
}
|
89
|
-
}
|
81
|
+
"unitary": {
|
82
|
+
"name": "unitary"
|
90
83
|
}
|
91
84
|
},
|
92
85
|
"positional_arg_declarations": []
|
@@ -97,9 +90,6 @@ SINGLE_PAULI = QuantumFunctionDeclaration.parse_raw(
|
|
97
90
|
"""{
|
98
91
|
"name": "single_pauli",
|
99
92
|
"param_decls": {
|
100
|
-
"reg_size": {
|
101
|
-
"kind": "int"
|
102
|
-
},
|
103
93
|
"slope": {
|
104
94
|
"kind": "real"
|
105
95
|
},
|
@@ -110,9 +100,6 @@ SINGLE_PAULI = QuantumFunctionDeclaration.parse_raw(
|
|
110
100
|
"port_declarations": {
|
111
101
|
"x": {
|
112
102
|
"name": "x",
|
113
|
-
"size": {
|
114
|
-
"expr": "reg_size"
|
115
|
-
},
|
116
103
|
"direction": "inout"
|
117
104
|
},
|
118
105
|
"q": {
|
@@ -150,12 +137,6 @@ LINEAR_PAULI_ROTATIONS = QuantumFunctionDeclaration.parse_raw(
|
|
150
137
|
"""{
|
151
138
|
"name": "linear_pauli_rotations",
|
152
139
|
"param_decls": {
|
153
|
-
"reg_size": {
|
154
|
-
"kind": "int"
|
155
|
-
},
|
156
|
-
"num_state_qubits": {
|
157
|
-
"kind": "int"
|
158
|
-
},
|
159
140
|
"bases": {
|
160
141
|
"kind": "list",
|
161
142
|
"element_type": {
|
@@ -178,16 +159,10 @@ LINEAR_PAULI_ROTATIONS = QuantumFunctionDeclaration.parse_raw(
|
|
178
159
|
"port_declarations": {
|
179
160
|
"x": {
|
180
161
|
"name": "x",
|
181
|
-
"size": {
|
182
|
-
"expr": "reg_size"
|
183
|
-
},
|
184
162
|
"direction": "inout"
|
185
163
|
},
|
186
164
|
"q": {
|
187
165
|
"name": "q",
|
188
|
-
"size": {
|
189
|
-
"expr": "num_state_qubits"
|
190
|
-
},
|
191
166
|
"direction": "inout"
|
192
167
|
}
|
193
168
|
},
|
@@ -380,17 +355,10 @@ GROVER_OPERATOR = QuantumFunctionDeclaration.parse_raw(
|
|
380
355
|
HADAMARD_TRANSFORM = QuantumFunctionDeclaration.parse_raw(
|
381
356
|
"""{
|
382
357
|
"name": "hadamard_transform",
|
383
|
-
"param_decls": {
|
384
|
-
"num_qubits": {
|
385
|
-
"kind": "int"
|
386
|
-
}
|
387
|
-
},
|
358
|
+
"param_decls": {},
|
388
359
|
"port_declarations": {
|
389
|
-
"
|
390
|
-
"name": "
|
391
|
-
"size": {
|
392
|
-
"expr": "num_qubits"
|
393
|
-
},
|
360
|
+
"target": {
|
361
|
+
"name": "target",
|
394
362
|
"direction": "inout"
|
395
363
|
}
|
396
364
|
},
|
@@ -402,17 +370,10 @@ HADAMARD_TRANSFORM = QuantumFunctionDeclaration.parse_raw(
|
|
402
370
|
APPLY_TO_ALL = QuantumFunctionDeclaration.parse_raw(
|
403
371
|
"""{
|
404
372
|
"name": "apply_to_all",
|
405
|
-
"param_decls": {
|
406
|
-
"num_qubits": {
|
407
|
-
"kind": "int"
|
408
|
-
}
|
409
|
-
},
|
373
|
+
"param_decls": {},
|
410
374
|
"port_declarations": {
|
411
|
-
"
|
412
|
-
"name": "
|
413
|
-
"size": {
|
414
|
-
"expr": "num_qubits"
|
415
|
-
},
|
375
|
+
"target": {
|
376
|
+
"name": "target",
|
416
377
|
"direction": "inout"
|
417
378
|
}
|
418
379
|
},
|
@@ -503,9 +464,6 @@ QAOA_MIXER_LAYER = QuantumFunctionDeclaration.parse_raw(
|
|
503
464
|
"""{
|
504
465
|
"name": "qaoa_mixer_layer",
|
505
466
|
"param_decls": {
|
506
|
-
"num_qubits": {
|
507
|
-
"kind": "int"
|
508
|
-
},
|
509
467
|
"b": {
|
510
468
|
"kind": "real"
|
511
469
|
}
|
@@ -513,9 +471,6 @@ QAOA_MIXER_LAYER = QuantumFunctionDeclaration.parse_raw(
|
|
513
471
|
"port_declarations": {
|
514
472
|
"target": {
|
515
473
|
"name": "target",
|
516
|
-
"size": {
|
517
|
-
"expr": "num_qubits"
|
518
|
-
},
|
519
474
|
"direction": "inout"
|
520
475
|
}
|
521
476
|
},
|
@@ -528,9 +483,6 @@ QAOA_COST_LAYER = QuantumFunctionDeclaration.parse_raw(
|
|
528
483
|
"""{
|
529
484
|
"name": "qaoa_cost_layer",
|
530
485
|
"param_decls": {
|
531
|
-
"num_qubits": {
|
532
|
-
"kind": "int"
|
533
|
-
},
|
534
486
|
"g": {
|
535
487
|
"kind": "real"
|
536
488
|
},
|
@@ -548,9 +500,6 @@ QAOA_COST_LAYER = QuantumFunctionDeclaration.parse_raw(
|
|
548
500
|
"port_declarations": {
|
549
501
|
"target": {
|
550
502
|
"name": "target",
|
551
|
-
"size": {
|
552
|
-
"expr": "num_qubits"
|
553
|
-
},
|
554
503
|
"direction": "inout"
|
555
504
|
}
|
556
505
|
},
|
@@ -563,9 +512,6 @@ QAOA_LAYER = QuantumFunctionDeclaration.parse_raw(
|
|
563
512
|
"""{
|
564
513
|
"name": "qaoa_layer",
|
565
514
|
"param_decls": {
|
566
|
-
"num_qubits": {
|
567
|
-
"kind": "int"
|
568
|
-
},
|
569
515
|
"g": {
|
570
516
|
"kind": "real"
|
571
517
|
},
|
@@ -586,9 +532,6 @@ QAOA_LAYER = QuantumFunctionDeclaration.parse_raw(
|
|
586
532
|
"port_declarations": {
|
587
533
|
"target": {
|
588
534
|
"name": "target",
|
589
|
-
"size": {
|
590
|
-
"expr": "num_qubits"
|
591
|
-
},
|
592
535
|
"direction": "inout"
|
593
536
|
}
|
594
537
|
},
|
@@ -600,17 +543,10 @@ QAOA_LAYER = QuantumFunctionDeclaration.parse_raw(
|
|
600
543
|
QAOA_INIT = QuantumFunctionDeclaration.parse_raw(
|
601
544
|
"""{
|
602
545
|
"name": "qaoa_init",
|
603
|
-
"param_decls": {
|
604
|
-
"num_qubits": {
|
605
|
-
"kind": "int"
|
606
|
-
}
|
607
|
-
},
|
546
|
+
"param_decls": {},
|
608
547
|
"port_declarations": {
|
609
548
|
"target": {
|
610
549
|
"name": "target",
|
611
|
-
"size": {
|
612
|
-
"expr": "num_qubits"
|
613
|
-
},
|
614
550
|
"direction": "inout"
|
615
551
|
}
|
616
552
|
},
|
@@ -750,6 +686,7 @@ FULL_HEA = QuantumFunctionDeclaration.parse_raw(
|
|
750
686
|
__all__ = [
|
751
687
|
"QFT_STEP",
|
752
688
|
"QFT",
|
689
|
+
"STANDARD_QPE",
|
753
690
|
"QPE",
|
754
691
|
"SINGLE_PAULI",
|
755
692
|
"LINEAR_PAULI_ROTATIONS",
|
@@ -1,8 +1,7 @@
|
|
1
|
-
import abc
|
2
1
|
import uuid
|
3
2
|
from datetime import datetime
|
4
3
|
from pathlib import Path
|
5
|
-
from typing import Dict, List,
|
4
|
+
from typing import Dict, List, Optional, Tuple, Union
|
6
5
|
|
7
6
|
import pydantic
|
8
7
|
from typing_extensions import TypeAlias
|
@@ -17,9 +16,7 @@ from classiq.interface.generator.circuit_code.types_and_constants import (
|
|
17
16
|
VENDOR_TO_INSTRUCTION_SET,
|
18
17
|
CodeAndSyntax,
|
19
18
|
)
|
20
|
-
from classiq.interface.generator.function_params import ArithmeticIODict
|
21
19
|
from classiq.interface.generator.generated_circuit_data import (
|
22
|
-
ExecutionCircuitData,
|
23
20
|
FunctionDebugInfo,
|
24
21
|
GeneratedCircuitData,
|
25
22
|
)
|
@@ -28,7 +25,6 @@ from classiq.interface.generator.model.model import ExecutionModel, SynthesisMod
|
|
28
25
|
from classiq.interface.generator.synthesis_metadata.synthesis_duration import (
|
29
26
|
SynthesisStepDurations,
|
30
27
|
)
|
31
|
-
from classiq.interface.helpers.pydantic_model_helpers import get_discriminator_field
|
32
28
|
from classiq.interface.helpers.versioned_model import VersionedModel
|
33
29
|
from classiq.interface.ide.ide_data import CircuitMetrics
|
34
30
|
|
@@ -55,12 +51,15 @@ def get_uuid_as_str() -> str:
|
|
55
51
|
return str(uuid.uuid4())
|
56
52
|
|
57
53
|
|
58
|
-
class
|
54
|
+
class GeneratedCircuit(VersionedModel, CircuitCodeInterface):
|
59
55
|
hardware_data: SynthesisHardwareData
|
60
|
-
data: Union[GeneratedCircuitData, ExecutionCircuitData]
|
61
56
|
initial_values: Optional[InitialConditions]
|
62
|
-
|
63
|
-
|
57
|
+
data: GeneratedCircuitData
|
58
|
+
model: SynthesisModel
|
59
|
+
transpiled_circuit: Optional[TranspiledCircuitData]
|
60
|
+
creation_time: str = pydantic.Field(default_factory=datetime.utcnow().isoformat)
|
61
|
+
synthesis_duration: Optional[SynthesisStepDurations]
|
62
|
+
debug_info: Optional[List[FunctionDebugInfo]]
|
64
63
|
program_id: str = pydantic.Field(default_factory=get_uuid_as_str)
|
65
64
|
|
66
65
|
def _hardware_agnostic_program_code(self) -> CodeAndSyntax:
|
@@ -135,41 +134,6 @@ class GeneratedCircuitBase(abc.ABC, VersionedModel, CircuitCodeInterface):
|
|
135
134
|
for name, init_value in initial_values.items()
|
136
135
|
}
|
137
136
|
|
138
|
-
@property
|
139
|
-
@abc.abstractmethod
|
140
|
-
def program_circuit(self) -> CircuitCodeInterface:
|
141
|
-
pass
|
142
|
-
|
143
|
-
@property
|
144
|
-
@abc.abstractmethod
|
145
|
-
def execution_model(self) -> ExecutionModel:
|
146
|
-
pass
|
147
|
-
|
148
|
-
|
149
|
-
class ExecutionCircuit(GeneratedCircuitBase):
|
150
|
-
circuit_type: Literal["execution"] = get_discriminator_field("execution")
|
151
|
-
data: ExecutionCircuitData
|
152
|
-
model: ExecutionModel
|
153
|
-
arithmetic_outputs: ArithmeticIODict = dict()
|
154
|
-
|
155
|
-
@property
|
156
|
-
def program_circuit(self) -> CircuitCodeInterface:
|
157
|
-
return self
|
158
|
-
|
159
|
-
@property
|
160
|
-
def execution_model(self) -> ExecutionModel:
|
161
|
-
return self.model
|
162
|
-
|
163
|
-
|
164
|
-
class GeneratedCircuit(GeneratedCircuitBase):
|
165
|
-
circuit_type: Literal["generated"] = get_discriminator_field("generated")
|
166
|
-
data: GeneratedCircuitData
|
167
|
-
model: SynthesisModel
|
168
|
-
transpiled_circuit: Optional[TranspiledCircuitData]
|
169
|
-
creation_time: str = pydantic.Field(default_factory=datetime.utcnow().isoformat)
|
170
|
-
synthesis_duration: Optional[SynthesisStepDurations]
|
171
|
-
debug_info: List[FunctionDebugInfo]
|
172
|
-
|
173
137
|
def save_results(self, filename: Optional[Union[str, Path]] = None) -> None:
|
174
138
|
"""
|
175
139
|
Saves generated circuit results as json.
|
@@ -83,26 +83,17 @@ class GeneratedFunction(pydantic.BaseModel):
|
|
83
83
|
)
|
84
84
|
|
85
85
|
|
86
|
-
class
|
86
|
+
class GeneratedCircuitData(pydantic.BaseModel):
|
87
87
|
width: int
|
88
88
|
circuit_parameters: List[ParameterName] = pydantic.Field(default_factory=list)
|
89
89
|
qubit_mapping: QubitMapping = pydantic.Field(default_factory=QubitMapping)
|
90
90
|
execution_data: Optional[ExecutionData] = pydantic.Field(default=None)
|
91
91
|
|
92
92
|
@classmethod
|
93
|
-
def from_empty_logic_flow(cls) -> "
|
93
|
+
def from_empty_logic_flow(cls) -> "GeneratedCircuitData":
|
94
94
|
return cls(width=0)
|
95
95
|
|
96
96
|
|
97
|
-
class ExecutionCircuitData(CircuitDataBase):
|
98
|
-
depth: Optional[int]
|
99
|
-
count_ops: Optional[Dict[str, int]]
|
100
|
-
|
101
|
-
|
102
|
-
class GeneratedCircuitData(CircuitDataBase):
|
103
|
-
pass
|
104
|
-
|
105
|
-
|
106
97
|
class FunctionDebugInfo(pydantic.BaseModel):
|
107
98
|
generated_function: Optional[GeneratedFunction]
|
108
99
|
children: List[Optional["FunctionDebugInfo"]]
|
@@ -65,6 +65,8 @@ class TranspilationOption(StrEnum):
|
|
65
65
|
AUTO_OPTIMIZE = "auto optimize"
|
66
66
|
LIGHT = "light"
|
67
67
|
MEDIUM = "medium"
|
68
|
+
INTENSIVE = "intensive"
|
69
|
+
CUSTOM = "custom"
|
68
70
|
|
69
71
|
def __bool__(self) -> bool:
|
70
72
|
return self != TranspilationOption.NONE
|
@@ -89,9 +91,9 @@ class Preferences(pydantic.BaseModel, extra=pydantic.Extra.forbid):
|
|
89
91
|
description="Custom hardware settings which will be used during optimization. "
|
90
92
|
"This field is ignored if backend preferences are given.",
|
91
93
|
)
|
92
|
-
|
94
|
+
debug_mode: bool = pydantic.Field(
|
93
95
|
default=True,
|
94
|
-
description="
|
96
|
+
description="Add debug information to the synthesized result. "
|
95
97
|
"Setting this option to False can potentially speed up the synthesis, and is "
|
96
98
|
"recommended for executing iterative algorithms.",
|
97
99
|
)
|
classiq/interface/hardware.py
CHANGED
classiq/interface/ide/show.py
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
import re
|
2
|
-
from typing import Union
|
3
2
|
|
4
3
|
import pydantic
|
5
4
|
|
6
5
|
from classiq.interface.analyzer.result import QasmCode
|
7
|
-
from classiq.interface.generator.generated_circuit import ExecutionCircuit
|
8
6
|
|
9
7
|
from classiq import GeneratedCircuit
|
10
8
|
from classiq._internals.api_wrapper import ApiWrapper
|
@@ -26,22 +24,11 @@ qasm_show_interactive = syncify_function(qasm_show_interactive_async)
|
|
26
24
|
CANT_PARSE_QUANTUM_PROGRAM_MSG = (
|
27
25
|
"Can not parse quantum_program into GeneratedCircuit, \n"
|
28
26
|
)
|
29
|
-
CANT_SHOW_EXECUTION_CIRCUIT_MSG = (
|
30
|
-
"It looks like the flag `support_circuit_visualization` in the model preferences "
|
31
|
-
"has been turned off. \n"
|
32
|
-
"The resulting circuit does not support visualization. \n"
|
33
|
-
"Make sure to set the flag to True, the default setting, and try again."
|
34
|
-
)
|
35
|
-
_Circuit = Union[GeneratedCircuit, ExecutionCircuit]
|
36
27
|
|
37
28
|
|
38
29
|
def show(quantum_program: SerializedQuantumProgram) -> None:
|
39
30
|
try:
|
40
31
|
circuit = GeneratedCircuit.parse_raw(quantum_program)
|
41
32
|
except pydantic.error_wrappers.ValidationError as exc:
|
42
|
-
|
43
|
-
ExecutionCircuit.parse_raw(quantum_program)
|
44
|
-
raise ClassiqValueError(CANT_SHOW_EXECUTION_CIRCUIT_MSG) from None
|
45
|
-
except pydantic.error_wrappers.ValidationError:
|
46
|
-
raise ClassiqValueError(CANT_PARSE_QUANTUM_PROGRAM_MSG) from exc
|
33
|
+
raise ClassiqValueError(CANT_PARSE_QUANTUM_PROGRAM_MSG) from exc
|
47
34
|
circuit.show() # type: ignore[attr-defined]
|
@@ -1,8 +1,12 @@
|
|
1
1
|
from typing import Mapping
|
2
2
|
|
3
|
+
import pydantic
|
4
|
+
|
3
5
|
from classiq.interface.model.handle_binding import HandleBinding
|
4
6
|
from classiq.interface.model.quantum_statement import QuantumOperation
|
5
7
|
|
8
|
+
from classiq.exceptions import ClassiqValueError
|
9
|
+
|
6
10
|
BIND_INPUT_NAME = "bind_input"
|
7
11
|
BIND_OUTPUT_NAME = "bind_output"
|
8
12
|
|
@@ -18,3 +22,9 @@ class BindOperation(QuantumOperation):
|
|
18
22
|
@property
|
19
23
|
def wiring_outputs(self) -> Mapping[str, HandleBinding]:
|
20
24
|
return {BIND_OUTPUT_NAME: self.out_handle}
|
25
|
+
|
26
|
+
@pydantic.validator("in_handle", "out_handle")
|
27
|
+
def validate_handle(cls, handle: HandleBinding) -> HandleBinding:
|
28
|
+
if not handle.is_bindable():
|
29
|
+
raise ClassiqValueError(f"Cannot bind '{handle}'") # noqa: B907
|
30
|
+
return handle
|
@@ -10,6 +10,12 @@ class HandleBinding(BaseModel):
|
|
10
10
|
frozen = True
|
11
11
|
extra = Extra.forbid
|
12
12
|
|
13
|
+
def __str__(self) -> str:
|
14
|
+
return self.name
|
15
|
+
|
16
|
+
def is_bindable(self) -> bool:
|
17
|
+
return True
|
18
|
+
|
13
19
|
|
14
20
|
class SubscriptHandleBinding(HandleBinding):
|
15
21
|
index: Expression
|
@@ -18,6 +24,12 @@ class SubscriptHandleBinding(HandleBinding):
|
|
18
24
|
frozen = True
|
19
25
|
extra = Extra.forbid
|
20
26
|
|
27
|
+
def __str__(self) -> str:
|
28
|
+
return f"{self.name}[{self.index}]"
|
29
|
+
|
30
|
+
def is_bindable(self) -> bool:
|
31
|
+
return False
|
32
|
+
|
21
33
|
|
22
34
|
class SlicedHandleBinding(HandleBinding):
|
23
35
|
start: Expression
|
@@ -26,3 +38,9 @@ class SlicedHandleBinding(HandleBinding):
|
|
26
38
|
class Config:
|
27
39
|
frozen = True
|
28
40
|
extra = Extra.forbid
|
41
|
+
|
42
|
+
def __str__(self) -> str:
|
43
|
+
return f"{self.name}[{self.start}:{self.end}]"
|
44
|
+
|
45
|
+
def is_bindable(self) -> bool:
|
46
|
+
return False
|
classiq/interface/model/model.py
CHANGED
@@ -54,8 +54,8 @@ TYPE_NAME_CONFLICT_USER = (
|
|
54
54
|
)
|
55
55
|
|
56
56
|
|
57
|
-
def
|
58
|
-
return
|
57
|
+
def _create_empty_main_function() -> NativeFunctionDefinition:
|
58
|
+
return NativeFunctionDefinition(name=MAIN_FUNCTION_NAME)
|
59
59
|
|
60
60
|
|
61
61
|
class VersionedSerializedModel(VersionedModel):
|
@@ -71,7 +71,7 @@ class Model(VersionedModel):
|
|
71
71
|
|
72
72
|
# Must be validated before logic_flow
|
73
73
|
functions: List[NativeFunctionDefinition] = pydantic.Field(
|
74
|
-
default_factory=
|
74
|
+
default_factory=list,
|
75
75
|
description="The user-defined custom type library.",
|
76
76
|
)
|
77
77
|
|
@@ -119,6 +119,15 @@ class Model(VersionedModel):
|
|
119
119
|
def function_dict(self) -> Dict[str, QuantumFunctionDeclaration]:
|
120
120
|
return nameables_to_dict(self.functions)
|
121
121
|
|
122
|
+
@pydantic.validator("functions", always=True)
|
123
|
+
def _add_empty_main(
|
124
|
+
cls, functions: List[NativeFunctionDefinition]
|
125
|
+
) -> List[NativeFunctionDefinition]:
|
126
|
+
function_dict = nameables_to_dict(functions)
|
127
|
+
if MAIN_FUNCTION_NAME not in function_dict:
|
128
|
+
functions.append(_create_empty_main_function())
|
129
|
+
return functions
|
130
|
+
|
122
131
|
@pydantic.root_validator()
|
123
132
|
def validate_static_correctness(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
124
133
|
functions: Optional[List[QuantumFunctionDeclaration]] = values.get("functions")
|
@@ -40,7 +40,8 @@ class AmplitudeLoadingOperation(QuantumExpressionOperation):
|
|
40
40
|
) -> Mapping[
|
41
41
|
str, Union[SlicedHandleBinding, SubscriptHandleBinding, HandleBinding]
|
42
42
|
]:
|
43
|
-
|
43
|
+
if len(self.var_handles) == 0:
|
44
|
+
return dict()
|
44
45
|
return {AMPLITUDE_IO_NAME: self.var_handles[0]}
|
45
46
|
|
46
47
|
def initialize_var_types(self, var_types: Dict[str, QuantumType]) -> None:
|
@@ -24,7 +24,9 @@ class ArithmeticOperation(QuantumExpressionOperation):
|
|
24
24
|
|
25
25
|
def initialize_var_types(self, var_types: Dict[str, QuantumType]) -> None:
|
26
26
|
super().initialize_var_types(var_types)
|
27
|
-
self._result_type = compute_arithmetic_result_type(
|
27
|
+
self._result_type = compute_arithmetic_result_type(
|
28
|
+
self.expression.expr, var_types
|
29
|
+
)
|
28
30
|
|
29
31
|
@property
|
30
32
|
def wiring_inouts(
|
@@ -4,6 +4,7 @@ from typing import Dict, List, Mapping, Optional, Set, Union
|
|
4
4
|
|
5
5
|
import pydantic
|
6
6
|
|
7
|
+
from classiq.interface.generator.expressions.expression import Expression
|
7
8
|
from classiq.interface.generator.expressions.sympy_supported_expressions import (
|
8
9
|
SYMPY_SUPPORTED_EXPRESSIONS,
|
9
10
|
)
|
@@ -30,12 +31,13 @@ class VarRefCollector(ast.NodeVisitor):
|
|
30
31
|
|
31
32
|
|
32
33
|
class QuantumExpressionOperation(QuantumOperation):
|
33
|
-
|
34
|
-
description="The expression in terms of quantum variables"
|
35
|
-
)
|
34
|
+
expression: Expression = pydantic.Field()
|
36
35
|
result_var: HandleBinding = pydantic.Field(
|
37
36
|
description="The variable storing the expression result"
|
38
37
|
)
|
38
|
+
_var_handles: List[HandleBinding] = pydantic.PrivateAttr(
|
39
|
+
default_factory=list,
|
40
|
+
)
|
39
41
|
_var_types: Dict[str, QuantumType] = pydantic.PrivateAttr(
|
40
42
|
default_factory=dict,
|
41
43
|
)
|
@@ -45,9 +47,10 @@ class QuantumExpressionOperation(QuantumOperation):
|
|
45
47
|
|
46
48
|
@property
|
47
49
|
def var_handles(self) -> List[HandleBinding]:
|
48
|
-
|
49
|
-
|
50
|
-
|
50
|
+
return self._var_handles
|
51
|
+
|
52
|
+
def set_var_handles(self, var_handles: List[HandleBinding]) -> None:
|
53
|
+
self._var_handles = var_handles
|
51
54
|
|
52
55
|
@property
|
53
56
|
def var_types(self) -> Dict[str, QuantumType]:
|