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