PaStiX Handbook  6.4.0
order_io.c
Go to the documentation of this file.
1 /**
2  *
3  * @file order_io.c
4  *
5  * PaStiX order functions to read/write the order structure from/to the disk.
6  *
7  * @copyright 2004-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8  * Univ. Bordeaux. All rights reserved.
9  *
10  * @version 6.4.0
11  * @author Francois Pellegrini
12  * @author Pierre Ramet
13  * @author Xavier Lacoste
14  * @author Mathieu Faverge
15  * @date 2024-07-05
16  *
17  **/
18 #include "common.h"
19 #include "order/order_internal.h"
20 
21 /**
22  *******************************************************************************
23  *
24  * @ingroup order_dev
25  *
26  * @brief Load an ordering from a file.
27  *
28  *******************************************************************************
29  *
30  * @param[inout] ordeptr
31  * The ordering structure to fill in.
32  *
33  * @param[in] stream
34  * The stream where to read the informations.
35  *
36  *******************************************************************************
37  *
38  * @retval PASTIX_SUCCESS on successful exit,
39  * @retval PASTIX_ERR_FILE if a problem occurs during the read.
40  *
41  *******************************************************************************/
42 static inline int
44  FILE *stream )
45 {
46  pastix_int_t versval;
47  pastix_int_t cblknbr;
48  pastix_int_t cblknum;
49  pastix_int_t vertnbr;
50  pastix_int_t vertnum;
51  pastix_int_t vertnnd;
52  pastix_int_t *permtax;
53  pastix_int_t *peritax;
54  int i;
55 
56  if ((intLoad (stream, &versval) +
57  intLoad (stream, &cblknbr) +
58  intLoad (stream, &vertnbr) != 3) ||
59  ((versval != 0) && (versval != 1)) ||
60  (cblknbr > vertnbr)) {
61  pastix_print_error( "orderLoad: bad input (1)" );
62  return PASTIX_ERR_FILE;
63  }
64 
65  pastixOrderAlloc(ordeptr, vertnbr, cblknbr);
66  ordeptr->vertnbr = vertnbr;
67  ordeptr->cblknbr = cblknbr;
68 
69  /* Read column-block data */
70  for (cblknum = 0, i = 1; (i == 1) && (cblknum <= cblknbr); cblknum ++)
71  i = intLoad (stream, &ordeptr->rangtab[cblknum]);
72 
73  /* Read direct permutation */
74  for (vertnum = 0; (i == 1) && (vertnum < vertnbr); vertnum ++)
75  i = intLoad (stream, &ordeptr->permtab[vertnum]);
76 
77  /* Read treetab data */
78  if ( versval == 1 ) {
79  for (cblknum = 0, i = 1; (i == 1) && (cblknum < cblknbr); cblknum ++)
80  i = intLoad (stream, &ordeptr->treetab[cblknum]);
81  }
82  else {
83  free( ordeptr->treetab );
84  ordeptr->treetab = NULL;
85  }
86 
87  if (i != 1) {
88  pastix_print_error( "pastixOrderLoad: bad input (2)" );
89  pastixOrderExit (ordeptr);
90  return PASTIX_ERR_FILE;
91  }
92 
93  /* Build inverse permutation */
94  permtax = ordeptr->permtab - ordeptr->rangtab[0];
95  peritax = ordeptr->peritab - ordeptr->rangtab[0];
96  for (vertnum = ordeptr->rangtab[0], vertnnd = vertnum + vertnbr;
97  vertnum < vertnnd; vertnum ++)
98  peritax[permtax[vertnum]] = vertnum;
99 
100  ordeptr->baseval = ordeptr->rangtab[0];
101 
102  return PASTIX_SUCCESS;
103 }
104 
105 /**
106  *******************************************************************************
107  *
108  * @ingroup pastix_order
109  *
110  * @brief Load an ordering from a file.
111  *
112  * The filename is defined by the environment variable PASTIX_FILE_ORDER, and if
113  * PASTIX_FILE_ORDER is not defined, the default filename "ordername" in the
114  * current directory is used.
115  *
116  *******************************************************************************
117  *
118  * @param[in] pastix_data
119  * The pointer to the solver instance to get options as rank,
120  * communicators, ...
121  *
122  * @param[inout] ordemesh
123  * The initialized ordering structure to fill in.
124  *
125  *******************************************************************************
126  *
127  * @retval PASTIX_SUCCESS on successful exit,
128  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect,
129  * @retval PASTIX_ERR_FILE if a problem occurs during the read.
130  *
131  *******************************************************************************/
132 int pastixOrderLoad( const pastix_data_t *pastix_data,
133  pastix_order_t *ordemesh )
134 {
135  FILE *stream = NULL;
136  char *filename = NULL;
137  int rc = PASTIX_SUCCESS;
138  int env = 1;
139 
140  /* Parameter checks */
141  if ( ordemesh == NULL ) {
143  }
144 
145  /*
146  * Get the environment variable as second option
147  */
148  filename = pastix_getenv( "PASTIX_FILE_ORDER" );
149 
150  /*
151  * Get the default name as third option
152  */
153  if ( filename == NULL ) {
154  filename = "ordername";
155  env = 0;
156  }
157 
158  stream = pastix_fopen( filename );
159  if ( stream ) {
160  rc = ordering_load(ordemesh, stream);
161  if (rc != PASTIX_SUCCESS)
162  {
163  pastix_print_error( "test: cannot load order" );
164  }
165  fclose(stream);
166  }
167 
168  if (env) {
169  pastix_cleanenv( filename );
170  }
171 
172  (void)pastix_data;
173  return rc;
174 }
175 
176 /**
177  *******************************************************************************
178  *
179  * @ingroup order_dev
180  *
181  * @brief Save an ordering to a file.
182  *
183  *******************************************************************************
184  *
185  * @param[inout] ordeptr
186  * The ordering structure to dump to disk.
187  *
188  * @param[in] stream
189  * The stream where to write the ordering.
190  *
191  *******************************************************************************
192  *
193  * @retval PASTIX_SUCCESS on successful exit,
194  * @retval PASTIX_ERR_BADPARAMETER if the ordeptr structure is incorrect,
195  * @retval PASTIX_ERR_FILE if a problem occurs during the write.
196  *
197  *******************************************************************************/
198 static inline int
200  FILE *stream )
201 {
202  pastix_int_t vertnbr;
203  pastix_int_t vertnum;
204  pastix_int_t cblknum;
205  int o;
206 
207  if (ordeptr->permtab == NULL) {
208  pastix_print_error( "pastixOrderSave: cannot save ordering without direct permutation data" );
210  }
211  if (ordeptr->rangtab == NULL) {
212  pastix_print_error( "pastixOrderSave: cannot save ordering without rangtab array" );
214  }
215  if (ordeptr->treetab == NULL) {
216  pastix_print_error( "pastixOrderSave: cannot save ordering without treetab array" );
218  }
219 
220  vertnbr = ordeptr->rangtab[ordeptr->cblknbr] - /* Get number of nodes */
221  ordeptr->rangtab[0];
222 
223  assert( vertnbr == ordeptr->vertnbr );
224  assert( ordeptr->rangtab[0] == ordeptr->baseval );
225 
226  if (fprintf (stream, "1\n%ld\t%ld\n",
227  (long) ordeptr->cblknbr,
228  (long) vertnbr) == EOF) {
229  pastix_print_error( "pastixOrderSave: bad output (1)" );
230  return PASTIX_ERR_FILE;
231  }
232 
233  /* Save column-block range array */
234  for (cblknum = 0, o = 1; (o == 1) && (cblknum < ordeptr->cblknbr); cblknum ++) {
235  o = intSave (stream, ordeptr->rangtab[cblknum]);
236  putc (((cblknum & 7) == 7) ? '\n' : '\t', stream);
237  }
238  o = intSave (stream, ordeptr->rangtab[cblknum]);
239  putc ('\n', stream);
240 
241  /* Save direct permutation */
242  for (vertnum = 0; (o == 1) && (vertnum < (vertnbr - 1)); vertnum ++) {
243  o = intSave (stream, ordeptr->permtab[vertnum]);
244  putc (((vertnum & 7) == 7) ? '\n' : '\t', stream);
245  }
246  o = intSave (stream, ordeptr->permtab[vertnum]);
247  putc ('\n', stream);
248 
249  /* Save treetab */
250  for (cblknum = 0; (o == 1) && (cblknum < ordeptr->cblknbr - 1); cblknum ++) {
251  o = intSave (stream, ordeptr->treetab[cblknum]);
252  putc (((cblknum & 7) == 7) ? '\n' : '\t', stream);
253  }
254  o = intSave (stream, ordeptr->treetab[cblknum]);
255  putc ('\n', stream);
256 
257  if (o != 1) {
258  pastix_print_error( "pastixOrderSave: bad output (2)" );
259  return PASTIX_ERR_FILE;
260  }
261 
262  return PASTIX_SUCCESS;
263 }
264 
265 /**
266  *******************************************************************************
267  *
268  * @ingroup pastix_order
269  *
270  * @brief Save an ordering to a file.
271  *
272  * The graph file is store in the directory pastix-XXXXXX uniquely generated per
273  * instance, and is named by the PASTIX_FILE_ORDER environment variable, or
274  * ordergen by default.
275  *
276  *******************************************************************************
277  *
278  * @param[in] pastix_data
279  * The pointer to the solver instance to get options as rank,
280  * communicators, ...
281  *
282  * @param[in] ordemesh
283  * The initialized ordering structure to save.
284  *
285  *******************************************************************************
286  *
287  * @retval PASTIX_SUCCESS on successful exit,
288  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect,
289  * @retval PASTIX_ERR_FILE if a problem occurs during the write.
290  *
291  *******************************************************************************/
292 int
294  const pastix_order_t *ordemesh )
295 {
296  FILE *stream = NULL;
297  int rc = PASTIX_SUCCESS;
298  int env = 1;
299  char *filename = NULL;
300 
301  /* Parameter checks */
302  if ( ordemesh == NULL ) {
304  }
305 
306  /*
307  * Get the environment variable as second option
308  */
309  filename = pastix_getenv( "PASTIX_FILE_ORDER" );
310 
311  /*
312  * Get the default name as third option
313  */
314  if ( filename == NULL ) {
315  filename = "ordergen";
316  env = 0;
317  }
318 
319  pastix_gendirectories( pastix_data );
320  if ( pastix_data->procnbr == 0 ) {
321  stream = pastix_fopenw( pastix_data->dir_global, filename, "w" );
322  rc = ordering_save(ordemesh, stream);
323  if (rc != PASTIX_SUCCESS )
324  {
325  pastix_print_error( "cannot save order" );
326  }
327  fclose(stream);
328  }
329  if (env) {
330  pastix_cleanenv( filename );
331  }
332 
333  return rc;
334 }
BEGIN_C_DECLS typedef int pastix_int_t
Definition: datatypes.h:51
static int ordering_load(pastix_order_t *ordeptr, FILE *stream)
Load an ordering from a file.
Definition: order_io.c:43
static int ordering_save(const pastix_order_t *ordeptr, FILE *stream)
Save an ordering to a file.
Definition: order_io.c:199
FILE * pastix_fopenw(const char *dirname, const char *filename, const char *mode)
Open a file in the unique directory of the pastix instance.
Definition: api.c:251
FILE * pastix_fopen(const char *filename)
Open a file in the current directory in read only mode.
Definition: api.c:298
void pastix_gendirectories(pastix_data_t *pastix_data)
Generate a unique temporary directory to store output files.
Definition: api.c:85
@ PASTIX_SUCCESS
Definition: api.h:367
@ PASTIX_ERR_FILE
Definition: api.h:375
@ PASTIX_ERR_BADPARAMETER
Definition: api.h:374
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
pastix_int_t vertnbr
Definition: order.h:49
int pastixOrderAlloc(pastix_order_t *ordeptr, pastix_int_t vertnbr, pastix_int_t cblknbr)
Allocate the order structure.
Definition: order.c:55
int pastixOrderSave(pastix_data_t *pastix_data, const pastix_order_t *ordeptr)
Save an ordering to a file.
Definition: order_io.c:293
void pastixOrderExit(pastix_order_t *ordeptr)
Free the arrays initialized in the order structure.
Definition: order.c:273
int pastixOrderLoad(const pastix_data_t *pastix_data, pastix_order_t *ordeptr)
Load an ordering from a file.
Definition: order_io.c:132
Order structure.
Definition: order.h:47
char * dir_global
Definition: pastixdata.h:110
Main PaStiX data structure.
Definition: pastixdata.h:68