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