Skip to content
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

Fix connection graph and truncate #70

Merged
merged 8 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading