Skip to content

Commit

Permalink
feat(barrier): add support for barrier meta instruction (#56)
Browse files Browse the repository at this point in the history
* chore(deps): update pydantic

* feat(barrier): add support for barrier meta instruction

* fix: include barriers under OpType

* fix: allow blocks inside the branches of conditionals
  • Loading branch information
qartik authored Feb 1, 2024
1 parent 1b154b1 commit aedff0c
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ repos:
- black==23.10.1

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.14
rev: v0.1.15
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Expand Down
26 changes: 22 additions & 4 deletions phir/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,24 @@ class ExportVar(Data):

DataMgmt: TypeAlias = CVarDefine | QVarDefine | ExportVar

# Meta Instructions


class Meta(BaseModel, abc.ABC):
"""Meta instructions base class."""

model_config = ConfigDict(extra="forbid")

meta: str


class Barrier(Meta):
"""Barrier instruction."""

meta: Literal["barrier"]
args: list[Bit]


# Operations


Expand Down Expand Up @@ -243,14 +261,14 @@ class MOp(Op):


QOp: TypeAlias = MeasOp | SQOp | TQOp
OpType: TypeAlias = FFCall | COp | QOp | MOp
OpType: TypeAlias = FFCall | COp | QOp | MOp | Barrier


# Blocks


class Block(BaseModel, abc.ABC):
"""General block type."""
"""Base class for block type."""

model_config = ConfigDict(extra="forbid")

Expand All @@ -277,8 +295,8 @@ class IfBlock(Block):

block: Literal["if"]
condition: COp
true_branch: list[OpType]
false_branch: list[OpType] | None = None
true_branch: list[OpType | BlockType]
false_branch: list[OpType | BlockType] | None = None


BlockType: TypeAlias = SeqBlock | QParBlock | IfBlock
Expand Down
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ autodoc-pydantic==2.0.1
build==1.0.3
mypy==1.8.0
pre-commit==3.6.0
pydantic==2.5.3
pydantic==2.6.0
pydata_sphinx_theme==0.15.2
pytest==8.0.0
rich==13.7.0
ruff==0.1.14
ruff==0.1.15
setuptools-scm==8.0.4
sphinx==7.2.6
wheel==0.42.0
4 changes: 2 additions & 2 deletions ruff.toml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ select = [
"YTT", # flake8-2020
]

ignore = ["COM812", "ISC001"] # conflicting with the formatter

[per-file-ignores]
"__init__.py" = ["F401", "CPY001"]
"docs/*" = [
Expand All @@ -71,8 +73,6 @@ select = [
"INP001",
]

ignore = ["COM812", "ISC001"] # conflicting with the formatter

[pydocstyle]
convention = "google"

Expand Down
64 changes: 64 additions & 0 deletions schema.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
{
"$defs": {
"Barrier": {
"additionalProperties": false,
"description": "Barrier instruction.",
"properties": {
"meta": {
"const": "barrier",
"title": "Meta"
},
"args": {
"items": {
"maxItems": 2,
"minItems": 2,
"prefixItems": [
{
"type": "string"
},
{
"minimum": 0,
"type": "integer"
}
],
"type": "array"
},
"title": "Args",
"type": "array"
}
},
"required": [
"meta",
"args"
],
"title": "Barrier",
"type": "object"
},
"COp": {
"additionalProperties": false,
"description": "Classical operation.",
Expand Down Expand Up @@ -374,6 +408,18 @@
},
{
"$ref": "#/$defs/MOp"
},
{
"$ref": "#/$defs/Barrier"
},
{
"$ref": "#/$defs/SeqBlock"
},
{
"$ref": "#/$defs/QParBlock"
},
{
"$ref": "#/$defs/IfBlock"
}
]
},
Expand Down Expand Up @@ -402,6 +448,18 @@
},
{
"$ref": "#/$defs/MOp"
},
{
"$ref": "#/$defs/Barrier"
},
{
"$ref": "#/$defs/SeqBlock"
},
{
"$ref": "#/$defs/QParBlock"
},
{
"$ref": "#/$defs/IfBlock"
}
]
},
Expand Down Expand Up @@ -776,6 +834,9 @@
{
"$ref": "#/$defs/MOp"
},
{
"$ref": "#/$defs/Barrier"
},
{
"$ref": "#/$defs/SeqBlock"
},
Expand Down Expand Up @@ -966,6 +1027,9 @@
{
"$ref": "#/$defs/MOp"
},
{
"$ref": "#/$defs/Barrier"
},
{
"$ref": "#/$defs/SeqBlock"
},
Expand Down
18 changes: 18 additions & 0 deletions spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,24 @@ bitwise/logical operations, or comparisons between two variables and/or bits. In
*Note:* While PHIR/PECOS can effectively manage nested if/else statements, extended OpenQASM 2.0 strictly permits only
non-nested if statements. Consequently, such nesting should be sidestepped when converting from OpenQASM 2.0 to PHIR.

