PaStiX Handbook 6.4.0
Loading...
Searching...
No Matches
order_compute_ptscotch.c
Go to the documentation of this file.
1/**
2 *
3 * @file order_compute_ptscotch.c
4 *
5 * PaStiX order driver to perform ordering with PT-Scotch library.
6 *
7 * @copyright 2004-2025 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8 * Univ. Bordeaux. All rights reserved.
9 *
10 * @version 6.4.0
11 * @author Xavier Lacoste
12 * @author Pierre Ramet
13 * @author Mathieu Faverge
14 * @author Tony Delarue
15 * @date 2024-07-05
16 *
17 **/
18#include "common.h"
19#include "graph/graph.h"
20#include "order/order_internal.h"
21#if defined(PASTIX_ORDERING_PTSCOTCH)
22#include <ptscotch.h>
23#endif
24
25/**
26 *******************************************************************************
27 *
28 * @ingroup pastix_order
29 *
30 * @brief Check the PT-Scotch distributed graph.
31 *
32 *******************************************************************************
33 *
34 * @param[in] graph
35 * Pointer to the SCOTCH_Dgraph structure.
36 *
37 * @param[in] procnum
38 * Procnum of the process. Output purpose.
39 *
40 *******************************************************************************/
41static inline void
42ocpts_graph_check( const SCOTCH_Dgraph *graph,
43 int procnum )
44{
45#if defined(PASTIX_DEBUG_ORDERING)
46 Clock timer;
47 clockStart(timer);
48 if ( SCOTCH_dgraphCheck( graph ) ) {
49 pastix_print_error( "pastix: dgraphCheck" );
50 }
51 clockStop(timer);
52 pastix_print( procnum, 0, "SCOTCH_dgraphCheck done in %lf second\n", clockVal(timer) );
53#else
54 (void)graph;
55 (void)procnum;
56#endif /* defined(PASTIX_DEBUG_ORDERING) */
57}
58
59/**
60 *******************************************************************************
61 *
62 * @ingroup pastix_order
63 *
64 * @brief Build the PT-Scotch distributed graph.
65 *
66 *******************************************************************************
67 *
68 * @param[inout] scotchgraph
69 * The SCOTCH_Dgraph structure that will be build.
70 *
71 * @param[inout] graph
72 * The graph prepared by graphPrepare function on which we want to
73 * perform the ordering.
74 *
75 * @param[in] comm
76 * PaStiX communicator.
77 *
78 *******************************************************************************/
79static inline void
80ocpts_graph_init( SCOTCH_Dgraph *scotchgraph,
81 pastix_graph_t *graph,
82 PASTIX_Comm comm )
83{
84 pastix_int_t *colptr, *rowptr;
85 pastix_int_t *weights;
86 pastix_int_t n, nnz, baseval;
87
88 /* Make sure graph is 0-based */
89 graphBase( graph, 0 );
90
91 n = graph->n;
92 nnz = graph->nnz;
93 colptr = graph->colptr;
94 rowptr = graph->rowptr;
95 baseval = graph->baseval;
96 weights = NULL;
97
98 assert( baseval == colptr[0] );
99 assert( nnz == colptr[n] - colptr[0] );
100
101 SCOTCH_dgraphInit( scotchgraph, comm );
102
103 /*
104 * Generate the vertex load array if dof != 1
105 */
106 weights = graphGetWeights( graph );
107
108 if ( SCOTCH_dgraphBuild( scotchgraph,
109 baseval, /* baseval */
110 n, /* Number of local vertices */
111 n, /* Maximum number of local vertices */
112 colptr,
113 NULL,
114 weights, /* Local vertex load array (if any) */
115 NULL, /* Local vertex label array (if any) */
116 nnz,
117 nnz,
118 rowptr, /* Local edge array */
119 NULL, /* Ghost edge array (if any); not const */
120 NULL ) )
121 {
122 pastix_print_error( "pastix : SCOTCH_dgraphBuild\n" );
123 }
124
125 /* Check the generated Scotch graph structure */
126 ocpts_graph_check( scotchgraph, graph->clustnum );
127
128 return;
129}
130
131/**
132 *******************************************************************************
133 *
134 * @ingroup pastix_order
135 *
136 * @brief Cleanup the PT-Scotch graph structure and free the associated data.
137 *
138 *******************************************************************************
139 *
140 * @param[inout] scotchgraph
141 * The SCOTCH_Dgraph structure that will be clean.
142 *
143 * @param[inout] comm
144 * The PaStiX communicator.
145 *
146 *******************************************************************************/
147static inline void
148ocpts_graph_exit( SCOTCH_Dgraph *scotchgraph,
149 PASTIX_Comm comm )
150{
151 pastix_int_t *colptr = NULL;
152 pastix_int_t *rowptr = NULL;
153 pastix_int_t *weights = NULL;
154
155 SCOTCH_dgraphData (
156 scotchgraph,
157 NULL, /* Base value */
158 NULL, /* Global number of vertices */
159 NULL, /* Local number of vertices */
160 NULL, /* Max number of local vertices */
161 NULL, /* Number of local and ghost vertices */
162 &colptr, /* Vertex array [vertnbr+1] */
163 NULL, /* Vertex array [vertnbr] */
164 &weights, /* Vertex load array */
165 NULL, /* Vertex label array */
166 NULL, /* Global number of edges (arcs) */
167 NULL, /* Declared size of the local edge array */
168 NULL, /* Max number of local edges */
169 &rowptr, /* Edge array [edgenbr] */
170 NULL, /* Ghost adjency array */
171 NULL, /* Edge load array */
172 &comm );
173
174 /* Free the vertex load array */
175 if ( weights != NULL ) {
176 memFree_null( weights );
177 }
178
179 /* SCOTCH_dgraphExit( scotchgraph ); */
180 return;
181}
182
183/**
184 *******************************************************************************
185 *
186 * @ingroup pastix_order
187 *
188 * @brief Compute the graph ordering
189 *
190 *******************************************************************************
191 *
192 * @param[inout] pastix_data
193 * Pointer to the pastix_data instance.
194 *
195 * @param[inout] scotchgraph
196 * The SCOTCH_Dgraph structure that will be ordered.
197 *
198 ********************************************************************************
199 *
200 * @retval The return value of SCOTCH_graphDOrderList.
201 *
202 *******************************************************************************/
203static inline int
205 SCOTCH_Dgraph *scotchgraph )
206{
207 pastix_order_t *ordemesh = pastix_data->ordemesh;
208 SCOTCH_Strat stratdat;
209 SCOTCH_Dordering ordedat;
210 SCOTCH_Ordering ordering;
211
212 /* Create Strategy string for Scotch */
213 SCOTCH_stratInit( &stratdat );
214
215 /* Init distributed ordering */
216 if ( SCOTCH_dgraphOrderInit(scotchgraph, &ordedat) )
217 {
218 pastix_print_error("pastix : SCOTCH_dgraphOrderInit\n");
219 }
220
221 /* Compute distributed ordering */
222 if ( SCOTCH_dgraphOrderCompute( scotchgraph, &ordedat, &stratdat ) )
223 {
224 pastix_print_error( "pastix : SCOTCH_dgraphOrderCompute" );
225 }
226
227 SCOTCH_stratExit( &stratdat );
228
229 /* Init centralized ordering */
230 if ( SCOTCH_dgraphCorderInit( scotchgraph,
231 &ordering,
232 (SCOTCH_Num *) ordemesh->permtab,
233 (SCOTCH_Num *) ordemesh->peritab,
234 (SCOTCH_Num *)&ordemesh->cblknbr,
235 (SCOTCH_Num *) ordemesh->rangtab,
236 (SCOTCH_Num *) ordemesh->treetab) )
237 {
238 pastix_print_error( "pastix : SCOTCH_dgraphCorderInit" );
239 }
240
241 /* Gather distributed ordering on node 0 */
242 if ( pastix_data->procnum == 0 ) {
243 SCOTCH_dgraphOrderGather( scotchgraph, &ordedat, &ordering );
244 }
245 else {
246 SCOTCH_dgraphOrderGather( scotchgraph, &ordedat, NULL );
247 }
248
249 /* Broadcast node 0 datas on all nodes */
250 {
251 int rangnbr, permnbr;
252 MPI_Bcast( &ordemesh->cblknbr, 1, PASTIX_MPI_INT, 0, pastix_data->pastix_comm );
253
254 rangnbr = ordemesh->cblknbr;
255 MPI_Bcast( ordemesh->rangtab, rangnbr+1, PASTIX_MPI_INT, 0, pastix_data->pastix_comm );
256 MPI_Bcast( ordemesh->treetab, rangnbr, PASTIX_MPI_INT, 0, pastix_data->pastix_comm );
257
258 permnbr = pastix_data->graph->gN;
259 MPI_Bcast( ordemesh->permtab, permnbr, PASTIX_MPI_INT, 0, pastix_data->pastix_comm );
260 MPI_Bcast( ordemesh->peritab, permnbr, PASTIX_MPI_INT, 0, pastix_data->pastix_comm );
261 }
262
263 /* Exit PT-Scotch ordering structures */
264 SCOTCH_dgraphCorderExit( scotchgraph, &ordering );
265 SCOTCH_dgraphOrderExit( scotchgraph, &ordedat );
266
267 return PASTIX_SUCCESS;
268}
269
270/**
271 *******************************************************************************
272 *
273 * @ingroup pastix_order
274 *
275 * @brief Compute the ordering of the graph given as parameter
276 * with PT-Scotch library.
277 *
278 * This routine is affected by the following parameters:
279 * IPARM_VERBOSE, IPARM_ORDERING_DEFAULT, IPARM_SCOTCH_SWITCH_LEVEL,
280 * IPARM_SCOTCH_CMIN, IPARM_SCOTCH_CMAX, IPARM_SCOTCH_FRAT
281 *
282 *******************************************************************************
283 *
284 * @param[inout] pastix_data
285 * The pastix_data structure that describes the solver instance.
286 * On exit, the field ordemesh is initialized with the result of the
287 * ordering realized by PT-Scotch.
288 *
289 * @param[inout] graph
290 * The graph prepared by graphPrepare function on which we want to
291 * perform the ordering. On exit, the graph might be rebased.
292 *
293 *******************************************************************************
294 *
295 * @retval PASTIX_SUCCESS on successful exit,
296 * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect,
297 * @retval PASTIX_ERR_OUTOFMEMORY if one allocation failed,
298 * @retval PASTIX_ERR_INTEGER_TYPE if Scotch integer type is not the
299 * same size as PaStiX ones,
300 * @retval PASTIX_ERR_INTERNAL if an error occurs internally to Scotch.
301 *
302 *******************************************************************************/
303int
305 pastix_graph_t *graph )
306{
307 SCOTCH_Dgraph scotchdgraph;
308 int ret = PASTIX_SUCCESS;
309 pastix_order_t *ordemesh = pastix_data->ordemesh;
310 pastix_int_t baseval = graph->baseval;
311
312 /* Check integer compatibility */
313 if ( sizeof(pastix_int_t) != sizeof(SCOTCH_Num) ) {
314 pastix_print_error( "orderComputePTScotch: Inconsistent integer type between Pastix and PT-Scotch\n" );
316 }
317
318 /* Enable this define to fix the SCOTCH random generator */
319#if defined(PASTIX_ORDERING_FIX_SEED)
320 SCOTCH_randomSeed( (SCOTCH_Num)(pastix_data->id) );
321 SCOTCH_randomReset();
322#endif
323
324 /* Build The Scotch Dgraph */
325 ocpts_graph_init( &scotchdgraph, graph, pastix_data->pastix_comm );
326
327 /* Allocate the ordering structure */
328 pastixOrderAlloc( ordemesh, graph->gN, graph->gN );
329
330 /* Compute the ordering */
331 ret = ocpts_compute_graph_ordering( pastix_data, &scotchdgraph );
332
333 /*
334 * SCOTCH_graphBase may have had side effects on our graph.
335 * Call this routine again with our saved baseval.
336 */
337 graphBase( graph, baseval );
338
339 /* Free the Scotch graph structure */
340 ocpts_graph_exit( &scotchdgraph, pastix_data->pastix_comm );
341
342 /* If something has failed in PT-Scotch */
343 if ( ret != PASTIX_SUCCESS ) {
344 pastixOrderExit( ordemesh );
345 return PASTIX_ERR_INTERNAL;
346 }
348
349 return ret;
350}
BEGIN_C_DECLS typedef int pastix_int_t
Definition datatypes.h:51
@ PASTIX_ERR_INTERNAL
Definition api.h:373
@ PASTIX_ERR_INTEGER_TYPE
Definition api.h:376
@ PASTIX_SUCCESS
Definition api.h:367
void graphBase(pastix_graph_t *graph, pastix_int_t baseval)
Rebase the graph to the given value.
Definition graph.c:102
pastix_int_t * graphGetWeights(const pastix_graph_t *graph)
Build the vertex weight array out of the dof array.
Definition graph.c:433
pastix_int_t baseval
Definition order.h:48
pastix_int_t * treetab
Definition order.h:54
pastix_int_t * permtab
Definition order.h:51
pastix_int_t * peritab
Definition order.h:52
pastix_int_t cblknbr
Definition order.h:50
pastix_int_t * rangtab
Definition order.h:53
int pastixOrderAlloc(pastix_order_t *ordeptr, pastix_int_t vertnbr, pastix_int_t cblknbr)
Allocate the order structure.
Definition order.c:55
static void ocpts_graph_init(SCOTCH_Dgraph *scotchgraph, pastix_graph_t *graph, PASTIX_Comm comm)
Build the PT-Scotch distributed graph.
static void ocpts_graph_exit(SCOTCH_Dgraph *scotchgraph, PASTIX_Comm comm)
Cleanup the PT-Scotch graph structure and free the associated data.
void order_scotch_reallocate_ordemesh(pastix_order_t *ordemesh)
Reallocate the ordering structure.
int orderComputePTScotch(pastix_data_t *pastix_data, pastix_graph_t *graph)
Compute the ordering of the graph given as parameter with PT-Scotch library.
static int ocpts_compute_graph_ordering(pastix_data_t *pastix_data, SCOTCH_Dgraph *scotchgraph)
Compute the graph ordering.
static void ocpts_graph_check(const SCOTCH_Dgraph *graph, int procnum)
Check the PT-Scotch distributed graph.
void pastixOrderExit(pastix_order_t *ordeptr)
Free the arrays initialized in the order structure.
Definition order.c:273
Order structure.
Definition order.h:47
PASTIX_Comm pastix_comm
Definition pastixdata.h:76
pastix_order_t * ordemesh
Definition pastixdata.h:98
pastix_int_t id
Definition pastixdata.h:69
pastix_graph_t * graph
Definition pastixdata.h:92
Main PaStiX data structure.
Definition pastixdata.h:68