Skip to content

Commit

Permalink
Add basic routine visualization and update README (#4)
Browse files Browse the repository at this point in the history
* Implement rendering to graphviz DAG

* Minor style fixes

* Add script for rendering serialized diagram

* Rename: hqar.experimental.visualization -> hqar.experimental.rendering

* Add flake8-copyright to pre-commit hooks

* Move loading of valid test programs to fixture

* Fix typo

* Add tests for rendering

* Add graphviz to dependencies

* Add GH action step with graphviz setup

* Make mypy ignore graphviz errors

* Add good-enough initial README

* Expand README

* Explain hierarchy and DAG in README

* Remove unnecessary comment

* List visualization tool as one of features

* Reword tricky -> hacky

---------

Co-authored-by: Konrad Jałowiecki <[email protected]>
  • Loading branch information
dexter2206 and Konrad Jałowiecki authored Mar 25, 2024
1 parent 46a8fd8 commit 057e39b
Show file tree
Hide file tree
Showing 20 changed files with 694 additions and 125 deletions.
5 changes: 4 additions & 1 deletion .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,7 @@ ignore =
per-file-ignores =
tests/**/test_*.py:D103,D102,D101
__init__.py:F401

copyright-check = True
copyright-regexp = Copyright\s+(©\s+)?\d{4}([-,]\d{4})*\s+%(author)s
copyright-author = PsiQuantum Corp.
copyright-min-file-size = 1
2 changes: 2 additions & 0 deletions .github/workflows/quality_checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Setup Graphviz
uses: ts-graphviz/setup-graphviz@v2
- name: Install dependencies and the package
run: |
python -m pip install --upgrade pip poetry
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ repos:
rev: 6.0.0
hooks:
- id: flake8

additional_dependencies: [flake8-copyright]
143 changes: 141 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,141 @@
# hqar
Hierarchical Quantum Algorithms Representation
# HQAR
Hierarchical Quantum Algorithms Representation is an open format for representing
quantum algorithms, optimized for usage in quantum resource estimation (QRE).

HQAR comprises:

- Definition of data format, formalized as a JSON schema.
- A Python library for validation of quantum programs written in HQAR format using [Pydantic](https://docs.pydantic.dev/).
- Rudimentary visualization tool `hqar-render`.

## Installation

Using HQAR data format does not require installation - you can easily write quantum
programs in YAML or JSON.

To install HQAR Python package, clone this repository and install it as usual with `pip`:

```bash
# Clone HQAR repo (you can use HTTP link as well)
git clone [email protected]:PsiQ/hqar.git
cd hqar
pip install .
```

## HQAR format

HQAR format represents quantum programs as a hierarchical directed acyclic graphs (DAGs).
That's a mouthful, so let us unpack what it means:

- *hierarchical*: each node can contain subgraphs, i.e. routines can be nested inside
larger routines.
- *directed*: information flow is unidirectional, and the direction is unambiguous.
- *acyclic*: meaning there are no loops.

Consider the following hierarchical DAG of a hypothetical quantum program:

![program example](example_routine.svg)

It can be succinctly written in HQAR format as:


```yaml
version: v1
program:
name: my_algorithm
ports:
- direction: input
name: in_0
size: 2
- direction: input
name: in_1
size: 2
- direction: output
name: out_0
size: 4
children:
- name: subroutine_1
ports:
- direction: input
name: in_0
size: 2
- direction: output
name: out_0
size: 3
- name: subroutine_2
ports:
- direction: input
name: in_0
size: 2
- direction: output
name: out_0
size: 1
- direction: output
name: out_1
size: 1
- name: merge
ports:
- direction: input
name: in_0
size: 1
- direction: input
name: in_1
size: 1
- direction: input
name: in_2
size: 2
- direction: output
name: out_0
size: 4
connections:
- source: in_0
target: subroutine_1.in_0
- source: in_1
target: subroutine_2.in_0
- source: subroutine_1.out_0
target: merge.in_2
- source: subroutine_2.out_0
target: merge.in_0
- source: subroutine_2.out_1
target: merge.in_1
- source: merge.out_0
target: out_0
```
For full description of HQAR format, check our [docs](https://example.com).
## Using HQAR package
### Using JSON schema for validating data in HQAR format
JSON schema for HQAR format can be obtained by calling `generate_program_schema` function.
Such schema can be then used for validating user's input, e.g. using `jsonschema` package:

```python
from jsonschema import validate
from hqar import generate_program_schema
# Hypothetical function loading your data as native Python dictionary.
data = load_some_program()
schema = generate_program_schema()
# This will raise if there are some validation errors.
validate(schema, data)
```

### Validation using Pydantic models

If you are familiar with Pydantic, you might find it easier to work with HQAR Pydantic
models instead of interacting with JSON schema directly. In the example below, we create
an instance of `SchemaV1` model from validated data stored in HQAR format:

```python
from hqar import SchemaV1
data = load_some_program()
# This will raise if data is not valid
program = SchemaV1.model_validate(data)
```

107 changes: 107 additions & 0 deletions example_routine.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 60 additions & 0 deletions example_routine.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
version: v1
program:
name: my_algorithm
ports:
- direction: input
name: in_0
size: 2
- direction: input
name: in_1
size: 2
- direction: output
name: out_0
size: 4
children:
- name: subroutine_1
ports:
- direction: input
name: in_0
size: 2
- direction: output
name: out_0
size: 3
- name: subroutine_2
ports:
- direction: input
name: in_0
size: 2
- direction: output
name: out_0
size: 1
- direction: output
name: out_1
size: 1
- name: merge
ports:
- direction: input
name: in_0
size: 1
- direction: input
name: in_1
size: 1
- direction: input
name: in_2
size: 2
- direction: output
name: out_0
size: 4
connections:
- source: in_0
target: subroutine_1.in_0
- source: in_1
target: subroutine_2.in_0
- source: subroutine_1.out_0
target: merge.in_2
- source: subroutine_2.out_0
target: merge.in_0
- source: subroutine_2.out_1
target: merge.in_1
- source: merge.out_0
target: out_0
18 changes: 17 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ readme = "README.md"
[tool.poetry.dependencies]
python = "^3.9"
pydantic = "^2.0"
graphviz = "^0.20.3"


[tool.poetry.group.dev.dependencies]
Expand All @@ -19,6 +20,11 @@ black = "^24.2.0"
pyyaml = "^6"
jsonschema = "^4"


[tool.poetry.scripts]
hqar-render = "hqar.experimental.rendering:render_entry_point"


[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Expand All @@ -27,3 +33,8 @@ build-backend = "poetry.core.masonry.api"
[tool.black]
line-length = 100
target-version = ['py39']


[[tool.mypy.overrides]]
module = "graphviz.*"
ignore_missing_imports = true
Loading

0 comments on commit 057e39b

Please sign in to comment.