PaStiX Handbook  6.3.2
graph.c
Go to the documentation of this file.
1 /**
2  *
3  * @file graph.c
4  *
5  * PaStiX graph structure routines
6  *
7  * @copyright 2004-2023 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8  * Univ. Bordeaux. All rights reserved.
9  *
10  * @version 6.3.2
11  * @author Xavier Lacoste
12  * @author Pierre Ramet
13  * @author Mathieu Faverge
14  * @author Tony Delarue
15  * @date 2023-12-07
16  *
17  * @addtogroup pastix_graph
18  * @{
19  *
20  **/
21 #include "common.h"
22 #include "graph/graph.h"
23 
24 #ifndef DOXYGEN_SHOULD_SKIP_THIS
25 #define assert_graph( _graph_ ) \
26  do { \
27  assert( (_graph_)->fmttype == SpmCSC ); \
28  assert( (_graph_)->flttype == SpmPattern ); \
29  assert( (_graph_)->values == NULL ); \
30  } while (0)
31 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
32 
33 /**
34  *******************************************************************************
35  *
36  * @brief Initialize an empty graph
37  *
38  *******************************************************************************
39  *
40  * @param[inout] graph
41  * The empty graph to init.
42  *
43  * @param[in] comm
44  * The MPI communicator used for the graph.
45  *
46  *******************************************************************************/
47 void
48 graphInitEmpty( pastix_graph_t *graph,
49  PASTIX_Comm comm )
50 {
51  spmInitDist( graph, comm );
52 
53  graph->flttype = SpmPattern;
54 
55  graph->colptr = malloc( sizeof( pastix_int_t ) );
56  graph->colptr[0] = 0;
57 
59 }
60 
61 /**
62  *******************************************************************************
63  *
64  * @brief Free the content of the graph structure.
65  *
66  *******************************************************************************
67  *
68  * @param[inout] graph
69  * The pointer graph structure to free.
70  *
71  *******************************************************************************/
72 void
73 graphExit( pastix_graph_t *graph )
74 {
75  /* Parameter checks */
76  if ( graph == NULL ) {
77  pastix_print_error( "graphExit: graph pointer is NULL" );
78  return;
79  }
80  assert_graph( graph );
81 
82  spmExit( graph );
83 
84  return;
85 }
86 
87 /**
88  *******************************************************************************
89  *
90  * @brief Rebase the graph to the given value.
91  *
92  *******************************************************************************
93  *
94  * @param[inout] graph
95  * The graph to rebase.
96  *
97  * @param[in] baseval
98  * The base value to use in the graph (0 or 1).
99  *
100  *******************************************************************************/
101 void
102 graphBase( pastix_graph_t *graph,
103  pastix_int_t baseval )
104 {
105  /* Parameter checks */
106  if ( graph == NULL ) {
107  pastix_print_error( "graphBase: graph pointer is NULL" );
108  return;
109  }
110  if ( (baseval != 0) &&
111  (baseval != 1) )
112  {
113  pastix_print_error( "graphBase: baseval is incorrect, must be 0 or 1" );
114  return;
115  }
116 
117  assert_graph( graph );
118 
119  spmBase( graph, baseval );
120 
121  return;
122 }
123 
124 /**
125  *******************************************************************************
126  *
127  * @ingroup pastix_graph
128  *
129  * @brief This routine copy a given ordering in a new one.
130  *
131  * This function copies a graph structure into another one. If all subpointers
132  * are NULL, then they are all allocated and contains the original graphsrc
133  * values on exit. If one or more array pointers are not NULL, then, only those
134  * are copied to the graphdst structure.
135  *
136  *******************************************************************************
137  *
138  * @param[out] graphdst
139  * The destination graph. Must be allocated on entry.
140  *
141  * @param[in] graphsrc
142  * The source graph
143  *
144  *******************************************************************************
145  *
146  * @retval PASTIX_SUCCESS on successful exit
147  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect.
148  *
149  *******************************************************************************/
150 int
151 graphCopy( pastix_graph_t *graphdst,
152  const pastix_graph_t *graphsrc )
153 {
154  /* Parameter checks */
155  if ( graphdst == NULL ) {
157  }
158  if ( graphsrc == NULL ) {
160  }
161  if ( graphsrc == graphdst ) {
163  }
164  assert_graph( graphsrc );
165 
166  /* Copy the source graph */
167  spmCopy( graphsrc, graphdst );
168 
169  return PASTIX_SUCCESS;
170 }
171 
172 /**
173  *******************************************************************************
174  *
175  * @ingroup pastix_graph
176  *
177  * @brief This routine scatter a graph from node root to the other nodes
178  *
179  *******************************************************************************
180  *
181  * @param[inout] graph
182  * On entry, the graph to scatter.
183  * On exit, the scattered graph
184  *
185  * @param[in] comm
186  * MPI communicator.
187  *
188  *******************************************************************************
189  *
190  * @retval 1 if the graph has been scattered, 0 if untouched
191  *
192  *******************************************************************************/
193 int
194 graphScatterInPlace( pastix_graph_t *graph,
195  PASTIX_Comm comm )
196 {
197  pastix_graph_t newgraph;
198  int rc;
199 
200  assert_graph( graph );
201  if ( graph->loc2glob != NULL ) {
202  return 0;
203  }
204 
205  /* Scatter the graph */
206  rc = spmScatter( &newgraph, -1, graph, -1, NULL, 1, comm );
207 
208  if ( rc == SPM_SUCCESS ) {
209  graphExit( graph );
210  memcpy( graph, &newgraph, sizeof( pastix_graph_t ) );
211 
212  assert_graph( graph );
213  return 1;
214  }
215  else {
216  return 0;
217  }
218 }
219 
220 /**
221  *******************************************************************************
222  *
223  * @ingroup pastix_graph
224  *
225  * @brief This routine gather a distributed graph on each node in place.
226  *
227  *******************************************************************************
228  *
229  * @param[in] graph
230  * On entry, the distributed graph.
231  * On exit, the gathered graph.
232  *
233  *******************************************************************************
234  *
235  * @retval 1 if the graph has been gathered, 0 if untouched
236  *
237  ********************************************************************************/
238 int
239 graphGatherInPlace( pastix_graph_t *graph )
240 {
241  pastix_graph_t newgraph;
242  int rc;
243 
244  assert_graph( graph );
245  if ( graph->loc2glob == NULL ) {
246  return 0;
247  }
248 
249  rc = spmGather( graph, -1, &newgraph );
250 
251  if ( rc == SPM_SUCCESS ) {
252  graphExit( graph );
253  memcpy( graph, &newgraph, sizeof( pastix_graph_t ) );
254 
255  assert_graph( graph );
256  return 1;
257  }
258  else {
259  return 0;
260  }
261 }
262 
263 /**
264  *******************************************************************************
265  *
266  * @ingroup pastix_graph
267  *
268  * @brief This routine sortes the subarray of edges of each vertex.
269  *
270  * WARNING: The sort is always performed, do not call this routine
271  * when it is not required.
272  *
273  *******************************************************************************
274  *
275  * @param[inout] graph
276  * On entry, the pointer to the graph structure.
277  * On exit, the same graph with subarrays of edges sorted by ascending
278  * order.
279  *
280  *******************************************************************************/
281 void
282 graphSort( pastix_graph_t *graph )
283 {
284  assert_graph( graph );
285  spmSort( graph );
286 }
287 
288 /**
289  *******************************************************************************
290  *
291  * @ingroup pastix_graph
292  *
293  * @brief Symmetrize a given graph
294  *
295  *******************************************************************************
296  *
297  * @param[inout] graph
298  * The initialized graph structure that will be symmetrized.
299  *
300  *******************************************************************************
301  *
302  * @retval PASTIX_SUCCESS on success,
303  * @retval PASTIX_ERR_BADPARAMETER if incorrect parameters are given.
304  *
305  *******************************************************************************/
306 int
307 graphSymmetrize( pastix_graph_t *graph )
308 {
309  /* Parameter checks */
310  if ( graph == NULL ) {
312  }
313  assert_graph( graph );
314 
315  spmSymmetrize( graph );
316  return PASTIX_SUCCESS;
317 }
318 
319 /**
320  *******************************************************************************
321  *
322  * @ingroup pastix_graph
323  *
324  * @brief Update dofs, nnz, nnzexp, gnnz, n, nexp, gN of a given graph
325  *
326  *******************************************************************************
327  *
328  * @param[inout] graph
329  * The initialized graph structure that will be updated.
330  *
331  *******************************************************************************
332  *
333  * @retval PASTIX_SUCCESS on success,
334  * @retval PASTIX_ERR_BADPARAMETER if incorrect parameters are given.
335  *
336  *******************************************************************************/
337 int
338 graphUpdateComputedFields( pastix_graph_t *graph )
339 {
340  /* Parameter checks */
341  if ( graph == NULL ) {
343  }
344  assert_graph( graph );
345 
346  spmUpdateComputedFields( graph );
347  return PASTIX_SUCCESS;
348 }
349 
350 /**
351  *******************************************************************************
352  *
353  * @ingroup pastix_graph
354  *
355  * @brief This routine build a graph thanks to an spm;
356  *
357  * This function copies an spm structure into a graph one. If all subpointers
358  * are NULL, then they are all allocated and contains the original spm
359  * values on exit. If one or more array pointers are not NULL, then, only those
360  * are copied to the graphdst structure.
361  * We will take care that our graph does not contain coefficients, therefore has
362  * SpmPattern floating type and is a SpmCSC format type.
363  *
364  *******************************************************************************
365  *
366  * @param[inout] graph
367  * The destination graph.
368  *
369  * @param[in] spm
370  * The source Sparse Matrix.
371  *
372  *******************************************************************************
373  *
374  * @retval PASTIX_SUCCESS on successful exit
375  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect.
376  *
377  *******************************************************************************/
378 int
379 graphSpm2Graph( pastix_graph_t *graph,
380  const spmatrix_t *spm )
381 {
382  spmatrix_t spmtmp;
383 
384  /* Parameter checks */
385  if ( graph == NULL ) {
387  }
388  if ( spm == NULL ) {
390  }
391 
392  /*
393  * Clear the prexisting graph
394  * Might be uninitialized, so we call spmExit instead of graphExit.
395  */
396  spmExit( graph );
397 
398  /* Copy existing datas */
399  memcpy( &spmtmp, spm, sizeof(pastix_graph_t) );
400 
401  /* A graph does not contain values */
402  spmtmp.flttype = SpmPattern;
403  spmtmp.values = NULL;
404 
405  /* Reallocate the arrays in case of modifications */
406  spmCopy( &spmtmp, graph );
407 
408  /* Make sure the graph is in CSC format */
409  spmConvert( SpmCSC, graph );
410 
411  return PASTIX_SUCCESS;
412 }
413 
414 
415 /**
416  *******************************************************************************
417  *
418  * @ingroup pastix_graph
419  *
420  * @brief Build the vertex weight array out of the dof array.
421  *
422  *******************************************************************************
423  *
424  * @param[in] graph
425  * Pointer to the graph structure.
426  *
427  *******************************************************************************
428  *
429  * @retval The vertex weight array if graph->dof != 1, NULL otherwise.
430  *
431  *******************************************************************************/
432 pastix_int_t *
433 graphGetWeights( const pastix_graph_t *graph )
434 {
435  pastix_int_t i, n;
436  pastix_int_t *weights, *wptr;
437 
438  if ( graph->dof == 1 ) {
439  return NULL;
440  }
441 
442  n = graph->n;
443  MALLOC_INTERN( weights, n, pastix_int_t );
444 
445  wptr = weights;
446  /* Constant dof */
447  if ( graph->dof > 1 ) {
448  for ( i=0; i<n; i++, wptr++ ) {
449  *wptr = graph->dof;
450  }
451  }
452  /* Variadic dof */
453  else {
454  pastix_int_t *dofptr = graph->dofs;
455  if ( graph->loc2glob == NULL ) {
456  for ( i=0; i<n; i++, wptr++, dofptr++ ) {
457  *wptr = dofptr[1] - dofptr[0];
458  }
459  }
460  else {
461  pastix_int_t *dofptr = graph->dofs - graph->baseval;
462  pastix_int_t *loc2glob = graph->loc2glob;
463 
464  for ( i=0; i<n; i++, wptr++, loc2glob++ ) {
465  *wptr = dofptr[ *loc2glob + 1 ] - dofptr[ *loc2glob ];
466  }
467  }
468  }
469 
470  return weights;
471 }
472 
473 /**
474  * @}
475  */
BEGIN_C_DECLS typedef int pastix_int_t
Definition: datatypes.h:51
@ PASTIX_SUCCESS
Definition: api.h:367
@ PASTIX_ERR_BADPARAMETER
Definition: api.h:374
int graphUpdateComputedFields(pastix_graph_t *graph)
Update dofs, nnz, nnzexp, gnnz, n, nexp, gN of a given graph.
Definition: graph.c:338
void graphExit(pastix_graph_t *graph)
Free the content of the graph structure.
Definition: graph.c:73
int graphScatterInPlace(pastix_graph_t *graph, PASTIX_Comm comm)
This routine scatter a graph from node root to the other nodes.
Definition: graph.c:194
int graphCopy(pastix_graph_t *graphdst, const pastix_graph_t *graphsrc)
This routine copy a given ordering in a new one.
Definition: graph.c:151
int graphSpm2Graph(pastix_graph_t *graph, const spmatrix_t *spm)
This routine build a graph thanks to an spm;.
Definition: graph.c:379
int graphSymmetrize(pastix_graph_t *graph)
Symmetrize a given graph.
Definition: graph.c:307
void graphInitEmpty(pastix_graph_t *graph, PASTIX_Comm comm)
Initialize an empty graph.
Definition: graph.c:48
int graphGatherInPlace(pastix_graph_t *graph)
This routine gather a distributed graph on each node in place.
Definition: graph.c:239
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
void graphSort(pastix_graph_t *graph)
This routine sortes the subarray of edges of each vertex.
Definition: graph.c:282