-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathnauthread1.c
139 lines (112 loc) · 3.89 KB
/
nauthread1.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* nauthread1.c
This program tests dense nauty running in multiple threads.
It must be linked with nauty as configured with
--enable-tls and will only run on systems which support
thread-local storage.
The method for building programs with Posix threads varies.
You might need to use pthreads.h or something else in place
of pthread.h below, and you probably need a library such as
-lpthread or -lpthreads on your compilation command.
*/
#include <pthread.h>
#include "nauty.h"
/* MAXN=0 is defined by nauty.h, which implies dynamic allocation */
#define THREADS 1000 /* Total number of threads to run */
#define ATONCE 20 /* Number of threads to run at once */
#define GRAPHSIZE 200 /* Least graph size to use */
typedef struct
{
int n;
boolean writeautoms;
} params; /* Used to pass parameters to the thread */
static void*
runit(void * threadarg) /* Main routine for one thread */
{
DYNALLSTAT(graph,g,g_sz);
DYNALLSTAT(int,lab,lab_sz);
DYNALLSTAT(int,ptn,ptn_sz);
DYNALLSTAT(int,orbits,orbits_sz);
DEFAULTOPTIONS_GRAPH(options);
statsblk stats;
set *gv;
int n,m,v;
n = ((params*)threadarg)->n;
/* Default options are set by the DEFAULTOPTIONS_GRAPH macro above.
Here we change those options that we want to be different from the
defaults. writeautoms=TRUE causes automorphisms to be written. */
options.writeautoms = ((params*)threadarg)->writeautoms;
m = SETWORDSNEEDED(n);
/* The following optional call verifies that we are linking
to compatible versions of the nauty routines. */
nauty_check(WORDSIZE,m,n,NAUTYVERSIONID);
DYNALLOC2(graph,g,g_sz,m,n,"malloc");
DYNALLOC1(int,lab,lab_sz,n,"malloc");
DYNALLOC1(int,ptn,ptn_sz,n,"malloc");
DYNALLOC1(int,orbits,orbits_sz,n,"malloc");
/* Now we will make a polygon of n vertices */
EMPTYGRAPH(g,m,n);
for (v = 0; v < n; ++v) ADDONEEDGE(g,v,(v+1)%n,m);
if (options.writeautoms)
printf("Generators for Aut(C[%d]):\n",n);
densenauty(g,lab,ptn,orbits,&options,&stats,m,n,NULL);
if (options.writeautoms)
{
printf("order = ");
writegroupsize(stdout,stats.grpsize1,stats.grpsize2);
printf("\n");
}
if (stats.numorbits != 1 || stats.grpsize1 != 2*n)
fprintf(stderr,">E group error\n");
/* If we are using multiple threads, we need to free all the dynamic
memory we have allocated. We don't have to do this after each
call to nauty, just once before the thread finishes. */
DYNFREE(g,g_sz);
DYNFREE(lab,lab_sz);
DYNFREE(ptn,ptn_sz);
DYNFREE(orbits,orbits_sz);
nauty_freedyn();
nautil_freedyn();
naugraph_freedyn(); /* Use nausparse_freedyn() instead if
sparse format is being used. */
return NULL;
}
int
main(int argc, char *argv[])
{
int n,ret;
pthread_t thread[THREADS];
params par[THREADS];
int started,finished;
#if !HAVE_TLS
fprintf(stderr,">E This program needs to be linked with a version\n");
fprintf(stderr," of nauty successfully configured with --enable-tls.\n");
exit(1);
#endif
for (started = finished = 0; finished < THREADS; )
{
if (started == THREADS || started-finished == ATONCE)
{
if ((ret = pthread_join(thread[finished],NULL)) != 0)
{
fprintf(stderr,">E Thread joining failed, code=%d\n",ret);
exit(1);
}
++finished;
}
else
{
/* We vary the graph size a bit as it tests the
thread independence better. */
par[started].n = GRAPHSIZE + (started % 17);
par[started].writeautoms = FALSE;
if ((ret = pthread_create(&thread[started],NULL,
runit,&par[started])) != 0)
{
fprintf(stderr,">E Thread creation failed, code=%d\n",ret);
exit(1);
}
++started;
}
}
exit(0);
}