1 /* Copyright 2007,2010 ENSEIRB, 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 : dorder_io_tree.c **/
35 /** **/
36 /** AUTHOR : Francois PELLEGRINI **/
37 /** **/
38 /** FUNCTION : This module handles distributed **/
39 /** orderings. **/
40 /** **/
41 /** DATES : # Version 5.0 : from : 26 jul 2007 **/
42 /** to 26 jul 2007 **/
43 /** # Version 5.1 : from : 30 jul 2010 **/
44 /** to 30 jul 2010 **/
45 /** **/
46 /************************************************************/
47
48 /*
49 ** The defines and includes.
50 */
51
52 #define DORDER
53
54 #include "module.h"
55 #include "common.h"
56 #include "comm.h"
57 #include "dgraph.h"
58 #include "order.h"
59 #include "dorder.h"
60
61 /************************************/
62 /* */
63 /* These routines handle orderings. */
64 /* */
65 /************************************/
66
67 /* This routine saves a distributed ordering.
68 ** It returns:
69 ** - 0 : on success.
70 ** - !0 : on error.
71 */
72
73 int
dorderSaveTree2(const Dorder * restrict const ordeptr,const Dgraph * restrict const grafptr,FILE * restrict const stream,int (* funcptr)(const Order * const,const Gnum * const,FILE * const))74 dorderSaveTree2 (
75 const Dorder * restrict const ordeptr,
76 const Dgraph * restrict const grafptr,
77 FILE * restrict const stream,
78 int (* funcptr) (const Order * const, const Gnum * const, FILE * const))
79 {
80 Order corddat; /* Centralized ordering for tree structure */
81 Gnum * restrict vlbltab;
82 int procglbnbr;
83 int protnum;
84 int reduloctab[3];
85 int reduglbtab[3];
86 int cheklocval;
87 int chekglbval;
88
89 if (stream != NULL) { /* If file provided */
90 reduloctab[0] = 1; /* This process is the root */
91 reduloctab[1] = ordeptr->proclocnum; /* Get its rank */
92 }
93 else {
94 reduloctab[0] = /* This process is not the root */
95 reduloctab[1] = 0;
96 }
97 reduloctab[2] = (grafptr->vlblloctax != NULL) ? 1 : 0; /* See if vertex labels provided */
98 if (MPI_Allreduce (reduloctab, reduglbtab, 3, MPI_INT, MPI_SUM, ordeptr->proccomm) != MPI_SUCCESS) {
99 errorPrint ("dorderSaveTree2: communication error (1)");
100 return (1);
101 }
102 if (reduglbtab[0] != 1) {
103 errorPrint ("dorderSaveTree2: should have only one root");
104 return (1);
105 }
106 MPI_Comm_size (ordeptr->proccomm, &procglbnbr);
107 if ((reduglbtab[2] != 0) && (reduglbtab[2] != procglbnbr)) {
108 errorPrint ("dorderSaveTree2: inconsistent parameters");
109 return (1);
110 }
111 protnum = (int) reduglbtab[1]; /* Get rank of root process */
112
113 cheklocval = 0;
114 vlbltab = NULL;
115 if (reduglbtab[2] != 0) {
116 if (protnum == ordeptr->proclocnum)
117 if ((vlbltab = memAlloc (ordeptr->vnodglbnbr * sizeof (Gnum))) == NULL) {
118 errorPrint ("dorderSaveTree2: out of memory");
119 cheklocval = 1;
120 }
121 #ifdef SCOTCH_DEBUG_DORDER1 /* Communication cannot be merged with a useful one */
122 if (MPI_Bcast (&cheklocval, 1, MPI_INT, protnum, ordeptr->proccomm) != MPI_SUCCESS) {
123 errorPrint ("dorderSaveTree2: communication error (2)");
124 return (1);
125 }
126 #endif /* SCOTCH_DEBUG_DORDER1 */
127 if (cheklocval != 0)
128 return (1);
129 if (commGatherv (grafptr->vlblloctax + grafptr->baseval, grafptr->vertlocnbr, GNUM_MPI,
130 vlbltab, grafptr->proccnttab, grafptr->procdsptab, GNUM_MPI, protnum, grafptr->proccomm) != MPI_SUCCESS) {
131 errorPrint ("dorderSaveTree2: communication error (3)");
132 return (1);
133 }
134 }
135
136 if (protnum == ordeptr->proclocnum)
137 cheklocval = orderInit (&corddat, ordeptr->baseval, ordeptr->vnodglbnbr, NULL);
138 #ifdef SCOTCH_DEBUG_DORDER1 /* Communication cannot be merged with a useful one */
139 if (MPI_Bcast (&cheklocval, 1, MPI_INT, protnum, ordeptr->proccomm) != MPI_SUCCESS) {
140 errorPrint ("dorderSaveTree2: communication error (4)");
141 return (1);
142 }
143 #endif /* SCOTCH_DEBUG_DORDER1 */
144 if (cheklocval != 0)
145 return (1);
146
147 if (protnum == ordeptr->proclocnum) {
148 cheklocval = dorderGather (ordeptr, &corddat); /* Need inverse permutation too */
149 if (cheklocval == 0)
150 cheklocval = funcptr (&corddat, vlbltab, stream);
151 orderExit (&corddat);
152 }
153 else
154 cheklocval = dorderGather (ordeptr, NULL);
155
156 if (vlbltab != NULL)
157 memFree (vlbltab);
158
159 #ifdef SCOTCH_DEBUG_DORDER1 /* Communication cannot be merged with a useful one */
160 if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, ordeptr->proccomm) != MPI_SUCCESS) {
161 errorPrint ("dorderSaveTree2: communication error (3)");
162 return (1);
163 }
164 #else /* SCOTCH_DEBUG_DORDER1 */
165 chekglbval = cheklocval;
166 #endif /* SCOTCH_DEBUG_DORDER1 */
167
168 return (chekglbval);
169 }
170
171 /* This routine saves the separator tree
172 ** data of the given distributed ordering.
173 ** It returns:
174 ** - 0 : on success.
175 ** - !0 : on error.
176 */
177
178 int
dorderSaveTree(const Dorder * restrict const ordeptr,const Dgraph * restrict const grafptr,FILE * restrict const stream)179 dorderSaveTree (
180 const Dorder * restrict const ordeptr,
181 const Dgraph * restrict const grafptr,
182 FILE * restrict const stream)
183 {
184 return (dorderSaveTree2 (ordeptr, grafptr, stream, orderSaveTree));
185 }
186
187 /* This routine saves the column block
188 ** mapping data of the given distributed
189 ** ordering.
190 ** It returns:
191 ** - 0 : on success.
192 ** - !0 : on error.
193 */
194
195 int
dorderSaveMap(const Dorder * restrict const ordeptr,const Dgraph * restrict const grafptr,FILE * restrict const stream)196 dorderSaveMap (
197 const Dorder * restrict const ordeptr,
198 const Dgraph * restrict const grafptr,
199 FILE * restrict const stream)
200 {
201 return (dorderSaveTree2 (ordeptr, grafptr, stream, orderSaveMap));
202 }
203