2011-01-24 22:54:24 +08:00
/*********************************************************************/
/* Copyright 2009, 2010 The University of Texas at Austin. */
/* All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or */
/* without modification, are permitted provided that the following */
/* conditions are met: */
/* */
/* 1. Redistributions of source code must retain the above */
/* copyright notice, this list of conditions and the following */
/* disclaimer. */
/* */
/* 2. Redistributions in binary form must reproduce the above */
/* copyright notice, this list of conditions and the following */
/* disclaimer in the documentation and/or other materials */
/* provided with the distribution. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF TEXAS AT */
/* AUSTIN ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, */
/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */
/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
/* DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT */
/* AUSTIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */
/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE */
/* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */
/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT */
/* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */
/* POSSIBILITY OF SUCH DAMAGE. */
/* */
/* The views and conclusions contained in the software and */
/* documentation are those of the authors and should not be */
/* interpreted as representing official policies, either expressed */
/* or implied, of The University of Texas at Austin. */
/*********************************************************************/
# include "common.h"
2014-01-24 02:05:59 +08:00
2011-01-24 22:54:24 +08:00
# ifdef ARCH_X86
# define EXTERN extern
# else
# define EXTERN
# endif
EXTERN gotoblas_t gotoblas_KATMAI ;
EXTERN gotoblas_t gotoblas_COPPERMINE ;
EXTERN gotoblas_t gotoblas_NORTHWOOD ;
EXTERN gotoblas_t gotoblas_BANIAS ;
EXTERN gotoblas_t gotoblas_ATHLON ;
extern gotoblas_t gotoblas_PRESCOTT ;
extern gotoblas_t gotoblas_ATOM ;
extern gotoblas_t gotoblas_NANO ;
extern gotoblas_t gotoblas_CORE2 ;
extern gotoblas_t gotoblas_PENRYN ;
extern gotoblas_t gotoblas_DUNNINGTON ;
extern gotoblas_t gotoblas_NEHALEM ;
extern gotoblas_t gotoblas_OPTERON ;
extern gotoblas_t gotoblas_OPTERON_SSE3 ;
extern gotoblas_t gotoblas_BARCELONA ;
2012-08-13 15:25:08 +08:00
extern gotoblas_t gotoblas_BOBCAT ;
2012-09-17 23:24:04 +08:00
# ifndef NO_AVX
extern gotoblas_t gotoblas_SANDYBRIDGE ;
2013-08-05 16:07:54 +08:00
extern gotoblas_t gotoblas_BULLDOZER ;
extern gotoblas_t gotoblas_PILEDRIVER ;
2014-12-28 20:16:46 +08:00
extern gotoblas_t gotoblas_STEAMROLLER ;
2015-05-14 05:16:30 +08:00
extern gotoblas_t gotoblas_EXCAVATOR ;
2014-07-16 08:37:55 +08:00
# ifdef NO_AVX2
# define gotoblas_HASWELL gotoblas_SANDYBRIDGE
# else
2013-08-13 00:54:59 +08:00
extern gotoblas_t gotoblas_HASWELL ;
2014-07-16 08:37:55 +08:00
# endif
2012-09-17 23:24:04 +08:00
# else
//Use NEHALEM kernels for sandy bridge
# define gotoblas_SANDYBRIDGE gotoblas_NEHALEM
2013-08-13 00:54:59 +08:00
# define gotoblas_HASWELL gotoblas_NEHALEM
2012-12-06 20:29:54 +08:00
# define gotoblas_BULLDOZER gotoblas_BARCELONA
2013-07-06 23:06:43 +08:00
# define gotoblas_PILEDRIVER gotoblas_BARCELONA
2014-12-28 20:16:46 +08:00
# define gotoblas_STEAMROLLER gotoblas_BARCELONA
2015-05-14 05:16:30 +08:00
# define gotoblas_EXCAVATOR gotoblas_BARCELONA
2013-08-05 16:07:54 +08:00
# endif
2013-08-13 00:54:59 +08:00
2011-01-24 22:54:24 +08:00
# define VENDOR_INTEL 1
# define VENDOR_AMD 2
# define VENDOR_CENTAUR 3
# define VENDOR_UNKNOWN 99
# define BITMASK(a, b, c) ((((a) >> (b)) & (c)))
2012-10-09 14:52:35 +08:00
# ifndef NO_AVX
2012-09-18 15:46:20 +08:00
static inline void xgetbv ( int op , int * eax , int * edx ) {
2013-01-22 00:18:21 +08:00
//Use binary code for xgetbv
2012-09-18 15:46:20 +08:00
__asm__ __volatile__
2013-01-22 00:18:21 +08:00
( " .byte 0x0f, 0x01, 0xd0 " : " =a " ( * eax ) , " =d " ( * edx ) : " c " ( op ) : " cc " ) ;
2012-09-18 15:46:20 +08:00
}
2012-10-09 14:52:35 +08:00
# endif
2012-09-18 15:46:20 +08:00
int support_avx ( ) {
2012-10-09 14:52:35 +08:00
# ifndef NO_AVX
2012-09-18 15:46:20 +08:00
int eax , ebx , ecx , edx ;
int ret = 0 ;
2014-06-28 03:05:18 +08:00
2012-09-18 15:46:20 +08:00
cpuid ( 1 , & eax , & ebx , & ecx , & edx ) ;
2013-06-06 22:50:43 +08:00
if ( ( ecx & ( 1 < < 28 ) ) ! = 0 & & ( ecx & ( 1 < < 27 ) ) ! = 0 & & ( ecx & ( 1 < < 26 ) ) ! = 0 ) {
2012-09-18 15:46:20 +08:00
xgetbv ( 0 , & eax , & edx ) ;
if ( ( eax & 6 ) = = 6 ) {
ret = 1 ; //OS support AVX
}
}
return ret ;
2012-10-09 14:52:35 +08:00
# else
return 0 ;
# endif
2012-09-18 15:46:20 +08:00
}
2014-01-24 02:05:59 +08:00
extern void openblas_warning ( int verbose , const char * msg ) ;
# define FALLBACK_VERBOSE 1
# define NEHALEM_FALLBACK "OpenBLAS : Your OS does not support AVX instructions. OpenBLAS is using Nehalem kernels as a fallback, which may give poorer performance.\n"
# define BARCELONA_FALLBACK "OpenBLAS : Your OS does not support AVX instructions. OpenBLAS is using Barcelona kernels as a fallback, which may give poorer performance.\n"
2011-01-24 22:54:24 +08:00
static int get_vendor ( void ) {
int eax , ebx , ecx , edx ;
2014-06-13 00:17:08 +08:00
union
{
char vchar [ 16 ] ;
int vint [ 4 ] ;
} vendor ;
2011-01-24 22:54:24 +08:00
cpuid ( 0 , & eax , & ebx , & ecx , & edx ) ;
2014-06-13 00:17:08 +08:00
* ( & vendor . vint [ 0 ] ) = ebx ;
* ( & vendor . vint [ 1 ] ) = edx ;
* ( & vendor . vint [ 2 ] ) = ecx ;
vendor . vchar [ 12 ] = ' \0 ' ;
if ( ! strcmp ( vendor . vchar , " GenuineIntel " ) ) return VENDOR_INTEL ;
if ( ! strcmp ( vendor . vchar , " AuthenticAMD " ) ) return VENDOR_AMD ;
if ( ! strcmp ( vendor . vchar , " CentaurHauls " ) ) return VENDOR_CENTAUR ;
2011-01-24 22:54:24 +08:00
if ( ( eax = = 0 ) | | ( ( eax & 0x500 ) ! = 0 ) ) return VENDOR_INTEL ;
return VENDOR_UNKNOWN ;
}
static gotoblas_t * get_coretype ( void ) {
int eax , ebx , ecx , edx ;
int family , exfamily , model , vendor , exmodel ;
cpuid ( 1 , & eax , & ebx , & ecx , & edx ) ;
family = BITMASK ( eax , 8 , 0x0f ) ;
exfamily = BITMASK ( eax , 20 , 0xff ) ;
model = BITMASK ( eax , 4 , 0x0f ) ;
exmodel = BITMASK ( eax , 16 , 0x0f ) ;
vendor = get_vendor ( ) ;
if ( vendor = = VENDOR_INTEL ) {
switch ( family ) {
case 0x6 :
switch ( exmodel ) {
case 0 :
if ( model < = 0x7 ) return & gotoblas_KATMAI ;
if ( ( model = = 0x8 ) | | ( model = = 0xa ) | | ( model = = 0xb ) ) return & gotoblas_COPPERMINE ;
if ( ( model = = 0x9 ) | | ( model = = 0xd ) ) return & gotoblas_BANIAS ;
if ( model = = 14 ) return & gotoblas_BANIAS ;
if ( model = = 15 ) return & gotoblas_CORE2 ;
return NULL ;
case 1 :
if ( model = = 6 ) return & gotoblas_CORE2 ;
if ( model = = 7 ) return & gotoblas_PENRYN ;
if ( model = = 13 ) return & gotoblas_DUNNINGTON ;
if ( ( model = = 10 ) | | ( model = = 11 ) | | ( model = = 14 ) | | ( model = = 15 ) ) return & gotoblas_NEHALEM ;
if ( model = = 12 ) return & gotoblas_ATOM ;
return NULL ;
2011-02-18 22:08:10 +08:00
2012-08-13 15:25:08 +08:00
case 2 :
//Intel Core (Clarkdale) / Core (Arrandale)
// Pentium (Clarkdale) / Pentium Mobile (Arrandale)
// Xeon (Clarkdale), 32nm
if ( model = = 5 ) return & gotoblas_NEHALEM ;
2014-06-28 03:05:18 +08:00
2012-08-13 15:25:08 +08:00
//Intel Xeon Processor 5600 (Westmere-EP)
//Xeon Processor E7 (Westmere-EX)
2012-12-18 08:57:46 +08:00
//Xeon E7540
if ( model = = 12 | | model = = 14 | | model = = 15 ) return & gotoblas_NEHALEM ;
2012-08-13 15:25:08 +08:00
//Intel Core i5-2000 /i7-2000 (Sandy Bridge)
//Intel Core i7-3000 / Xeon E5
2012-09-18 15:46:20 +08:00
if ( model = = 10 | | model = = 13 ) {
if ( support_avx ( ) )
return & gotoblas_SANDYBRIDGE ;
else {
2014-01-24 02:05:59 +08:00
openblas_warning ( FALLBACK_VERBOSE , NEHALEM_FALLBACK ) ;
2012-09-18 15:46:20 +08:00
return & gotoblas_NEHALEM ; //OS doesn't support AVX. Use old kernels.
}
}
2012-08-13 15:25:08 +08:00
return NULL ;
case 3 :
//Intel Sandy Bridge 22nm (Ivy Bridge?)
2014-01-05 23:44:29 +08:00
if ( model = = 10 | | model = = 14 ) {
2012-09-18 15:46:20 +08:00
if ( support_avx ( ) )
return & gotoblas_SANDYBRIDGE ;
else {
2014-01-24 02:05:59 +08:00
openblas_warning ( FALLBACK_VERBOSE , NEHALEM_FALLBACK ) ;
2012-09-18 15:46:20 +08:00
return & gotoblas_NEHALEM ; //OS doesn't support AVX. Use old kernels.
}
}
2013-06-30 06:26:56 +08:00
//Intel Haswell
2014-01-05 23:44:29 +08:00
if ( model = = 12 | | model = = 15 ) {
2013-06-30 06:26:56 +08:00
if ( support_avx ( ) )
return & gotoblas_HASWELL ;
else {
2014-01-24 02:05:59 +08:00
openblas_warning ( FALLBACK_VERBOSE , NEHALEM_FALLBACK ) ;
2013-06-30 06:26:56 +08:00
return & gotoblas_NEHALEM ; //OS doesn't support AVX. Use old kernels.
}
}
2015-04-03 00:08:03 +08:00
//Intel Broadwell
if ( model = = 13 ) {
if ( support_avx ( ) )
return & gotoblas_HASWELL ;
else {
openblas_warning ( FALLBACK_VERBOSE , NEHALEM_FALLBACK ) ;
return & gotoblas_NEHALEM ; //OS doesn't support AVX. Use old kernels.
}
}
2013-06-30 06:26:56 +08:00
return NULL ;
case 4 :
//Intel Haswell
2014-01-05 23:44:29 +08:00
if ( model = = 5 | | model = = 6 ) {
2013-06-30 06:26:56 +08:00
if ( support_avx ( ) )
return & gotoblas_HASWELL ;
else {
2014-01-24 02:05:59 +08:00
openblas_warning ( FALLBACK_VERBOSE , NEHALEM_FALLBACK ) ;
2015-04-03 00:08:03 +08:00
return & gotoblas_NEHALEM ; //OS doesn't support AVX. Use old kernels.
}
}
//Intel Broadwell
if ( model = = 7 | | model = = 15 ) {
if ( support_avx ( ) )
return & gotoblas_HASWELL ;
else {
openblas_warning ( FALLBACK_VERBOSE , NEHALEM_FALLBACK ) ;
return & gotoblas_NEHALEM ; //OS doesn't support AVX. Use old kernels.
}
}
2015-09-09 23:47:17 +08:00
//Intel Skylake
if ( model = = 14 ) {
if ( support_avx ( ) )
return & gotoblas_HASWELL ;
else {
openblas_warning ( FALLBACK_VERBOSE , NEHALEM_FALLBACK ) ;
return & gotoblas_NEHALEM ; //OS doesn't support AVX. Use old kernels.
}
}
2016-02-02 16:00:18 +08:00
//Intel Avoton
if ( model = = 13 ) {
openblas_warning ( FALLBACK_VERBOSE , NEHALEM_FALLBACK ) ;
return & gotoblas_NEHALEM ;
}
2015-04-03 00:08:03 +08:00
return NULL ;
case 5 :
//Intel Broadwell
if ( model = = 6 ) {
if ( support_avx ( ) )
return & gotoblas_HASWELL ;
else {
openblas_warning ( FALLBACK_VERBOSE , NEHALEM_FALLBACK ) ;
2013-06-30 06:26:56 +08:00
return & gotoblas_NEHALEM ; //OS doesn't support AVX. Use old kernels.
}
}
2015-09-09 23:00:23 +08:00
//Intel Skylake
2015-09-09 23:47:17 +08:00
if ( model = = 14 | | model = = 5 ) {
2015-09-09 23:00:23 +08:00
if ( support_avx ( ) )
return & gotoblas_HASWELL ;
else {
openblas_warning ( FALLBACK_VERBOSE , NEHALEM_FALLBACK ) ;
return & gotoblas_NEHALEM ; //OS doesn't support AVX. Use old kernels.
}
}
2012-08-13 15:25:08 +08:00
return NULL ;
2011-01-24 22:54:24 +08:00
}
case 0xf :
if ( model < = 0x2 ) return & gotoblas_NORTHWOOD ;
return & gotoblas_PRESCOTT ;
}
}
if ( vendor = = VENDOR_AMD ) {
2013-08-28 20:27:59 +08:00
if ( family < = 0xe ) {
// Verify that CPU has 3dnow and 3dnowext before claiming it is Athlon
cpuid ( 0x80000000 , & eax , & ebx , & ecx , & edx ) ;
2014-06-13 00:17:08 +08:00
if ( ( eax & 0xffff ) > = 0x01 ) {
2013-08-28 20:27:59 +08:00
cpuid ( 0x80000001 , & eax , & ebx , & ecx , & edx ) ;
if ( ( edx & ( 1 < < 30 ) ) = = 0 | | ( edx & ( 1 < < 31 ) ) = = 0 )
return NULL ;
}
else
return NULL ;
return & gotoblas_ATHLON ;
}
2011-01-24 22:54:24 +08:00
if ( family = = 0xf ) {
if ( ( exfamily = = 0 ) | | ( exfamily = = 2 ) ) {
2014-06-28 03:05:18 +08:00
if ( ecx & ( 1 < < 0 ) ) return & gotoblas_OPTERON_SSE3 ;
2011-01-24 22:54:24 +08:00
else return & gotoblas_OPTERON ;
2012-08-13 15:25:08 +08:00
} else if ( exfamily = = 5 ) {
return & gotoblas_BOBCAT ;
2012-12-06 20:29:54 +08:00
} else if ( exfamily = = 6 ) {
2013-07-06 23:06:43 +08:00
if ( model = = 1 ) {
//AMD Bulldozer Opteron 6200 / Opteron 4200 / AMD FX-Series
2012-12-06 20:29:54 +08:00
if ( support_avx ( ) )
return & gotoblas_BULLDOZER ;
else {
2014-01-24 02:05:59 +08:00
openblas_warning ( FALLBACK_VERBOSE , BARCELONA_FALLBACK ) ;
2012-12-06 20:29:54 +08:00
return & gotoblas_BARCELONA ; //OS doesn't support AVX. Use old kernels.
2013-07-06 23:06:43 +08:00
}
2015-10-29 02:53:29 +08:00
} else if ( model = = 2 | | model = = 3 ) {
2013-07-06 23:06:43 +08:00
//AMD Bulldozer Opteron 6300 / Opteron 4300 / Opteron 3300
if ( support_avx ( ) )
return & gotoblas_PILEDRIVER ;
else {
2014-01-24 02:05:59 +08:00
openblas_warning ( FALLBACK_VERBOSE , BARCELONA_FALLBACK ) ;
2013-07-06 23:06:43 +08:00
return & gotoblas_BARCELONA ; //OS doesn't support AVX. Use old kernels.
}
2014-12-28 20:16:46 +08:00
} else if ( model = = 0 ) {
2015-10-29 02:53:29 +08:00
if ( exmodel = = 1 ) {
//AMD Trinity
if ( support_avx ( ) )
return & gotoblas_PILEDRIVER ;
else {
openblas_warning ( FALLBACK_VERBOSE , BARCELONA_FALLBACK ) ;
return & gotoblas_BARCELONA ; //OS doesn't support AVX. Use old kernels.
}
} else if ( exmodel = = 3 ) {
2015-05-14 05:16:30 +08:00
//AMD STEAMROLLER
if ( support_avx ( ) )
return & gotoblas_STEAMROLLER ;
else {
openblas_warning ( FALLBACK_VERBOSE , BARCELONA_FALLBACK ) ;
return & gotoblas_BARCELONA ; //OS doesn't support AVX. Use old kernels.
}
} else if ( exmodel = = 6 ) {
if ( support_avx ( ) )
return & gotoblas_EXCAVATOR ;
else {
openblas_warning ( FALLBACK_VERBOSE , BARCELONA_FALLBACK ) ;
return & gotoblas_BARCELONA ; //OS doesn't support AVX. Use old kernels.
}
2014-12-28 20:16:46 +08:00
}
2013-07-06 23:06:43 +08:00
}
2014-12-28 20:16:46 +08:00
2012-08-13 15:25:08 +08:00
} else {
2011-01-24 22:54:24 +08:00
return & gotoblas_BARCELONA ;
}
}
}
if ( vendor = = VENDOR_CENTAUR ) {
switch ( family ) {
case 0x6 :
return & gotoblas_NANO ;
break ;
}
}
2014-06-28 03:05:18 +08:00
2011-01-24 22:54:24 +08:00
return NULL ;
}
static char * corename [ ] = {
" Unknown " ,
" Katmai " ,
" Coppermine " ,
" Northwood " ,
" Prescott " ,
" Banias " ,
" Atom " ,
" Core2 " ,
" Penryn " ,
" Dunnington " ,
" Nehalem " ,
" Athlon " ,
" Opteron " ,
2016-03-01 20:13:08 +08:00
" Opteron_SSE3 " ,
2011-01-24 22:54:24 +08:00
" Barcelona " ,
" Nano " ,
2012-08-13 15:25:08 +08:00
" Sandybridge " ,
" Bobcat " ,
2012-12-06 20:29:54 +08:00
" Bulldozer " ,
2013-07-06 23:06:43 +08:00
" Piledriver " ,
2013-08-13 00:54:59 +08:00
" Haswell " ,
2014-12-28 20:16:46 +08:00
" Steamroller " ,
2015-05-14 05:16:30 +08:00
" Excavator " ,
2011-01-24 22:54:24 +08:00
} ;
char * gotoblas_corename ( void ) {
if ( gotoblas = = & gotoblas_KATMAI ) return corename [ 1 ] ;
if ( gotoblas = = & gotoblas_COPPERMINE ) return corename [ 2 ] ;
if ( gotoblas = = & gotoblas_NORTHWOOD ) return corename [ 3 ] ;
if ( gotoblas = = & gotoblas_PRESCOTT ) return corename [ 4 ] ;
if ( gotoblas = = & gotoblas_BANIAS ) return corename [ 5 ] ;
if ( gotoblas = = & gotoblas_ATOM ) return corename [ 6 ] ;
if ( gotoblas = = & gotoblas_CORE2 ) return corename [ 7 ] ;
if ( gotoblas = = & gotoblas_PENRYN ) return corename [ 8 ] ;
if ( gotoblas = = & gotoblas_DUNNINGTON ) return corename [ 9 ] ;
if ( gotoblas = = & gotoblas_NEHALEM ) return corename [ 10 ] ;
if ( gotoblas = = & gotoblas_ATHLON ) return corename [ 11 ] ;
2014-06-28 03:05:18 +08:00
if ( gotoblas = = & gotoblas_OPTERON_SSE3 ) return corename [ 12 ] ;
2011-01-24 22:54:24 +08:00
if ( gotoblas = = & gotoblas_OPTERON ) return corename [ 13 ] ;
if ( gotoblas = = & gotoblas_BARCELONA ) return corename [ 14 ] ;
if ( gotoblas = = & gotoblas_NANO ) return corename [ 15 ] ;
2012-08-13 15:25:08 +08:00
if ( gotoblas = = & gotoblas_SANDYBRIDGE ) return corename [ 16 ] ;
if ( gotoblas = = & gotoblas_BOBCAT ) return corename [ 17 ] ;
2012-12-06 20:29:54 +08:00
if ( gotoblas = = & gotoblas_BULLDOZER ) return corename [ 18 ] ;
2013-08-13 00:54:59 +08:00
if ( gotoblas = = & gotoblas_PILEDRIVER ) return corename [ 19 ] ;
if ( gotoblas = = & gotoblas_HASWELL ) return corename [ 20 ] ;
2014-12-28 20:16:46 +08:00
if ( gotoblas = = & gotoblas_STEAMROLLER ) return corename [ 21 ] ;
2015-05-14 05:16:30 +08:00
if ( gotoblas = = & gotoblas_EXCAVATOR ) return corename [ 22 ] ;
2012-08-13 15:25:08 +08:00
2011-01-24 22:54:24 +08:00
return corename [ 0 ] ;
}
2014-06-12 20:20:03 +08:00
static gotoblas_t * force_coretype ( char * coretype ) {
int i ;
int found = - 1 ;
char message [ 128 ] ;
2015-03-20 04:57:22 +08:00
//char mname[20];
2014-06-12 20:20:03 +08:00
2016-04-25 15:08:38 +08:00
for ( i = 1 ; i < = 22 ; i + + )
2014-06-12 20:20:03 +08:00
{
if ( ! strncasecmp ( coretype , corename [ i ] , 20 ) )
{
found = i ;
break ;
}
}
if ( found < 0 )
{
2015-03-20 04:57:22 +08:00
//strncpy(mname,coretype,20);
snprintf ( message , 128 , " Core not found: %s \n " , coretype ) ;
2014-06-28 03:05:18 +08:00
openblas_warning ( 1 , message ) ;
2014-06-12 20:20:03 +08:00
return ( NULL ) ;
}
switch ( found )
{
2015-05-14 05:16:30 +08:00
case 22 : return ( & gotoblas_EXCAVATOR ) ;
2014-12-28 20:16:46 +08:00
case 21 : return ( & gotoblas_STEAMROLLER ) ;
2014-06-12 20:20:03 +08:00
case 20 : return ( & gotoblas_HASWELL ) ;
case 19 : return ( & gotoblas_PILEDRIVER ) ;
case 18 : return ( & gotoblas_BULLDOZER ) ;
case 17 : return ( & gotoblas_BOBCAT ) ;
case 16 : return ( & gotoblas_SANDYBRIDGE ) ;
case 15 : return ( & gotoblas_NANO ) ;
case 14 : return ( & gotoblas_BARCELONA ) ;
case 13 : return ( & gotoblas_OPTERON ) ;
case 12 : return ( & gotoblas_OPTERON_SSE3 ) ;
case 11 : return ( & gotoblas_ATHLON ) ;
case 10 : return ( & gotoblas_NEHALEM ) ;
case 9 : return ( & gotoblas_DUNNINGTON ) ;
case 8 : return ( & gotoblas_PENRYN ) ;
case 7 : return ( & gotoblas_CORE2 ) ;
case 6 : return ( & gotoblas_ATOM ) ;
case 5 : return ( & gotoblas_BANIAS ) ;
case 4 : return ( & gotoblas_PRESCOTT ) ;
case 3 : return ( & gotoblas_NORTHWOOD ) ;
case 2 : return ( & gotoblas_COPPERMINE ) ;
case 1 : return ( & gotoblas_KATMAI ) ;
}
return ( NULL ) ;
}
2014-06-28 03:05:18 +08:00
2014-06-12 20:20:03 +08:00
2011-01-24 22:54:24 +08:00
void gotoblas_dynamic_init ( void ) {
2014-06-28 03:05:18 +08:00
2014-06-12 20:20:03 +08:00
char coremsg [ 128 ] ;
char coren [ 22 ] ;
char * p ;
2014-06-28 03:05:18 +08:00
2014-06-12 20:20:03 +08:00
2011-01-24 22:54:24 +08:00
if ( gotoblas ) return ;
2014-06-12 20:20:03 +08:00
p = getenv ( " OPENBLAS_CORETYPE " ) ;
if ( p )
{
gotoblas = force_coretype ( p ) ;
}
else
{
gotoblas = get_coretype ( ) ;
}
2014-06-28 03:05:18 +08:00
2011-01-24 22:54:24 +08:00
# ifdef ARCH_X86
2011-01-25 00:04:17 +08:00
if ( gotoblas = = NULL ) gotoblas = & gotoblas_KATMAI ;
2011-01-24 22:54:24 +08:00
# else
2011-01-25 00:04:17 +08:00
if ( gotoblas = = NULL ) gotoblas = & gotoblas_PRESCOTT ;
2012-12-15 20:29:46 +08:00
/* sanity check, if 64bit pointer we can't have a 32 bit cpu */
if ( sizeof ( void * ) = = 8 ) {
if ( gotoblas = = & gotoblas_KATMAI | |
gotoblas = = & gotoblas_COPPERMINE | |
gotoblas = = & gotoblas_NORTHWOOD | |
gotoblas = = & gotoblas_BANIAS | |
gotoblas = = & gotoblas_ATHLON )
gotoblas = & gotoblas_PRESCOTT ;
}
2011-01-24 22:54:24 +08:00
# endif
2014-06-28 03:05:18 +08:00
2011-01-24 22:54:24 +08:00
if ( gotoblas & & gotoblas - > init ) {
2014-06-12 20:20:03 +08:00
strncpy ( coren , gotoblas_corename ( ) , 20 ) ;
sprintf ( coremsg , " Core: %s \n " , coren ) ;
2014-06-28 03:05:18 +08:00
openblas_warning ( 2 , coremsg ) ;
2011-01-24 22:54:24 +08:00
gotoblas - > init ( ) ;
} else {
2014-01-24 02:05:59 +08:00
openblas_warning ( 0 , " OpenBLAS : Architecture Initialization failed. No initialization function found. \n " ) ;
2011-01-24 22:54:24 +08:00
exit ( 1 ) ;
}
2014-06-28 03:05:18 +08:00
2011-01-24 22:54:24 +08:00
}
void gotoblas_dynamic_quit ( void ) {
2014-06-28 03:05:18 +08:00
2011-01-24 22:54:24 +08:00
gotoblas = NULL ;
}