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

Introduce retworkx-core crate #459

Merged
merged 29 commits into from
Oct 13, 2021
Merged

Introduce retworkx-core crate #459

merged 29 commits into from
Oct 13, 2021

Conversation

mtreinish
Copy link
Member

@mtreinish mtreinish commented Oct 9, 2021

This commit adds a new workspace crate to retworkx, retworkx-lib, which
contains a pure rust library built on top of petgraph for retworkx
algorithms and additional non-python specific data structures. Prior to
this we didn't really have a public rust API for retworkx as the main
output from the retworkx crate was a cdynlib for use with python. By
creating a new crate this gives us a place to enable rust reuse of the
library for functionality that is not specific to python. Any potential
functionality in retworkx-lib will need to be solely reusable in rust
without pyo3 or python.

The primary retworkx crate will still be primarily for the python
library. But for places where it makes sense to expose a rust api we can
use the retworkx-lib crate to export those for other rust usage.

Closes #108

TODO (probably for 0.12.0 Done)

  • Figure out why setuptools-rust doesn't like the new workspace
  • Add real API documentation (needed to close Native rust API documentation? #108)
  • Add retworkx-lib README
  • Migrate additional generic functions still in base retworkx crate
  • Add description of retworkx-lib and what code goes in it to the contributing docs

This commit adds a new workspace crate to retworkx, retworkx-lib, which
contains a pure rust library built on top of petgraph for retworkx
algorithms and additional non-python specific data structures. Prior to
this we didn't really have a public rust API for retworkx as the main
output from the retworkx crate was a cdynlib for use with python. By
creating a new crate this gives us a place to enable rust reuse of the
library for functionality that is not specific to python. Any potential
functionality in retworkx-lib will need to be solely reusable in rust
without pyo3 or python.

The primary retworkx crate will still be primarily for the python
library. But for places where it makes sense to expose a rust api we can
use the retworkx-lib crate to export those for other rust usage.

Closes Qiskit#108
The MANIFEST.in was missing the retworkx-lib crate directory which meant
when setuptools built the sdist it wasn't including the source for the
crate. So when setuptools-rust was called on building the sdist it
errors because it can't find the Cargo.toml for retworkx-lib or any of
the source.
@coveralls
Copy link

coveralls commented Oct 9, 2021

Pull Request Test Coverage Report for Build 1337196070

  • 332 of 334 (99.4%) changed or added relevant lines in 14 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.05%) to 98.406%

Changes Missing Coverage Covered Lines Changed/Added Lines %
retworkx-core/src/centrality.rs 227 229 99.13%
Totals Coverage Status
Change from base Build 1334930575: 0.05%
Covered Lines: 10371
Relevant Lines: 10539

💛 - Coveralls

@mtreinish mtreinish changed the title [WIP] Introduce retworkx-lib crate Introduce retworkx-lib crate Oct 10, 2021
@mtreinish
Copy link
Member Author

Ok, I think this is ready for review now. I've moved over all the current generic functions except for the dot generator because the generic version in petgraph is good enough if you don't need python.

@mtreinish mtreinish requested a review from georgios-ts October 10, 2021 18:26
@mtreinish
Copy link
Member Author

@jlapeyre this should introduce a standalone Rust library/API per our discussions in #418 and #108. This seemed like the cleanest way to do it, making a separate rust crate/package with the library API for the generic rust functionality built on top of petgraph. Then downstream rust users can just use retworkx-lib to get that rust api and the retwork crate remains solely the python pieces. I started by moving the existing generic functionality over to the lib crate here and we can expand it over time.

@mtreinish mtreinish removed the on hold label Oct 10, 2021
@mtreinish mtreinish requested a review from jlapeyre October 10, 2021 18:35
@jlapeyre
Copy link
Collaborator

Thanks for taking the initiative. I agree this is the right approach.

Copy link
Collaborator

@georgios-ts georgios-ts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for doing this! It definitely increases the value of retworkx project.

