PaStiX Handbook  6.2.1
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-2021 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
8  * Univ. Bordeaux. All rights reserved.
9  *
10  * @version 6.0.3
11  * @author Francois Pellegrini
12  * @author Pierre Ramet
13  * @author Xavier Lacoste
14  * @author Mathieu Faverge
15  * @date 2019-11-12
16  *
17  **/
18 #include "common.h"
19 #include "pastix/order.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  errorPrint ("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  errorPrint ("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  errorPrint("test: cannot load order");
164  EXIT(MOD_SOPALIN, PASTIX_ERR_INTERNAL);
165  }
166  fclose(stream);
167  }
168 
169  if (env) {
170  pastix_cleanenv( filename );
171  }
172 
173  (void)pastix_data;
174  return rc;
175 }
176 
177 /**
178  *******************************************************************************
179  *
180  * @ingroup order_dev
181  *
182  * @brief Save an ordering to a file.
183  *
184  *******************************************************************************
185  *
186  * @param[inout] ordeptr
187  * The ordering structure to dump to disk.
188  *
189  * @param[in] stream
190  * The stream where to write the ordering.
191  *
192  *******************************************************************************
193  *
194  * @retval PASTIX_SUCCESS on successful exit,
195  * @retval PASTIX_ERR_BADPARAMETER if the ordeptr structure is incorrect,
196  * @retval PASTIX_ERR_FILE if a problem occurs during the write.
197  *
198  *******************************************************************************/
199 static inline int
201  FILE *stream )
202 {
203  pastix_int_t vertnbr;
204  pastix_int_t vertnum;
205  pastix_int_t cblknum;
206  int o;
207 
208  if (ordeptr->permtab == NULL) {
209  errorPrint ("pastixOrderSave: cannot save ordering without direct permutation data");
211  }
212  if (ordeptr->rangtab == NULL) {
213  errorPrint ("pastixOrderSave: cannot save ordering without rangtab array");
215  }
216  if (ordeptr->treetab == NULL) {
217  errorPrint ("pastixOrderSave: cannot save ordering without treetab array");
219  }
220 
221  vertnbr = ordeptr->rangtab[ordeptr->cblknbr] - /* Get number of nodes */
222  ordeptr->rangtab[0];
223 
224  assert( vertnbr == ordeptr->vertnbr );
225  assert( ordeptr->rangtab[0] == ordeptr->baseval );
226 
227  if (fprintf (stream, "1\n%ld\t%ld\n",
228  (long) ordeptr->cblknbr,
229  (long) vertnbr) == EOF) {
230  errorPrint ("pastixOrderSave: bad output (1)");
231  return PASTIX_ERR_FILE;
232  }
233 
234  /* Save column-block range array */
235  for (cblknum = 0, o = 1; (o == 1) && (cblknum < ordeptr->cblknbr); cblknum ++) {
236  o = intSave (stream, ordeptr->rangtab[cblknum]);
237  putc (((cblknum & 7) == 7) ? '\n' : '\t', stream);
238  }
239  o = intSave (stream, ordeptr->rangtab[cblknum]);
240  putc ('\n', stream);
241 
242  /* Save direct permutation */
243  for (vertnum = 0; (o == 1) && (vertnum < (vertnbr - 1)); vertnum ++) {
244  o = intSave (stream, ordeptr->permtab[vertnum]);
245  putc (((vertnum & 7) == 7) ? '\n' : '\t', stream);
246  }
247  o = intSave (stream, ordeptr->permtab[vertnum]);
248  putc ('\n', stream);
249 
250  /* Save treetab */
251  for (cblknum = 0; (o == 1) && (cblknum < ordeptr->cblknbr - 1); cblknum ++) {
252  o = intSave (stream, ordeptr->treetab[cblknum]);
253  putc (((cblknum & 7) == 7) ? '\n' : '\t', stream);
254  }
255  o = intSave (stream, ordeptr->treetab[cblknum]);
256  putc ('\n', stream);
257 
258  if (o != 1) {
259  errorPrint ("pastixOrderSave: bad output (2)");
260  return PASTIX_ERR_FILE;
261  }
262 
263  return PASTIX_SUCCESS;
264 }
265 
266 /**
267  *******************************************************************************
268  *
269  * @ingroup pastix_order
270  *
271  * @brief Save an ordering to a file.
272  *
273  * The graph file is store in the directory pastix-XXXXXX uniquely generated per
274  * instance, and is named by the PASTIX_FILE_ORDER environment variable, or
275  * ordergen by default.
276  *
277  *******************************************************************************
278  *
279  * @param[in] pastix_data
280  * The pointer to the solver instance to get options as rank,
281  * communicators, ...
282  *
283  * @param[in] ordemesh
284  * The initialized ordering structure to save.
285  *
286  *******************************************************************************
287  *
288  * @retval PASTIX_SUCCESS on successful exit,
289  * @retval PASTIX_ERR_BADPARAMETER if one parameter is incorrect,
290  * @retval PASTIX_ERR_FILE if a problem occurs during the write.
291  *
292  *******************************************************************************/
293 int
294 pastixOrderSave( pastix_data_t *pastix_data,
295  const pastix_order_t *ordemesh )
296 {
297  FILE *stream = NULL;
298  int rc = PASTIX_SUCCESS;
299  int env = 1;
300  char *filename = NULL;
301 
302  /* Parameter checks */
303  if ( ordemesh == NULL ) {
305  }
306 
307  /*
308  * Get the environment variable as second option
309  */
310  filename = pastix_getenv( "PASTIX_FILE_ORDER" );
311 
312  /*
313  * Get the default name as third option
314  */
315  if ( filename == NULL ) {
316  filename = "ordergen";
317  env = 0;
318  }
319 
320  pastix_gendirectories( pastix_data );
321  if ( pastix_data->procnbr == 0 ) {
322  stream = pastix_fopenw( pastix_data->dir_global, filename, "w" );
323  rc = ordering_save(ordemesh, stream);
324  if (rc != PASTIX_SUCCESS )
325  {
326  errorPrint ("cannot save order");
327  }
328  fclose(stream);
329  }
330  if (env) {
331  pastix_cleanenv( filename );
332  }
333 
334  return rc;
335 }
pastix_order_s::cblknbr
pastix_int_t cblknbr
Definition: order.h:48
pastixOrderSave
int pastixOrderSave(pastix_data_t *pastix_data, const pastix_order_t *ordeptr)
Save an ordering to a file.
Definition: order_io.c:294
ordering_save
static int ordering_save(const pastix_order_t *ordeptr, FILE *stream)
Save an ordering to a file.
Definition: order_io.c:200
pastix_order_s::peritab
pastix_int_t * peritab
Definition: order.h:50
pastix_order_s::permtab
pastix_int_t * permtab
Definition: order.h:49
pastixOrderExit
void pastixOrderExit(pastix_order_t *const ordeptr)
Free the arrays initialized in the order structure.
Definition: order.c:273
pastix_gendirectories
void pastix_gendirectories(pastix_data_t *pastix_data)
Generate a unique temporary directory to store output files.
Definition: api.c:69
pastix_order_s::treetab
pastix_int_t * treetab
Definition: order.h:52
pastix_order_s
Order structure.
Definition: order.h:45
pastix_order_s::vertnbr
pastix_int_t vertnbr
Definition: order.h:47
PASTIX_ERR_FILE
@ PASTIX_ERR_FILE
Definition: api.h:352
PASTIX_SUCCESS
@ PASTIX_SUCCESS
Definition: api.h:344
pastix_fopenw
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:232
pastixOrderAlloc
int pastixOrderAlloc(pastix_order_t *const ordeptr, pastix_int_t vertnbr, pastix_int_t cblknbr)
Allocate the order structure.
Definition: order.c:55
pastix_order_s::baseval
pastix_int_t baseval
Definition: order.h:46
pastix_order_s::rangtab
pastix_int_t * rangtab
Definition: order.h:51
order.h
PASTIX_ERR_INTERNAL
@ PASTIX_ERR_INTERNAL
Definition: api.h:350
pastixOrderLoad
int pastixOrderLoad(const pastix_data_t *pastix_data, pastix_order_t *ordeptr)
Load an ordering from a file.
Definition: order_io.c:132
ordering_load
static int ordering_load(pastix_order_t *ordeptr, FILE *stream)
Load an ordering from a file.
Definition: order_io.c:43
pastix_fopen
FILE * pastix_fopen(const char *filename)
Open a file in the current directory in read only mode.
Definition: api.c:279
PASTIX_ERR_BADPARAMETER
@ PASTIX_ERR_BADPARAMETER
Definition: api.h:351