1 /* Copyright 2007,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       : library_dgraph_gather.c                 **/
35 /**                                                        **/
36 /**   AUTHOR     : Francois PELLEGRINI                     **/
37 /**                                                        **/
38 /**   FUNCTION   : This module is the API for the distri-  **/
39 /**                buted source graph handling routines of **/
40 /**                the libSCOTCH library.                  **/
41 /**                                                        **/
42 /**   DATES      : # Version 5.0  : from : 12 jul 2007     **/
43 /**                                 to     17 jul 2007     **/
44 /**                # Version 6.0  : from : 29 nov 2012     **/
45 /**                                 to     29 nov 2012     **/
46 /**                                                        **/
47 /************************************************************/
48 
49 /*
50 **  The defines and includes.
51 */
52 
53 #define LIBRARY
54 
55 #include "module.h"
56 #include "common.h"
57 #include "graph.h"
58 #include "dgraph.h"
59 #include "ptscotch.h"
60 
61 /************************************/
62 /*                                  */
63 /* These routines are the C API for */
64 /* the graph handling routines.     */
65 /*                                  */
66 /************************************/
67 
68 /*+ This routine gathers the data of a
69 *** distributed graph on a centralized graph.
70 *** It returns:
71 *** - 0   : if the centralization succeeded.
72 *** - !0  : on error.
73 +*/
74 
75 int
SCOTCH_dgraphGather(const SCOTCH_Dgraph * const dgrfptr,SCOTCH_Graph * const cgrfptr)76 SCOTCH_dgraphGather (
77 const SCOTCH_Dgraph * const dgrfptr,
78 SCOTCH_Graph * const        cgrfptr)
79 {
80   Dgraph * restrict   srcdgrfptr;
81   Gnum                reduloctab[3];
82   Gnum                reduglbtab[3];
83 
84   srcdgrfptr = (Dgraph *) dgrfptr;
85 
86   if ((cgrfptr != NULL) && (((void *) cgrfptr) != ((void *) dgrfptr))) { /* If centralized graph provided */
87     reduloctab[0] = 1;                            /* Process is a potential root                          */
88     reduloctab[1] = (Gnum) srcdgrfptr->proclocnum;
89   }
90   else {                                          /* Process is not a root */
91     reduloctab[0] = 0;
92     reduloctab[1] = 0;
93   }
94 
95   if (srcdgrfptr->edloloctax == NULL)             /* Compute sum of edge loads for access to low-level routines */
96     reduloctab[2] = srcdgrfptr->edgelocnbr;
97   else {
98     Gnum                vertlocnum;
99     Gnum                edlolocsum;
100 
101     for (vertlocnum = srcdgrfptr->baseval, edlolocsum = 0;
102          vertlocnum < srcdgrfptr->vertlocnnd; vertlocnum ++) {
103       Gnum                edgelocnum;
104       Gnum                edgelocnnd;
105 
106       for (edgelocnum = srcdgrfptr->vertloctax[vertlocnum],
107            edgelocnnd = srcdgrfptr->vendloctax[vertlocnum];
108            edgelocnum < edgelocnnd; edgelocnum ++)
109         edlolocsum += srcdgrfptr->edloloctax[edgelocnum];
110     }
111     reduloctab[2] = edlolocsum;
112   }
113 
114   if (MPI_Allreduce (reduloctab, reduglbtab, 3, GNUM_MPI, MPI_SUM, srcdgrfptr->proccomm) != MPI_SUCCESS) {
115     errorPrint ("SCOTCH_dgraphGather: communication error");
116     return     (1);
117   }
118   if (reduglbtab[0] == 1)                         /* If only one single root */
119     return (dgraphGatherAll2 (srcdgrfptr, (Graph *) cgrfptr, reduglbtab[2], (int) reduglbtab[1]));
120   else if (reduglbtab[0] == srcdgrfptr->procglbnbr) /* If all processes are roots */
121     return (dgraphGatherAll2 (srcdgrfptr, (Graph *) cgrfptr, reduglbtab[2], -1));
122 
123   errorPrint ("SCOTCH_dgraphGather: invalid number of roots");
124   return     (1);
125 }
126