1 /* ========================================================================= */
2 /* === amd_internal.h ====================================================== */
3 /* ========================================================================= */
4 
5 /* ------------------------------------------------------------------------- */
6 /* AMD, Copyright (c) Timothy A. Davis,                                      */
7 /* Patrick R. Amestoy, and Iain S. Duff.  See ../README.txt for License.     */
8 /* email: DrTimothyAldenDavis@gmail.com                                      */
9 /* ------------------------------------------------------------------------- */
10 
11 /* This file is for internal use in AMD itself, and does not normally need to
12  * be included in user code (it is included in UMFPACK, however).   All others
13  * should use amd.h instead.
14  */
15 
16 /* ========================================================================= */
17 /* === NDEBUG ============================================================== */
18 /* ========================================================================= */
19 
20 /*
21  * Turning on debugging takes some work (see below).   If you do not edit this
22  * file, then debugging is always turned off, regardless of whether or not
23  * -DNDEBUG is specified in your compiler options.
24  *
25  * If AMD is being compiled as a mexFunction, then MATLAB is defined,
26  * and mxAssert is used instead of assert.  If debugging is not enabled, no
27  * MATLAB include files or functions are used.  Thus, the AMD library libamd.a
28  * can be safely used in either a stand-alone C program or in another
29  * mexFunction, without any change.
30  */
31 
32 /*
33     AMD will be exceedingly slow when running in debug mode.  The next three
34     lines ensure that debugging is turned off.
35 */
36 //#define NDEBUG
37 
38 /*
39     To enable debugging, uncomment the following line:
40 #undef NDEBUG
41 */
42 module amd_internal;
43 
44 nothrow @nogc extern(C):
45 
46 import glob_opts;
47 import SuiteSparse_config;
48 import amd_postorder;
49 import amd_preprocess;
50 import amd_aat;
51 import amd_valid;
52 import amd_1;
53 import amd_2;
54 
55 /* ------------------------------------------------------------------------- */
56 /* ANSI include files */
57 /* ------------------------------------------------------------------------- */
58 
59 import core.stdc.stdlib;  // size_t, malloc, free, realloc, and calloc
60 import core.stdc.stdarg;
61 
62 //#if !defined(NPRINT) || !defined(NDEBUG)
63 version (NPRINT){}
64 else {
65 /* from stdio.h:  printf.  Not included if NPRINT is defined at compile time.
66  * fopen and fscanf are used when debugging. */
67 import core.stdc.stdio;
68 }
69 
70 version (NDEBUG){}
71 else {
72 /* from stdio.h:  printf.  Not included if NPRINT is defined at compile time.
73  * fopen and fscanf are used when debugging. */
74 import core.stdc.stdio;
75 }
76 
77 /* from limits.h:  INT_MAX and LONG_MAX */
78 import core.stdc.limits;
79 
80 /* from math.h: sqrt */
81 import core.stdc.math;
82 
83 /* ------------------------------------------------------------------------- */
84 /* MATLAB include files (only if being used in or via MATLAB) */
85 /* ------------------------------------------------------------------------- */
86 
87 version(MATLAB){
88 //#include "matrix.h"
89 //#include "mex.h"
90 import matrix;
91 import meh;
92 }
93 
94 /* ------------------------------------------------------------------------- */
95 /* basic definitions */
96 /* ------------------------------------------------------------------------- */
97 /*
98 #ifdef FLIP
99 #undef FLIP
100 #endif
101 
102 #ifdef MAX
103 #undef MAX
104 #endif
105 
106 #ifdef MIN
107 #undef MIN
108 #endif
109 
110 #ifdef EMPTY
111 #undef EMPTY
112 #endif
113 
114 #ifdef GLOBAL
115 #undef GLOBAL
116 #endif
117 
118 #ifdef PRIVATE
119 #undef PRIVATE
120 #endif
121 */
122 /* FLIP is a "negation about -1", and is used to mark an integer i that is
123  * normally non-negative.  FLIP (EMPTY) is EMPTY.  FLIP of a number > EMPTY
124  * is negative, and FLIP of a number < EMTPY is positive.  FLIP (FLIP (i)) = i
125  * for all integers i.  UNFLIP (i) is >= EMPTY. */
126 enum c_int EMPTY = -1;
127 
128 //#define FLIP(i) (-(i)-2)
129 //#define UNFLIP(i) ((i < EMPTY) ? FLIP (i) : (i))
130 // todo  test it
131 c_int FLIP(c_int i) {return (-(i)-2);}
132 c_int UNFLIP(c_int i) {return ((i < EMPTY) ? FLIP (i) : (i));}
133 
134 /* for integer MAX/MIN, or for c_floats when we don't care how NaN's behave: */
135 //#define MAX(a,b) (((a) > (b)) ? (a) : (b))
136 //#define MIN(a,b) (((a) < (b)) ? (a) : (b))
137 auto MAX(T)(auto ref T a, auto ref T b) {return (((a) > (b)) ? (a) : (b));}
138 auto MIN(T)(auto ref T a, auto ref T b) {return (((a) < (b)) ? (a) : (b));}
139 
140 /* logical expression of p implies q: */
141 //#define IMPLIES(p,q) (!(p) || (q))
142 bool IMPLIES(T1, T2)(auto ref T1 p, auto ref T2 q) { return (!(p) || (q));}
143 
144 /* Note that the IBM RS 6000 xlc predefines TRUE and FALSE in <types.h>. */
145 /* The Compaq Alpha also predefines TRUE and FALSE. */
146 /*
147 #ifdef TRUE
148 #undef TRUE
149 #endif
150 #ifdef FALSE
151 #undef FALSE
152 #endif
153 */
154 enum c_int TRUE = 1;
155 enum c_int FALSE = 0;
156 //#define PRIVATE static
157 // todo : check it
158 //alias PRIVATE = static
159 //#define GLOBAL
160 //#define EMPTY (-1)
161 //enum c_int EMPTY = -1;
162 
163 /* Note that Linux's gcc 2.96 defines NULL as ((void *) 0), but other */
164 /* compilers (even gcc 2.95.2 on Solaris) define NULL as 0 or (0).  We */
165 /* need to use the ANSI standard value of 0. */
166 /*
167 #ifdef NULL
168 #undef NULL
169 #endif
170 */
171 auto NULL = null;
172 
173 /* largest value of size_t */
174 /*
175 #ifndef SIZE_T_MAX
176 #ifdef SIZE_MAX
177 // C99 only 
178 #define SIZE_T_MAX SIZE_MAX
179 #else
180 #define SIZE_T_MAX ((size_t) (-1))
181 #endif
182 #endif
183 */
184 enum c_int SIZE_T_MAX = (cast(size_t) (-1));
185 
186 
187 version(NDEBUG){
188     void AMD_debug_init ( string s ) {};
189     void AMD_dump
190     (
191         Int n,
192         Int *Pe ,
193         Int *Iw,
194         Int *Len,
195         Int iwlen,
196         Int pfree,
197         Int *Nv,
198         Int *Next,
199         Int *Last,
200         Int *Head,
201         Int *Elen,
202         Int *Degree,
203         Int *W,
204         Int nel
205     ) {};
206 }
207 else {
208     //void AMD_debug_init ( char *s ) ;
209     void AMD_debug_init ( string s ) ;
210 
211     void AMD_dump
212     (
213         Int n,
214         Int *Pe ,
215         Int *Iw,
216         Int *Len,
217         Int iwlen,
218         Int pfree,
219         Int *Nv,
220         Int *Next,
221         Int *Last,
222         Int *Head,
223         Int *Elen,
224         Int *Degree,
225         Int *W,
226         Int nel
227     );
228 }
229 /* ------------------------------------------------------------------------- */
230 /* integer type for AMD: int or SuiteSparse_long */
231 /* ------------------------------------------------------------------------- */
232 
233 import amd;
234 
235 //#if defined (DLONG) || defined (ZLONG)
236 version(DLONG){
237     alias Int = SuiteSparse_long;
238     alias UInt = ulong;
239     alias ID = SuiteSparse_long_idd;
240     alias Int_MAX = SuiteSparse_long_max;
241 /*    alias amd_l_order = AMD_order;
242     alias amd_l_defaults = AMD_defaults;
243     alias amd_l_control = AMD_control;
244     alias amd_l_info = AMD_info;
245     alias amd_l1 = AMD_1;
246     alias amd_l2 = AMD_2;
247     alias amd_l_valid = AMD_valid;
248     alias amd_l_aat = AMD_aat;
249     alias amd_l_postorder = AMD_postorder;
250     alias amd_l_post_tree = AMD_post_tree;
251     alias amd_l_dump = AMD_dump;
252     alias amd_l_debug = AMD_debug;
253     alias amd_l_debug_init = AMD_debug_init;
254     alias amd_l_preprocess = AMD_preprocess;*/
255 }
256 else {
257     version(ZLONG){
258         alias Int = SuiteSparse_long;
259         alias UInt = ulong;
260         alias ID = SuiteSparse_long_idd;
261         alias Int_MAX = SuiteSparse_long_max;
262     /*    alias AMD_order = amd_l_order;
263         alias AMD_defaults = amd_l_defaults;
264         alias amd_l_control = AMD_control;
265         alias amd_l_info = AMD_info;
266         alias amd_l1 = AMD_1;
267         alias amd_l2 = AMD_2;
268         alias amd_l_valid = AMD_valid;
269         alias amd_l_aat = AMD_aat;
270         alias amd_l_postorder = AMD_postorder;
271         alias amd_l_post_tree = AMD_post_tree;
272         alias amd_l_dump = AMD_dump;
273         alias amd_l_debug = AMD_debug;
274         alias amd_l_debug_init = AMD_debug_init;
275         alias amd_l_preprocess = AMD_preprocess;*/
276     }
277     else {
278         alias Int = int;
279         alias UInt = uint;
280         enum string ID = "%d";        
281         alias Int_MAX = INT_MAX;
282         
283     /*    alias amd_order = AMD_order;
284         alias amd_defaults = AMD_defaults;
285         alias amd_control = AMD_control;
286         alias amd_info = AMD_info;
287         alias amd_1 = AMD_1;
288         alias amd_2 = AMD_2;
289         alias amd_valid = AMD_valid;
290         alias amd_aat = AMD_aat;
291         alias amd_postorder = AMD_postorder;
292         alias amd_post_tree = AMD_post_tree;
293         alias amd_dump = AMD_dump;
294         alias amd_debug = AMD_debug;
295         alias amd_debug_init = AMD_debug_init;
296         alias amd_preprocess = AMD_preprocess;*/
297     }
298 }
299 
300 /* ------------------------------------------------------------------------- */
301 /* debugging definitions */
302 /* ------------------------------------------------------------------------- */
303 
304 version (NDEBUG){
305 /* no debugging */
306 //#define ASSERT(expression)
307 //#define AMD_DEBUG0(params)
308 //#define AMD_DEBUG1(params)
309 //#define AMD_DEBUG2(params)
310 //#define AMD_DEBUG3(params)
311 //#define AMD_DEBUG4(params)
312 
313 void ASSERT(T)(auto ref T expression) {}
314 void AMD_DEBUG0(T)(auto ref T params, ...) {}
315 void AMD_DEBUG1(T)(auto ref T params, ...) {}
316 void AMD_DEBUG2(T)(auto ref T params, ...) {}
317 void AMD_DEBUG3(T)(auto ref T params, ...) {}
318 void AMD_DEBUG4(T)(auto ref T params, ...) {}
319 //__gshared Int AMD_debug = 0;
320 }
321 else 
322 {
323     /* from assert.h:  assert macro */
324     // todo : maybe no need special import for assert
325     //#include <assert.h>
326     //import core.sync.exception;
327     //import core.stdcpp.exception;    
328 
329     //#ifndef EXTERN
330     //#define EXTERN extern
331     //#endif
332 
333     //EXTERN Int AMD_debug ;
334     //__gshared Int AMD_debug = 3; // todo : AMD_debug declared nowhere in C code
335 
336     //#ifdef ASSERT
337     //#undef ASSERT
338     //#endif
339 
340     /* Use mxAssert if AMD is compiled into a mexFunction */
341     version(MATLAB){
342         //#define ASSERT(expression) (mxAssert ((expression), ""))
343         void ASSERT(T)(T expression) { mxAssert((expression), ""); }
344     }else {
345         //#define ASSERT(expression) (assert (expression))
346         void ASSERT(T)(T expression) { assert(expression); }
347     }
348 
349     //#define AMD_DEBUG0(params) { SUITESPARSE_PRINTF (params) ; }
350     //#define AMD_DEBUG1(params) { if (AMD_debug >= 1) SUITESPARSE_PRINTF (params) ; }
351     //#define AMD_DEBUG2(params) { if (AMD_debug >= 2) SUITESPARSE_PRINTF (params) ; }
352     //#define AMD_DEBUG3(params) { if (AMD_debug >= 3) SUITESPARSE_PRINTF (params) ; }
353     //#define AMD_DEBUG4(params) { if (AMD_debug >= 4) SUITESPARSE_PRINTF (params) ; }
354     void AMD_DEBUG0(T)(auto ref T params, ...) { SUITESPARSE_PRINTF (params); }
355     // todo : AMD_debug declared nowhere in C code
356     void AMD_DEBUG1(T)(auto ref T params, ...) { /*if (AMD_debug >= 1)*/ SUITESPARSE_PRINTF (params); }
357     void AMD_DEBUG2(T)(auto ref T params, ...) { /*if (AMD_debug >= 2) */SUITESPARSE_PRINTF (params); }
358     void AMD_DEBUG3(T)(auto ref T params, ...) { /*if (AMD_debug >= 3)*/ SUITESPARSE_PRINTF (params); }
359     void AMD_DEBUG4(T)(auto ref T params, ...) { /*if (AMD_debug >= 4) */SUITESPARSE_PRINTF (params); }
360 
361 } // !NDEBUG