Skip to content

Commit

Permalink
Fix connection graph and truncate (#70)
Browse files Browse the repository at this point in the history
* Fix incorrect mapping update for routing env from grid size (#68). (#69)

* Fix incorrect mapping update for routing env from grid size.

Relabel the nodes to be indexed when creating connection graph from grid size.

* Use networkx builtin function to convert node labels to integers.

* Styling

* Bugfix initial mappong truncation

* Update tests

* Bump version number

* update details Rares/Joris

* update paper publication details.

* Update root_docs

---------

Co-authored-by: jhenstra <[email protected]>
Co-authored-by: Willem de kok <[email protected]>
  • Loading branch information
3 people authored Feb 23, 2024
1 parent 5d190be commit b9047e6
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 40 deletions.
18 changes: 11 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,18 @@ Currently `qgym` has support for Python 3.7, 3.8, 3.9, 3.10 and 3.11.

## Publication
The paper on `qgym` has been presented in the [1st International Workshop on Quantum Machine Learning: From Foundations to Applications (QML@QCE'23)](https://qml.lfdr.de/2023/).
The publication can be found on [computer.org](https://www.computer.org/csdl/proceedings-article/qce/2023/432302a026/1SuQRWR5uCI)
You can find the preprint of the paper on [arxiv](https://arxiv.org/pdf/2308.02536.pdf).

```terminal
@article{van2023qgym,
@inproceedings{van2023qgym,
title={qgym: A Gym for training and benchmarking RL-based quantum compilation},
author={van der Linde, Stan and de Kok, Willem and Bontekoe, Tariq and Feld, Sebastian},
journal={arXiv preprint arXiv:2308.02536},
year={2023}
author={Van Der Linde, Stan and De Kok, Willem and Bontekoe, Tariq and Feld, Sebastian},
booktitle={2023 IEEE International Conference on Quantum Computing and Engineering (QCE)},
volume={2},
pages={26--30},
year={2023},
organization={IEEE}
}
```
## Team
Expand All @@ -46,6 +50,6 @@ Building qgym is a joint effort.
- [Tariq Bontekoe](https://nl.linkedin.com/in/tariq-bontekoe-53214817a)
- [Sebastian Feld](https://nl.linkedin.com/in/sebastian-feld?)

### Power users
- Joris Henstra
- Rares Oancea
### Contributors and Power Users
- [Joris Henstra](https://www.linkedin.com/in/jorishenstra/)
- [Rares Oancea](https://www.linkedin.com/in/rares-adrian-oancea-8a67b0204/)
21 changes: 12 additions & 9 deletions docs_files/templates/root_doc.rst_t
Original file line number Diff line number Diff line change
Expand Up @@ -45,15 +45,19 @@ Currently :obj:`~qgym` has support for Python 3.7, 3.8, 3.9, 3.10 and 3.11.
Publication
============
The paper on :obj:`~qgym` has been presented in the `1st International Workshop on Quantum Machine Learning: From Foundations to Applications (QML@QCE'23) <https://qml.lfdr.de/2023/>`_.
The publication can be found on `computer.org <https://www.computer.org/csdl/proceedings-article/qce/2023/432302a026/1SuQRWR5uCI>`_.
You can find the preprint of the paper on `arxiv <https://arxiv.org/pdf/2308.02536.pdf>`_.

.. code-block:: console

@article{van2023qgym,
@inproceedings{van2023qgym,
title={qgym: A Gym for training and benchmarking RL-based quantum compilation},
author={van der Linde, Stan and de Kok, Willem and Bontekoe, Tariq and Feld, Sebastian},
journal={arXiv preprint arXiv:2308.02536},
year={2023}
author={Van Der Linde, Stan and De Kok, Willem and Bontekoe, Tariq and Feld, Sebastian},
booktitle={2023 IEEE International Conference on Quantum Computing and Engineering (QCE)},
volume={2},
pages={26--30},
year={2023},
organization={IEEE}
}

Team
Expand All @@ -67,11 +71,10 @@ Core developers
- `Tariq Bontekoe <https://nl.linkedin.com/in/tariq-bontekoe-53214817a>`_
- `Sebastian Feld <https://nl.linkedin.com/in/sebastian-feld?>`_

Power users
------------
- Joris Henstra
- Rares Oancea

Contributors and Power Users
-----------------------------
- `Joris Henstra <https://www.linkedin.com/in/jorishenstra/>`_
- `Rares Oancea <https://www.linkedin.com/in/rares-adrian-oancea-8a67b0204/>`_

.. toctree::
:maxdepth: {{ mastertocmaxdepth }}
Expand Down
2 changes: 1 addition & 1 deletion qgym/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@
"""

__version__ = "0.2.0"
__version__ = "0.2.1"
2 changes: 1 addition & 1 deletion qgym/envs/initial_mapping/initial_mapping_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def is_truncated(self) -> bool:
is truncated if the number of steps in the current episode is more than 10
times the number of nodes in the connection graph.
"""
return bool(self.steps_done < self.n_nodes * 10)
return bool(self.steps_done > self.n_nodes * 10)

def obtain_info(self) -> dict[str, Any]:
"""Obtain additional information.
Expand Down
8 changes: 6 additions & 2 deletions qgym/utils/input_parsing.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""This module contains function which parse user input.
With parsing we mean that the user input is validated and transformed to a predictable
format. In this way, user can give different input formats, but internally we are
format. In this way, user can give different input formats, but internally we are
assured that the data has the same format."""

from __future__ import annotations
Expand Down Expand Up @@ -105,7 +105,11 @@ def parse_connection_graph(

if grid_size is not None:
# Generate connection grid graph
return nx.grid_graph(grid_size)
graph = nx.grid_graph(grid_size)

# Relabel the nodes to be integers
graph = nx.convert_node_labels_to_integers(graph)
return graph

raise ValueError("No valid arguments for a connection graph were given")

Expand Down
7 changes: 5 additions & 2 deletions qgym/utils/input_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ def check_adjacency_matrix(adjacency_matrix: ArrayLike) -> NDArray[Any]:


def check_graph_is_valid_topology(graph: nx.Graph, name: str) -> None:
"""Check if `graph` with name 'name' is an instance of ``networkx.Graph`` and check
if the graph is valid topology graph.
"""Check if `graph` with name 'name' is an instance of ``networkx.Graph``, check
if the graph is valid topology graph and check if the nodes are integers.
Args:
graph: Graph to check.
Expand All @@ -226,6 +226,9 @@ def check_graph_is_valid_topology(graph: nx.Graph, name: str) -> None:
if len(graph) == 0:
raise ValueError(f"'{name}' has no nodes")

if any(not isinstance(node, int) for node in graph):
raise TypeError(f"'{name}' has nodes that are not integers")


def check_instance(x: Any, name: str, dtype: type) -> None:
"""Check if `x` with name 'name' is an instance of dtype.
Expand Down
31 changes: 26 additions & 5 deletions tests/envs/initial_mapping/test_initial_mapping_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,32 @@ def small_env(small_graph: nx.Graph) -> InitialMapping:
return InitialMapping(0.5, connection_graph=small_graph)


def test_validity(small_env: InitialMapping) -> None:
check_env(
small_env, warn=True
) # todo: maybe switch this to the gymnasium env checker
assert True
class TestEnvironment:

def test_validity(self, small_env: InitialMapping) -> None:
# todo: maybe switch this to the gymnasium env checker
check_env(small_env, warn=True)

def test_episode(self, small_env: InitialMapping):
obs, reward, is_done, truncated, _ = small_env.step(np.array([0, 1]))
np.testing.assert_array_equal(obs["mapping"], [1, 2])
assert reward == 0
assert not is_done
assert not truncated

obs, reward, is_done, truncated, _ = small_env.step(np.array([1, 0]))
np.testing.assert_array_equal(obs["mapping"], [1, 0])
assert is_done
assert not truncated

def test_truncation(self, small_env: InitialMapping):
truncated = False
for _ in range(10000):
_, _, is_done, truncated, _ = small_env.step(np.array([0, 0]))
if is_done or truncated:
break
assert not is_done
assert truncated


@pytest.mark.parametrize(
Expand Down
13 changes: 10 additions & 3 deletions tests/envs/routing/test_routing_env.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import numpy as np
import pytest
from stable_baselines3.common.env_checker import check_env

Expand All @@ -19,6 +20,12 @@
},
],
)
def test_validity(kwargs: dict[str, tuple[int, int] | bool]) -> None:
env = Routing(**kwargs) # type: ignore[arg-type]
check_env(env, warn=True) # todo: maybe switch this to the gym env checker
class TestEnvironment:
def test_validity(self, kwargs: dict[str, tuple[int, int] | bool]) -> None:
env = Routing(**kwargs) # type: ignore[arg-type]
check_env(env, warn=True) # todo: maybe switch this to the gym env checker

def test_step(self, kwargs):
env = Routing(**kwargs) # type: ignore[arg-type]
obs = env.step(0)[0]
np.testing.assert_array_equal(obs["mapping"], [2, 1, 0, 3])
32 changes: 22 additions & 10 deletions tests/utils/test_input_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,19 +153,31 @@ def test_check_adjacency_matrix_errors(self, arg: Any) -> None:
check_adjacency_matrix(arg)


def test_check_graph_is_valid_topology() -> None:
graph = nx.Graph()
msg = "'test' has no nodes"
with pytest.raises(ValueError, match=msg):
class TestGraphValidTopology:
def test_empty_graph(self) -> None:
graph = nx.Graph()
msg = "'test' has no nodes"
with pytest.raises(ValueError, match=msg):
check_graph_is_valid_topology(graph, "test")

def test_line_graph(self) -> None:
graph = nx.cycle_graph(2)
check_graph_is_valid_topology(graph, "test")

graph.add_edge(1, 2)
check_graph_is_valid_topology(graph, "test")
def test_self_loop(self) -> None:
graph = nx.Graph()
graph.add_edge(1, 1)
msg = "'test' contains self-loops"
with pytest.raises(ValueError, match=msg):
check_graph_is_valid_topology(graph, "test")

def test_non_int_label(self) -> None:
graph = nx.Graph()
graph.add_node((0, 0))

graph.add_edge(1, 1)
msg = "'test' contains self-loops"
with pytest.raises(ValueError, match=msg):
check_graph_is_valid_topology(graph, "test")
msg = "'test' has nodes that are not integers"
with pytest.raises(TypeError, match=msg):
check_graph_is_valid_topology(graph, "test")


class TestCheckInstance:
Expand Down

0 comments on commit b9047e6

Please sign in to comment.