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