Besides the inline comments, graph traits in dfs_edges, betweeness_centrality and max_weight_matching can probably be simplified a bit (i.e we don't restrict G::NodeId = NodeIndex) but we can do this in a follow-up since this PR is getting quite large.

Another thing that we should discuss is testing. doc tests are nice. Do you think that we should also do some unit tests in retworkx-lib? I mean, testing both in Python and rust can slowdown a bit the development process.

Oh, and once we are ready i'd be really curious to run the benchmarks (https://github.com/mtreinish/retworkx-comparison-benchmarks) in pure rust to have an estimate of the Python overhead in cases we interact with python weights.

CONTRIBUTING.md Show resolved Hide resolved
retworkx-lib/src/dfs_edges.rs Outdated Show resolved Hide resolved
retworkx-lib/src/lib.rs Outdated Show resolved Hide resolved
retworkx-lib/src/lib.rs Outdated Show resolved Hide resolved
retworkx-lib/src/shortest_path/k_shortest_path.rs Outdated Show resolved Hide resolved
@mtreinish
Copy link
Member Author

Thanks for doing this! It definitely increases the value of retworkx project.

Besides the inline comments, graph traits in dfs_edges, betweeness_centrality and max_weight_matching can probably be simplified a bit (i.e we don't restrict G::NodeId = NodeIndex) but we can do this in a follow-up since this PR is getting quite large.

Yeah we can work on improving that in follow up PRs. We're not locked into an api until the 0.11.0 release so we have time to play with and tweak things. This PR is more about making sure we're happy with the split and setting things up to work with 2 crates.

Another thing that we should discuss is testing. doc tests are nice. Do you think that we should also do some unit tests in retworkx-lib? I mean, testing both in Python and rust can slowdown a bit the development process.

I think it's expected that we'll have rust unit tests in retworkx-lib (I mentioned this in the CONTRIBUTING.md section on retworkx-lib tests). I have CI setup to run all tests including doc tests as part of the first CI job now. I didn't add any additional tests on top of the doc strings in this PR mostly because we have coverage of it via python already and I was concerned about making the PR larger than it already is. But I think we should expect more thorough testing in future contributions the retworkx-lib.

Copy link
Collaborator

@georgios-ts georgios-ts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates!

One last thing is that we could define a type in retworkx-lib like

use std::convert::Infallible;

/// A convenient type alias that by default assumes no error can happen.
///
/// It can be used to avoid type annotations when the function you want
/// to use needs a callback that returns [`Result`] but in your case no
/// error can happen.
pub type Result<T, E = Infallible> = core::result::Result<T, E>;

and use this as the return type in places like the shortest path algorithms and max weight matching (and in the docs). Users can also use this in order to avoid giving dummy type hints to the compiler.

retworkx-lib/src/lib.rs Outdated Show resolved Hide resolved
retworkx-lib/src/shortest_path/k_shortest_path.rs Outdated Show resolved Hide resolved
@IvanIsCoding
Copy link
Collaborator

This is a great step forward! There are still some items we can untie from PyO3 (e.g. one of the Floyd-Warshalls), but just having retworkx-lib as is a big step.

I will take some time to review this because the expectations for Rust crates are different than those from Python libraries.

@mtreinish
Copy link
Member Author

mtreinish commented Oct 11, 2021

Thanks for the updates!

One last thing is that we could define a type in retworkx-lib like

use std::convert::Infallible;

/// A convenient type alias that by default assumes no error can happen.
///
/// It can be used to avoid type annotations when the function you want
/// to use needs a callback that returns [`Result`] but in your case no
/// error can happen.
pub type Result<T, E = Infallible> = core::result::Result<T, E>;

and use this as the return type in places like the shortest path algorithms and max weight matching (and in the docs). Users can also use this in order to avoid giving dummy type hints to the compiler.

I added this in: 2c0cb3e but feel free to tweak it if how I used it in the doc tests wasn't what you were thinking.

src/matching/mod.rs Outdated Show resolved Hide resolved
@georgios-ts
Copy link
Collaborator

I added this in: 2c0cb3e but feel free to tweak it if how I used it in the doc tests wasn't what you were thinking.

Yeah, this is more or less what I was thinking. It's not much, users could easily define it on their own but it might be convenient to have it in the library.

Overall, LGTM

Copy link
Collaborator

@IvanIsCoding IvanIsCoding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry to bring up naming but: do you think we should name the crate retworkx-core instead of retworkx-lib? retworkx-lib gets confusing too when we talk about the retworkx Python library.

I was checking crates.io and I got the impression that *-lib crates are complete and *-core crates are the ones where they split some of the core logic from their main crate. I think we are the second case.

retworkx-lib/Cargo.toml Outdated Show resolved Hide resolved
@mtreinish
Copy link
Member Author

I'm not strongly attached to the name retworkx-lib it's just the first thing that came to mind. I would say other rust *-lib crates are a bit different in that they're consumable from rust so it's not an exact parallel. But, I'll rename it retworkx-core since that works just as well and is in line with other libraries out there.

@IvanIsCoding IvanIsCoding changed the title Introduce retworkx-lib crate Introduce retworkx-core crate Oct 13, 2021
Copy link
Collaborator

@IvanIsCoding IvanIsCoding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving the PR, I am happy we are releasing some part of our code to the Rust community

retworkx-core/Cargo.toml Show resolved Hide resolved
@mtreinish mtreinish merged commit 1e570d1 into Qiskit:main Oct 13, 2021
@mtreinish mtreinish deleted the retworkx-lib branch October 13, 2021 14:37
mtreinish pushed a commit that referenced this pull request Oct 15, 2021
Profiting from #459 that made weight_callable generic to remove
some code duplication
mtreinish added a commit to mtreinish/retworkx that referenced this pull request Dec 17, 2021
This commit updates the lint job definition in the tox.ini to work now
that we have workspaces in the rust package. In Qiskit#459 we added a new
workspace for the dedicated rust package retworkx-core. But having
workspaces means that running cargo fmt outside from the tests/
directory (as we do with tox) means cargo doesn't know which workspace
to run against. To correct this issue this commit adds the --all flag to
the cargo fmt call in the tox job definition to ensure we're able to run
from any directory in the repo and check the formatting on all the rust
files in the project.
IvanIsCoding added a commit that referenced this pull request Dec 17, 2021
This commit updates the lint job definition in the tox.ini to work now
that we have workspaces in the rust package. In #459 we added a new
workspace for the dedicated rust package retworkx-core. But having
workspaces means that running cargo fmt outside from the tests/
directory (as we do with tox) means cargo doesn't know which workspace
to run against. To correct this issue this commit adds the --all flag to
the cargo fmt call in the tox job definition to ensure we're able to run
from any directory in the repo and check the formatting on all the rust
files in the project.

Co-authored-by: Ivan Carvalho <[email protected]>
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.

Native rust API documentation?
5 participants