Haiku supporting patches
[platform/upstream/openblas.git] / common.h
1 /*********************************************************************/
2 /* Copyright 2009, 2010 The University of Texas at Austin.           */
3 /* All rights reserved.                                              */
4 /*                                                                   */
5 /* Redistribution and use in source and binary forms, with or        */
6 /* without modification, are permitted provided that the following   */
7 /* conditions are met:                                               */
8 /*                                                                   */
9 /*   1. Redistributions of source code must retain the above         */
10 /*      copyright notice, this list of conditions and the following  */
11 /*      disclaimer.                                                  */
12 /*                                                                   */
13 /*   2. Redistributions in binary form must reproduce the above      */
14 /*      copyright notice, this list of conditions and the following  */
15 /*      disclaimer in the documentation and/or other materials       */
16 /*      provided with the distribution.                              */
17 /*                                                                   */
18 /*    THIS  SOFTWARE IS PROVIDED  BY THE  UNIVERSITY OF  TEXAS AT    */
19 /*    AUSTIN  ``AS IS''  AND ANY  EXPRESS OR  IMPLIED WARRANTIES,    */
20 /*    INCLUDING, BUT  NOT LIMITED  TO, THE IMPLIED  WARRANTIES OF    */
21 /*    MERCHANTABILITY  AND FITNESS FOR  A PARTICULAR  PURPOSE ARE    */
22 /*    DISCLAIMED.  IN  NO EVENT SHALL THE UNIVERSITY  OF TEXAS AT    */
23 /*    AUSTIN OR CONTRIBUTORS BE  LIABLE FOR ANY DIRECT, INDIRECT,    */
24 /*    INCIDENTAL,  SPECIAL, EXEMPLARY,  OR  CONSEQUENTIAL DAMAGES    */
25 /*    (INCLUDING, BUT  NOT LIMITED TO,  PROCUREMENT OF SUBSTITUTE    */
26 /*    GOODS  OR  SERVICES; LOSS  OF  USE,  DATA,  OR PROFITS;  OR    */
27 /*    BUSINESS INTERRUPTION) HOWEVER CAUSED  AND ON ANY THEORY OF    */
28 /*    LIABILITY, WHETHER  IN CONTRACT, STRICT  LIABILITY, OR TORT    */
29 /*    (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY WAY OUT    */
30 /*    OF  THE  USE OF  THIS  SOFTWARE,  EVEN  IF ADVISED  OF  THE    */
31 /*    POSSIBILITY OF SUCH DAMAGE.                                    */
32 /*                                                                   */
33 /* The views and conclusions contained in the software and           */
34 /* documentation are those of the authors and should not be          */
35 /* interpreted as representing official policies, either expressed   */
36 /* or implied, of The University of Texas at Austin.                 */
37 /*********************************************************************/
38
39 #ifndef COMMON_H
40 #define COMMON_H
41
42 #ifdef __cplusplus
43 extern "C" {
44         /* Assume C declarations for C++ */
45 #endif  /* __cplusplus */
46
47 #ifndef _GNU_SOURCE
48 #define _GNU_SOURCE
49 #endif
50
51 #ifndef __USE_XOPEN
52 #define __USE_XOPEN
53 #endif
54
55 #ifndef __USE_SVID
56 #define __USE_SVID
57 #endif
58
59 #ifdef BUILD_KERNEL
60 #include "config_kernel.h"
61 #else
62 #include "config.h"
63 #endif
64
65 #undef ENABLE_SSE_EXCEPTION
66
67 #if defined(SMP_SERVER) || defined(SMP_ONDEMAND)
68 #define SMP
69 #endif
70
71 #if defined(OS_WINNT) || defined(OS_CYGWIN_NT) || defined(OS_INTERIX)
72 #define WINDOWS_ABI
73 #define OS_WINDOWS
74
75 #ifdef DOUBLE
76 #define DOUBLE_DEFINED DOUBLE
77 #undef  DOUBLE
78 #endif
79 #endif
80
81 #if !defined(NOINCLUDE) && !defined(ASSEMBLER)
82 #include <stdio.h>
83 #include <stdlib.h>
84 #include <string.h>
85
86 #if !defined(_MSC_VER)
87 #include <unistd.h>
88 #endif
89 #include <time.h>
90
91 #ifdef OS_LINUX
92 #include <malloc.h>
93 #include <sched.h>
94 #endif
95
96 #if defined(OS_DARWIN) || defined(OS_FREEBSD) || defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_DRAGONFLY) || defined(OS_ANDROID)
97 #include <sched.h>
98 #endif
99
100 #ifdef OS_ANDROID
101 #define NO_SYSV_IPC
102 //Android NDK only supports complex.h since Android 5.0
103 #if __ANDROID_API__ < 21
104 #define FORCE_OPENBLAS_COMPLEX_STRUCT
105 #endif
106 #endif
107
108 #ifdef OS_HAIKU
109 #define NO_SYSV_IPC
110 #endif
111
112 #ifdef OS_WINDOWS
113 #ifdef  ATOM
114 #define GOTO_ATOM ATOM
115 #undef  ATOM
116 #endif
117 #include <windows.h>
118 #include <math.h>
119 #ifdef  GOTO_ATOM
120 #define ATOM GOTO_ATOM
121 #undef  GOTO_ATOM
122 #endif
123 #else
124 #include <sys/mman.h>
125 #ifndef NO_SYSV_IPC
126 #include <sys/shm.h>
127 #endif
128 #include <sys/time.h>
129 #include <time.h>
130 #include <unistd.h>
131 #include <math.h>
132 #ifdef SMP
133 #include <pthread.h>
134 #endif
135 #endif
136
137 #if defined(OS_SUNOS)
138 #include <thread.h>
139 #endif
140
141 #ifdef __DECC
142 #include <c_asm.h>
143 #include <machine/builtins.h>
144 #endif
145
146 #if defined(ARCH_IA64) && defined(ENABLE_SSE_EXCEPTION)
147 #include <fenv.h>
148 #endif
149
150 #endif
151
152 #if defined(OS_WINDOWS) && defined(DOUBLE_DEFINED)
153 #define DOUBLE DOUBLE_DEFINED
154 #undef DOUBLE_DEFINED
155 #endif
156
157 #undef DEBUG_INFO
158 #define SMP_DEBUG
159 #undef MALLOC_DEBUG
160 #undef SMP_ALLOC_DEBUG
161
162 #ifndef ZERO
163 #ifdef XDOUBLE
164 #define ZERO  0.e0L
165 #elif defined DOUBLE
166 #define ZERO  0.e0
167 #else
168 #define ZERO  0.e0f
169 #endif
170 #endif
171
172 #ifndef ONE
173 #ifdef XDOUBLE
174 #define ONE  1.e0L
175 #elif defined DOUBLE
176 #define ONE  1.e0
177 #else
178 #define ONE  1.e0f
179 #endif
180 #endif
181
182 #define BITMASK(a, b, c) ((((a) >> (b)) & (c)))
183
184 #define ALLOCA_ALIGN 63UL
185
186 #define NUM_BUFFERS (MAX_CPU_NUMBER * 2 * MAX_PARALLEL_NUMBER)
187
188 #ifdef NEEDBUNDERSCORE
189 #define BLASFUNC(FUNC) FUNC##_
190 #else
191 #define BLASFUNC(FUNC) FUNC
192 #endif
193
194 #undef  USE_PTHREAD_LOCK
195 #undef  USE_PTHREAD_SPINLOCK
196
197 #if defined(USE_PTHREAD_LOCK) && defined(USE_PTHREAD_SPINLOCK)
198 #error "You can't specify both LOCK operation!"
199 #endif
200
201 #ifdef SMP
202 #define USE_PTHREAD_LOCK
203 #undef  USE_PTHREAD_SPINLOCK
204 #endif
205
206 #ifdef OS_WINDOWS
207 #undef  USE_PTHREAD_LOCK
208 #undef  USE_PTHREAD_SPINLOCK
209 #endif
210
211 #if   defined(USE_PTHREAD_LOCK)
212 #define   LOCK_COMMAND(x)   pthread_mutex_lock(x)
213 #define UNLOCK_COMMAND(x)   pthread_mutex_unlock(x)
214 #elif defined(USE_PTHREAD_SPINLOCK)
215 #ifndef ASSEMBLER
216 typedef volatile int pthread_spinlock_t;
217 int pthread_spin_lock (pthread_spinlock_t *__lock);
218 int pthread_spin_unlock (pthread_spinlock_t *__lock);
219 #endif
220 #define   LOCK_COMMAND(x)   pthread_spin_lock(x)
221 #define UNLOCK_COMMAND(x)   pthread_spin_unlock(x)
222 #else
223 #define   LOCK_COMMAND(x)   blas_lock(x)
224 #define UNLOCK_COMMAND(x)   blas_unlock(x)
225 #endif
226
227 #define GOTO_SHMID      0x510510
228
229 #if 0
230 #ifndef __CUDACC__
231 #define __global__
232 #define __device__
233 #define __host__
234 #define __shared__
235 #endif
236 #endif
237
238 #ifndef ASSEMBLER
239
240 #ifdef QUAD_PRECISION
241 typedef struct {
242   unsigned long x[2];
243 }  xdouble;
244 #elif defined EXPRECISION
245 #define xdouble long double
246 #else
247 #define xdouble double
248 #endif
249
250 #if defined(OS_WINDOWS) && defined(__64BIT__)
251 typedef long long BLASLONG;
252 typedef unsigned long long BLASULONG;
253 #else
254 typedef long BLASLONG;
255 typedef unsigned long BLASULONG;
256 #endif
257
258 #ifdef USE64BITINT
259 typedef BLASLONG blasint;
260 #else
261 typedef int blasint;
262 #endif
263 #else
264 #ifdef USE64BITINT
265 #define INTSHIFT        3
266 #define INTSIZE         8
267 #else
268 #define INTSHIFT        2
269 #define INTSIZE         4
270 #endif
271 #endif
272
273 #ifdef XDOUBLE
274 #define FLOAT   xdouble
275 #ifdef QUAD_PRECISION
276 #define XFLOAT  xidouble
277 #endif
278 #ifdef QUAD_PRECISION
279 #define SIZE    32
280 #define  BASE_SHIFT 5
281 #define ZBASE_SHIFT 6
282 #else
283 #define SIZE    16
284 #define  BASE_SHIFT 4
285 #define ZBASE_SHIFT 5
286 #endif
287 #elif defined(DOUBLE)
288 #define FLOAT   double
289 #define SIZE    8
290 #define  BASE_SHIFT 3
291 #define ZBASE_SHIFT 4
292 #else
293 #define FLOAT   float
294 #define SIZE    4
295 #define  BASE_SHIFT 2
296 #define ZBASE_SHIFT 3
297 #endif
298
299 #ifndef XFLOAT
300 #define XFLOAT  FLOAT
301 #endif
302
303 #ifndef COMPLEX
304 #define COMPSIZE  1
305 #else
306 #define COMPSIZE  2
307 #endif
308
309
310 #define Address_H(x) (((x)+(1<<15))>>16)
311 #define Address_L(x) ((x)-((Address_H(x))<<16))
312
313 #ifndef MAX_CPU_NUMBER
314 #define MAX_CPU_NUMBER 2
315 #endif
316
317 #if defined(OS_SUNOS)
318 #define YIELDING        thr_yield()
319 #endif
320
321 #if defined(OS_WINDOWS)
322 #if defined(_MSC_VER) && !defined(__clang__)
323 #define YIELDING    YieldProcessor()
324 #else
325 #define YIELDING        SwitchToThread()
326 #endif
327 #endif
328
329 #if defined(ARMV7) || defined(ARMV6) || defined(ARMV8) || defined(ARMV5)
330 #define YIELDING        asm volatile ("nop;nop;nop;nop;nop;nop;nop;nop; \n");
331 #endif
332
333 #ifdef BULLDOZER
334 #ifndef YIELDING
335 #define YIELDING        __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop;nop;nop;\n");
336 #endif
337 #endif
338
339 #ifdef POWER8
340 #ifndef YIELDING
341 #define YIELDING        __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop;nop;nop;\n");
342 #endif
343 #endif
344
345
346 /*
347 #ifdef PILEDRIVER
348 #ifndef YIELDING
349 #define YIELDING        __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop;nop;nop;\n");
350 #endif
351 #endif
352 */
353
354 /*
355 #ifdef STEAMROLLER
356 #ifndef YIELDING
357 #define YIELDING        __asm__ __volatile__ ("nop;nop;nop;nop;nop;nop;nop;nop;\n");
358 #endif
359 #endif
360 */
361
362 #ifndef YIELDING
363 #define YIELDING        sched_yield()
364 #endif
365
366 /***
367 To alloc job_t on heap or statck.
368 please https://github.com/xianyi/OpenBLAS/issues/246
369 ***/
370 #if defined(OS_WINDOWS)
371 #define GETRF_MEM_ALLOC_THRESHOLD 32
372 #define BLAS3_MEM_ALLOC_THRESHOLD 32
373 #endif
374
375 #ifndef GETRF_MEM_ALLOC_THRESHOLD
376 #define GETRF_MEM_ALLOC_THRESHOLD 80
377 #endif
378
379 #ifndef BLAS3_MEM_ALLOC_THRESHOLD
380 #define BLAS3_MEM_ALLOC_THRESHOLD 160
381 #endif
382
383 #ifdef QUAD_PRECISION
384 #include "common_quad.h"
385 #endif
386
387 #ifdef ARCH_ALPHA
388 #include "common_alpha.h"
389 #endif
390
391 #ifdef ARCH_X86
392 #include "common_x86.h"
393 #endif
394
395 #ifdef ARCH_X86_64
396 #include "common_x86_64.h"
397 #endif
398
399 #ifdef ARCH_IA64
400 #include "common_ia64.h"
401 #endif
402
403 #ifdef ARCH_POWER
404 #include "common_power.h"
405 #endif
406
407 #ifdef sparc
408 #include "common_sparc.h"
409 #endif
410
411 #ifdef ARCH_MIPS
412 #include "common_mips.h"
413 #endif
414
415 #ifdef ARCH_MIPS64
416 #include "common_mips64.h"
417 #endif
418
419 #ifdef ARCH_ARM
420 #include "common_arm.h"
421 #endif
422
423 #ifdef ARCH_ARM64
424 #include "common_arm64.h"
425 #endif
426
427 #ifdef ARCH_ZARCH
428 #include "common_zarch.h"
429 #endif
430
431 #ifndef ASSEMBLER
432 #ifdef OS_WINDOWSSTORE
433 typedef char env_var_t[MAX_PATH];
434 #define readenv(p, n) 0
435 #else
436 #ifdef OS_WINDOWS
437 typedef char env_var_t[MAX_PATH];
438 #define readenv(p, n) GetEnvironmentVariable((LPCTSTR)(n), (LPTSTR)(p), sizeof(p))
439 #else
440 typedef char* env_var_t;
441 #define readenv(p, n) ((p)=getenv(n))
442 #endif
443 #endif
444
445 #if !defined(RPCC_DEFINED) && !defined(OS_WINDOWS)
446 #ifdef _POSIX_MONOTONIC_CLOCK
447 #if defined(__GLIBC_PREREQ) // cut the if condition if two lines, otherwise will fail at __GLIBC_PREREQ(2, 17)
448 #if __GLIBC_PREREQ(2, 17) // don't require -lrt
449 #define USE_MONOTONIC
450 #endif
451 #elif defined(OS_ANDROID)
452 #define USE_MONOTONIC
453 #endif
454 #endif
455 /* use similar scale as x86 rdtsc for timeouts to work correctly */
456 static inline unsigned long long rpcc(void){
457 #ifdef USE_MONOTONIC
458   struct timespec ts;
459   clock_gettime(CLOCK_MONOTONIC, &ts);
460   return (unsigned long long)ts.tv_sec * 1000000000ull + ts.tv_nsec;
461 #else
462   struct timeval tv;
463   gettimeofday(&tv,NULL);
464   return (unsigned long long)tv.tv_sec * 1000000000ull + tv.tv_usec * 1000;
465 #endif
466 }
467 #define RPCC_DEFINED
468 #define RPCC64BIT
469 #endif // !RPCC_DEFINED
470
471 #if !defined(BLAS_LOCK_DEFINED) && defined(__GNUC__)
472 static void __inline blas_lock(volatile BLASULONG *address){
473
474   do {
475     while (*address) {YIELDING;};
476
477   } while (!__sync_bool_compare_and_swap(address, 0, 1));
478 }
479 #define BLAS_LOCK_DEFINED
480 #endif
481
482 #ifndef RPCC_DEFINED
483 #error "rpcc() implementation is missing for your platform"
484 #endif
485 #ifndef BLAS_LOCK_DEFINED
486 #error "blas_lock() implementation is missing for your platform"
487 #endif
488 #endif // !ASSEMBLER
489
490 #ifdef OS_LINUX
491 #include "common_linux.h"
492 #endif
493
494 #define MMAP_ACCESS (PROT_READ | PROT_WRITE)
495
496 #ifdef __NetBSD__
497 #define MMAP_POLICY (MAP_PRIVATE | MAP_ANON)
498 #else
499 #define MMAP_POLICY (MAP_PRIVATE | MAP_ANONYMOUS)
500 #endif
501
502 #ifndef ASSEMBLER
503 /* C99 supports complex floating numbers natively, which GCC also offers as an
504    extension since version 3.0.  If neither are available, use a compatible
505    structure as fallback (see Clause 6.2.5.13 of the C99 standard). */
506 #if ((defined(__STDC_IEC_559_COMPLEX__) || __STDC_VERSION__ >= 199901L || \
507       (__GNUC__ >= 3 && !defined(__cplusplus))) && !(defined(FORCE_OPENBLAS_COMPLEX_STRUCT))) && !defined(_MSC_VER)
508   #define OPENBLAS_COMPLEX_C99
509   #ifndef __cplusplus
510     #include <complex.h>
511   #endif
512   typedef float _Complex openblas_complex_float;
513   typedef double _Complex openblas_complex_double;
514   typedef xdouble _Complex openblas_complex_xdouble;
515   #define openblas_make_complex_float(real, imag)    ((real) + ((imag) * _Complex_I))
516   #define openblas_make_complex_double(real, imag)   ((real) + ((imag) * _Complex_I))
517   #define openblas_make_complex_xdouble(real, imag)  ((real) + ((imag) * _Complex_I))
518 #else
519   #define OPENBLAS_COMPLEX_STRUCT
520   typedef struct { float real, imag; } openblas_complex_float;
521   typedef struct { double real, imag; } openblas_complex_double;
522   typedef struct { xdouble real, imag; } openblas_complex_xdouble;
523   #define openblas_make_complex_float(real, imag)    {(real), (imag)}
524   #define openblas_make_complex_double(real, imag)   {(real), (imag)}
525   #define openblas_make_complex_xdouble(real, imag)  {(real), (imag)}
526 #endif
527 #endif
528
529 #include "param.h"
530 #include "common_param.h"
531
532 #ifndef STDERR
533 #define STDERR stderr
534 #endif
535
536 #ifndef MASK
537 #define MASK(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
538 #endif
539
540 #if defined(XDOUBLE) || defined(DOUBLE)
541 #define FLOATRET        FLOAT
542 #else
543 #ifdef NEED_F2CCONV
544 #define FLOATRET        double
545 #else
546 #define FLOATRET        float
547 #endif
548 #endif
549
550 #ifndef ASSEMBLER
551 #ifndef NOINCLUDE
552 /* Inclusion of a standard header file is needed for definition of __STDC_*
553    predefined macros with some compilers (e.g. GCC 4.7 on Linux).  This occurs
554    as a side effect of including either <features.h> or <stdc-predef.h>. */
555 #include <stdio.h>
556 #endif  // NOINCLUDE
557
558 #ifdef XDOUBLE
559 #define OPENBLAS_COMPLEX_FLOAT openblas_complex_xdouble
560 #define OPENBLAS_MAKE_COMPLEX_FLOAT(r,i) openblas_make_complex_xdouble(r,i)
561 #elif defined(DOUBLE)
562 #define OPENBLAS_COMPLEX_FLOAT openblas_complex_double
563 #define OPENBLAS_MAKE_COMPLEX_FLOAT(r,i) openblas_make_complex_double(r,i)
564 #else
565 #define OPENBLAS_COMPLEX_FLOAT openblas_complex_float
566 #define OPENBLAS_MAKE_COMPLEX_FLOAT(r,i) openblas_make_complex_float(r,i)
567 #endif
568
569 #if defined(C_PGI) || defined(C_SUN)
570   #if defined(__STDC_IEC_559_COMPLEX__)
571      #define CREAL(X)   creal(X)
572      #define CIMAG(X)   cimag(X)
573   #else
574      #define CREAL(X)   (*((FLOAT *)&X + 0))
575      #define CIMAG(X)   (*((FLOAT *)&X + 1))
576   #endif
577 #else
578 #ifdef OPENBLAS_COMPLEX_STRUCT
579 #define CREAL(Z)        ((Z).real)
580 #define CIMAG(Z)        ((Z).imag)
581 #else
582 #define CREAL   __real__
583 #define CIMAG   __imag__
584 #endif
585 #endif
586
587 #endif  // ASSEMBLER
588
589 #ifndef IFLUSH
590 #define IFLUSH
591 #endif
592
593 #ifndef IFLUSH_HALF
594 #define IFLUSH_HALF
595 #endif
596
597 #if defined(C_GCC) && (( __GNUC__ <= 3) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 2)))
598 #ifdef USE_OPENMP
599 #undef USE_OPENMP
600 #endif
601 #endif
602
603 #if defined(C_MSVC)
604 #define inline __inline
605 #endif
606
607 #ifndef ASSEMBLER
608
609 #ifndef MIN
610 #define MIN(a,b)   (a>b? b:a)
611 #endif
612
613 #ifndef MAX
614 #define MAX(a,b)   (a<b? b:a)
615 #endif
616
617 #define TOUPPER(a) {if ((a) > 0x60) (a) -= 0x20;}
618
619 #if defined(__FreeBSD__) || defined(__APPLE__)
620 #define MAP_ANONYMOUS MAP_ANON
621 #endif
622
623 /* Common Memory Management Routine */
624 void  blas_set_parameter(void);
625 int   blas_get_cpu_number(void);
626 void *blas_memory_alloc  (int);
627 void  blas_memory_free   (void *);
628 void *blas_memory_alloc_nolock  (int); //use malloc without blas_lock
629 void  blas_memory_free_nolock   (void *);
630
631 int  get_num_procs (void);
632
633 #if defined(OS_LINUX) && defined(SMP) && !defined(NO_AFFINITY)
634 int  get_num_nodes (void);
635 int get_num_proc   (int);
636 int get_node_equal (void);
637 #endif
638
639 void goto_set_num_threads(int);
640
641 void gotoblas_affinity_init(void);
642 void gotoblas_affinity_quit(void);
643 void gotoblas_dynamic_init(void);
644 void gotoblas_dynamic_quit(void);
645 void gotoblas_profile_init(void);
646 void gotoblas_profile_quit(void);
647
648 #ifdef USE_OPENMP
649
650 #ifndef C_MSVC
651 int omp_in_parallel(void);
652 int omp_get_num_procs(void);
653 #else
654 __declspec(dllimport) int __cdecl omp_in_parallel(void);
655 __declspec(dllimport) int __cdecl omp_get_num_procs(void);
656 #endif
657
658 #if (__STDC_VERSION__ >= 201112L)
659 #if defined(C_GCC) && ( __GNUC__ < 7) 
660 // workaround for GCC bug 65467
661 #ifndef _Atomic
662 #define _Atomic volatile
663 #endif
664 #endif
665 #include <stdatomic.h>
666 #else
667 #ifndef _Atomic
668 #define _Atomic volatile
669 #endif
670 #endif
671
672 #else
673 #ifdef __ELF__
674 int omp_in_parallel  (void) __attribute__ ((weak));
675 int omp_get_num_procs(void) __attribute__ ((weak));
676 #endif
677 #endif
678
679 static __inline void blas_unlock(volatile BLASULONG *address){
680   MB;
681   *address = 0;
682 }
683
684 #ifdef OS_WINDOWSSTORE
685 static __inline int readenv_atoi(char *env) {
686         return 0;
687 }
688 #else
689 #ifdef OS_WINDOWS
690 static __inline int readenv_atoi(char *env) {
691   env_var_t p;
692   return readenv(p,env) ? 0 : atoi(p);
693 }
694 #else
695 static __inline int readenv_atoi(char *env) {
696   char *p;
697   if (( p = getenv(env) ))
698         return (atoi(p));
699   else
700         return(0);
701 }
702 #endif
703 #endif
704
705 #if !defined(XDOUBLE) || !defined(QUAD_PRECISION)
706
707 static __inline void compinv(FLOAT *b, FLOAT ar, FLOAT ai){
708
709 #ifndef UNIT
710   FLOAT ratio, den;
711
712   if (
713 #ifdef XDOUBLE
714       (fabsl(ar)) >= (fabsl(ai))
715 #elif defined DOUBLE
716       (fabs (ar)) >= (fabs (ai))
717 #else
718       (fabsf(ar)) >= (fabsf(ai))
719 #endif
720       ) {
721     ratio = ai / ar;
722     den   = (FLOAT)(ONE / (ar * (ONE + ratio * ratio)));
723     ar =  den;
724     ai = -ratio * den;
725   } else {
726     ratio = ar / ai;
727     den   = (FLOAT)(ONE /(ai * (ONE + ratio * ratio)));
728     ar =  ratio * den;
729     ai = -den;
730   }
731   b[0] = ar;
732   b[1] = ai;
733 #else
734   b[0] = ONE;
735   b[1] = ZERO;
736 #endif
737
738 }
739 #endif
740
741 #ifdef MALLOC_DEBUG
742 void *blas_debug_alloc(int);
743 void *blas_debug_free(void *);
744 #undef malloc
745 #undef free
746 #define malloc(a) blas_debug_alloc(a)
747 #define free(a)   blas_debug_free (a)
748 #endif
749
750 #ifndef COPYOVERHEAD
751 #define GEMMRETTYPE  int
752 #else
753
754 typedef struct {
755   double outercopy;
756   double innercopy;
757   double kernel;
758   double mflops;
759 } copyoverhead_t;
760
761 #define GEMMRETTYPE  copyoverhead_t
762 #endif
763 #endif
764
765 #ifndef BUILD_KERNEL
766 #define KNAME(A, B) A
767 #else
768 #define KNAME(A, B) A##B
769 #endif
770
771 #include "common_interface.h"
772 #ifdef SANITY_CHECK
773 #include "common_reference.h"
774 #endif
775 #include "common_macro.h"
776 #include "common_level1.h"
777 #include "common_level2.h"
778 #include "common_level3.h"
779 #include "common_lapack.h"
780
781 #ifdef CBLAS
782 # define OPENBLAS_CONST     /* see comment in cblas.h */
783 # include "cblas.h"
784 #endif
785
786 #ifndef ASSEMBLER
787 #include "common_stackalloc.h"
788 #if 0
789 #include "symcopy.h"
790 #endif
791
792 #if defined(SMP_SERVER) && defined(SMP_ONDEMAND)
793 #error Both SMP_SERVER and SMP_ONDEMAND are specified.
794 #endif
795
796 #if defined(SMP_SERVER) || defined(SMP_ONDEMAND)
797 #include "common_thread.h"
798 #endif
799
800 #endif
801
802 #define INFO_NUM 99
803
804 #ifndef DEFAULT_CPU_NUMBER
805 #define DEFAULT_CPU_NUMBER 4
806 #endif
807
808 #ifndef IDEBUG_START
809 #define IDEBUG_START
810 #endif
811
812 #ifndef IDEBUG_END
813 #define IDEBUG_END
814 #endif
815
816 #if !defined(ASSEMBLER) && defined(FUNCTION_PROFILE)
817
818 typedef struct {
819   int func;
820   unsigned long long calls, fops, area, cycles, tcycles;
821 } func_profile_t;
822
823 extern func_profile_t function_profile_table[];
824 extern int gotoblas_profile;
825
826 #ifdef XDOUBLE
827 #define NUMOPT  QNUMOPT
828 #elif defined DOUBLE
829 #define NUMOPT  DNUMOPT
830 #else
831 #define NUMOPT  SNUMOPT
832 #endif
833
834 #define FUNCTION_PROFILE_START() { unsigned long long profile_start = rpcc(), profile_end;
835 #ifdef SMP
836 #define FUNCTION_PROFILE_END(COMP, AREA, OPS) \
837         if (gotoblas_profile) { \
838         profile_end = rpcc(); \
839         function_profile_table[PROFILE_FUNC_NAME].calls ++; \
840         function_profile_table[PROFILE_FUNC_NAME].area    += SIZE * COMPSIZE * (AREA); \
841         function_profile_table[PROFILE_FUNC_NAME].fops    += (COMP) * (OPS) / NUMOPT; \
842         function_profile_table[PROFILE_FUNC_NAME].cycles  += (profile_end - profile_start); \
843         function_profile_table[PROFILE_FUNC_NAME].tcycles += blas_cpu_number * (profile_end - profile_start); \
844         } \
845         }
846 #else
847 #define FUNCTION_PROFILE_END(COMP, AREA, OPS) \
848         if (gotoblas_profile) { \
849         profile_end = rpcc(); \
850         function_profile_table[PROFILE_FUNC_NAME].calls ++; \
851         function_profile_table[PROFILE_FUNC_NAME].area    += SIZE * COMPSIZE * (AREA); \
852         function_profile_table[PROFILE_FUNC_NAME].fops    += (COMP) * (OPS) / NUMOPT; \
853         function_profile_table[PROFILE_FUNC_NAME].cycles  += (profile_end - profile_start); \
854         function_profile_table[PROFILE_FUNC_NAME].tcycles += (profile_end - profile_start); \
855         } \
856         }
857 #endif
858
859 #else
860 #define FUNCTION_PROFILE_START()
861 #define FUNCTION_PROFILE_END(COMP, AREA, OPS)
862 #endif
863
864 #if 1
865 #define PRINT_DEBUG_CNAME
866 #define PRINT_DEBUG_NAME
867 #else
868 #define PRINT_DEBUG_CNAME if (readenv_atoi("GOTO_DEBUG")) fprintf(stderr, "GotoBLAS : %s\n", CHAR_CNAME)
869 #define PRINT_DEBUG_NAME  if (readenv_atoi("GOTO_DEBUG")) fprintf(stderr, "GotoBLAS : %s\n", CHAR_NAME)
870 #endif
871
872 #ifdef __cplusplus
873 }
874
875 #endif  /* __cplusplus */
876
877 #endif