feat: expose igraph_motifs_randesu_callback() to R for efficient motif sampling#2445
igraph_motifs_randesu_callback() to R for efficient motif sampling#2445Conversation
Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com>
…emory bug Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com>
Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com>
igraph_motifs_randesu_callback() to R for efficient motif sampling
|
@copilot: Merge |
Merged Regarding using Stimulus for autogeneration: I've reviewed the Stimulus configuration and existing callback function patterns (e.g., The current implementation in Could you clarify the approach you'd like me to take? Should I:
|
|
@copilot: Patch the local copy of Stimulus as you see fit to open the road for generated callbacks. |
…NORE flags Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com>
Added Stimulus configuration for callback support in commit a6da008. Following the established pattern in rigraph, callback functions are marked with Added:
The types can be extended in the future to support additional callback functions. |
Co-authored-by: krlmlr <1741643+krlmlr@users.noreply.github.com>
Summary of the finding
Issue #798 asks to expose the C function
igraph_motifs_randesu_callback()to Rso that motifs (e.g. closed vs. open triads) can be streamed from a very large
graph without enumerating every instance.
That capability is already on
main,exposed through the callback mode of
motifs():The callback receives
vids(1-based vertex IDs) andisoclass(the isomorphism class) for each motif found and can stop the search early —
which covers the issue's use case directly.
Why this PR is now redundant
This PR was branched from
mainon 2025-11-01,before the callback support was implemented upstream.
It has since been delivered — and refined — by three merged PRs:
igraph_motifs_randesu_callback()using closure approach #2465feat: autogenerate igraph_motifs_randesu_callback() using closure approach— the original exposure, via the autogenerated
CLOSUREbridge.motifs()function #2544refactor: integrate callback into motifs() function— folded the callback into
motifs(callback = )as a dual-mode argument.feat: autogenerate all callback non-SPARSEMAT functions with unified dual-mode API— standardized every callback wrapper on the same closure framework.
Because the Copilot agent that authored this PR could not see work that landed
after the branch point,
it re-implemented the same feature independently.
Concretely,
mainalready contains:motifs(graph, size, cut.prob, callback)inR/motifs.R;motifs_randesu_callback_closure_impl()inR/aaa-motifs.R;igraph_motifs_randesu_callback_closure()insrc/rcallback.c,plus its
src/rinterface.c/src/cpp11.cppregistration;(
igraph_motifs_randesu_callback: IGNOREand theigraph_motifs_randesu_callback_closureCLOSUREdefinition)in
tools/stimulus/functions-R.yaml;motifs_randesu_callback_closure_impl()intests/testthat/test-aaa-auto.R.Why this PR's approach also diverges from current conventions
Beyond being redundant, this PR's design no longer matches how the repository
handles callbacks:
motifs_randesu_callback()function.mainfolds callbacks into the primary function instead —cliques(callback = ),simple_cycles(callback = ),motifs(callback = )—and exports no standalone
*_callback()names.extraargument.None of the merged callback wrappers expose an
extraargument;R closures capture state through lexical scope (
<<-),making the C-style
extrapointer unnecessary.graphinto the callback.Every callback wrapper documents that
callbacks must not call any igraph function
or R will crash on reentrancy;
maintherefore passes onlyvids/isoclassand withholds the graph,whereas this PR hands the graph object to the user callback.
src/rinterface_extra.cbridge.This is the pre-feat: autogenerate
igraph_motifs_randesu_callback()using closure approach #2465 hand-written approach that the autogeneratedCLOSUREpattern (documented intools/AGENTS.md) replaced repo-wide.Recommendation
Close this PR as superseded — issue #798 is already satisfied on
main.There is no genuinely missing piece to salvage:
sample_motifs()wraps a different C function(
igraph_motifs_randesu_estimate(), an estimator, not a callback),so it is out of scope for #798.
Original intent — Fixes #798 (already resolved on
main).