File: nauthread2.c

package info (click to toggle)
nauty 2.6r7%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 15,252 kB
  • ctags: 3,948
  • sloc: ansic: 56,634; makefile: 968; sh: 123
file content (140 lines) | stat: -rw-r--r-- 3,860 bytes parent folder | download | duplicates (5)
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
140
/* nauthread2.c

   This program tests sparse 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.
*/

#include <pthread.h>
#include "nauty.h"   
#include "nausparse.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 500   /* 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(int,lab,lab_sz);
    DYNALLSTAT(int,ptn,ptn_sz);
    DYNALLSTAT(int,orbits,orbits_sz);
    DEFAULTOPTIONS_SPARSEGRAPH(options);
    statsblk stats;
    sparsegraph sg;   /* Declare sparse graph structure */

    int n,m,i;

    n = ((params*)threadarg)->n;
    options.writeautoms = ((params*)threadarg)->writeautoms;

 /* Initialise sparse graph structure. */

    SG_INIT(sg);

    m = SETWORDSNEEDED(n);
    nauty_check(WORDSIZE,m,n,NAUTYVERSIONID);

    DYNALLOC1(int,lab,lab_sz,n,"malloc");
    DYNALLOC1(int,ptn,ptn_sz,n,"malloc");
    DYNALLOC1(int,orbits,orbits_sz,n,"malloc");

 /* SG_ALLOC makes sure that the v,d,e fields of a sparse graph
    structure point to arrays that are large enough.  This only
    works if the structure has been initialised. */

    SG_ALLOC(sg,n,2*n,"malloc");

    sg.nv = n;              /* Number of vertices */
    sg.nde = 2*n;           /* Number of directed edges */

    for (i = 0; i < n; ++i)
    {
        sg.v[i] = 2*i;
        sg.d[i] = 2;
        sg.e[2*i] = (i+n-1)%n;      /* edge i->i-1 */
        sg.e[2*i+1] = (i+n+1)%n;    /* edge i->i+1 */
    }

    if (options.writeautoms)
        printf("Generators for Aut(C[%d]):\n",n);
    sparsenauty(&sg,lab,ptn,orbits,&options,&stats,NULL);

    if (options.writeautoms)
    {
        printf("Automorphism group size = ");
        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. */

    SG_FREE(sg);
    DYNFREE(lab,lab_sz);
    DYNFREE(ptn,ptn_sz);
    DYNFREE(orbits,orbits_sz);
    nauty_freedyn();
    nautil_freedyn();
    nausparse_freedyn();  /* Use naugraph_freedyn() instead if
                            dense 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 using --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);
}