diff options
Diffstat (limited to 'nauty')
| -rw-r--r-- | nauty/geng-iter.c | 74 | ||||
| -rw-r--r-- | nauty/geng.c | 54 | ||||
| -rw-r--r-- | nauty/geng.h | 18 |
3 files changed, 85 insertions, 61 deletions
diff --git a/nauty/geng-iter.c b/nauty/geng-iter.c index f2acf1c..cec9834 100644 --- a/nauty/geng-iter.c +++ b/nauty/geng-iter.c @@ -1,17 +1,9 @@ #include "gtools.h" +#include "geng.h" #include <ucontext.h> #include <stdint.h> #include <stdbool.h> -// TODO: move that to struct so that this code would be thread-safe (probably) -static unsigned long counter; -static graph *cur; -static int gn; -extern int generate_done; -int iter_done; -ucontext_t geng_worker, geng_user; -char geng_stack[1 << 20]; - // TODO: only on macos #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" @@ -35,11 +27,11 @@ printgraph(graph *g, int n) // TODO: probably don't need to name this function with macro void -OUTPROC(__attribute__((unused)) FILE *outfile, graph *g, int n) +OUTPROC(__attribute__((unused)) FILE *outfile, + graph *g, int n, struct geng_iterator *iter) { - cur = g; - gn = n; - ++counter; + iter->cur = g; + iter->graph_size = n; // TODO: add support for generating graphs in batches (for speed) #if 0 @@ -51,25 +43,26 @@ OUTPROC(__attribute__((unused)) FILE *outfile, graph *g, int n) i = 0; } #else - swapcontext(&geng_worker, &geng_user); + swapcontext(&iter->geng_worker, &iter->geng_user); #endif } // TODO: probably don't need to name this function with macro -// TODO: geng.h maybe? +// TODO: move to geng.h maybe? extern int GENG_MAIN(int argc, char *argv[]); -struct geng_iterator -{ - ucontext_t geng_worker, geng_user; - char geng_stack[1 << 20]; -}; - +// geng_iterator_init gives ownership of iterator memory to caller void -geng_iterator_init(__attribute__((unused)) struct geng_iterator *iter, int n) +geng_iterator_create(struct geng_iterator **iterator_ptr, + size_t graph_size, + size_t batch_capacity) { - iter_done = 0; + // TODO: malloc geng_iterator batch + *iterator_ptr = malloc(sizeof(struct geng_iterator)); + + struct geng_iterator *iterator = *iterator_ptr; + iterator->iteration_done = false; // TODO: add support for more arguments int geng_argc = 3; @@ -78,7 +71,7 @@ geng_iterator_init(__attribute__((unused)) struct geng_iterator *iter, int n) geng_argv[0] = "geng"; geng_argv[1] = "-q"; char n_str[20]; - snprintf(n_str, sizeof(n_str), "%u", n); + snprintf(n_str, sizeof(n_str), "%zu", graph_size); geng_argv[2] = n_str; geng_argv[3] = NULL; @@ -86,29 +79,34 @@ geng_iterator_init(__attribute__((unused)) struct geng_iterator *iter, int n) p_argv[0] = (uint32_t) (((size_t) &geng_argv) & ((1llu << 32) - 1llu)); p_argv[1] = ((size_t) &geng_argv) >> 32; - counter = 0; + uint32_t p_iter[2]; + p_iter[0] = (uint32_t) (((size_t) &iterator) & ((1llu << 32) - 1llu)); + p_iter[1] = ((size_t) &iterator) >> 32; - getcontext(&geng_user); - geng_worker = geng_user; - geng_worker.uc_stack.ss_sp = geng_stack; - geng_worker.uc_stack.ss_size = sizeof(geng_stack); - geng_worker.uc_link = &geng_user; + getcontext(&iterator->geng_user); + iterator->geng_worker = iterator->geng_user; + iterator->geng_worker.uc_stack.ss_sp = iterator->geng_stack; + iterator->geng_worker.uc_stack.ss_size = sizeof(iterator->geng_stack); + iterator->geng_worker.uc_link = &iterator->geng_user; - makecontext(&geng_worker, (void (*) (void)) GENG_MAIN, 3, geng_argc, p_argv[0], p_argv[1]); - swapcontext(&geng_user, &geng_worker); + makecontext( + &iterator->geng_worker, (void (*) (void)) GENG_MAIN, + 5, geng_argc, p_argv[0], p_argv[1], p_iter[0], p_iter[1] + ); + swapcontext(&iterator->geng_user, &iterator->geng_worker); free(geng_argv); } bool -geng_iterator_next(__attribute__((unused)) struct geng_iterator *iter, graph *g) +geng_iterator_next(struct geng_iterator *iter, graph *g) { - if (iter_done == 1) return false; + if (iter->iteration_done) return false; else { - memcpy(g, cur, sizeof(set) * gn); - swapcontext(&geng_user, &geng_worker); - if (iter_done == 0 && generate_done == 1) - iter_done = 1; + memcpy(g, iter->cur, sizeof(set) * iter->graph_size); + swapcontext(&iter->geng_user, &iter->geng_worker); + if (!iter->iteration_done && iter->generation_done) + iter->iteration_done = true; return true; } } diff --git a/nauty/geng.c b/nauty/geng.c index 8ebd629..7ea0085 100644 --- a/nauty/geng.c +++ b/nauty/geng.c @@ -416,8 +416,10 @@ efficient to use the res/mod feature than to split by numbers of edges. #define ONE_WORD_SETS #include "gtools.h" /* which includes nauty.h and stdio.h */ +#include "geng.h" +#include <stdint.h> -int generate_done; +struct geng_iterator; /* No need for TLS if not calling from a program. */ #ifndef GENG_MAIN @@ -427,7 +429,7 @@ int generate_done; typedef setword xword; -static TLS_ATTR void (*outproc)(FILE*,graph*,int); +static TLS_ATTR void (*outproc)(FILE*,graph*,int,struct geng_iterator *); static TLS_ATTR FILE *outfile; /* file for output graphs */ static TLS_ATTR int connec; /* 1 for -c, 2 for -C, 0 for neither */ @@ -2030,7 +2032,8 @@ xbnds(int n, int ne, int dmax) static void spaextend(graph *g, int n, int *deg, int ne, boolean rigid, - int xlb, int xub, void (*makeh)(graph*,xword*,int)) + int xlb, int xub, void (*makeh)(graph*,xword*,int), + struct geng_iterator *iter) /* extend from n to n+1 -- version for restricted graphs */ { xword x,d,dlow; @@ -2102,7 +2105,7 @@ spaextend(graph *g, int n, int *deg, int ne, boolean rigid, haschild = TRUE; #endif ++ecount[ne+xc]; - (*outproc)(outfile,canonise ? gcan : gx,nx); + (*outproc)(outfile,canonise ? gcan : gx,nx, iter); } } } @@ -2136,7 +2139,7 @@ spaextend(graph *g, int n, int *deg, int ne, boolean rigid, #ifdef INSTRUMENT haschild = TRUE; #endif - spaextend(gx,nx,degx,ne+xc,rigidx,xlbx,xubx,makeh); + spaextend(gx,nx,degx,ne+xc,rigidx,xlbx,xubx,makeh,iter); } } } @@ -2152,7 +2155,7 @@ spaextend(graph *g, int n, int *deg, int ne, boolean rigid, /**************************************************************************/ static void -genextend(graph *g, int n, int *deg, int ne, boolean rigid, int xlb, int xub) +genextend(graph *g, int n, int *deg, int ne, boolean rigid, int xlb, int xub, struct geng_iterator *iter) /* extend from n to n+1 -- version for general graphs */ { xword x,d,dlow; @@ -2224,7 +2227,7 @@ genextend(graph *g, int n, int *deg, int ne, boolean rigid, int xlb, int xub) haschild = TRUE; #endif ++ecount[ne+xc]; - (*outproc)(outfile,canonise ? gcan : gx,nx); + (*outproc)(outfile,canonise ? gcan : gx,nx, iter); } } } @@ -2256,7 +2259,7 @@ genextend(graph *g, int n, int *deg, int ne, boolean rigid, int xlb, int xub) #ifdef INSTRUMENT haschild = TRUE; #endif - genextend(gx,nx,degx,ne+xc,rigidx,xlbx,xubx); + genextend(gx,nx,degx,ne+xc,rigidx,xlbx,xubx,iter); } } @@ -2274,12 +2277,14 @@ genextend(graph *g, int n, int *deg, int ne, boolean rigid, int xlb, int xub) // TODO: probably rework #ifdef GENG_MAIN void -GENG_MAIN(int geng_argc, unsigned int argv1, unsigned int argv2) +GENG_MAIN(int argc, uint32_t argv1, uint32_t argv2, uint32_t iter1, uint32_t iter2) { - int argc = geng_argc; size_t *p_argv = (size_t *) (((size_t) argv1) | (((size_t) argv2) << 32)); char **argv = (char **) *p_argv; - generate_done = 0; + + size_t *p_iter = (size_t *) (((size_t) iter1) | (((size_t) iter2) << 32)); + struct geng_iterator *iter = (struct geng_iterator *) *p_iter; + iter->generation_done = false; #else int main(int argc, char *argv[]) @@ -2297,7 +2302,6 @@ main(int argc, char *argv[]) double t1,t2; char msg[201]; - /* HELP; PUTVERSION; */ nauty_check(WORDSIZE,1,MAXN,NAUTYVERSIONID); badargs = FALSE; @@ -2596,7 +2600,7 @@ PLUGIN_INIT if (res == 0 && connec < 2) { ++ecount[0]; - (*outproc)(outfile,g,1); + (*outproc)(outfile,g,1,iter); } } else @@ -2633,25 +2637,31 @@ PLUGIN_INIT if (bipartite) if (squarefree) spaextend(g,1,deg,0,TRUE, - data[1].xlb,data[1].xub,makeb6graph); + data[1].xlb,data[1].xub,makeb6graph, + iter); else spaextend(g,1,deg,0,TRUE, - data[1].xlb,data[1].xub,makebgraph); + data[1].xlb,data[1].xub,makebgraph, + iter); else if (trianglefree) if (squarefree) spaextend(g,1,deg,0,TRUE, - data[1].xlb,data[1].xub,makeg5graph); + data[1].xlb,data[1].xub,makeg5graph, + iter); else spaextend(g,1,deg,0,TRUE, - data[1].xlb,data[1].xub,makexgraph); + data[1].xlb,data[1].xub,makexgraph, + iter); else if (squarefree) spaextend(g,1,deg,0,TRUE, - data[1].xlb,data[1].xub,makesgraph); + data[1].xlb,data[1].xub,makesgraph, + iter); else if (savemem) spaextend(g,1,deg,0,TRUE, - data[1].xlb,data[1].xub,make0graph); + data[1].xlb,data[1].xub,make0graph, + iter); else - genextend(g,1,deg,0,TRUE,data[1].xlb,data[1].xub); + genextend(g,1,deg,0,TRUE,data[1].xlb,data[1].xub,iter); } } t2 = CPUTIME; @@ -2711,9 +2721,7 @@ PLUGIN_INIT free(data[i].xinv); free(data[i].xcard); } - generate_done = 1; - // TODO: probably rework - /* return 0; */ + iter->generation_done = true; #else exit(0); #endif diff --git a/nauty/geng.h b/nauty/geng.h new file mode 100644 index 0000000..751be5c --- /dev/null +++ b/nauty/geng.h @@ -0,0 +1,18 @@ +#include "gtools.h" +#include <ucontext.h> +#include <stdbool.h> + +struct geng_iterator +{ + ucontext_t geng_worker, geng_user; + char geng_stack[1 << 20]; + int graph_size; + bool generation_done; + bool iteration_done; + int batch_size; + int batch_capacity; + graph **batch; + + // TODO: remove + graph *cur; +}; |