1 /* Copyright 2004,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       : library_graph_f.c                       **/
35 /**                                                        **/
36 /**   AUTHOR     : Francois PELLEGRINI                     **/
37 /**                                                        **/
38 /**   FUNCTION   : This file contains the Fortran API for  **/
39 /**                the source graph handling routines of   **/
40 /**                the libSCOTCH library.                  **/
41 /**                                                        **/
42 /**   DATES      : # Version 3.4  : from : 02 dec 1999     **/
43 /**                                 to     15 nov 2001     **/
44 /**                # Version 4.0  : from : 11 dec 2001     **/
45 /**                                 to     17 mar 2005     **/
46 /**                # Version 5.0  : from : 11 jul 2007     **/
47 /**                                 to     11 jul 2007     **/
48 /**                # Version 5.1  : from : 27 mar 2010     **/
49 /**                                 to     15 apr 2010     **/
50 /**                                                        **/
51 /************************************************************/
52 
53 /*
54 **  The defines and includes.
55 */
56 
57 #define LIBRARY
58 
59 #include "module.h"
60 #include "common.h"
61 #include "scotch.h"
62 
63 /**************************************/
64 /*                                    */
65 /* These routines are the Fortran API */
66 /* for the graph handling routines.   */
67 /*                                    */
68 /**************************************/
69 
70 /*
71 **
72 */
73 
74 FORTRAN (                                       \
75 SCOTCHFGRAPHINIT, scotchfgraphinit, (           \
76 SCOTCH_Graph * const        grafptr,            \
77 int * const                 revaptr),           \
78 (grafptr, revaptr))
79 {
80   *revaptr = SCOTCH_graphInit (grafptr);
81 }
82 
83 /*
84 **
85 */
86 
87 FORTRAN (                                       \
88 SCOTCHFGRAPHEXIT, scotchfgraphexit, (           \
89 SCOTCH_Graph * const        grafptr),           \
90 (grafptr))
91 {
92   SCOTCH_graphExit (grafptr);
93 }
94 
95 /*
96 **
97 */
98 
99 FORTRAN (                                       \
100 SCOTCHFGRAPHFREE, scotchfgraphfree, (           \
101 SCOTCH_Graph * const        grafptr),           \
102 (grafptr))
103 {
104   SCOTCH_graphFree (grafptr);
105 }
106 
107 /* When an input stream is built from the given
108 ** file handle, it is set as unbuffered, so as to
109 ** allow for multiple stream reads from the same
110 ** file handle. If it were buffered, too many
111 ** input characters would be read on the first
112 ** block read.
113 */
114 
115 FORTRAN (                                       \
116 SCOTCHFGRAPHLOAD, scotchfgraphload, (           \
117 SCOTCH_Graph * const        grafptr,            \
118 int * const                 fileptr,            \
119 const SCOTCH_Num * const    baseptr,            \
120 const SCOTCH_Num * const    flagptr,            \
121 int * const                 revaptr),           \
122 (grafptr, fileptr, baseptr, flagptr, revaptr))
123 {
124   FILE *              stream;                     /* Stream to build from handle */
125   int                 filenum;                    /* Duplicated handle           */
126   int                 o;
127 
128   if ((filenum = dup (*fileptr)) < 0) {           /* If cannot duplicate file descriptor */
129     errorPrint ("SCOTCHFGRAPHLOAD: cannot duplicate handle");
130     *revaptr = 1;                                 /* Indicate error */
131     return;
132   }
133   if ((stream = fdopen (filenum, "r")) == NULL) { /* Build stream from handle */
134     errorPrint ("SCOTCHFGRAPHLOAD: cannot open input stream");
135     close      (filenum);
136     *revaptr = 1;
137     return;
138   }
139   setbuf (stream, NULL);                          /* Do not buffer on input */
140 
141   o = SCOTCH_graphLoad (grafptr, stream, *baseptr, *flagptr);
142 
143   fclose (stream);                                /* This closes filenum too */
144 
145   *revaptr = o;
146 }
147 
148 /*
149 **
150 */
151 
152 FORTRAN (                                       \
153 SCOTCHFGRAPHSAVE, scotchfgraphsave, (           \
154 const SCOTCH_Graph * const  grafptr,            \
155 int * const                 fileptr,            \
156 int * const                 revaptr),           \
157 (grafptr, fileptr, revaptr))
158 {
159   FILE *              stream;                     /* Stream to build from handle */
160   int                 filenum;                    /* Duplicated handle           */
161   int                 o;
162 
163   if ((filenum = dup (*fileptr)) < 0) {           /* If cannot duplicate file descriptor */
164     errorPrint ("SCOTCHFGRAPHSAVE: cannot duplicate handle");
165 
166     *revaptr = 1;                                 /* Indicate error */
167     return;
168   }
169   if ((stream = fdopen (filenum, "w")) == NULL) { /* Build stream from handle */
170     errorPrint ("SCOTCHFGRAPHSAVE: cannot open output stream");
171     close      (filenum);
172     *revaptr = 1;
173     return;
174   }
175 
176   o = SCOTCH_graphSave (grafptr, stream);
177 
178   fclose (stream);                                /* This closes filenum too */
179 
180   *revaptr = o;
181 }
182 
183 /*
184 **
185 */
186 
187 FORTRAN (                                       \
188 SCOTCHFGRAPHBUILD, scotchfgraphbuild, (         \
189 SCOTCH_Graph * const        grafptr,            \
190 const SCOTCH_Num * const    baseptr,            \
191 const SCOTCH_Num * const    vertptr,            \
192 const SCOTCH_Num * const    verttab,            \
193 const SCOTCH_Num * const    vendtab,            \
194 const SCOTCH_Num * const    velotab,            \
195 const SCOTCH_Num * const    vlbltab,            \
196 const SCOTCH_Num * const    edgeptr,            \
197 const SCOTCH_Num * const    edgetab,            \
198 const SCOTCH_Num * const    edlotab,            \
199 int * const                 revaptr),           \
200 (grafptr, baseptr, vertptr, verttab, vendtab,   \
201  velotab, vlbltab, edgeptr, edgetab, edlotab,   \
202  revaptr))
203 {
204   *revaptr = SCOTCH_graphBuild (grafptr, *baseptr, *vertptr, verttab, vendtab,
205                                 velotab, vlbltab, *edgeptr, edgetab, edlotab);
206 }
207 
208 /*
209 **
210 */
211 
212 FORTRAN (                                       \
213 SCOTCHFGRAPHSIZE, scotchfgraphsize, (           \
214 const SCOTCH_Graph * const  grafptr,            \
215 SCOTCH_Num * const          vertptr,            \
216 SCOTCH_Num * const          edgeptr),           \
217 (grafptr, vertptr, edgeptr))
218 {
219   SCOTCH_graphSize (grafptr, vertptr, edgeptr);
220 }
221 
222 /*
223 **
224 */
225 
226 FORTRAN (                                       \
227 SCOTCHFGRAPHDATA, scotchfgraphdata, (           \
228 const SCOTCH_Graph * const  grafptr,            \
229 const SCOTCH_Num * const    indxptr,            \
230 SCOTCH_Num * const          baseptr,            \
231 SCOTCH_Num * const          vertptr,            \
232 SCOTCH_Idx * const          vertidx,            \
233 SCOTCH_Idx * const          vendidx,            \
234 SCOTCH_Idx * const          veloidx,            \
235 SCOTCH_Idx * const          vlblidx,            \
236 SCOTCH_Num * const          edgeptr,            \
237 SCOTCH_Idx * const          edgeidx,            \
238 SCOTCH_Idx * const          edloidx),           \
239 (grafptr, indxptr, baseptr,                     \
240  vertptr, vertidx, vendidx, veloidx, vlblidx,   \
241  edgeptr, edgeidx, edloidx))
242 {
243   SCOTCH_Num *        verttab;                    /* Pointer to graph arrays */
244   SCOTCH_Num *        vendtab;
245   SCOTCH_Num *        velotab;
246   SCOTCH_Num *        vlbltab;
247   SCOTCH_Num *        edgetab;
248   SCOTCH_Num *        edlotab;
249 
250   SCOTCH_graphData (grafptr, baseptr, vertptr, &verttab, &vendtab, &velotab, &vlbltab,
251                     edgeptr, &edgetab, &edlotab);
252   *vertidx = (verttab - indxptr) + 1;             /* Add 1 since Fortran indices start at 1 */
253   *vendidx = (vendtab - indxptr) + 1;
254   *veloidx = (velotab != NULL) ? (velotab - indxptr) + 1 : *vertidx;
255   *vlblidx = (vlbltab != NULL) ? (vlbltab - indxptr) + 1 : *vertidx;
256   *edgeidx = (edgetab - indxptr) + 1;
257   *edloidx = (edlotab != NULL) ? (edlotab - indxptr) + 1 : *edgeidx;
258 }
259 
260 /*
261 **
262 */
263 
264 FORTRAN (                                       \
265 SCOTCHFGRAPHSTAT, scotchfgraphstat, (           \
266 const SCOTCH_Graph * const  grafptr,            \
267 SCOTCH_Num * const          velominptr,         \
268 SCOTCH_Num * const          velomaxptr,         \
269 SCOTCH_Num * const          velosumptr,         \
270 double *                    veloavgptr,         \
271 double *                    velodltptr,         \
272 SCOTCH_Num * const          degrminptr,         \
273 SCOTCH_Num * const          degrmaxptr,         \
274 double *                    degravgptr,         \
275 double *                    degrdltptr,         \
276 SCOTCH_Num * const          edlominptr,         \
277 SCOTCH_Num * const          edlomaxptr,         \
278 SCOTCH_Num * const          edlosumptr,         \
279 double *                    edloavgptr,         \
280 double *                    edlodltptr),        \
281 (grafptr, velominptr, velomaxptr, velosumptr,   \
282  veloavgptr, velodltptr, degrminptr,            \
283  degrmaxptr, degravgptr, degrdltptr,            \
284  edlominptr, edlomaxptr, edlosumptr,            \
285  edloavgptr, edlodltptr))
286 {
287   SCOTCH_graphStat (grafptr,
288                     velominptr, velomaxptr, velosumptr, veloavgptr, velodltptr,
289                     degrminptr, degrmaxptr, degravgptr, degrdltptr,
290                     edlominptr, edlomaxptr, edlosumptr, edloavgptr, edlodltptr);
291 }
292