-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CQT-250 add barrier directives #370
base: develop
Are you sure you want to change the base?
Changes from 13 commits
ff86d73
cf5e51f
7b18e6e
3d3ba5f
c134201
49fcf63
39627a0
db14c43
62c395f
c79b3c1
6d46c43
4594653
31814d5
701cf0a
7961238
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from opensquirrel.ir import Barrier, QubitLike, named_directive | ||
|
||
|
||
@named_directive | ||
def barrier(q: QubitLike) -> Barrier: | ||
return Barrier(q) | ||
|
||
|
||
default_directive_set = [barrier] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,18 @@ | ||
from __future__ import annotations | ||
|
||
import functools | ||
import operator | ||
from math import acos, cos, floor, log10, sin | ||
from typing import TYPE_CHECKING, Any | ||
|
||
import numpy as np | ||
|
||
from opensquirrel.circuit import Circuit | ||
from opensquirrel.common import ATOL | ||
from opensquirrel.default_gates import I, default_bloch_sphere_rotations_without_params | ||
from opensquirrel.ir import BlochSphereRotation, Comment, Qubit | ||
from opensquirrel.ir import Barrier, BlochSphereRotation, Comment, Qubit, Statement | ||
|
||
if TYPE_CHECKING: | ||
from opensquirrel.circuit import Circuit | ||
|
||
|
||
def compose_bloch_sphere_rotations(a: BlochSphereRotation, b: BlochSphereRotation) -> BlochSphereRotation: | ||
|
@@ -79,6 +86,41 @@ def try_name_anonymous_bloch(bsr: BlochSphereRotation) -> BlochSphereRotation: | |
return bsr | ||
|
||
|
||
def _flatten_list(list_to_flatten: list[list[Any]]) -> list[Any]: | ||
return functools.reduce(operator.iadd, list_to_flatten, []) | ||
|
||
|
||
def merge_barriers(statement_list: list[Statement]) -> list[Statement]: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there is a problem with this code, and it shows in the first test,
We should end up with:
Right? Correct me if I'm wrong. Because However, because of the way this code works, we end up with:
Why does the code behave like that? Because, even if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At face value, the following result is permitted, given the meaning of the barriers:
including optimization this would become:
But since both restructurings influence the order of statements and such processing should be contained within a (rudimentary) Scheduling pass, which is not part of OpenSquirrel atm, the resulting expected result should be:
(basically no change... it couldn't be easier 😅 :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Can you explain what's "the strategy of merging the barriers"?
But there is no barrier wall in the input code. There are two separate barriers. The only reason |
||
"""Receives a list of statements. | ||
Returns an ordered version of the input list of statements where groups of barriers are merged together, | ||
and placed as late in the list as possible. | ||
|
||
Args: | ||
statement_list: list of statements | ||
|
||
Returns: | ||
Statement list with the barriers merged. | ||
""" | ||
barrier_list: list[Barrier] = [] | ||
ordered_statement_list: list[Statement] = [] | ||
for _, statement in enumerate(statement_list): | ||
juanboschero marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if isinstance(statement, Barrier): | ||
barrier_list.append(statement) | ||
else: | ||
if len(barrier_list) > 0 and hasattr(statement, "get_qubit_operands"): | ||
rturrado marked this conversation as resolved.
Show resolved
Hide resolved
|
||
instruction_qubits = statement.get_qubit_operands() | ||
barrier_qubits = _flatten_list([barrier.get_qubit_operands() for barrier in barrier_list]) | ||
if any(qubit in barrier_qubits for qubit in instruction_qubits): | ||
ordered_statement_list.extend(barrier_list) | ||
barrier_list = [] | ||
ordered_statement_list.append(statement) | ||
|
||
if len(barrier_list) > 0: | ||
ordered_statement_list.extend(barrier_list) | ||
|
||
return ordered_statement_list | ||
|
||
|
||
def merge_single_qubit_gates(circuit: Circuit) -> None: | ||
"""Merge all consecutive 1-qubit gates in the circuit. | ||
|
||
|
@@ -126,3 +168,5 @@ def merge_single_qubit_gates(circuit: Circuit) -> None: | |
if accumulated_bloch_sphere_rotation.is_anonymous: | ||
accumulated_bloch_sphere_rotation = try_name_anonymous_bloch(accumulated_bloch_sphere_rotation) | ||
ir.statements.append(accumulated_bloch_sphere_rotation) | ||
|
||
ir.statements = merge_barriers(circuit.ir.statements) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add this function to a
utils/list.py
file (with aflatten_list
name). This is a function that is probably going to be used from many places in the code, so it is useful to have it in a utilities file.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rename
utils/list_utils.py
toutils/list.py
.