1 /* Copyright 2009-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS
2 **
3 ** This file is part of the Scotch software package for static mapping,
4 ** graph partitioning and sparse matrix ordering.
5 **
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".
11 **
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
16 ** liability.
17 **
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.
28 **
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.
31 */
32 /************************************************************/
33 /** **/
34 /** NAME : gscat.c **/
35 /** **/
36 /** AUTHOR : Francois PELLEGRINI **/
37 /** **/
38 /** FUNCTION : This program writes a centralized **/
39 /** source graph file in the form of a **/
40 /** distributed source graph. **/
41 /** **/
42 /** DATES : # Version 5.1 : from : 26 apr 2009 **/
43 /** to : 14 feb 2011 **/
44 /** # Version 6.0 : from : 01 jan 2012 **/
45 /** to : 12 nov 2014 **/
46 /** **/
47 /************************************************************/
48
49 /*
50 ** The defines and includes.
51 */
52
53 #define GSCAT
54
55 #include "module.h"
56 #include "common.h"
57 #include "scotch.h"
58 #include "gscat.h"
59
60 /*
61 ** The static variables.
62 */
63
64 static int C_paraNum = 0; /* Number of parameters */
65 static int C_fileNum = 0; /* Number of file in arg list */
66 static File C_fileTab[C_FILENBR] = { /* File array */
67 { "r" },
68 { "w" } };
69
70 static const char * C_usageList[] = { /* Usage */
71 "gscat <nparts> <input source file> <output target file pattern> <options>",
72 " -h : Display this help",
73 " -V : Print program version and copyright",
74 NULL };
75
76 /******************************/
77 /* */
78 /* This is the main function. */
79 /* */
80 /******************************/
81
82 int
main(int argc,char * argv[])83 main (
84 int argc,
85 char * argv[])
86 {
87 SCOTCH_Num p[1] = { 1 }; /* Number of parts */
88 int i;
89
90 errorProg ("gscat");
91
92 if ((argc >= 2) && (argv[1][0] == '?')) { /* If need for help */
93 usagePrint (stdout, C_usageList);
94 return (0);
95 }
96
97 fileBlockInit (C_fileTab, C_FILENBR); /* Set default stream pointers */
98
99 for (i = 1; i < argc; i ++) { /* Loop for all option codes */
100 if ((argv[i][0] != '-') || (argv[i][1] == '\0') || (argv[i][1] == '.')) { /* If found a file name */
101 if (C_paraNum < 1) { /* If number of parameters not reached */
102 if ((p[C_paraNum ++] = atoi (argv[i])) < 1) { /* Get number of parts */
103 errorPrint ("main: invalid number of parts '%s'", argv[i]);
104 return (1);
105 }
106 continue; /* Process the other parameters */
107 }
108 if (C_fileNum < C_FILEARGNBR) /* A file name has been given */
109 fileBlockName (C_fileTab, C_fileNum ++) = argv[i];
110 else {
111 errorPrint ("main: too many file names given");
112 return (1);
113 }
114 }
115 else { /* If found an option name */
116 switch (argv[i][1]) {
117 case 'H' : /* Give the usage message */
118 case 'h' :
119 usagePrint (stdout, C_usageList);
120 return (0);
121 case 'V' :
122 fprintf (stderr, "gscat, version " SCOTCH_VERSION_STRING "\n");
123 fprintf (stderr, "Copyright 2009-2012,2014 IPB, Universite de Bordeaux, INRIA & CNRS, France\n");
124 fprintf (stderr, "This software is libre/free software under CeCILL-C -- see the user's manual for more information\n");
125 return (0);
126 default :
127 errorPrint ("main: unprocessed option '%s'", argv[i]);
128 return (1);
129 }
130 }
131 }
132
133 fileBlockOpen (C_fileTab, 1); /* Open input graph file */
134
135 C_graphScat (C_filepntrsrcinp, p[0], C_filenamesrcout);
136
137 fileBlockClose (C_fileTab, 1); /* Always close explicitely to end eventual (un)compression tasks */
138
139 #ifdef COMMON_PTHREAD
140 pthread_exit ((void *) 0); /* Allow potential (un)compression tasks to complete */
141 #endif /* COMMON_PTHREAD */
142 return (0);
143 }
144
145 static
146 int
C_graphScat(FILE * const stream,SCOTCH_Num procnbr,char * const nameptr)147 C_graphScat (
148 FILE * const stream,
149 SCOTCH_Num procnbr,
150 char * const nameptr)
151 {
152 SCOTCH_Num versval;
153 SCOTCH_Num propval;
154 char proptab[4];
155 int flagtab[3];
156 SCOTCH_Num baseval;
157 SCOTCH_Num vertglbnbr;
158 SCOTCH_Num edgeglbnbr;
159 SCOTCH_Num procnum;
160
161 if (intLoad (stream, &versval) != 1) { /* Read version number */
162 errorPrint ("C_graphScat: bad input (1)");
163 return (1);
164 }
165 if (versval != 0) { /* If version not zero */
166 errorPrint ("C_graphScat: only centralized graphs supported");
167 return (1);
168 }
169
170 if ((intLoad (stream, &vertglbnbr) != 1) || /* Read rest of header */
171 (intLoad (stream, &edgeglbnbr) != 1) ||
172 (intLoad (stream, &baseval) != 1) ||
173 (intLoad (stream, &propval) != 1) ||
174 (propval < 0) ||
175 (propval > 111)) {
176 errorPrint ("C_graphScat: bad input (2)");
177 return (1);
178 }
179 sprintf (proptab, "%3.3d", (int) propval); /* Compute file properties */
180 flagtab[0] = proptab[0] - '0'; /* Vertex labels flag */
181 flagtab[1] = proptab[1] - '0'; /* Edge weights flag */
182 flagtab[2] = proptab[2] - '0'; /* Vertex loads flag */
183
184 for (procnum = 0; procnum < procnbr; procnum ++) {
185 char * nametmp;
186 FILE * ostream;
187 SCOTCH_Num vertlocnbr;
188 SCOTCH_Num vertlocnum;
189 SCOTCH_Num edgelocnbr;
190
191 nametmp = nameptr;
192 ostream = NULL;
193 if (fileNameDistExpand (&nametmp, procnbr, procnum, -1) == 0) {
194 ostream = fopen (nametmp, "w+");
195 memFree (nametmp); /* Expanded name no longer needed anyway */
196 }
197 if (ostream == NULL) {
198 errorPrint ("C_graphScat: cannot open file");
199 return (1);
200 }
201
202 vertlocnbr = DATASIZE (vertglbnbr, procnbr, procnum);
203
204 if (fprintf (ostream, "2\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n" SCOTCH_NUMSTRING "\t%015d\n" SCOTCH_NUMSTRING "\t%3s\n", /* Write file header */
205 (SCOTCH_Num) procnbr,
206 (SCOTCH_Num) procnum,
207 (SCOTCH_Num) vertglbnbr,
208 (SCOTCH_Num) edgeglbnbr,
209 (SCOTCH_Num) vertlocnbr,
210 0, /* Number of edges not yet known */
211 (SCOTCH_Num) baseval,
212 proptab) == EOF) {
213 errorPrint ("C_graphScat: bad output (1)");
214 return (1);
215 }
216
217 for (vertlocnum = edgelocnbr = 0; vertlocnum < vertlocnbr; vertlocnum ++) {
218 SCOTCH_Num degrval;
219
220 if (flagtab[0] != 0) { /* If must read label */
221 SCOTCH_Num vlblval; /* Value where to read vertex label */
222
223 if (intLoad (stream, &vlblval) != 1) { /* Read label data */
224 errorPrint ("C_graphScat: bad input (3)");
225 return (1);
226 }
227 intSave (ostream, vlblval);
228 putc ('\t', ostream);
229 }
230 if (flagtab[2] != 0) { /* If must read vertex load */
231 SCOTCH_Num veloval; /* Value where to read vertex load */
232
233 if (intLoad (stream, &veloval) != 1) { /* Read vertex load data */
234 errorPrint ("C_graphScat: bad input (4)");
235 return (1);
236 }
237 intSave (ostream, veloval);
238 putc ('\t', ostream);
239 }
240 if (intLoad (stream, °rval) != 1) { /* Read vertex degree */
241 errorPrint ("C_graphScat: bad input (5)");
242 return (1);
243 }
244 intSave (ostream, degrval);
245
246 edgelocnbr += degrval;
247
248 for ( ; degrval > 0; degrval --) {
249 SCOTCH_Num edgeval; /* Value where to read edge end */
250
251 if (flagtab[1] != 0) { /* If must read edge load */
252 SCOTCH_Num edloval; /* Value where to read edge load */
253
254 if (intLoad (stream, &edloval) != 1) { /* Read edge load data */
255 errorPrint ("C_graphScat: bad input (6)");
256 return (1);
257 }
258 putc ('\t', ostream);
259 intSave (ostream, edloval);
260 }
261
262 if (intLoad (stream, &edgeval) != 1) { /* Read edge data */
263 errorPrint ("C_graphScat: bad input (7)");
264 return (1);
265 }
266 putc ('\t', ostream);
267 intSave (ostream, edgeval);
268 }
269 putc ('\n', ostream);
270 }
271
272 rewind (ostream);
273
274 if (fprintf (ostream, "2\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n" SCOTCH_NUMSTRING "\t" SCOTCH_NUMSTRING "\n" SCOTCH_NUMSTRING "\t%015lld\n" SCOTCH_NUMSTRING "\t%3s\n", /* Write file header */
275 (SCOTCH_Num) procnbr,
276 (SCOTCH_Num) procnum,
277 (SCOTCH_Num) vertglbnbr,
278 (SCOTCH_Num) edgeglbnbr,
279 (SCOTCH_Num) vertlocnbr,
280 (long long) edgelocnbr, /* Now we know the exact number of edges */
281 (SCOTCH_Num) baseval,
282 proptab) == EOF) {
283 errorPrint ("C_graphScat: bad output (2)");
284 return (1);
285 }
286
287 fclose (ostream);
288 }
289
290 return (0);
291 }
292