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