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