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.5 kB

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