1
/* Copyright 2008,2010 ENSEIRB, INRIA & CNRS
3
** This file is part of the Scotch software package for static mapping,
4
** graph partitioning and sparse matrix ordering.
6
** This software is governed by the CeCILL-C license under French law
7
** and abiding by the rules of distribution of free software. You can
8
** use, modify and/or redistribute the software under the terms of the
9
** CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
10
** URL: "http://www.cecill.info".
12
** As a counterpart to the access to the source code and rights to copy,
13
** modify and redistribute granted by the license, users are provided
14
** only with a limited warranty and the software's author, the holder of
15
** the economic rights, and the successive licensors have only limited
18
** In this respect, the user's attention is drawn to the risks associated
19
** with loading, using, modifying and/or developing or reproducing the
20
** software by the user in light of its specific status of free software,
21
** that may mean that it is complicated to manipulate, and that also
22
** therefore means that it is reserved for developers and experienced
23
** professionals having in-depth computer knowledge. Users are therefore
24
** encouraged to load and test the software's suitability as regards
25
** their requirements in conditions enabling the security of their
26
** systems and/or data to be ensured and, more generally, to use and
27
** operate it in the same conditions as regards security.
29
** The fact that you are presently reading this means that you have had
30
** knowledge of the CeCILL-C license and that you accept its terms.
32
/************************************************************/
34
/** NAME : dggath.c **/
36
/** AUTHOR : Francois PELLEGRINI **/
38
/** FUNCTION : This program gathers the fragments of a **/
39
/** distributed graph and saves it as a **/
40
/** centralized source graph. **/
41
/** This module contains the main function. **/
43
/** DATES : # Version 5.1 : from : 26 oct 2008 **/
44
/** to : 26 oct 2008 **/
46
/************************************************************/
49
** The defines and includes.
53
#define SCOTCH_PTSCOTCH
61
** The static and global definitions.
64
static int C_fileNum = 0; /* Number of file in arg list */
65
static File C_fileTab[C_FILENBR] = { /* File array */
69
static const char * C_usageList[] = {
70
"dggath [<input (distributed) source file> [<output centralized source file>]] <options>",
71
" -c : Check the input graph after loading",
72
" -h : Display this help",
73
" -r<num> : Set root process for centralized files (default is 0)",
74
" -V : Print program version and copyright",
77
/*********************/
79
/* The main routine. */
81
/*********************/
88
SCOTCH_Graph * cgrfptr;
90
SCOTCH_Dgraph dgrfdat;
93
int protglbnum; /* Root process */
101
#endif /* SCOTCH_PTHREAD */
103
errorProg ("dggath");
105
#ifdef SCOTCH_PTHREAD
106
thrdlvlreqval = MPI_THREAD_MULTIPLE;
107
if (MPI_Init_thread (&argc, &argv, thrdlvlreqval, &thrdlvlproval) != MPI_SUCCESS)
108
errorPrint ("main: Cannot initialize (1)");
109
if (thrdlvlreqval > thrdlvlproval)
110
errorPrint ("main: MPI implementation is not thread-safe: recompile without SCOTCH_PTHREAD");
111
#else /* SCOTCH_PTHREAD */
112
if (MPI_Init (&argc, &argv) != MPI_SUCCESS)
113
errorPrint ("main: Cannot initialize (2)");
114
#endif /* SCOTCH_PTHREAD */
116
MPI_Comm_size (MPI_COMM_WORLD, &procglbnbr); /* Get communicator data */
117
MPI_Comm_rank (MPI_COMM_WORLD, &proclocnum);
118
protglbnum = 0; /* Assume root process is process 0 */
120
if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */
121
usagePrint (stdout, C_usageList);
125
flagval = C_FLAGNONE;
127
for (i = 0; i < C_FILENBR; i ++) /* Set default stream pointers */
128
C_fileTab[i].pntr = (C_fileTab[i].mode[0] == 'r') ? stdin : stdout;
130
for (i = 1; i < argc; i ++) { /* Loop for all option codes */
131
if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */
132
if (C_fileNum < C_FILEARGNBR) /* File name has been given */
133
C_fileTab[C_fileNum ++].name = argv[i];
135
errorPrint ("main: too many file names given");
137
else { /* If found an option name */
138
switch (argv[i][1]) {
141
flagval |= C_FLAGCHECK;
143
#ifdef SCOTCH_DEBUG_ALL
146
flagval |= C_FLAGDEBUG;
148
#endif /* SCOTCH_DEBUG_ALL */
149
case 'H' : /* Give the usage message */
151
usagePrint (stdout, C_usageList);
153
case 'R' : /* Root process (if necessary) */
155
protglbnum = atoi (&argv[i][2]);
156
if ((protglbnum < 0) ||
157
(protglbnum >= procglbnbr) ||
158
((protglbnum == 0) && (argv[i][2] != '0'))) {
159
errorPrint ("main: invalid root process number");
164
fprintf (stderr, "dggath, version " SCOTCH_VERSION_STRING "\n");
165
fprintf (stderr, "Copyright 2008,2010 ENSEIRB, INRIA & CNRS, France\n");
166
fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n");
169
errorPrint ("main: unprocessed option (\"%s\")", argv[i]);
174
#ifdef SCOTCH_DEBUG_ALL
175
if ((flagval & C_FLAGDEBUG) != 0) {
176
fprintf (stderr, "Proc %4d of %d, pid %d\n", proclocnum, procglbnbr, getpid ());
177
if (proclocnum == protglbnum) { /* Synchronize on keybord input */
180
printf ("Waiting for key press...\n");
183
MPI_Barrier (MPI_COMM_WORLD);
185
#endif /* SCOTCH_DEBUG_ALL */
187
fileBlockOpenDist (C_fileTab, C_FILENBR, procglbnbr, proclocnum, protglbnum); /* Open all files */
189
if (C_filepntrsrcout == NULL) {
197
reduloctab[1] = proclocnum;
199
if (MPI_Allreduce (reduloctab, reduglbtab, 2, MPI_INT, MPI_SUM, MPI_COMM_WORLD) != MPI_SUCCESS)
200
errorPrint ("main: communication error");
202
if (reduglbtab[0] != 1)
203
errorPrint ("main: should have only one root");
204
if (reduglbtab[1] != protglbnum)
205
errorPrint ("main: root process mismatch");
207
SCOTCH_dgraphInit (&dgrfdat, MPI_COMM_WORLD);
208
SCOTCH_dgraphLoad (&dgrfdat, C_filepntrsrcinp, -1, 0);
210
if ((flagval & C_FLAGCHECK) != 0)
211
SCOTCH_dgraphCheck (&dgrfdat);
213
SCOTCH_graphInit (&cgrfdat);
214
SCOTCH_dgraphGather (&dgrfdat, cgrfptr);
216
SCOTCH_graphSave (cgrfptr, C_filepntrsrcout);
218
fileBlockClose (C_fileTab, C_FILENBR); /* Always close explicitely to end eventual (un)compression tasks */
220
SCOTCH_graphExit (&cgrfdat);
221
SCOTCH_dgraphExit (&dgrfdat);
224
#ifdef COMMON_PTHREAD
225
pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */
226
#endif /* COMMON_PTHREAD */