Skip to content

Conversation

gluonhiggs
Copy link
Contributor

To resolve #840
I have added a stepping stone for graphml serialization, but I think I need more reviews on this to resolve the first part of the issue. Because this is a little bit different to other rustworkx functions for graph calculations, please elaborate what I should do next.

@coveralls
Copy link

Pull Request Test Coverage Report for Build 15484870606

Details

  • 1 of 239 (0.42%) changed or added relevant lines in 2 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-1.1%) to 94.156%

Changes Missing Coverage Covered Lines Changed/Added Lines %
src/graphml.rs 0 238 0.0%
Totals Coverage Status
Change from base Build 15448809297: -1.1%
Covered Lines: 18963
Relevant Lines: 20140

💛 - Coveralls

@IvanIsCoding
Copy link
Collaborator

I will give a more detailed review later, but definitely check if you can reuse any https://github.com/jonasbb/petgraph-graphml either by importing the library or forking some of the code.

thierry-martinez added a commit to thierry-martinez/rustworkx that referenced this pull request Jun 9, 2025
This commit adds a GraphML serializer:

```python
def write_graphml(
    graphs: list[PyGraph | PyDiGraph],
    keys: list[tuple[str, Domain, str, Type, Any]],
    path: str,
    /,
    compression: str | None = ...,
) -> None: ...
```

`keys` is a list of tuples: id, domain, name of the key, type, and
default value. This commit also introduces the
`read_graphml_with_keys` function, which returns the key definitions
in the same format, along with the list of parsed graphs.

The implementation preserves the ids of graphs, nodes, and edges when
possible. If some ids conflict, fresh ids are generated in the written
GraphML file. The `read_graphml` function has also been updated to
store the graph id in the graph attributes, just like node and edge
ids are stored in the corresponding attributes.

The `write_graphml` function supports gzip compression, as does
`read_graphml`.

