Non-deterministic behavior when generating graph.json #1090
|
Across 4 runs of graphify update locally without changing my repo, I see minor differences:
I was under the impression that this initial step would be deterministic, but maybe the underlying Leiden algorithm is unseeded or something is in some way introducing some variability. First time commenter- amazing tool @safishamsi -Ahmed |
Replies: 2 comments 3 replies
|
Great catch @AhmedGenbai, and welcome! You are right that it is non-determinism, but Leiden is not the culprit — it is properly seeded ( Root cause: Why runs 3 and 4 had identical node/link counts but different community counts: the node and link totals stabilised (same files, same collision winners by chance) but the edge attribute values ( Fix committed in Will ship in the next PyPI release. Thanks again for the detailed reproduction table — the four-run comparison made the diagnosis straightforward. |
|
Thanks for pushing on this @AhmedGenbai - two separate things here: The 77-88% "changed community" is a labeling artifact, not real regrouping. Each node's The ±1-2 community-count drift is a tiny real residual (~0.1%). I verified the graph fed to clustering is byte-identical across runs and the top-level partition is deterministic - the wobble is graspologic Leiden being slightly non-deterministic only when re-splitting small low-cohesion subgraphs. It doesn't affect god-nodes or overall structure. Note the default install uses Louvain, which is fully deterministic (verified 20/20 identical runs) - so if you need byte-stable |
Great catch @AhmedGenbai, and welcome!
You are right that it is non-determinism, but Leiden is not the culprit — it is properly seeded (
random_seed=42,trials=1) and its input is canonically sorted before each run. The root cause is upstream.Root cause:
os.walk()indetect.pyreturns files in filesystem b-tree order, which shifts between runs depending on kernel cache state, recent directory writes, or mount. Several downstream passes are first-writer-wins (cross-file import resolution, label dedup, symbol resolution) so whichever file happened to be seen first would win name collisions — producing different node IDs, edge targets, and Leiden input edge attributes each run.Why runs 3 an…