-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #112 from QunaSys/circuit_model
- Loading branch information
Showing
12 changed files
with
182 additions
and
156 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import dataclasses | ||
from collections import deque | ||
from itertools import chain | ||
from typing import Deque, List, Optional, Sequence, Tuple | ||
|
||
import dataclasses_json | ||
|
||
|
||
@dataclasses_json.dataclass_json | ||
@dataclasses.dataclass | ||
class ControlQubitInfo: | ||
index: int | ||
control_value: int | ||
|
||
|
||
@dataclasses_json.dataclass_json | ||
@dataclasses.dataclass | ||
class GateData: | ||
name: str | ||
target_bits: List[int] = dataclasses.field(default_factory=list) | ||
control_bit_infos: List[ControlQubitInfo] = dataclasses.field(default_factory=list) | ||
|
||
@property | ||
def indices(self) -> Tuple[int, ...]: | ||
return tuple(chain(self.target_bits, (c.index for c in self.control_bit_infos))) | ||
|
||
@property | ||
def max_index(self) -> int: | ||
return max(self.indices) | ||
|
||
@property | ||
def min_index(self) -> int: | ||
return min(self.indices) | ||
|
||
|
||
GateDataSeq = Sequence[Sequence[GateData]] | ||
|
||
|
||
@dataclasses_json.dataclass_json | ||
@dataclasses.dataclass | ||
class CircuitData: | ||
qubit_count: int | ||
layer_count: int | ||
gates: GateDataSeq | ||
|
||
@staticmethod | ||
def from_gate_sequence( | ||
gates: Sequence[GateData], qubit_count: Optional[int] = None | ||
) -> "CircuitData": | ||
""" | ||
Construct a CircuitData model from a list of gates. | ||
Parameters | ||
---------- | ||
gates : Sequence[GateData] | ||
List of gates | ||
qubit_count : int optional | ||
Number of qubits this quantum circuit has | ||
Returns | ||
------- | ||
CircuitData : CircuitData | ||
Constructed CircuitData model | ||
""" | ||
if qubit_count is None: | ||
qubit_count = max(g.max_index for g in gates) | ||
temp_lines: List[Deque[GateData]] = [deque() for _ in range(qubit_count)] | ||
for gate in gates: | ||
_align_layers(temp_lines, gate.min_index, gate.max_index) | ||
for index in range(gate.min_index, gate.max_index + 1): | ||
line = temp_lines[index] | ||
if index == gate.target_bits[0]: | ||
line.append(gate) | ||
elif index in gate.target_bits: | ||
line.append(GateData("ghost")) | ||
else: | ||
line.append(GateData("wire")) | ||
|
||
_align_layers(temp_lines, 0, qubit_count) | ||
layer_count = len(temp_lines[0]) | ||
return CircuitData( | ||
qubit_count=qubit_count, | ||
layer_count=layer_count, | ||
gates=[list(queue) for queue in temp_lines], | ||
) | ||
|
||
|
||
def _align_layers( | ||
lines: Sequence[Deque[GateData]], min_line_index: int, max_line_index: int | ||
) -> None: | ||
""" | ||
Align layer sizes for a specified range of rows. | ||
Parameters | ||
---------- | ||
lines: Sequence[Deque[GateData]] | ||
Circuit data during parsing without layer length alignment | ||
min_line_index : int | ||
Minimum row index to be aligned. | ||
max_line_index : int | ||
Maximum row index to be aligned. | ||
""" | ||
if min_line_index > max_line_index: | ||
min_line_index, max_line_index = max_line_index, min_line_index | ||
lines = lines[min_line_index : max_line_index + 1] | ||
layer_counts = [len(queue) for queue in lines] | ||
max_layer_count = max(layer_counts) | ||
|
||
for queue, layer_count in zip(lines, layer_counts): | ||
for _ in range(max_layer_count - layer_count): | ||
queue.append(GateData("wire")) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from qulacs import QuantumCircuit | ||
|
||
from ..models.circuit import CircuitData, ControlQubitInfo, GateData | ||
|
||
|
||
def to_model(circuit: QuantumCircuit) -> CircuitData: | ||
qubit_count = circuit.get_qubit_count() | ||
gates = [] | ||
|
||
for position in range(circuit.get_gate_count()): | ||
gate = circuit.get_gate(position) | ||
target_index_list = gate.get_target_index_list() | ||
control_index_value_list = [ | ||
ControlQubitInfo(index, control_value) | ||
for index, control_value in gate.get_control_index_value_list() | ||
] | ||
gate_name = gate.get_name() | ||
gates.append(GateData(gate_name, target_index_list, control_index_value_list)) | ||
|
||
return CircuitData.from_gate_sequence(gates, qubit_count) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.