1 /* Copyright 2007,2010,2012 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 : hdgraph_gather.c **/
35 /** **/
36 /** AUTHORS : Francois PELLEGRINI **/
37 /** **/
38 /** FUNCTION : This module contains the routine which **/
39 /** builds a centralized halo graph by **/
40 /** gathering the pieces of a distributed **/
41 /** halo graph. **/
42 /** **/
43 /** DATES : # Version 5.0 : from : 19 apr 2006 **/
44 /** to : 10 sep 2007 **/
45 /** # Version 5.1 : from : 30 jul 2010 **/
46 /** to : 30 jul 2010 **/
47 /** # Version 6.0 : from : 27 nov 2012 **/
48 /** to 27 nov 2012 **/
49 /** **/
50 /************************************************************/
51
52 /*
53 ** The defines and includes.
54 */
55
56 #define HDGRAPH_GATHER
57
58 #include "module.h"
59 #include "common.h"
60 #include "comm.h"
61 #include "graph.h"
62 #include "hgraph.h"
63 #include "dgraph.h"
64 #include "hdgraph.h"
65
66 /******************************/
67 /* */
68 /* These routines handle halo */
69 /* distributed source graphs. */
70 /* */
71 /******************************/
72
73 /* This function gathers the pieces of
74 ** a distributed halo graph to build a
75 ** centralized halo graph.
76 ** There is no gathered vnumtab array if
77 ** the original graph did not have one, as
78 ** vertices are gathered in global order, or
79 ** else the original vnumloctab is gathered.
80 ** It returns:
81 ** - 0 : if graph data are consistent.
82 ** - !0 : on error.
83 */
84
85 int
hdgraphGather(Hdgraph * restrict const dgrfptr,Hgraph * restrict const cgrfptr)86 hdgraphGather (
87 Hdgraph * restrict const dgrfptr, /* Distributed halo graph */
88 Hgraph * restrict const cgrfptr) /* Centralized halo graph */
89 {
90 Gnum vertlocnum;
91 Gnum vertlocadj; /* Local vertex array adjust */
92 Gnum vhallocnnd;
93 int vhallocnbr; /* Local copy for sending as a MPI_INT */
94 Gnum * restrict verthaltax;
95 Gnum * restrict edgehaltax;
96 Gnum edgehalnum;
97 int ehallocnbr; /* Local copy for sending as a MPI_INT */
98 int rootnum; /* Index of root process */
99 Gnum reduloctab[4]; /* Arrays for reductions */
100 Gnum reduglbtab[4];
101 int * restrict recvcnttab; /* Arrays for parametrizing gather operations */
102 int * restrict recvdsptab;
103 int cheklocval;
104 int chekglbval;
105 Gnum degrmax;
106
107 if (cgrfptr != NULL) { /* If centralized graph provided */
108 reduloctab[0] = 1; /* This process is the root */
109 reduloctab[1] = (Gnum) dgrfptr->s.proclocnum; /* Get its rank */
110 }
111 else {
112 reduloctab[0] = /* This process is not the root */
113 reduloctab[1] = 0;
114 }
115 reduloctab[2] = dgrfptr->vhallocnbr;
116 reduloctab[3] = dgrfptr->ehallocnbr;
117 if (MPI_Allreduce (reduloctab, reduglbtab, 4, GNUM_MPI, MPI_SUM, dgrfptr->s.proccomm) != MPI_SUCCESS) {
118 errorPrint ("hdgraphGather: communication error (1)");
119 return (1);
120 }
121 if (reduglbtab[0] != 1) {
122 errorPrint ("hdgraphGather: should have only one root");
123 return (1);
124 }
125 rootnum = (int) reduglbtab[1]; /* Get rank of root process */
126 degrmax = dgrfptr->s.degrglbmax; /* Distributed degree does not account for halo edges */
127
128 cheklocval = 0;
129 if (cgrfptr != NULL) { /* If process is root */
130 Gnum vnohnbr;
131 Gnum vertnbr;
132 Gnum velonbr;
133 Gnum vnumnbr;
134 Gnum * restrict velotax;
135 Gnum * restrict vnumtax;
136 Gnum edgenbr;
137
138 vnohnbr = dgrfptr->s.vertglbnbr;
139 vertnbr = vnohnbr + reduglbtab[2];
140 velonbr = (dgrfptr->s.veloloctax != NULL) ? vertnbr : 0;
141 vnumnbr = (dgrfptr->s.vnumloctax != NULL) ? vnohnbr : 0; /* Vertex numbers only serve for non-halo vertices */
142 edgenbr = dgrfptr->s.edgeglbnbr + 2 * reduglbtab[3]; /* Twice since halo vertices will be created for real */
143
144 cgrfptr->s.flagval = GRAPHFREEEDGE | GRAPHEDGEGROUP | GRAPHFREEVERT | GRAPHVERTGROUP; /* In case of premature freeing on error */
145 recvcnttab = NULL;
146 if (memAllocGroup ((void **) (void *)
147 &cgrfptr->s.verttax, (size_t) ((vertnbr + 1) * sizeof (Gnum)), /* Compact vertex array */
148 &velotax, (size_t) (velonbr * sizeof (Gnum)),
149 &vnumtax, (size_t) (vnumnbr * sizeof (Gnum)),
150 &cgrfptr->vnhdtax, (size_t) (vnohnbr * sizeof (Gnum)), NULL) == NULL) {
151 errorPrint ("hdgraphGather: out of memory (1)");
152 cheklocval = 1;
153 }
154 else if (cgrfptr->s.verttax -= dgrfptr->s.baseval,
155 cgrfptr->s.velotax = (dgrfptr->s.veloloctax != NULL) ? velotax - dgrfptr->s.baseval : NULL,
156 cgrfptr->s.vnumtax = (dgrfptr->s.vnumloctax != NULL) ? vnumtax - dgrfptr->s.baseval : NULL,
157 cgrfptr->vnhdtax -= dgrfptr->s.baseval,
158 ((cgrfptr->s.edgetax = (Gnum *) memAlloc (edgenbr * sizeof (Gnum))) == NULL)) {
159 errorPrint ("hdgraphGather: out of memory (2)");
160 cheklocval = 1;
161 }
162 else if (cgrfptr->s.edgetax -= dgrfptr->s.baseval,
163 memAllocGroup ((void **) (void *)
164 &recvcnttab, (size_t) (dgrfptr->s.procglbnbr * sizeof (int)),
165 &recvdsptab, (size_t) (dgrfptr->s.procglbnbr * sizeof (int)), NULL) == NULL) {
166 errorPrint ("hdgraphGather: out of memory (3)");
167 cheklocval = 1;
168 }
169 else {
170 cgrfptr->s.baseval = dgrfptr->s.baseval;
171 cgrfptr->s.vertnbr = vertnbr;
172 cgrfptr->s.vertnnd = vertnbr + dgrfptr->s.baseval;
173 cgrfptr->s.vendtax = cgrfptr->s.verttax + 1; /* Compact edge array */
174 cgrfptr->s.velosum = dgrfptr->s.veloglbsum + reduglbtab[2]; /* Halo vertices have unity vertex loads */
175 cgrfptr->s.vlbltax = NULL;
176 cgrfptr->s.edgenbr = edgenbr;
177 cgrfptr->s.edlotax = NULL;
178 cgrfptr->s.edlosum = edgenbr;
179 cgrfptr->s.procptr = NULL; /* Not a multi-sequential gather: no communication possible */
180 cgrfptr->vnohnbr = vnohnbr;
181 cgrfptr->vnohnnd = vnohnbr + dgrfptr->s.baseval;
182 cgrfptr->vnlosum = dgrfptr->s.veloglbsum;
183 cgrfptr->enohnbr =
184 cgrfptr->enohsum = dgrfptr->s.edgeglbnbr;
185 cgrfptr->levlnum = dgrfptr->levlnum;
186 }
187 }
188 if ((cheklocval == 0) &&
189 (memAllocGroup ((void **) (void *)
190 &verthaltax, (size_t) (dgrfptr->vhallocnbr * sizeof (Gnum)),
191 &edgehaltax, (size_t) (dgrfptr->ehallocnbr * sizeof (Gnum)), NULL) == NULL)) {
192 errorPrint ("hdgraphGather: out of memory (4)");
193 cheklocval = 1;
194 }
195 else {
196 verthaltax -= dgrfptr->s.baseval;
197 edgehaltax -= dgrfptr->s.baseval;
198 }
199 if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_SUM, dgrfptr->s.proccomm) != MPI_SUCCESS) {
200 errorPrint ("hdgraphGather: communication error (2)");
201 return (1);
202 }
203 if (chekglbval != 0) {
204 if (verthaltax != NULL)
205 memFree (verthaltax + dgrfptr->s.baseval);
206 if (cgrfptr != NULL) { /* If data were previously allocated */
207 if (recvcnttab != NULL)
208 memFree (recvcnttab);
209 hgraphExit (cgrfptr);
210 }
211 return (1);
212 }
213
214 if (dgrfptr->vhndloctax == dgrfptr->s.vertloctax + 1) { /* If distributed halo graph is compact */
215 Gnum procglbnum;
216 Gnum edgenum;
217
218 if (cgrfptr != NULL) {
219 Gnum vertnum;
220
221 cgrfptr->s.verttax[dgrfptr->s.baseval] = dgrfptr->s.baseval;
222 if (commGatherv (dgrfptr->s.vertloctax + 1 + dgrfptr->s.baseval, /* Do not send first index, it is always equal to baseval */
223 dgrfptr->s.vertlocnbr, GNUM_MPI,
224 cgrfptr->s.verttax + 1, /* First index will always be equal to baseval too, and procdsptab holds based values */
225 dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
226 errorPrint ("hdgraphGather: communication error (3)");
227 return (1);
228 }
229 if (commGatherv (dgrfptr->s.vendloctax + dgrfptr->s.baseval,
230 dgrfptr->s.vertlocnbr, GNUM_MPI, cgrfptr->vnhdtax, /* procdsptab holds based values */
231 dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
232 errorPrint ("hdgraphGather: communication error (4)");
233 return (1);
234 }
235
236 for (procglbnum = 1, vertnum = dgrfptr->s.procdsptab[1] + 1; /* Adjust index sub-arrays for all processors except the first one */
237 procglbnum < dgrfptr->s.procglbnbr; procglbnum ++) {
238 Gnum vertnnd;
239 Gnum edgeadj;
240
241 for (vertnnd = dgrfptr->s.procdsptab[procglbnum + 1] + 1,
242 edgeadj = cgrfptr->s.verttax[vertnum - 1] - dgrfptr->s.baseval;
243 vertnum < vertnnd; vertnum ++) {
244 cgrfptr->s.verttax[vertnum] += edgeadj;
245 cgrfptr->vnhdtax[vertnum - 1] += edgeadj;
246 }
247 }
248
249 for (procglbnum = 0, edgenum = dgrfptr->s.baseval; /* Build arrays for MPI_Gatherv on edge arrays */
250 procglbnum < dgrfptr->s.procglbnbr; procglbnum ++) {
251 recvcnttab[procglbnum] = cgrfptr->s.verttax[dgrfptr->s.procdsptab[procglbnum + 1]] -
252 cgrfptr->s.verttax[dgrfptr->s.procdsptab[procglbnum]]; /* verttax used twice since centralized graph is compact */
253 recvdsptab[procglbnum] = edgenum;
254 edgenum += recvcnttab[procglbnum];
255 }
256 if (MPI_Gatherv (dgrfptr->s.edgeloctax + dgrfptr->s.baseval, /* Gather edge arrays with global vertex indices */
257 (int) (dgrfptr->s.edgelocnbr + dgrfptr->ehallocnbr), GNUM_MPI, cgrfptr->s.edgetax,
258 recvcnttab, recvdsptab, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
259 errorPrint ("hdgraphGather: communication error (5)");
260 return (1);
261 }
262 }
263 else {
264 if (MPI_Gatherv (dgrfptr->s.vertloctax + 1 + dgrfptr->s.baseval, /* Do not send first index, it is always equal to baseval */
265 (int) dgrfptr->s.vertlocnbr, GNUM_MPI, NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
266 errorPrint ("hdgraphGather: communication error (6)");
267 return (1);
268 }
269 if (MPI_Gatherv (dgrfptr->s.vendloctax + dgrfptr->s.baseval,
270 (int) dgrfptr->s.vertlocnbr, GNUM_MPI, NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
271 errorPrint ("hdgraphGather: communication error (7)");
272 return (1);
273 }
274 if (MPI_Gatherv (dgrfptr->s.edgeloctax + dgrfptr->s.baseval, /* Gather edge arrays with global vertex indices */
275 (int) (dgrfptr->s.edgelocnbr + dgrfptr->ehallocnbr), GNUM_MPI,
276 NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
277 errorPrint ("hdgraphGather: communication error (8)");
278 return (1);
279 }
280 }
281 }
282 else {
283 errorPrint ("hdgraphGather: Not implemented"); /* Not really necessary as all Hdgraph structures created by Scotch itself are compact */
284 return (1);
285 }
286
287 memSet (verthaltax + dgrfptr->s.baseval, 0, dgrfptr->vhallocnbr * sizeof (Gnum)); /* Initialize halo end vertex count array */
288 for (vertlocnum = dgrfptr->s.baseval; vertlocnum < dgrfptr->s.vertlocnnd; vertlocnum ++) {
289 Gnum edgelocnum;
290
291 for (edgelocnum = dgrfptr->s.vendloctax[vertlocnum]; edgelocnum < dgrfptr->vhndloctax[vertlocnum]; edgelocnum ++)
292 verthaltax[dgrfptr->s.edgeloctax[edgelocnum]] ++; /* One more edge to this halo vertex */
293 }
294 vhallocnbr = (int) dgrfptr->vhallocnbr;
295 if (MPI_Gather (&vhallocnbr, 1, MPI_INT, recvcnttab, 1, MPI_INT, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
296 errorPrint ("hdgraphGather: communication error (9)");
297 return (1);
298 }
299 if (cgrfptr != NULL) { /* Build gather parameter array to receive halo edge counts */
300 Gnum procglbnum;
301 Gnum vertnum;
302
303 for (procglbnum = 0, vertnum = 0; procglbnum < dgrfptr->s.procglbnbr; procglbnum ++) { /* Displacements start from zero because adjusted later */
304 recvdsptab[procglbnum] = vertnum;
305 vertnum += recvcnttab[procglbnum];
306 }
307 if (MPI_Gatherv (verthaltax + dgrfptr->s.baseval, (int) dgrfptr->vhallocnbr, GNUM_MPI, /* Gather count arrays of halo vertices */
308 cgrfptr->s.verttax + cgrfptr->vnohnnd + 1, recvcnttab, recvdsptab, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
309 errorPrint ("hdgraphGather: communication error (10)");
310 return (1);
311 }
312
313 for (procglbnum = 0, vertnum = dgrfptr->s.baseval; /* Adjust end vertex indices for halo edges */
314 procglbnum < dgrfptr->s.procglbnbr; procglbnum ++) {
315 Gnum vertnnd;
316 Gnum vertadj;
317
318 for (vertnnd = dgrfptr->s.procdsptab[procglbnum + 1], vertadj = cgrfptr->vnohnbr + recvdsptab[procglbnum];
319 vertnum < vertnnd; vertnum ++) {
320 Gnum edgenum;
321
322 if (degrmax < (cgrfptr->s.vendtax[vertnum] - cgrfptr->s.verttax[vertnum])) /* Account for halo edges in maximum degree */
323 degrmax = (cgrfptr->s.vendtax[vertnum] - cgrfptr->s.verttax[vertnum]);
324 for (edgenum = cgrfptr->vnhdtax[vertnum]; edgenum < cgrfptr->s.vendtax[vertnum]; edgenum ++)
325 cgrfptr->s.edgetax[edgenum] += vertadj;
326 }
327 }
328 }
329 else {
330 if (MPI_Gatherv (verthaltax + dgrfptr->s.baseval, (int) dgrfptr->vhallocnbr, GNUM_MPI, /* Gather count arrays of halo vertices */
331 NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
332 errorPrint ("hdgraphGather: communication error (11)");
333 return (1);
334 }
335 }
336 for (vertlocnum = edgehalnum = dgrfptr->s.baseval, vhallocnnd = dgrfptr->vhallocnbr + dgrfptr->s.baseval;
337 vertlocnum < vhallocnnd; vertlocnum ++) { /* Prepare index array for edge collection */
338 Gnum degrlocval;
339
340 degrlocval = verthaltax[vertlocnum];
341 verthaltax[vertlocnum] = edgehalnum;
342 edgehalnum += degrlocval;
343 }
344 vertlocadj = dgrfptr->s.procdsptab[dgrfptr->s.proclocnum] - dgrfptr->s.baseval;
345 for (vertlocnum = dgrfptr->s.baseval; vertlocnum < dgrfptr->s.vertlocnnd; vertlocnum ++) { /* Collect halo edge ends */
346 Gnum edgelocnum;
347
348 for (edgelocnum = dgrfptr->s.vendloctax[vertlocnum]; edgelocnum < dgrfptr->vhndloctax[vertlocnum]; edgelocnum ++)
349 edgehaltax[verthaltax[dgrfptr->s.edgeloctax[edgelocnum]] ++] = vertlocnum + vertlocadj;
350 }
351 ehallocnbr = (int) dgrfptr->ehallocnbr;
352 if (MPI_Gather (&ehallocnbr, 1, MPI_INT, recvcnttab, 1, MPI_INT, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) { /* Gather halo edge counts */
353 errorPrint ("hdgraphGather: communication error (12)");
354 return (1);
355 }
356 if (cgrfptr != NULL) { /* Compute receive arrays for edge sub-arrays of halo vertices */
357 Gnum procglbnum;
358 Gnum edgeadj;
359
360 for (procglbnum = 0, edgeadj = 0; procglbnum < dgrfptr->s.procglbnbr; procglbnum ++) {
361 recvdsptab[procglbnum] = edgeadj;
362 edgeadj += recvcnttab[procglbnum];
363 }
364 if (MPI_Gatherv (edgehaltax + dgrfptr->s.baseval, (int) dgrfptr->ehallocnbr, GNUM_MPI, /* Gather edge arrays of halo vertices */
365 cgrfptr->s.edgetax + cgrfptr->enohnbr + reduglbtab[3] + dgrfptr->s.baseval, recvcnttab, recvdsptab, GNUM_MPI,
366 rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
367 errorPrint ("hdgraphGather: communication error (13)");
368 return (1);
369 }
370 }
371 else {
372 if (MPI_Gatherv (edgehaltax + dgrfptr->s.baseval, (int) dgrfptr->ehallocnbr, GNUM_MPI, /* Gather edge arrays of halo vertices */
373 NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
374 errorPrint ("hdgraphGather: communication error (14)");
375 return (1);
376 }
377 }
378
379 memFree (verthaltax + dgrfptr->s.baseval); /* Free group leader */
380
381 if (cgrfptr != NULL) { /* Finalize vertex and edge arrays of centralized graph */
382 Gnum vertnum;
383 Gnum edgeadj;
384
385 if (dgrfptr->s.veloloctax != NULL) { /* Get vertex loads if any */
386 if (commGatherv (dgrfptr->s.veloloctax + dgrfptr->s.baseval, dgrfptr->s.vertlocnbr, GNUM_MPI,
387 cgrfptr->s.velotax, dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GNUM_MPI,
388 rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
389 errorPrint ("hdgraphGather: communication error (15)");
390 return (1);
391 }
392
393 for (vertnum = cgrfptr->vnohnnd; vertnum < cgrfptr->s.vertnnd; vertnum ++) /* complete filling of vertex load array */
394 cgrfptr->s.velotax[vertnum] = 1;
395 }
396 if (dgrfptr->s.vnumloctax != NULL) { /* Get vertex numbers if any */
397 if (commGatherv (dgrfptr->s.vnumloctax + dgrfptr->s.baseval, dgrfptr->s.vertlocnbr, GNUM_MPI,
398 cgrfptr->s.vnumtax, dgrfptr->s.proccnttab, dgrfptr->s.procdsptab, GNUM_MPI,
399 rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
400 errorPrint ("hdgraphGather: communication error (16)");
401 return (1);
402 }
403 }
404
405 memFree (recvcnttab); /* Free group leader */
406
407 for (vertnum = cgrfptr->vnohnnd + 1, edgeadj = cgrfptr->s.verttax[cgrfptr->vnohnnd]; /* Adjust vertex array for halo vertices */
408 vertnum <= cgrfptr->s.vertnnd; vertnum ++) {
409 Gnum degrval;
410
411 degrval = cgrfptr->s.verttax[vertnum];
412 if (degrmax < degrval) /* Account for halo edges in maximum degree */
413 degrmax = degrval;
414 edgeadj += degrval;
415 cgrfptr->s.verttax[vertnum] = edgeadj;
416 }
417 cgrfptr->s.degrmax = degrmax;
418 }
419 else {
420 if (dgrfptr->s.veloloctax != NULL) { /* Get vertex loads if any */
421 if (MPI_Gatherv (dgrfptr->s.veloloctax + dgrfptr->s.baseval, (int) dgrfptr->s.vertlocnbr, GNUM_MPI,
422 NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
423 errorPrint ("hdgraphGather: communication error (17)");
424 return (1);
425 }
426 }
427 if (dgrfptr->s.vnumloctax != NULL) { /* Get vertex numbers if any */
428 if (MPI_Gatherv (dgrfptr->s.vnumloctax + dgrfptr->s.baseval, (int) dgrfptr->s.vertlocnbr, GNUM_MPI,
429 NULL, NULL, NULL, GNUM_MPI, rootnum, dgrfptr->s.proccomm) != MPI_SUCCESS) {
430 errorPrint ("hdgraphGather: communication error (18)");
431 return (1);
432 }
433 }
434 }
435
436 #ifdef SCOTCH_DEBUG_HDGRAPH2
437 cheklocval = (cgrfptr != NULL) ? hgraphCheck (cgrfptr) : 0;
438 if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, dgrfptr->s.proccomm) != MPI_SUCCESS) {
439 errorPrint ("hdgraphGather: communication error (19)");
440 return (1);
441 }
442 if (chekglbval != 0) {
443 errorPrint ("hdgraphGather: internal error");
444 if (cgrfptr != NULL)
445 hgraphExit (cgrfptr);
446 return (1);
447 }
448 #endif /* SCOTCH_DEBUG_HDGRAPH2 */
449
450 return (0);
451 }
452