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