Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions handbook/architecture/stimulus/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ The code generator that writes the R/C interface: `src/rinterface.c` and `R/aaa-
the C library's own `src/vendor/cigraph/interfaces/functions.yaml` and `types.yaml`,
together with this package's `tools/stimulus/functions-R.yaml`, `types-RC.yaml` and `types-RR.yaml`.
Stimulus writes one `.build/aaa-auto.R`, which `tools/split-aaa-auto.R` splits into the per-category `R/aaa-*.R` files that `tools/aaa-categories.yaml` names.
A generated function without an entry there stops the split, so a function a newer C core adds needs its category first.
Entries for functions the vendored core does not generate yet are ignored, so they can go to `main` ahead of the core that adds them.
`tools/rebuild-cats.R` holds the placements and rewrites the YAML.
A change to the interface goes to those YAML files, or to a `patch/` entry when the C library's own definition is wrong
([`operations/vendoring/adaptation/`](/handbook/operations/vendoring/adaptation/README.md)).

Expand Down
24 changes: 24 additions & 0 deletions tools/aaa-categories.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ basic-igraph:
- igraph_delete_edges
- igraph_delete_vertices
- igraph_delete_vertices_idx
- igraph_delete_vertices_map
basic-query-operations:
- igraph_degree
- igraph_ecount
Expand All @@ -32,10 +33,12 @@ bipartite:
bipartite-adjacency-matrices:
- igraph_biadjacency
- igraph_get_biadjacency
- igraph_weighted_biadjacency
create-two-mode-networks:
- igraph_bipartite_game
- igraph_bipartite_game_gnm
- igraph_bipartite_game_gnp
- igraph_bipartite_iea_game
- igraph_create_bipartite
- igraph_full_bipartite
other-operations-on-bipartite-graphs:
Expand Down Expand Up @@ -97,6 +100,7 @@ community:
community-structure-based-on-the-optimization-of-modularity:
- igraph_community_fastgreedy
- igraph_community_leiden
- igraph_community_leiden_simple
- igraph_community_multilevel
edge-betweenness-based-community-detection:
- igraph_community_eb_get_merges
Expand Down Expand Up @@ -218,6 +222,7 @@ games:
- igraph_erdos_renyi_game_gnp
- igraph_hsbm_game
- igraph_hsbm_list_game
- igraph_iea_game
- igraph_preference_game
- igraph_sbm_game
growing-random-games:
Expand All @@ -239,6 +244,9 @@ games:
- igraph_recent_degree_aging_game
- igraph_recent_degree_game
random-vectors:
- igraph_rng_sample_dirichlet
- igraph_rng_sample_sphere_surface
- igraph_rng_sample_sphere_volume
- igraph_sample_dirichlet
- igraph_sample_sphere_surface
- igraph_sample_sphere_volume
Expand Down Expand Up @@ -273,7 +281,9 @@ generators:
- igraph_circulant
- igraph_cycle_graph
- igraph_extended_chordal_ring
- igraph_hamming
- igraph_hypercube
- igraph_lcf
- igraph_lcf_vector
- igraph_path_graph
- igraph_ring
Expand Down Expand Up @@ -321,8 +331,11 @@ isomorphism:
- igraph_isoclass_subgraph
isomorphism-simple-interface:
- igraph_automorphism_group
- igraph_automorphism_group_bliss
- igraph_canonical_permutation
- igraph_canonical_permutation_bliss
- igraph_count_automorphisms
- igraph_count_automorphisms_bliss
- igraph_isomorphic
- igraph_subisomorphic
isomorphism-utility-functions:
Expand Down Expand Up @@ -379,6 +392,7 @@ motifs:
finding-triangles:
- igraph_count_adjacent_triangles
- igraph_count_triangles
- igraph_is_triangle_free
- igraph_list_triangles
graph-motifs:
- igraph_motifs_randesu
Expand Down Expand Up @@ -463,6 +477,16 @@ separators:
spatial:
nongraph-spatial:
- igraph_convex_hull_2d
proximity-graphs:
- igraph_beta_weighted_gabriel_graph
- igraph_circle_beta_skeleton
- igraph_delaunay_graph
- igraph_gabriel_graph
- igraph_lune_beta_skeleton
- igraph_nearest_neighbor_graph
- igraph_relative_neighborhood_graph
edge-lengths:
- igraph_spatial_edge_lengths

structural:
basic-properties:
Expand Down
73 changes: 44 additions & 29 deletions tools/rebuild-cats.R
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,38 @@ placements <- rbind(

c("structural", "summary-statistics", "igraph_density"),
c("structural", "summary-statistics", "igraph_diversity"),
c("structural", "summary-statistics", "igraph_mean_degree")
c("structural", "summary-statistics", "igraph_mean_degree"),

# --- Ahead of the vendored C core: functions only igraph 1.0 generates. ---
# tools/split-aaa-auto.R ignores entries for functions that are not
# generated, so placing them now keeps a rebuild on a newer core from
# producing R/aaa-uncategorized.R.

# renamed or added beside a function placed above
c("basic-igraph", "adding-and-deleting-vertices-and-edges", "igraph_delete_vertices_map"),
c("generators", "regular-structure-generators", "igraph_lcf"),
c("games", "random-vectors", "igraph_rng_sample_dirichlet"),
c("games", "random-vectors", "igraph_rng_sample_sphere_surface"),
c("games", "random-vectors", "igraph_rng_sample_sphere_volume"),
c("isomorphism", "isomorphism-simple-interface", "igraph_automorphism_group_bliss"),
c("isomorphism", "isomorphism-simple-interface", "igraph_canonical_permutation_bliss"),
c("isomorphism", "isomorphism-simple-interface", "igraph_count_automorphisms_bliss"),

# new
c("bipartite", "bipartite-adjacency-matrices", "igraph_weighted_biadjacency"),
c("bipartite", "create-two-mode-networks", "igraph_bipartite_iea_game"),
c("community", "community-structure-based-on-the-optimization-of-modularity", "igraph_community_leiden_simple"),
c("games", "erdos-renyi-games", "igraph_iea_game"),
c("generators", "regular-structure-generators", "igraph_hamming"),
c("motifs", "finding-triangles", "igraph_is_triangle_free"),
c("spatial", "proximity-graphs", "igraph_beta_weighted_gabriel_graph"),
c("spatial", "proximity-graphs", "igraph_circle_beta_skeleton"),
c("spatial", "proximity-graphs", "igraph_delaunay_graph"),
c("spatial", "proximity-graphs", "igraph_gabriel_graph"),
c("spatial", "proximity-graphs", "igraph_lune_beta_skeleton"),
c("spatial", "proximity-graphs", "igraph_nearest_neighbor_graph"),
c("spatial", "proximity-graphs", "igraph_relative_neighborhood_graph"),
c("spatial", "edge-lengths", "igraph_spatial_edge_lengths")
)
colnames(placements) <- c("category", "subcategory", "fn")
placements <- as.data.frame(placements, stringsAsFactors = FALSE)
Expand Down Expand Up @@ -302,26 +333,9 @@ subcategory_order_overrides <- list(

# ---- 3. Truly stale entries to remove --------------------------------------

stale_to_remove <- c(
"igraph_automorphism_group_bliss",
"igraph_canonical_permutation_bliss",
"igraph_count_automorphisms_bliss",
"igraph_bipartite_iea_game",
"igraph_iea_game",
"igraph_community_leiden_simple",
"igraph_delete_vertices_map",
"igraph_hamming",
"igraph_lcf",
"igraph_weighted_biadjacency",
"igraph_beta_weighted_gabriel_graph",
"igraph_circle_beta_skeleton",
"igraph_delaunay_graph",
"igraph_gabriel_graph",
"igraph_lune_beta_skeleton",
"igraph_nearest_neighbor_graph",
"igraph_relative_neighborhood_graph",
"igraph_spatial_edge_lengths"
)
# Functions that are generated by no vendored C core, old or new. Functions
# only a newer core generates are not stale: they keep their placement.
stale_to_remove <- character()

# ---- 4. Load current cats.yml and build the working structure --------------

Expand Down Expand Up @@ -387,10 +401,11 @@ tbl <- rbind(tbl, placements)

# ---- 6. Validate ------------------------------------------------------------
# Missing fns (in the generated wrappers but not in cats.yml) are appended to a
# top-level `uncategorized:` flat list and warned about — this keeps the YAML in
# sync with upstream Stimulus additions without erroring. Extra fns (in cats.yml
# but not in the wrappers) are warned about too, but left in place so a human
# can decide whether to move them into `stale_to_remove`.
# top-level `uncategorized:` flat list and warned about. tools/split-aaa-auto.R
# stops on a function without a category and takes `uncategorized:` as the
# explicit opt-out, so move them to a real placement before committing. Extra
# fns (in cats.yml but not in the wrappers) are reported and left in place:
# a newer vendored C core generates them.

have <- sort(unique(tbl$fn))
missing <- setdiff(canonical, have)
Expand All @@ -414,11 +429,11 @@ if (length(missing)) {
)
}
if (length(extra)) {
warning(
"Extra entries in cats.yml with no matching wrapper:\n ",
message(
"Entries in cats.yml with no matching wrapper, kept:\n ",
paste(extra, collapse = "\n "),
"\nRemove them from tools/aaa-categories.yaml or add to `stale_to_remove`.",
call. = FALSE
"\nExpected for functions only a newer vendored C core generates;",
" add any that no core generates to `stale_to_remove`."
)
}

Expand Down
13 changes: 6 additions & 7 deletions tools/split-aaa-auto.R
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,10 @@ message("parsed ", length(impls), " _impl wrappers from source")

# ---- map each impl to (category, subcategory); validate no gaps ---------

# Functions not listed in aaa-categories.yaml are emitted into
# R/aaa-uncategorized.R with a warning, so a new wrapper landing upstream
# never breaks the build. The warning lists exactly what needs a home.
# Every impl needs a category in aaa-categories.yaml: a function without one
# stops the build rather than landing in R/aaa-uncategorized.R unnoticed. The
# error lists exactly what needs a home. Listing a function under a top-level
# `uncategorized:` key is the explicit opt-out, and writes it to that file.
unassigned <- character()
for (i in seq_along(impls)) {
lookup <- cat_lookup[[impls[[i]]$c_function]]
Expand All @@ -174,18 +175,16 @@ for (i in seq_along(impls)) {
unassigned,
paste0(impls[[i]]$impl_name, " -> ", impls[[i]]$c_function)
)
impls[[i]]$category <- "uncategorized"
impls[[i]]$subcategory <- NA_character_
} else {
impls[[i]]$category <- lookup$category
impls[[i]]$subcategory <- lookup$subcategory
}
}
if (length(unassigned)) {
warning(
stop(
"impls without a category in ",
CATS,
" — written to R/aaa-uncategorized.R:\n ",
":\n ",
paste(unassigned, collapse = "\n "),
"\nAdd placements in tools/rebuild-cats.R and rerun it to clear this.",
call. = FALSE
Expand Down
Loading