From 1d6c6d53e1f40389ceeb276b5559a38ddc69932d Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Sun, 21 May 2023 14:58:15 +0200 Subject: [PATCH 1/7] `from` altrep vector --- src/init.cpp | 2 ++ src/rinterface_extra.c | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 47279863acc..cc36f9609fe 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -3,9 +3,11 @@ #include "igraph.h" extern "C" void R_igraph_init_handlers(DllInfo* dll); +extern "C" void R_igraph_init_vector_class(DllInfo* dll); [[cpp11::init]] void igraph_init(DllInfo* dll) { R_igraph_init_handlers(dll); + R_igraph_init_vector_class(dll); } diff --git a/src/rinterface_extra.c b/src/rinterface_extra.c index bed4b7877cf..31c282fbb28 100644 --- a/src/rinterface_extra.c +++ b/src/rinterface_extra.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "rinterface.h" #include "rrandom.h" @@ -2547,6 +2548,36 @@ int R_igraph_status_handler(const char *message, void *data) { return 0; } +static R_xlen_t R_igraph_vector_Length(SEXP vec) { + SEXP xp=Rf_findVar(Rf_install("igraph"), R_altrep_data1(vec)); + igraph_t *g=(igraph_t*)(R_ExternalPtrAddr(xp)); + return igraph_ecount(g); +} + +static void *R_igraph_vector_Dataptr(SEXP vec, Rboolean writeable) { + SEXP data = R_altrep_data2(vec); + if (data == R_NilValue) { + SEXP xp=Rf_findVar(Rf_install("igraph"), R_altrep_data1(vec)); + igraph_t *g=(igraph_t*)(R_ExternalPtrAddr(xp)); + + long int no_of_edges=igraph_ecount(g); + data=NEW_NUMERIC(no_of_edges); + memcpy(REAL(data), g->from.stor_begin, sizeof(igraph_real_t)*(size_t) no_of_edges); + R_set_altrep_data2(vec, data); + } + + return REAL(data); +} + +static R_altrep_class_t R_altrep_vector_class; + +void R_igraph_init_vector_class(DllInfo *dll) { + R_altrep_vector_class=R_make_altreal_class("igraph_vector", "base", dll); + + R_set_altrep_Length_method(R_altrep_vector_class, R_igraph_vector_Length); + R_set_altvec_Dataptr_method(R_altrep_vector_class, R_igraph_vector_Dataptr); +} + void R_igraph_init_handlers(DllInfo *dll) { igraph_rng_R_install(); @@ -2952,10 +2983,7 @@ igraph_bool_t R_igraph_get_directed(SEXP graph) { } void R_igraph_set_from(SEXP rgraph, const igraph_t *graph) { - long int no_of_edges=igraph_ecount(graph); - SET_VECTOR_ELT(rgraph, igraph_t_idx_from, NEW_NUMERIC(no_of_edges)); - memcpy(REAL(VECTOR_ELT(rgraph, igraph_t_idx_from)), graph->from.stor_begin, - sizeof(igraph_real_t)*(size_t) no_of_edges); + SET_VECTOR_ELT(rgraph, igraph_t_idx_from, R_new_altrep(R_altrep_vector_class, R_igraph_graph_env(rgraph), R_NilValue)); } void R_igraph_get_from(SEXP graph, igraph_vector_t* from) { @@ -3004,7 +3032,6 @@ SEXP R_igraph_to_SEXP(const igraph_t *graph) { PROTECT(result=NEW_LIST(igraph_t_idx_max)); R_igraph_set_n(result, graph); R_igraph_set_directed(result, graph); - R_igraph_set_from(result, graph); R_igraph_set_to(result, graph); SET_CLASS(result, Rf_ScalarString(Rf_mkChar("igraph"))); @@ -3017,6 +3044,7 @@ SEXP R_igraph_to_SEXP(const igraph_t *graph) { SET_VECTOR_ELT(result, igraph_t_idx_env, R_NilValue); R_igraph_add_env(result); R_igraph_set_pointer(result, graph); + R_igraph_set_from(result, graph); UNPROTECT(1); return result; From 041354ef2dfbd4dc09886bd0a311b68ba1ec2dbc Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Sun, 21 May 2023 15:20:58 +0200 Subject: [PATCH 2/7] `to` altrep vector --- src/rinterface_extra.c | 42 ++++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/rinterface_extra.c b/src/rinterface_extra.c index 31c282fbb28..3b490bc316d 100644 --- a/src/rinterface_extra.c +++ b/src/rinterface_extra.c @@ -2548,13 +2548,13 @@ int R_igraph_status_handler(const char *message, void *data) { return 0; } -static R_xlen_t R_igraph_vector_Length(SEXP vec) { +static R_xlen_t R_igraph_altrep_length(SEXP vec) { SEXP xp=Rf_findVar(Rf_install("igraph"), R_altrep_data1(vec)); igraph_t *g=(igraph_t*)(R_ExternalPtrAddr(xp)); return igraph_ecount(g); } -static void *R_igraph_vector_Dataptr(SEXP vec, Rboolean writeable) { +static void *R_igraph_altrep_from(SEXP vec, Rboolean writeable) { SEXP data = R_altrep_data2(vec); if (data == R_NilValue) { SEXP xp=Rf_findVar(Rf_install("igraph"), R_altrep_data1(vec)); @@ -2569,13 +2569,33 @@ static void *R_igraph_vector_Dataptr(SEXP vec, Rboolean writeable) { return REAL(data); } -static R_altrep_class_t R_altrep_vector_class; +static void *R_igraph_altrep_to(SEXP vec, Rboolean writeable) { + SEXP data = R_altrep_data2(vec); + if (data == R_NilValue) { + SEXP xp=Rf_findVar(Rf_install("igraph"), R_altrep_data1(vec)); + igraph_t *g=(igraph_t*)(R_ExternalPtrAddr(xp)); + + long int no_of_edges=igraph_ecount(g); + data=NEW_NUMERIC(no_of_edges); + memcpy(REAL(data), g->to.stor_begin, sizeof(igraph_real_t)*(size_t) no_of_edges); + R_set_altrep_data2(vec, data); + } + + return REAL(data); +} + +static R_altrep_class_t R_igraph_altrep_from_class; +static R_altrep_class_t R_igraph_altrep_to_class; void R_igraph_init_vector_class(DllInfo *dll) { - R_altrep_vector_class=R_make_altreal_class("igraph_vector", "base", dll); + R_igraph_altrep_from_class=R_make_altreal_class("igraph_from", "base", dll); + R_igraph_altrep_to_class=R_make_altreal_class("igraph_to", "base", dll); - R_set_altrep_Length_method(R_altrep_vector_class, R_igraph_vector_Length); - R_set_altvec_Dataptr_method(R_altrep_vector_class, R_igraph_vector_Dataptr); + R_set_altrep_Length_method(R_igraph_altrep_from_class, R_igraph_altrep_length); + R_set_altvec_Dataptr_method(R_igraph_altrep_from_class, R_igraph_altrep_from); + + R_set_altrep_Length_method(R_igraph_altrep_to_class, R_igraph_altrep_length); + R_set_altvec_Dataptr_method(R_igraph_altrep_to_class, R_igraph_altrep_to); } void R_igraph_init_handlers(DllInfo *dll) { @@ -2983,7 +3003,7 @@ igraph_bool_t R_igraph_get_directed(SEXP graph) { } void R_igraph_set_from(SEXP rgraph, const igraph_t *graph) { - SET_VECTOR_ELT(rgraph, igraph_t_idx_from, R_new_altrep(R_altrep_vector_class, R_igraph_graph_env(rgraph), R_NilValue)); + SET_VECTOR_ELT(rgraph, igraph_t_idx_from, R_new_altrep(R_igraph_altrep_from_class, R_igraph_graph_env(rgraph), R_NilValue)); } void R_igraph_get_from(SEXP graph, igraph_vector_t* from) { @@ -2992,10 +3012,7 @@ void R_igraph_get_from(SEXP graph, igraph_vector_t* from) { } void R_igraph_set_to(SEXP rgraph, const igraph_t *graph) { - long int no_of_edges=igraph_ecount(graph); - SET_VECTOR_ELT(rgraph, igraph_t_idx_to, NEW_NUMERIC(no_of_edges)); - memcpy(REAL(VECTOR_ELT(rgraph, igraph_t_idx_to)), graph->to.stor_begin, - sizeof(igraph_real_t)*(size_t) no_of_edges); + SET_VECTOR_ELT(rgraph, igraph_t_idx_to, R_new_altrep(R_igraph_altrep_to_class, R_igraph_graph_env(rgraph), R_NilValue)); } void R_igraph_get_to(SEXP graph, igraph_vector_t* to) { @@ -3032,7 +3049,6 @@ SEXP R_igraph_to_SEXP(const igraph_t *graph) { PROTECT(result=NEW_LIST(igraph_t_idx_max)); R_igraph_set_n(result, graph); R_igraph_set_directed(result, graph); - R_igraph_set_to(result, graph); SET_CLASS(result, Rf_ScalarString(Rf_mkChar("igraph"))); @@ -3044,7 +3060,9 @@ SEXP R_igraph_to_SEXP(const igraph_t *graph) { SET_VECTOR_ELT(result, igraph_t_idx_env, R_NilValue); R_igraph_add_env(result); R_igraph_set_pointer(result, graph); + /* Set from and to requires environment */ R_igraph_set_from(result, graph); + R_igraph_set_to(result, graph); UNPROTECT(1); return result; From ab9ea7f135936ddc5f29ba4dc709c95a79b5151c Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Mon, 22 May 2023 13:21:42 +0200 Subject: [PATCH 3/7] add `igraph.verbose` option --- src/rinterface_extra.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/rinterface_extra.c b/src/rinterface_extra.c index 3b490bc316d..b685a5b480f 100644 --- a/src/rinterface_extra.c +++ b/src/rinterface_extra.c @@ -2557,6 +2557,11 @@ static R_xlen_t R_igraph_altrep_length(SEXP vec) { static void *R_igraph_altrep_from(SEXP vec, Rboolean writeable) { SEXP data = R_altrep_data2(vec); if (data == R_NilValue) { + SEXP option=Rf_GetOption(Rf_install("igraph.verbose"), R_BaseEnv); + if (option != R_NilValue && !Rf_isNull(option) && LOGICAL_ELT(option, 0) == 1) { + Rprintf("Materializing 'from' vector.\n"); + } + SEXP xp=Rf_findVar(Rf_install("igraph"), R_altrep_data1(vec)); igraph_t *g=(igraph_t*)(R_ExternalPtrAddr(xp)); @@ -2572,6 +2577,11 @@ static void *R_igraph_altrep_from(SEXP vec, Rboolean writeable) { static void *R_igraph_altrep_to(SEXP vec, Rboolean writeable) { SEXP data = R_altrep_data2(vec); if (data == R_NilValue) { + SEXP option=Rf_GetOption(Rf_install("igraph.verbose"), R_BaseEnv); + if (option != R_NilValue && !Rf_isNull(option) && LOGICAL_ELT(option, 0) == 1) { + Rprintf("Materializing 'to' vector.\n"); + } + SEXP xp=Rf_findVar(Rf_install("igraph"), R_altrep_data1(vec)); igraph_t *g=(igraph_t*)(R_ExternalPtrAddr(xp)); From e20b990f816a882e354b4ed45ad740bc8b233fc1 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Mon, 22 May 2023 13:26:20 +0200 Subject: [PATCH 4/7] fix spaces --- src/rinterface_extra.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/rinterface_extra.c b/src/rinterface_extra.c index b685a5b480f..0fa15fc6a53 100644 --- a/src/rinterface_extra.c +++ b/src/rinterface_extra.c @@ -2555,7 +2555,7 @@ static R_xlen_t R_igraph_altrep_length(SEXP vec) { } static void *R_igraph_altrep_from(SEXP vec, Rboolean writeable) { - SEXP data = R_altrep_data2(vec); + SEXP data=R_altrep_data2(vec); if (data == R_NilValue) { SEXP option=Rf_GetOption(Rf_install("igraph.verbose"), R_BaseEnv); if (option != R_NilValue && !Rf_isNull(option) && LOGICAL_ELT(option, 0) == 1) { @@ -2575,7 +2575,7 @@ static void *R_igraph_altrep_from(SEXP vec, Rboolean writeable) { } static void *R_igraph_altrep_to(SEXP vec, Rboolean writeable) { - SEXP data = R_altrep_data2(vec); + SEXP data=R_altrep_data2(vec); if (data == R_NilValue) { SEXP option=Rf_GetOption(Rf_install("igraph.verbose"), R_BaseEnv); if (option != R_NilValue && !Rf_isNull(option) && LOGICAL_ELT(option, 0) == 1) { @@ -2959,8 +2959,7 @@ void R_igraph_restore_pointer(SEXP graph) { igraph_integer_t i, s=igraph_vector_size(&from); igraph_vector_init(&v, s*2); - for (i = 0; i < s; ++i) - { + for (i = 0; i < s; ++i) { igraph_vector_set(&v, i*2, VECTOR(to)[i]); igraph_vector_set(&v, i*2+1, VECTOR(from)[i]); } From d02f7492701a827e9efc68bf9daa8e4c2a3b3d3e Mon Sep 17 00:00:00 2001 From: Antonov Misha Date: Tue, 23 May 2023 23:18:15 +0200 Subject: [PATCH 5/7] Update src/rinterface_extra.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kirill Müller --- src/rinterface_extra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rinterface_extra.c b/src/rinterface_extra.c index f99189d89a4..90f591a372d 100644 --- a/src/rinterface_extra.c +++ b/src/rinterface_extra.c @@ -2558,7 +2558,7 @@ static void *R_igraph_altrep_from(SEXP vec, Rboolean writeable) { SEXP data=R_altrep_data2(vec); if (data == R_NilValue) { SEXP option=Rf_GetOption(Rf_install("igraph.verbose"), R_BaseEnv); - if (option != R_NilValue && !Rf_isNull(option) && LOGICAL_ELT(option, 0) == 1) { + if (option != R_NilValue && TYPEOF(option) == LGLSXP && Rf_xlength(option) == 1 && LOGICAL_ELT(option, 0) == 1) { Rprintf("Materializing 'from' vector.\n"); } From a8853f640632ef3039876c4b09db36cea8b7b9fa Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Thu, 25 May 2023 13:18:04 +0200 Subject: [PATCH 6/7] add external pointer logs --- src/rinterface_extra.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/rinterface_extra.c b/src/rinterface_extra.c index 90f591a372d..49da0e8f956 100644 --- a/src/rinterface_extra.c +++ b/src/rinterface_extra.c @@ -2557,11 +2557,7 @@ static R_xlen_t R_igraph_altrep_length(SEXP vec) { static void *R_igraph_altrep_from(SEXP vec, Rboolean writeable) { SEXP data=R_altrep_data2(vec); if (data == R_NilValue) { - SEXP option=Rf_GetOption(Rf_install("igraph.verbose"), R_BaseEnv); - if (option != R_NilValue && TYPEOF(option) == LGLSXP && Rf_xlength(option) == 1 && LOGICAL_ELT(option, 0) == 1) { - Rprintf("Materializing 'from' vector.\n"); - } - + R_igraph_status_handler("Materializing 'from' vector.\n", NULL); SEXP xp=Rf_findVar(Rf_install("igraph"), R_altrep_data1(vec)); igraph_t *g=(igraph_t*)(R_ExternalPtrAddr(xp)); @@ -2577,10 +2573,7 @@ static void *R_igraph_altrep_from(SEXP vec, Rboolean writeable) { static void *R_igraph_altrep_to(SEXP vec, Rboolean writeable) { SEXP data=R_altrep_data2(vec); if (data == R_NilValue) { - SEXP option=Rf_GetOption(Rf_install("igraph.verbose"), R_BaseEnv); - if (option != R_NilValue && !Rf_isNull(option) && LOGICAL_ELT(option, 0) == 1) { - Rprintf("Materializing 'to' vector.\n"); - } + R_igraph_status_handler("Materializing 'to' vector.\n", NULL); SEXP xp=Rf_findVar(Rf_install("igraph"), R_altrep_data1(vec)); igraph_t *g=(igraph_t*)(R_ExternalPtrAddr(xp)); @@ -2920,6 +2913,7 @@ SEXP R_igraph_graph_env(SEXP graph) { } static void free_graph(SEXP xp) { + R_igraph_status_handler("Free graph external pointer.\n", NULL); igraph_t *graph = (igraph_t*)(R_ExternalPtrAddr(xp)); igraph_vector_destroy(&graph->from); igraph_vector_destroy(&graph->to); @@ -2936,6 +2930,8 @@ void R_igraph_set_pointer(SEXP result, const igraph_t* graph) { igraph_t *pgraph = IGRAPH_CALLOC(1, igraph_t); *pgraph = *graph; + R_igraph_status_handler("Make graph external pointer.\n", NULL); + SEXP l1 = PROTECT(Rf_install("igraph")); px++; SEXP l2 = PROTECT(R_MakeExternalPtr(pgraph, R_NilValue, R_NilValue)); px++; Rf_defineVar(l1, l2, R_igraph_graph_env(result)); @@ -2950,6 +2946,8 @@ void R_igraph_restore_pointer(SEXP graph) { igraph_integer_t n=REAL(VECTOR_ELT(graph, igraph_t_idx_n))[0]; igraph_bool_t directed=LOGICAL(VECTOR_ELT(graph, igraph_t_idx_directed))[0]; + R_igraph_status_handler("Restore graph external pointer.\n", NULL); + igraph_vector_t from; R_SEXP_to_vector(VECTOR_ELT(graph, igraph_t_idx_from), &from); From ec9940826b3530ae6ef20fe702e6877962a17e1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sat, 27 May 2023 09:43:08 +0200 Subject: [PATCH 7/7] Require R 3.5.0 for ALTREP --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index bd12fccd5a4..844343ed912 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -28,7 +28,7 @@ URL: https://r.igraph.org/, https://igraph.org/, BugReports: https://github.com/igraph/rigraph/issues Depends: methods, - R (>= 3.0.2) + R (>= 3.5.0) Imports: cli, graphics,