1 /* ========================================================================== */
2 /* === Include/cholmod_blas.h =============================================== */
3 /* ========================================================================== */
4 
5 /* This does not need to be included in the user's program. */
6 
7 #ifndef CHOLMOD_BLAS_H
8 #define CHOLMOD_BLAS_H
9 
10 /* ========================================================================== */
11 /* === Architecture ========================================================= */
12 /* ========================================================================== */
13 
14 #if defined (__sun) || defined (MSOL2) || defined (ARCH_SOL2)
15 #define CHOLMOD_SOL2
16 #define CHOLMOD_ARCHITECTURE "Sun Solaris"
17 
18 #elif defined (__sgi) || defined (MSGI) || defined (ARCH_SGI)
19 #define CHOLMOD_SGI
20 #define CHOLMOD_ARCHITECTURE "SGI Irix"
21 
22 #elif defined (__linux) || defined (MGLNX86) || defined (ARCH_GLNX86)
23 #define CHOLMOD_LINUX
24 #define CHOLMOD_ARCHITECTURE "Linux"
25 
26 #elif defined (__APPLE__)
27 #define CHOLMOD_MAC
28 #define CHOLMOD_ARCHITECTURE "Mac"
29 
30 #elif defined (_AIX) || defined (MIBM_RS) || defined (ARCH_IBM_RS)
31 #define CHOLMOD_AIX
32 #define CHOLMOD_ARCHITECTURE "IBM AIX"
33 /* recent reports from IBM AIX seem to indicate that this is not needed: */
34 /* #define BLAS_NO_UNDERSCORE */
35 
36 #elif defined (__alpha) || defined (MALPHA) || defined (ARCH_ALPHA)
37 #define CHOLMOD_ALPHA
38 #define CHOLMOD_ARCHITECTURE "Compaq Alpha"
39 
40 #elif defined (_WIN32) || defined (WIN32) || defined (_WIN64) || defined (WIN64)
41 #if defined (__MINGW32__) || defined (__MINGW32__)
42 #define CHOLMOD_MINGW
43 #elif defined (__CYGWIN32__) || defined (__CYGWIN32__)
44 #define CHOLMOD_CYGWIN
45 #else
46 #define CHOLMOD_WINDOWS
47 #define BLAS_NO_UNDERSCORE
48 #endif
49 #define CHOLMOD_ARCHITECTURE "Microsoft Windows"
50 
51 #elif defined (__hppa) || defined (__hpux) || defined (MHPUX) || defined (ARCH_HPUX)
52 #define CHOLMOD_HP
53 #define CHOLMOD_ARCHITECTURE "HP Unix"
54 #define BLAS_NO_UNDERSCORE
55 
56 #elif defined (__hp700) || defined (MHP700) || defined (ARCH_HP700)
57 #define CHOLMOD_HP
58 #define CHOLMOD_ARCHITECTURE "HP 700 Unix"
59 #define BLAS_NO_UNDERSCORE
60 
61 #else
62 /* If the architecture is unknown, and you call the BLAS, you may need to */
63 /* define BLAS_BY_VALUE, BLAS_NO_UNDERSCORE, and/or BLAS_CHAR_ARG yourself. */
64 #define CHOLMOD_ARCHITECTURE "unknown"
65 #endif
66 
67 /* ========================================================================== */
68 /* === BLAS and LAPACK names ================================================ */
69 /* ========================================================================== */
70 
71 /* Prototypes for the various versions of the BLAS.  */
72 
73 /* Determine if the 64-bit Sun Performance BLAS is to be used */
74 #if defined(CHOLMOD_SOL2) && !defined(NSUNPERF) && defined(BLAS64)
75 #define SUN64
76 #endif
77 
78 #ifdef SUN64
79 
80 #define BLAS_DTRSV dtrsv_64_
81 #define BLAS_DGEMV dgemv_64_
82 #define BLAS_DTRSM dtrsm_64_
83 #define BLAS_DGEMM dgemm_64_
84 #define BLAS_DSYRK dsyrk_64_
85 #define BLAS_DGER  dger_64_
86 #define BLAS_DSCAL dscal_64_
87 #define LAPACK_DPOTRF dpotrf_64_
88 
89 #define BLAS_ZTRSV ztrsv_64_
90 #define BLAS_ZGEMV zgemv_64_
91 #define BLAS_ZTRSM ztrsm_64_
92 #define BLAS_ZGEMM zgemm_64_
93 #define BLAS_ZHERK zherk_64_
94 #define BLAS_ZGER  zgeru_64_
95 #define BLAS_ZSCAL zscal_64_
96 #define LAPACK_ZPOTRF zpotrf_64_
97 
98 #elif defined (BLAS_NO_UNDERSCORE)
99 
100 #define BLAS_DTRSV dtrsv
101 #define BLAS_DGEMV dgemv
102 #define BLAS_DTRSM dtrsm
103 #define BLAS_DGEMM dgemm
104 #define BLAS_DSYRK dsyrk
105 #define BLAS_DGER  dger
106 #define BLAS_DSCAL dscal
107 #define LAPACK_DPOTRF dpotrf
108 
109 #define BLAS_ZTRSV ztrsv
110 #define BLAS_ZGEMV zgemv
111 #define BLAS_ZTRSM ztrsm
112 #define BLAS_ZGEMM zgemm
113 #define BLAS_ZHERK zherk
114 #define BLAS_ZGER  zgeru
115 #define BLAS_ZSCAL zscal
116 #define LAPACK_ZPOTRF zpotrf
117 
118 #else
119 
120 #define BLAS_DTRSV dtrsv_
121 #define BLAS_DGEMV dgemv_
122 #define BLAS_DTRSM dtrsm_
123 #define BLAS_DGEMM dgemm_
124 #define BLAS_DSYRK dsyrk_
125 #define BLAS_DGER  dger_
126 #define BLAS_DSCAL dscal_
127 #define LAPACK_DPOTRF dpotrf_
128 
129 #define BLAS_ZTRSV ztrsv_
130 #define BLAS_ZGEMV zgemv_
131 #define BLAS_ZTRSM ztrsm_
132 #define BLAS_ZGEMM zgemm_
133 #define BLAS_ZHERK zherk_
134 #define BLAS_ZGER  zgeru_
135 #define BLAS_ZSCAL zscal_
136 #define LAPACK_ZPOTRF zpotrf_
137 
138 #endif
139 
140 /* ========================================================================== */
141 /* === BLAS and LAPACK integer arguments ==================================== */
142 /* ========================================================================== */
143 
144 /* Compile CHOLMOD, UMFPACK, and SPQR with -DBLAS64 if you have a BLAS that
145  * uses 64-bit integers */
146 
147 #if defined (LONGBLAS) || defined (BLAS64)
148 #define BLAS_INT SuiteSparse_long
149 #else
150 #define BLAS_INT int
151 #endif
152 
153 /* If the BLAS integer is smaller than the basic CHOLMOD integer, then we need
154  * to check for integer overflow when converting from Int to BLAS_INT.  If
155  * any integer overflows, the externally-defined BLAS_OK variable is
156  * set to FALSE.  BLAS_OK should be set to TRUE before calling any
157  * BLAS_* macro.
158  */
159 
160 #define CHECK_BLAS_INT (sizeof (BLAS_INT) < sizeof (Int))
161 #define EQ(K,k) (((BLAS_INT) K) == ((Int) k))
162 
163 /* ========================================================================== */
164 /* === BLAS and LAPACK prototypes and macros ================================ */
165 /* ========================================================================== */
166 
167 void BLAS_DGEMV (char *trans, BLAS_INT *m, BLAS_INT *n, double *alpha,
168 	double *A, BLAS_INT *lda, double *X, BLAS_INT *incx, double *beta,
169 	double *Y, BLAS_INT *incy) ;
170 
171 #define BLAS_dgemv(trans,m,n,alpha,A,lda,X,incx,beta,Y,incy) \
172 { \
173     BLAS_INT M = m, N = n, LDA = lda, INCX = incx, INCY = incy ; \
174     if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (LDA,lda) && \
175         EQ (INCX,incx) && EQ (INCY,incy))) \
176     { \
177 	BLAS_OK = FALSE ; \
178     } \
179     if (!CHECK_BLAS_INT || BLAS_OK) \
180     { \
181 	BLAS_DGEMV (trans, &M, &N, alpha, A, &LDA, X, &INCX, beta, Y, &INCY) ; \
182     } \
183 }
184 
185 void BLAS_ZGEMV (char *trans, BLAS_INT *m, BLAS_INT *n, double *alpha,
186 	double *A, BLAS_INT *lda, double *X, BLAS_INT *incx, double *beta,
187 	double *Y, BLAS_INT *incy) ;
188 
189 #define BLAS_zgemv(trans,m,n,alpha,A,lda,X,incx,beta,Y,incy) \
190 { \
191     BLAS_INT M = m, N = n, LDA = lda, INCX = incx, INCY = incy ; \
192     if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (LDA,lda) && \
193         EQ (INCX,incx) && EQ (INCY,incy))) \
194     { \
195 	BLAS_OK = FALSE ; \
196     } \
197     if (!CHECK_BLAS_INT || BLAS_OK) \
198     { \
199 	BLAS_ZGEMV (trans, &M, &N, alpha, A, &LDA, X, &INCX, beta, Y, &INCY) ; \
200     } \
201 }
202 
203 void BLAS_DTRSV (char *uplo, char *trans, char *diag, BLAS_INT *n, double *A,
204 	BLAS_INT *lda, double *X, BLAS_INT *incx) ;
205 
206 #define BLAS_dtrsv(uplo,trans,diag,n,A,lda,X,incx) \
207 { \
208     BLAS_INT N = n, LDA = lda, INCX = incx ; \
209     if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (LDA,lda) && EQ (INCX,incx))) \
210     { \
211 	BLAS_OK = FALSE ; \
212     } \
213     if (!CHECK_BLAS_INT || BLAS_OK) \
214     { \
215 	BLAS_DTRSV (uplo, trans, diag, &N, A, &LDA, X, &INCX) ; \
216     } \
217 }
218 
219 void BLAS_ZTRSV (char *uplo, char *trans, char *diag, BLAS_INT *n, double *A,
220 	BLAS_INT *lda, double *X, BLAS_INT *incx) ;
221 
222 #define BLAS_ztrsv(uplo,trans,diag,n,A,lda,X,incx) \
223 { \
224     BLAS_INT N = n, LDA = lda, INCX = incx ; \
225     if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (LDA,lda) && EQ (INCX,incx))) \
226     { \
227 	BLAS_OK = FALSE ; \
228     } \
229     if (!CHECK_BLAS_INT || BLAS_OK) \
230     { \
231 	BLAS_ZTRSV (uplo, trans, diag, &N, A, &LDA, X, &INCX) ; \
232     } \
233 }
234 
235 void BLAS_DTRSM (char *side, char *uplo, char *transa, char *diag, BLAS_INT *m,
236 	BLAS_INT *n, double *alpha, double *A, BLAS_INT *lda, double *B,
237 	BLAS_INT *ldb) ;
238 
239 #define BLAS_dtrsm(side,uplo,transa,diag,m,n,alpha,A,lda,B,ldb) \
240 { \
241     BLAS_INT M = m, N = n, LDA = lda, LDB = ldb ; \
242     if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (LDA,lda) && \
243         EQ (LDB,ldb))) \
244     { \
245 	BLAS_OK = FALSE ; \
246     } \
247     if (!CHECK_BLAS_INT || BLAS_OK) \
248     { \
249 	BLAS_DTRSM (side, uplo, transa, diag, &M, &N, alpha, A, &LDA, B, &LDB);\
250     } \
251 }
252 
253 void BLAS_ZTRSM (char *side, char *uplo, char *transa, char *diag, BLAS_INT *m,
254 	BLAS_INT *n, double *alpha, double *A, BLAS_INT *lda, double *B,
255 	BLAS_INT *ldb) ;
256 
257 #define BLAS_ztrsm(side,uplo,transa,diag,m,n,alpha,A,lda,B,ldb) \
258 { \
259     BLAS_INT M = m, N = n, LDA = lda, LDB = ldb ; \
260     if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (LDA,lda) && \
261         EQ (LDB,ldb))) \
262     { \
263 	BLAS_OK = FALSE ; \
264     } \
265     if (!CHECK_BLAS_INT || BLAS_OK) \
266     { \
267 	BLAS_ZTRSM (side, uplo, transa, diag, &M, &N, alpha, A, &LDA, B, &LDB);\
268     } \
269 }
270 
271 void BLAS_DGEMM (char *transa, char *transb, BLAS_INT *m, BLAS_INT *n,
272 	BLAS_INT *k, double *alpha, double *A, BLAS_INT *lda, double *B,
273 	BLAS_INT *ldb, double *beta, double *C, BLAS_INT *ldc) ;
274 
275 #define BLAS_dgemm(transa,transb,m,n,k,alpha,A,lda,B,ldb,beta,C,ldc) \
276 { \
277     BLAS_INT M = m, N = n, K = k, LDA = lda, LDB = ldb, LDC = ldc ; \
278     if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (K,k) && \
279         EQ (LDA,lda) && EQ (LDB,ldb) && EQ (LDC,ldc))) \
280     { \
281 	BLAS_OK = FALSE ; \
282     } \
283     if (!CHECK_BLAS_INT || BLAS_OK) \
284     { \
285 	BLAS_DGEMM (transa, transb, &M, &N, &K, alpha, A, &LDA, B, &LDB, beta, \
286 	    C, &LDC) ; \
287     } \
288 }
289 
290 void BLAS_ZGEMM (char *transa, char *transb, BLAS_INT *m, BLAS_INT *n,
291 	BLAS_INT *k, double *alpha, double *A, BLAS_INT *lda, double *B,
292 	BLAS_INT *ldb, double *beta, double *C, BLAS_INT *ldc) ;
293 
294 #define BLAS_zgemm(transa,transb,m,n,k,alpha,A,lda,B,ldb,beta,C,ldc) \
295 { \
296     BLAS_INT M = m, N = n, K = k, LDA = lda, LDB = ldb, LDC = ldc ; \
297     if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (K,k) && \
298         EQ (LDA,lda) && EQ (LDB,ldb) && EQ (LDC,ldc))) \
299     { \
300 	BLAS_OK = FALSE ; \
301     } \
302     if (!CHECK_BLAS_INT || BLAS_OK) \
303     { \
304 	BLAS_ZGEMM (transa, transb, &M, &N, &K, alpha, A, &LDA, B, &LDB, beta, \
305 	    C, &LDC) ; \
306     } \
307 }
308 
309 void BLAS_DSYRK (char *uplo, char *trans, BLAS_INT *n, BLAS_INT *k,
310 	double *alpha, double *A, BLAS_INT *lda, double *beta, double *C,
311 	BLAS_INT *ldc) ;
312 
313 #define BLAS_dsyrk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc) \
314 { \
315     BLAS_INT N = n, K = k, LDA = lda, LDC = ldc ; \
316     if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (K,k) && EQ (LDA,lda) && \
317         EQ (LDC,ldc))) \
318     { \
319 	BLAS_OK = FALSE ; \
320     } \
321     if (!CHECK_BLAS_INT || BLAS_OK) \
322     { \
323 	BLAS_DSYRK (uplo, trans, &N, &K, alpha, A, &LDA, beta, C, &LDC) ; \
324     } \
325 } \
326 
327 void BLAS_ZHERK (char *uplo, char *trans, BLAS_INT *n, BLAS_INT *k,
328 	double *alpha, double *A, BLAS_INT *lda, double *beta, double *C,
329 	BLAS_INT *ldc) ;
330 
331 #define BLAS_zherk(uplo,trans,n,k,alpha,A,lda,beta,C,ldc) \
332 { \
333     BLAS_INT N = n, K = k, LDA = lda, LDC = ldc ; \
334     if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (K,k) && EQ (LDA,lda) && \
335         EQ (LDC,ldc))) \
336     { \
337 	BLAS_OK = FALSE ; \
338     } \
339     if (!CHECK_BLAS_INT || BLAS_OK) \
340     { \
341 	BLAS_ZHERK (uplo, trans, &N, &K, alpha, A, &LDA, beta, C, &LDC) ; \
342     } \
343 } \
344 
345 void LAPACK_DPOTRF (char *uplo, BLAS_INT *n, double *A, BLAS_INT *lda,
346 	BLAS_INT *info) ;
347 
348 #define LAPACK_dpotrf(uplo,n,A,lda,info) \
349 { \
350     BLAS_INT N = n, LDA = lda, INFO = 1 ; \
351     if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (LDA,lda))) \
352     { \
353 	BLAS_OK = FALSE ; \
354     } \
355     if (!CHECK_BLAS_INT || BLAS_OK) \
356     { \
357 	LAPACK_DPOTRF (uplo, &N, A, &LDA, &INFO) ; \
358     } \
359     info = INFO ; \
360 }
361 
362 void LAPACK_ZPOTRF (char *uplo, BLAS_INT *n, double *A, BLAS_INT *lda,
363 	BLAS_INT *info) ;
364 
365 #define LAPACK_zpotrf(uplo,n,A,lda,info) \
366 { \
367     BLAS_INT N = n, LDA = lda, INFO = 1 ; \
368     if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (LDA,lda))) \
369     { \
370 	BLAS_OK = FALSE ; \
371     } \
372     if (!CHECK_BLAS_INT || BLAS_OK) \
373     { \
374 	LAPACK_ZPOTRF (uplo, &N, A, &LDA, &INFO) ; \
375     } \
376     info = INFO ; \
377 }
378 
379 /* ========================================================================== */
380 
381 void BLAS_DSCAL (BLAS_INT *n, double *alpha, double *Y, BLAS_INT *incy) ;
382 
383 #define BLAS_dscal(n,alpha,Y,incy) \
384 { \
385     BLAS_INT N = n, INCY = incy ; \
386     if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (INCY,incy))) \
387     { \
388 	BLAS_OK = FALSE ; \
389     } \
390     if (!CHECK_BLAS_INT || BLAS_OK) \
391     { \
392 	BLAS_DSCAL (&N, alpha, Y, &INCY) ; \
393     } \
394 }
395 
396 void BLAS_ZSCAL (BLAS_INT *n, double *alpha, double *Y, BLAS_INT *incy) ;
397 
398 #define BLAS_zscal(n,alpha,Y,incy) \
399 { \
400     BLAS_INT N = n, INCY = incy ; \
401     if (CHECK_BLAS_INT && !(EQ (N,n) && EQ (INCY,incy))) \
402     { \
403 	BLAS_OK = FALSE ; \
404     } \
405     if (!CHECK_BLAS_INT || BLAS_OK) \
406     { \
407 	BLAS_ZSCAL (&N, alpha, Y, &INCY) ; \
408     } \
409 }
410 
411 void BLAS_DGER (BLAS_INT *m, BLAS_INT *n, double *alpha,
412 	double *X, BLAS_INT *incx, double *Y, BLAS_INT *incy,
413 	double *A, BLAS_INT *lda) ;
414 
415 #define BLAS_dger(m,n,alpha,X,incx,Y,incy,A,lda) \
416 { \
417     BLAS_INT M = m, N = n, LDA = lda, INCX = incx, INCY = incy ; \
418     if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (LDA,lda) && \
419           EQ (INCX,incx) && EQ (INCY,incy))) \
420     { \
421 	BLAS_OK = FALSE ; \
422     } \
423     if (!CHECK_BLAS_INT || BLAS_OK) \
424     { \
425 	BLAS_DGER (&M, &N, alpha, X, &INCX, Y, &INCY, A, &LDA) ; \
426     } \
427 }
428 
429 void BLAS_ZGER (BLAS_INT *m, BLAS_INT *n, double *alpha,
430 	double *X, BLAS_INT *incx, double *Y, BLAS_INT *incy,
431 	double *A, BLAS_INT *lda) ;
432 
433 #define BLAS_zgeru(m,n,alpha,X,incx,Y,incy,A,lda) \
434 { \
435     BLAS_INT M = m, N = n, LDA = lda, INCX = incx, INCY = incy ; \
436     if (CHECK_BLAS_INT && !(EQ (M,m) && EQ (N,n) && EQ (LDA,lda) && \
437           EQ (INCX,incx) && EQ (INCY,incy))) \
438     { \
439 	BLAS_OK = FALSE ; \
440     } \
441     if (!CHECK_BLAS_INT || BLAS_OK) \
442     { \
443 	BLAS_ZGER (&M, &N, alpha, X, &INCX, Y, &INCY, A, &LDA) ; \
444     } \
445 }
446 
447 #endif
448