Note that the JSON node-link serializer (the other part of Qiskit#840) was
already implemented in Qiskit#1091.

Compared to Qiskit#1462:

- Keys are passed explicitly instead of being inferred (which allows
to use the types `float` and `int`, and to use default values);

- Attributes for graphs, nodes, and edges are taken from the weight of elements, instead of relying on callbacks. This allows write_graphml to act as a proper reciprocal of read_graphml. Round-trip tests have been added.

- IDs are taken from attributes when possible, instead of being generated from indices.

- Multiple graphs can be written to the same file.

- Gzip compression is supported.

- Tests have been added.

Regarding @IvanIsCoding's
comment (Qiskit#1462 (comment)),
about using https://github.com/jonasbb/petgraph-graphml:

- Rustworkx's `graphml.rs` introduces an internal `Graph` data
structure, which is used for `read_graphml`. It is natural to
have `write_graphml` rely on the same data structure.

- `petgraph-graphml` generates ids from indices, which prevents us
from preserving ids accross the `read_graphml`/`write_graphml` round
trip.
@1ucian0
Copy link
Member

1ucian0 commented Jun 10, 2025

if you can reuse any https://github.com/jonasbb/petgraph-graphml either by importing the library or forking some of the code.

If you bring code from petgraph-graphml, remember to follow the license terms.

@IvanIsCoding
Copy link
Collaborator

Thanks for writing this! After reviewing #1464, I will be candid the chances of it getting merged are higher than this PR as #1464 reuses our existing code and already has unit tests baked into it.

For the purpose of optimizing Unitary Hack bounties, I'd suggest focusing on #1463 as you are currently the only assignee working on that task.

@gluonhiggs
Copy link
Contributor Author

I agree! I believe #1464 has covered more than what I have done in this PR.
p/s: is there anything else I should do in #1463 @IvanIsCoding ?

@1ucian0
Copy link
Member

1ucian0 commented Jun 16, 2025

Closing this PR in favor of #1464 . Thanks!

@1ucian0 1ucian0 closed this Jun 16, 2025
github-merge-queue bot pushed a commit that referenced this pull request Jun 17, 2025
* Fix #840: Add GraphML serializer

This commit adds a GraphML serializer:

```python
def write_graphml(
    graphs: list[PyGraph | PyDiGraph],
    keys: list[tuple[str, Domain, str, Type, Any]],
    path: str,
    /,
    compression: str | None = ...,
) -> None: ...
```

`keys` is a list of tuples: id, domain, name of the key, type, and
default value. This commit also introduces the
`read_graphml_with_keys` function, which returns the key definitions
in the same format, along with the list of parsed graphs.

The implementation preserves the ids of graphs, nodes, and edges when
possible. If some ids conflict, fresh ids are generated in the written
GraphML file. The `read_graphml` function has also been updated to
store the graph id in the graph attributes, just like node and edge
ids are stored in the corresponding attributes.

The `write_graphml` function supports gzip compression, as does
`read_graphml`.

Note that the JSON node-link serializer (the other part of #840) was
already implemented in #1091.

Compared to #1462:

- Keys are passed explicitly instead of being inferred (which allows
to use the types `float` and `int`, and to use default values);

- Attributes for graphs, nodes, and edges are taken from the weight of elements, instead of relying on callbacks. This allows write_graphml to act as a proper reciprocal of read_graphml. Round-trip tests have been added.

- IDs are taken from attributes when possible, instead of being generated from indices.

- Multiple graphs can be written to the same file.

- Gzip compression is supported.

- Tests have been added.

Regarding @IvanIsCoding's
comment (#1462 (comment)),
about using https://github.com/jonasbb/petgraph-graphml:

- Rustworkx's `graphml.rs` introduces an internal `Graph` data
structure, which is used for `read_graphml`. It is natural to
have `write_graphml` rely on the same data structure.

- `petgraph-graphml` generates ids from indices, which prevents us
from preserving ids accross the `read_graphml`/`write_graphml` round
trip.

* Fix clippy comments

* Prefix types with GraphML

Suggested by @IvanIsCoding: #1464 (comment)

* Black

* Add release notes

* Fix stubs error

* Add documentation

* Remove read_graphml_with_keys / write_graphml for single graph only

* Use `DictMap` everywhere

Suggested by @IvanIsCoding: #1464 (comment)

* rustfmt and clippy

* Remove unused math module (ruff check)

* Use `from __future__ import annotations` for Python <3.10

* Add stub for `write_graphml`

* Remove `read_graphml_with_keys` from documentation

* Apply suggestions from code review

* Update rustworkx/__init__.py

* Apply suggestions from code review

---------

Co-authored-by: Ivan Carvalho <8753214+IvanIsCoding@users.noreply.github.com>
SILIZ4 pushed a commit to SILIZ4/rustworkx that referenced this pull request Jul 4, 2025
* Fix Qiskit#840: Add GraphML serializer

This commit adds a GraphML serializer:

```python
def write_graphml(
    graphs: list[PyGraph | PyDiGraph],
    keys: list[tuple[str, Domain, str, Type, Any]],
    path: str,
    /,
    compression: str | None = ...,
) -> None: ...
```

`keys` is a list of tuples: id, domain, name of the key, type, and
default value. This commit also introduces the
`read_graphml_with_keys` function, which returns the key definitions
in the same format, along with the list of parsed graphs.

The implementation preserves the ids of graphs, nodes, and edges when
possible. If some ids conflict, fresh ids are generated in the written
GraphML file. The `read_graphml` function has also been updated to
store the graph id in the graph attributes, just like node and edge
ids are stored in the corresponding attributes.

The `write_graphml` function supports gzip compression, as does
`read_graphml`.

Note that the JSON node-link serializer (the other part of Qiskit#840) was
already implemented in Qiskit#1091.

Compared to Qiskit#1462:

- Keys are passed explicitly instead of being inferred (which allows
to use the types `float` and `int`, and to use default values);

- Attributes for graphs, nodes, and edges are taken from the weight of elements, instead of relying on callbacks. This allows write_graphml to act as a proper reciprocal of read_graphml. Round-trip tests have been added.

- IDs are taken from attributes when possible, instead of being generated from indices.

- Multiple graphs can be written to the same file.

- Gzip compression is supported.

- Tests have been added.

Regarding @IvanIsCoding's
comment (Qiskit#1462 (comment)),
about using https://github.com/jonasbb/petgraph-graphml:

- Rustworkx's `graphml.rs` introduces an internal `Graph` data
structure, which is used for `read_graphml`. It is natural to
have `write_graphml` rely on the same data structure.

- `petgraph-graphml` generates ids from indices, which prevents us
from preserving ids accross the `read_graphml`/`write_graphml` round
trip.

* Fix clippy comments

* Prefix types with GraphML

Suggested by @IvanIsCoding: Qiskit#1464 (comment)

* Black

* Add release notes

* Fix stubs error

* Add documentation

* Remove read_graphml_with_keys / write_graphml for single graph only

* Use `DictMap` everywhere

Suggested by @IvanIsCoding: Qiskit#1464 (comment)

* rustfmt and clippy

* Remove unused math module (ruff check)

* Use `from __future__ import annotations` for Python <3.10

* Add stub for `write_graphml`

* Remove `read_graphml_with_keys` from documentation

* Apply suggestions from code review

* Update rustworkx/__init__.py

* Apply suggestions from code review

---------

Co-authored-by: Ivan Carvalho <8753214+IvanIsCoding@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add reverse direction serialization
4 participants