You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

dynamic_arm64.c 8.3 kB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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. #include "common.h"
  39. #if (defined OS_LINUX || defined OS_ANDROID)
  40. #include <asm/hwcap.h>
  41. #include <sys/auxv.h>
  42. #endif
  43. extern gotoblas_t gotoblas_ARMV8;
  44. extern gotoblas_t gotoblas_CORTEXA53;
  45. extern gotoblas_t gotoblas_CORTEXA57;
  46. extern gotoblas_t gotoblas_CORTEXA72;
  47. extern gotoblas_t gotoblas_CORTEXA73;
  48. extern gotoblas_t gotoblas_FALKOR;
  49. extern gotoblas_t gotoblas_THUNDERX;
  50. extern gotoblas_t gotoblas_THUNDERX2T99;
  51. extern gotoblas_t gotoblas_TSV110;
  52. extern gotoblas_t gotoblas_EMAG8180;
  53. extern gotoblas_t gotoblas_NEOVERSEN1;
  54. extern void openblas_warning(int verbose, const char * msg);
  55. #define NUM_CORETYPES 11
  56. /*
  57. * In case asm/hwcap.h is outdated on the build system, make sure
  58. * that HWCAP_CPUID is defined
  59. */
  60. #ifndef HWCAP_CPUID
  61. #define HWCAP_CPUID (1 << 11)
  62. #endif
  63. #define get_cpu_ftr(id, var) ({ \
  64. asm("mrs %0, "#id : "=r" (var)); \
  65. })
  66. static char *corename[] = {
  67. "armv8",
  68. "cortexa53",
  69. "cortexa57",
  70. "cortexa72",
  71. "cortexa73",
  72. "falkor",
  73. "thunderx",
  74. "thunderx2t99",
  75. "tsv110",
  76. "emag8180",
  77. "neoversen1",
  78. "unknown"
  79. };
  80. char *gotoblas_corename(void) {
  81. if (gotoblas == &gotoblas_ARMV8) return corename[ 0];
  82. if (gotoblas == &gotoblas_CORTEXA53) return corename[ 1];
  83. if (gotoblas == &gotoblas_CORTEXA57) return corename[ 2];
  84. if (gotoblas == &gotoblas_CORTEXA72) return corename[ 3];
  85. if (gotoblas == &gotoblas_CORTEXA73) return corename[ 4];
  86. if (gotoblas == &gotoblas_FALKOR) return corename[ 5];
  87. if (gotoblas == &gotoblas_THUNDERX) return corename[ 6];
  88. if (gotoblas == &gotoblas_THUNDERX2T99) return corename[ 7];
  89. if (gotoblas == &gotoblas_TSV110) return corename[ 8];
  90. if (gotoblas == &gotoblas_EMAG8180) return corename[ 9];
  91. if (gotoblas == &gotoblas_NEOVERSEN1) return corename[10];
  92. return corename[NUM_CORETYPES];
  93. }
  94. static gotoblas_t *force_coretype(char *coretype) {
  95. int i ;
  96. int found = -1;
  97. char message[128];
  98. for ( i=0 ; i < NUM_CORETYPES; i++)
  99. {
  100. if (!strncasecmp(coretype, corename[i], 20))
  101. {
  102. found = i;
  103. break;
  104. }
  105. }
  106. switch (found)
  107. {
  108. case 0: return (&gotoblas_ARMV8);
  109. case 1: return (&gotoblas_CORTEXA53);
  110. case 2: return (&gotoblas_CORTEXA57);
  111. case 3: return (&gotoblas_CORTEXA72);
  112. case 4: return (&gotoblas_CORTEXA73);
  113. case 5: return (&gotoblas_FALKOR);
  114. case 6: return (&gotoblas_THUNDERX);
  115. case 7: return (&gotoblas_THUNDERX2T99);
  116. case 8: return (&gotoblas_TSV110);
  117. case 9: return (&gotoblas_EMAG8180);
  118. case 10: return (&gotoblas_NEOVERSEN1);
  119. }
  120. snprintf(message, 128, "Core not found: %s\n", coretype);
  121. openblas_warning(1, message);
  122. return NULL;
  123. }
  124. static gotoblas_t *get_coretype(void) {
  125. int implementer, variant, part, arch, revision, midr_el1;
  126. #if (defined OS_LINUX || defined OS_ANDROID)
  127. if (!(getauxval(AT_HWCAP) & HWCAP_CPUID)) {
  128. char coremsg[128];
  129. snprintf(coremsg, 128, "Kernel lacks cpuid feature support. Auto detection of core type failed !!!\n");
  130. openblas_warning(1, coremsg);
  131. return NULL;
  132. }
  133. #else
  134. return NULL;
  135. #endif
  136. get_cpu_ftr(MIDR_EL1, midr_el1);
  137. /*
  138. * MIDR_EL1
  139. *
  140. * 31 24 23 20 19 16 15 4 3 0
  141. * -----------------------------------------------------------------
  142. * | Implementer | Variant | Architecture | Part Number | Revision |
  143. * -----------------------------------------------------------------
  144. */
  145. implementer = (midr_el1 >> 24) & 0xFF;
  146. part = (midr_el1 >> 4) & 0xFFF;
  147. switch(implementer)
  148. {
  149. case 0x41: // ARM
  150. switch (part)
  151. {
  152. case 0xd03: // Cortex A53
  153. return &gotoblas_CORTEXA53;
  154. case 0xd07: // Cortex A57
  155. return &gotoblas_CORTEXA57;
  156. case 0xd08: // Cortex A72
  157. return &gotoblas_CORTEXA72;
  158. case 0xd09: // Cortex A73
  159. return &gotoblas_CORTEXA73;
  160. case 0xd0c: // Neoverse N1
  161. return &gotoblas_NEOVERSEN1;
  162. }
  163. break;
  164. case 0x42: // Broadcom
  165. switch (part)
  166. {
  167. case 0x516: // Vulcan
  168. return &gotoblas_THUNDERX2T99;
  169. }
  170. break;
  171. case 0x43: // Cavium
  172. switch (part)
  173. {
  174. case 0x0a1: // ThunderX
  175. return &gotoblas_THUNDERX;
  176. case 0x0af: // ThunderX2
  177. return &gotoblas_THUNDERX2T99;
  178. }
  179. break;
  180. case 0x48: // HiSilicon
  181. switch (part)
  182. {
  183. case 0xd01: // tsv110
  184. return &gotoblas_TSV110;
  185. }
  186. break;
  187. case 0x50: // Ampere
  188. switch (part)
  189. {
  190. case 0x000: // Skylark/EMAG8180
  191. return &gotoblas_EMAG8180;
  192. }
  193. break;
  194. case 0x51: // Qualcomm
  195. switch (part)
  196. {
  197. case 0xc00: // Falkor
  198. return &gotoblas_FALKOR;
  199. }
  200. break;
  201. }
  202. return NULL;
  203. }
  204. void gotoblas_dynamic_init(void) {
  205. char coremsg[128];
  206. char coren[22];
  207. char *p;
  208. if (gotoblas) return;
  209. p = getenv("OPENBLAS_CORETYPE");
  210. if ( p )
  211. {
  212. gotoblas = force_coretype(p);
  213. }
  214. else
  215. {
  216. gotoblas = get_coretype();
  217. }
  218. if (gotoblas == NULL)
  219. {
  220. snprintf(coremsg, 128, "Falling back to generic ARMV8 core\n");
  221. openblas_warning(1, coremsg);
  222. gotoblas = &gotoblas_ARMV8;
  223. }
  224. if (gotoblas && gotoblas->init) {
  225. strncpy(coren, gotoblas_corename(), 20);
  226. sprintf(coremsg, "Core: %s\n", coren);
  227. openblas_warning(2, coremsg);
  228. gotoblas -> init();
  229. } else {
  230. openblas_warning(0, "OpenBLAS : Architecture Initialization failed. No initialization function found.\n");
  231. exit(1);
  232. }
  233. }
  234. void gotoblas_dynamic_quit(void) {
  235. gotoblas = NULL;
  236. }