## Meta Instructions

Instructions that communicate information such as a compiler hints and debugging commands that have influence beyond
a quantum program.

### Barrier

A barrier instruction provides a hint to the compiler/emulator that qubits involved in barrier may not be optimized or
parallelized across the barrier. Effectively, it enforces an ordering in time for how quantum state is manipulated by
the machine.

```json5
{
"meta": "barrier",
"args": [qubit_id, ...] // list of qubit IDs
}
```

## Overall PHIR Example with Quantinuum's Extended OpenQASM 2.0

A simple quantum program might look like:
Expand Down
54 changes: 54 additions & 0 deletions tests/cond_barrier_qparallel.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"format": "PHIR/JSON",
"version": "0.1.0",
"metadata": { "strict_parallelism": "true" },
"ops": [
{
"data": "qvar_define",
"data_type": "qubits",
"variable": "q",
"size": 2
},
{ "data": "cvar_define", "data_type": "u32", "variable": "m", "size": 2 },
{
"block": "sequence",
"ops": [
{
"block": "if",
"condition": { "cop": "==", "args": ["m", 0] },
"true_branch": [
{
"meta": "barrier",
"args": [
["q", 0],
["q", 1]
]
}
]
},
{
"block": "if",
"condition": { "cop": "==", "args": ["m", 1] },
"true_branch": [
{
"block": "qparallel",
"ops": [
{ "qop": "SZdg", "args": [["q", 0]] },
{ "qop": "SZ", "args": [["q", 1]] }
]
}
],
"false_branch": [
{
"block": "qparallel",
"ops": [
{ "qop": "SZdg", "args": [["q", 0]] },
{ "qop": "SZ", "args": [["q", 1]] }
]
}
]
}
]
}
]
}
21 changes: 17 additions & 4 deletions tests/test_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#
##############################################################################

# mypy: disable-error-code="misc"

"""Basic validation tests."""

import json
Expand All @@ -14,9 +16,20 @@
from phir.model import PHIRModel


def test_spec_example() -> None: # noqa: D103
# From https://github.com/CQCL/phir/blob/main/spec.md#overall-phir-example-with-quantinuums-extended-openqasm-20
def test_spec_example() -> None:
"""From https://github.com/CQCL/phir/blob/main/spec.md .
Specifically "Overall PHIR Example with Quantinuum's Extended OpenQASM 2.0"
"""
with Path("tests/example.json").open() as f:
data = json.load(f) # type: ignore [misc]
data = json.load(f)

PHIRModel.model_validate(data)


def test_conditional_barrier() -> None:
"""Checks for barriers and qparallel blocks inside conditionals."""
with Path("tests/cond_barrier_qparallel.json").open() as f:
data = json.load(f)

PHIRModel.model_validate(data) # type: ignore [misc]
PHIRModel.model_validate(data)

0 comments on commit aedff0c

Please sign in to comment.