Skip to content

feat: add networkit flavor for parallel Leiden clustering#4170

Draft
amalia-k510 wants to merge 11 commits into
scverse:mainfrom
amalia-k510:networkit_gve
Draft

feat: add networkit flavor for parallel Leiden clustering#4170
amalia-k510 wants to merge 11 commits into
scverse:mainfrom
amalia-k510:networkit_gve

Conversation

@amalia-k510

Copy link
Copy Markdown
Contributor

This PR adds NetworKit's ParallelLeiden as a new flavor option for scanpy.tl.leiden, enabling multithreaded Leiden community detection via scanpy.tl.leiden(adata, flavor="networkit"). The motivation behind is that scanpy's current Leiden backends (igraph, leidenalg) are single-threaded. For atlas-scale datasets (500k+ cells), clustering becomes a bottleneck. NetworKit's ParallelLeiden is a C++ parallel implementation available via pip with no additional compilation, making it the lowest-friction path to parallel Leiden in scanpy.

@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 30.23256% with 30 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.74%. Comparing base (7df9ad6) to head (1d6ad93).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/scanpy/tools/_leiden.py 32.25% 21 Missing ⚠️
src/scanpy/_utils/__init__.py 18.18% 9 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4170      +/-   ##
==========================================
- Coverage   79.91%   79.74%   -0.17%     
==========================================
  Files         121      121              
  Lines       12949    12989      +40     
==========================================
+ Hits        10348    10358      +10     
- Misses       2601     2631      +30     
Flag Coverage Δ
hatch-test.low-vers 78.87% <30.23%> (-0.17%) ⬇️
hatch-test.pre 79.69% <30.23%> (-0.17%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/scanpy/_settings/presets.py 90.84% <100.00%> (ø)
src/scanpy/_utils/__init__.py 74.04% <18.18%> (-1.43%) ⬇️
src/scanpy/tools/_leiden.py 75.86% <32.25%> (-16.10%) ⬇️

@ilan-gold ilan-gold left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nice! Would be best to run the installation check :)

Also please add an extra to our pyproject.toml.

Let's try to use a heuristic about warning users about large inputs to igraph and the faster alternative

Comment thread src/scanpy/_utils/__init__.py Outdated
Comment thread src/scanpy/_utils/__init__.py Outdated
Comment thread src/scanpy/tools/_leiden.py
networkit.setSeed(seed, useThreadId=True)
# only undirected for Parallel Leiden
g = _utils.get_networkit_from_adjacency(adjacency, weighted=use_weights)
iterations = n_iterations if n_iterations > 0 else 3

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Where did the number 3 come from?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I checked the the NetworKit's header file for the ParallelLeiden and found that default for ParallelLeiden.iterations is set to three; hence why I decided to use it here as well.
explicit ParallelLeiden(const Graph &graph, int iterations = 3, bool randomize = true, double gamma = 1);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we document that? Also, why isn't it the default then for python?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I checked and turns out that iterations=3 is already the default on the Python side for ParallelLeiden. I could drop it, but I left it explicit so the value is obvious at the call site and clearly maps to scanpy's n_iterations.

@ilan-gold

Copy link
Copy Markdown
Contributor

Also can you point this branch at networkit/networkit#1422 (and then main after merge followed by the correct min version when released) and use this method (also in your notebook) to make sure it works properly?

Comment on lines +314 to +315
if importlib.util.find_spec("networkit") is None:
return

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Would still warn even if there is no networkit installed :)

Do you have a benchmarking notebook as a gist somewhere?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think this is already handled. It returns early if find_spec("networkit") is None, so the hint only fires when networkit's actually installed. Might've been from before I pushed the guard? Let me know if you're still seeing it warn without networkit and I'll take another look.

@amalia-k510 amalia-k510 Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Also, I tried to create gist, and it is erroring out on the notebook. I think the file is too large with the embedded outputs. Want me to push it to the PR branch, strip the outputs and re-upload to a gist, or just share it another way?

@amalia-k510 amalia-k510 changed the title Adding "networkit" flavour to scanpy.tl.leiden for parallel community detection feat: add networkit flavor for parallel Leiden clustering Jul 13, 2026
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.

2 participants