ARM64: Use THUNDERX2T99 Neon Kernels for ARMV8
[platform/upstream/openblas.git] / driver / others / parameter.c
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 #include <stdio.h>
40 #include <string.h>
41 #include "common.h"
42
43 extern int openblas_block_factor();
44 int get_L2_size(void);
45
46 #define DEFAULT_GEMM_P 128
47 #define DEFAULT_GEMM_Q 128
48 #define DEFAULT_GEMM_R 128
49 #define DEFAULT_GEMM_OFFSET_A 0
50 #define DEFAULT_GEMM_OFFSET_B 0
51
52 /* Global Parameter */
53 #if GEMM_OFFSET_A == gemm_offset_a
54 BLASLONG gemm_offset_a = DEFAULT_GEMM_OFFSET_A;
55 #else
56 BLASLONG gemm_offset_a = GEMM_OFFSET_A;
57 #endif
58
59 #if GEMM_OFFSET_B == gemm_offset_b
60 BLASLONG gemm_offset_b = DEFAULT_GEMM_OFFSET_B;
61 #else
62 BLASLONG gemm_offset_b = GEMM_OFFSET_B;
63 #endif
64
65 #if SGEMM_P == sgemm_p
66 BLASLONG sgemm_p = DEFAULT_GEMM_P;
67 #else
68 BLASLONG sgemm_p = SGEMM_P;
69 #endif
70 #if DGEMM_P == dgemm_p
71 BLASLONG dgemm_p = DEFAULT_GEMM_P;
72 #else
73 BLASLONG dgemm_p = DGEMM_P;
74 #endif
75 #if CGEMM_P == cgemm_p
76 BLASLONG cgemm_p = DEFAULT_GEMM_P;
77 #else
78 BLASLONG cgemm_p = CGEMM_P;
79 #endif
80 #if ZGEMM_P == zgemm_p
81 BLASLONG zgemm_p = DEFAULT_GEMM_P;
82 #else
83 BLASLONG zgemm_p = ZGEMM_P;
84 #endif
85
86 #if SGEMM_Q == sgemm_q
87 BLASLONG sgemm_q = DEFAULT_GEMM_Q;
88 #else
89 BLASLONG sgemm_q = SGEMM_Q;
90 #endif
91 #if DGEMM_Q == dgemm_q
92 BLASLONG dgemm_q = DEFAULT_GEMM_Q;
93 #else
94 BLASLONG dgemm_q = DGEMM_Q;
95 #endif
96 #if CGEMM_Q == cgemm_q
97 BLASLONG cgemm_q = DEFAULT_GEMM_Q;
98 #else
99 BLASLONG cgemm_q = CGEMM_Q;
100 #endif
101 #if ZGEMM_Q == zgemm_q
102 BLASLONG zgemm_q = DEFAULT_GEMM_Q;
103 #else
104 BLASLONG zgemm_q = ZGEMM_Q;
105 #endif
106
107 #if SGEMM_R == sgemm_r
108 BLASLONG sgemm_r = DEFAULT_GEMM_R;
109 #else
110 BLASLONG sgemm_r = SGEMM_R;
111 #endif
112 #if DGEMM_R == dgemm_r
113 BLASLONG dgemm_r = DEFAULT_GEMM_R;
114 #else
115 BLASLONG dgemm_r = DGEMM_R;
116 #endif
117 #if CGEMM_R == cgemm_r
118 BLASLONG cgemm_r = DEFAULT_GEMM_R;
119 #else
120 BLASLONG cgemm_r = CGEMM_R;
121 #endif
122 #if ZGEMM_R == zgemm_r
123 BLASLONG zgemm_r = DEFAULT_GEMM_R;
124 #else
125 BLASLONG zgemm_r = ZGEMM_R;
126 #endif
127
128 #if defined(EXPRECISION) || defined(QUAD_PRECISION)
129 #if QGEMM_P == qgemm_p
130 BLASLONG qgemm_p = DEFAULT_GEMM_P;
131 #else
132 BLASLONG qgemm_p = QGEMM_P;
133 #endif
134 #if XGEMM_P == xgemm_p
135 BLASLONG xgemm_p = DEFAULT_GEMM_P;
136 #else
137 BLASLONG xgemm_p = XGEMM_P;
138 #endif
139 #if QGEMM_Q == qgemm_q
140 BLASLONG qgemm_q = DEFAULT_GEMM_Q;
141 #else
142 BLASLONG qgemm_q = QGEMM_Q;
143 #endif
144 #if XGEMM_Q == xgemm_q
145 BLASLONG xgemm_q = DEFAULT_GEMM_Q;
146 #else
147 BLASLONG xgemm_q = XGEMM_Q;
148 #endif
149 #if QGEMM_R == qgemm_r
150 BLASLONG qgemm_r = DEFAULT_GEMM_R;
151 #else
152 BLASLONG qgemm_r = QGEMM_R;
153 #endif
154 #if XGEMM_R == xgemm_r
155 BLASLONG xgemm_r = DEFAULT_GEMM_R;
156 #else
157 BLASLONG xgemm_r = XGEMM_R;
158 #endif
159 #endif
160
161 #if defined(ARCH_X86) || defined(ARCH_X86_64)
162
163 int get_L2_size(void){
164
165   int eax, ebx, ecx, edx;
166
167 #if defined(ATHLON) || defined(OPTERON) || defined(BARCELONA) || defined(BOBCAT) || defined(BULLDOZER) || \
168     defined(CORE_PRESCOTT) || defined(CORE_CORE2) || defined(PENRYN) || defined(DUNNINGTON) || \
169     defined(CORE_NEHALEM) || defined(CORE_SANDYBRIDGE) || defined(ATOM) || defined(GENERIC) || \
170     defined(PILEDRIVER) || defined(HASWELL) || defined(STEAMROLLER) || defined(EXCAVATOR) || defined(ZEN) || defined(SKYLAKEX)
171
172   cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
173
174   return BITMASK(ecx, 16, 0xffff);
175
176 #else
177
178   int info[15];
179   int i;
180
181   cpuid(2, &eax, &ebx, &ecx, &edx);
182
183   info[ 0] = BITMASK(eax,  8, 0xff);
184   info[ 1] = BITMASK(eax, 16, 0xff);
185   info[ 2] = BITMASK(eax, 24, 0xff);
186
187   info[ 3] = BITMASK(ebx,  0, 0xff);
188   info[ 4] = BITMASK(ebx,  8, 0xff);
189   info[ 5] = BITMASK(ebx, 16, 0xff);
190   info[ 6] = BITMASK(ebx, 24, 0xff);
191
192   info[ 7] = BITMASK(ecx,  0, 0xff);
193   info[ 8] = BITMASK(ecx,  8, 0xff);
194   info[ 9] = BITMASK(ecx, 16, 0xff);
195   info[10] = BITMASK(ecx, 24, 0xff);
196
197   info[11] = BITMASK(edx,  0, 0xff);
198   info[12] = BITMASK(edx,  8, 0xff);
199   info[13] = BITMASK(edx, 16, 0xff);
200   info[14] = BITMASK(edx, 24, 0xff);
201
202   for (i = 0; i < 15; i++){
203
204     switch (info[i]){
205       case 0x3b :
206       case 0x41 :
207       case 0x79 :
208         return  128;
209         break;
210
211       case 0x3c :
212       case 0x42 :
213       case 0x7a :
214       case 0x7e :
215       case 0x82 :
216         return  256;
217         break;
218
219       case 0x43 :
220       case 0x7b :
221       case 0x7f :
222       case 0x83 :
223       case 0x86 :
224         return  512;
225         break;
226
227       case 0x44 :
228       case 0x78 :
229       case 0x7c :
230       case 0x84 :
231       case 0x87 :
232         return 1024;
233         break;
234
235       case 0x45 :
236       case 0x7d :
237       case 0x85 :
238         return 2048;
239
240       case 0x49 :
241         return 4096;
242         break;
243     }
244   }
245
246   /* Never reached */
247   return 0;
248 #endif
249 }
250
251 void blas_set_parameter(void){
252
253   int factor;
254 #if defined(BULLDOZER) || defined(PILEDRIVER) || defined(SANDYBRIDGE) || defined(NEHALEM) || defined(HASWELL) || defined(STEAMROLLER) || defined(EXCAVATOR) || defined(ZEN) || defined(SKYLAKEX)
255   int size = 16;
256 #else
257   int size = get_L2_size();
258 #endif
259
260 #if defined(CORE_KATMAI)  || defined(CORE_COPPERMINE) || defined(CORE_BANIAS)
261   size >>= 7;
262
263 #if defined(CORE_BANIAS) && (HAVE_HIT > 1)
264   sgemm_p =  64 / HAVE_HIT * size;
265   dgemm_p =  32 / HAVE_HIT * size;
266   cgemm_p =  32 / HAVE_HIT * size;
267   zgemm_p =  16 / HAVE_HIT * size;
268 #ifdef EXPRECISION
269   qgemm_p =  16 / HAVE_HIT * size;
270   xgemm_p =   8 / HAVE_HIT * size;
271 #endif
272 #ifdef QUAD_PRECISION
273   qgemm_p =   8 / HAVE_HIT * size;
274   xgemm_p =   4 / HAVE_HIT * size;
275 #endif
276 #else
277   sgemm_p =  64 * size;
278   dgemm_p =  32 * size;
279   cgemm_p =  32 * size;
280   zgemm_p =  16 * size;
281 #ifdef EXPRECISION
282   qgemm_p =  16 * size;
283   xgemm_p =   8 * size;
284 #endif
285 #ifdef QUAD_PRECISION
286   qgemm_p =   8 * size;
287   xgemm_p =   4 * size;
288 #endif
289 #endif
290 #endif
291
292 #if defined(CORE_NORTHWOOD)
293   size >>= 7;
294
295 #ifdef ALLOC_HUGETLB
296   sgemm_p = 128 * size;
297   dgemm_p =  64 * size;
298   cgemm_p =  64 * size;
299   zgemm_p =  32 * size;
300 #ifdef EXPRECISION
301   qgemm_p =  32 * size;
302   xgemm_p =  16 * size;
303 #endif
304 #ifdef QUAD_PRECISION
305   qgemm_p =  16 * size;
306   xgemm_p =   8 * size;
307 #endif
308 #else
309   sgemm_p =  96 * size;
310   dgemm_p =  48 * size;
311   cgemm_p =  48 * size;
312   zgemm_p =  24 * size;
313 #ifdef EXPRECISION
314   qgemm_p =  24 * size;
315   xgemm_p =  12 * size;
316 #endif
317 #ifdef QUAD_PRECISION
318   qgemm_p =  12 * size;
319   xgemm_p =   6 * size;
320 #endif
321 #endif
322 #endif
323
324 #if defined(CORE_CORE2)
325
326   size >>= 9;
327
328   sgemm_p =  92 * size;
329   dgemm_p =  46 * size;
330   cgemm_p =  46 * size;
331   zgemm_p =  23 * size;
332
333 #ifdef EXPRECISION
334   qgemm_p =  23 * size;
335   xgemm_p =  11 * size;
336 #endif
337 #ifdef QUAD_PRECISION
338   qgemm_p =  11 * size;
339   xgemm_p =   5 * size;
340 #endif
341 #endif
342
343 #if defined(PENRYN)
344
345   size >>= 9;
346
347   sgemm_p = 1024;
348   dgemm_p =  512;
349   cgemm_p =  512;
350   zgemm_p =  256;
351
352 #ifdef EXPRECISION
353   qgemm_p =  256;
354   xgemm_p =  128;
355 #endif
356 #ifdef QUAD_PRECISION
357   qgemm_p =  21 * size + 4;
358   xgemm_p =  10 * size + 2;
359 #endif
360 #endif
361
362 #if defined(DUNNINGTON)
363
364   size >>= 9;
365
366   sgemm_p = 384;
367   dgemm_p = 384;
368   cgemm_p = 384;
369   zgemm_p = 384;
370
371 #ifdef EXPRECISION
372   qgemm_p = 384;
373   xgemm_p = 384;
374 #endif
375 #ifdef QUAD_PRECISION
376   qgemm_p =  21 * size + 4;
377   xgemm_p =  10 * size + 2;
378 #endif
379 #endif
380
381 #if defined(NEHALEM)
382   sgemm_p = 1024;
383   dgemm_p =  512;
384   cgemm_p =  512;
385   zgemm_p =  256;
386 #ifdef EXPRECISION
387   qgemm_p =  256;
388   xgemm_p =  128;
389 #endif
390 #endif
391
392 #if defined(SANDYBRIDGE)
393   sgemm_p = 1024;
394   dgemm_p =  512;
395   cgemm_p =  512;
396   zgemm_p =  256;
397 #ifdef EXPRECISION
398   qgemm_p =  256;
399   xgemm_p =  128;
400 #endif
401 #endif
402
403 #if defined(CORE_PRESCOTT)  || defined(GENERIC)
404   size >>= 6;
405
406   if (size > 16) size = 16;
407
408   sgemm_p =  56 * size;
409   dgemm_p =  28 * size;
410   cgemm_p =  28 * size;
411   zgemm_p =  14 * size;
412 #ifdef EXPRECISION
413   qgemm_p =  14 * size;
414   xgemm_p =   7 * size;
415 #endif
416 #ifdef QUAD_PRECISION
417   qgemm_p =   7 * size;
418   xgemm_p =   3 * size;
419 #endif
420 #endif
421
422 #if defined(CORE_OPTERON)
423   sgemm_p =  224 + 14 * (size >> 5);
424   dgemm_p =  112 + 14 * (size >> 6);
425   cgemm_p =  116 + 14 * (size >> 6);
426   zgemm_p =   58 + 14 * (size >> 7);
427 #ifdef EXPRECISION
428   qgemm_p =   58 + 14 * (size >> 7);
429   xgemm_p =   29 + 14 * (size >> 8);
430 #endif
431 #ifdef QUAD_PRECISION
432   qgemm_p =   29 + 14 * (size >> 8);
433   xgemm_p =   15 + 14 * (size >> 9);
434 #endif
435 #endif
436
437 #if defined(ATOM)
438   size >>= 8;
439
440   sgemm_p =  256;
441   dgemm_p =  128;
442   cgemm_p =  128;
443   zgemm_p =   64;
444 #ifdef EXPRECISION
445   qgemm_p =   64;
446   xgemm_p =   32;
447 #endif
448 #ifdef QUAD_PRECISION
449   qgemm_p =   32;
450   xgemm_p =   16;
451 #endif
452 #endif
453
454 #if defined(CORE_BARCELONA) || defined(CORE_BOBCAT)
455   size >>= 8;
456
457   sgemm_p = 232 * size;
458   dgemm_p = 116 * size;
459   cgemm_p = 116 * size;
460   zgemm_p =  58 * size;
461 #ifdef EXPRECISION
462   qgemm_p =  58 * size;
463   xgemm_p =  26 * size;
464 #endif
465 #ifdef QUAD_PRECISION
466   qgemm_p =  26 * size;
467   xgemm_p =  13 * size;
468 #endif
469 #endif
470
471   factor=openblas_block_factor();
472   if (factor>0) {
473     if (factor <  10) factor =  10;
474     if (factor > 200) factor = 200;
475
476     sgemm_p = ((long)((double)sgemm_p * (double)factor * 1.e-2)) & ~7L;
477     dgemm_p = ((long)((double)dgemm_p * (double)factor * 1.e-2)) & ~7L;
478     cgemm_p = ((long)((double)cgemm_p * (double)factor * 1.e-2)) & ~7L;
479     zgemm_p = ((long)((double)zgemm_p * (double)factor * 1.e-2)) & ~7L;
480 #ifdef EXPRECISION
481     qgemm_p = ((long)((double)qgemm_p * (double)factor * 1.e-2)) & ~7L;
482     xgemm_p = ((long)((double)xgemm_p * (double)factor * 1.e-2)) & ~7L;
483 #endif
484   }
485
486   if (sgemm_p == 0) sgemm_p = 64;
487   if (dgemm_p == 0) dgemm_p = 64;
488   if (cgemm_p == 0) cgemm_p = 64;
489   if (zgemm_p == 0) zgemm_p = 64;
490 #ifdef EXPRECISION
491   if (qgemm_p == 0) qgemm_p = 64;
492   if (xgemm_p == 0) xgemm_p = 64;
493 #endif
494
495 #ifdef QUAD_PRECISION
496   if (qgemm_p == 0) qgemm_p = 64;
497   if (xgemm_p == 0) xgemm_p = 64;
498 #endif
499
500   sgemm_p = ((sgemm_p + SGEMM_UNROLL_M - 1)/SGEMM_UNROLL_M) * SGEMM_UNROLL_M;
501   dgemm_p = ((dgemm_p + DGEMM_UNROLL_M - 1)/DGEMM_UNROLL_M) * DGEMM_UNROLL_M;
502   cgemm_p = ((cgemm_p + CGEMM_UNROLL_M - 1)/CGEMM_UNROLL_M) * CGEMM_UNROLL_M;
503   zgemm_p = ((zgemm_p + ZGEMM_UNROLL_M - 1)/ZGEMM_UNROLL_M) * ZGEMM_UNROLL_M;
504 #ifdef QUAD_PRECISION
505   qgemm_p = ((qgemm_p + QGEMM_UNROLL_M - 1)/QGEMM_UNROLL_M) * QGEMM_UNROLL_M;
506   xgemm_p = ((xgemm_p + XGEMM_UNROLL_M - 1)/XGEMM_UNROLL_M) * XGEMM_UNROLL_M;
507 #endif
508
509   sgemm_r = (((BUFFER_SIZE - ((SGEMM_P * SGEMM_Q *  4 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (SGEMM_Q *  4)) - 15) & ~15;
510   dgemm_r = (((BUFFER_SIZE - ((DGEMM_P * DGEMM_Q *  8 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (DGEMM_Q *  8)) - 15) & ~15;
511   cgemm_r = (((BUFFER_SIZE - ((CGEMM_P * CGEMM_Q *  8 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (CGEMM_Q *  8)) - 15) & ~15;
512   zgemm_r = (((BUFFER_SIZE - ((ZGEMM_P * ZGEMM_Q * 16 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (ZGEMM_Q * 16)) - 15) & ~15;
513 #if defined(EXPRECISION) || defined(QUAD_PRECISION)
514   qgemm_r = (((BUFFER_SIZE - ((QGEMM_P * QGEMM_Q * 16 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (QGEMM_Q * 16)) - 15) & ~15;
515   xgemm_r = (((BUFFER_SIZE - ((XGEMM_P * XGEMM_Q * 32 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (XGEMM_Q * 32)) - 15) & ~15;
516 #endif
517
518 #if 0
519   fprintf(stderr, "SGEMM ... %3d, %3d, %3d\n", SGEMM_P, SGEMM_Q, SGEMM_R);
520   fprintf(stderr, "DGEMM ... %3d, %3d, %3d\n", DGEMM_P, DGEMM_Q, DGEMM_R);
521   fprintf(stderr, "CGEMM ... %3d, %3d, %3d\n", CGEMM_P, CGEMM_Q, CGEMM_R);
522   fprintf(stderr, "ZGEMM ... %3d, %3d, %3d\n", ZGEMM_P, ZGEMM_Q, ZGEMM_R);
523 #endif
524
525   return;
526 }
527
528 #if 0
529
530 int get_current_cpu_info(void){
531
532   int nlprocs, ncores, cmplegacy;
533   int htt     = 0;
534   int apicid  = 0;
535
536 #if defined(CORE_PRESCOTT) || defined(CORE_OPTERON)
537   int eax, ebx, ecx, edx;
538
539   cpuid(1, &eax, &ebx, &ecx, &edx);
540   nlprocs = BITMASK(ebx, 16, 0xff);
541   apicid  = BITMASK(ebx, 24, 0xff);
542   htt     = BITMASK(edx, 28, 0x01);
543 #endif
544
545 #if defined(CORE_PRESCOTT)
546   cpuid(4, &eax, &ebx, &ecx, &edx);
547   ncores = BITMASK(eax, 26, 0x3f);
548
549   if (htt == 0)  nlprocs = 0;
550 #endif
551
552 #if defined(CORE_OPTERON)
553   cpuid(0x80000008, &eax, &ebx, &ecx, &edx);
554   ncores = BITMASK(ecx,  0, 0xff);
555
556   cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
557   cmplegacy = BITMASK(ecx,  1, 0x01);
558
559   if (htt == 0) {
560     nlprocs = 0;
561     ncores  = 0;
562     cmplegacy = 0;
563   }
564 #endif
565
566   ncores  ++;
567
568   fprintf(stderr, "APICID = %d  Number of core = %d\n", apicid, ncores);
569
570   return 0;
571 }
572 #endif
573
574 #endif
575
576 #if defined(ARCH_IA64)
577
578 static inline BLASULONG cpuid(BLASULONG regnum){
579   BLASULONG value;
580
581 #ifndef __ECC
582   asm ("mov %0=cpuid[%r1]" : "=r"(value) : "rO"(regnum));
583 #else
584  value = __getIndReg(_IA64_REG_INDR_CPUID, regnum);
585 #endif
586
587   return value;
588 }
589
590 #if 1
591
592 void blas_set_parameter(void){
593
594   BLASULONG cpuid3, size;
595
596   cpuid3 = cpuid(3);
597
598   size = BITMASK(cpuid3, 16, 0xff);
599
600   sgemm_p = 192 * (size + 1);
601   dgemm_p =  96 * (size + 1);
602   cgemm_p =  96 * (size + 1);
603   zgemm_p =  48 * (size + 1);
604 #ifdef EXPRECISION
605   qgemm_p =  64 * (size + 1);
606   xgemm_p =  32 * (size + 1);
607 #endif
608 #ifdef QUAD_PRECISION
609   qgemm_p =  32 * (size + 1);
610   xgemm_p =  16 * (size + 1);
611 #endif
612
613   sgemm_r = (((BUFFER_SIZE - ((SGEMM_P * SGEMM_Q *  4 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (SGEMM_Q *  4)) - 15) & ~15;
614   dgemm_r = (((BUFFER_SIZE - ((DGEMM_P * DGEMM_Q *  8 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (DGEMM_Q *  8)) - 15) & ~15;
615   cgemm_r = (((BUFFER_SIZE - ((CGEMM_P * CGEMM_Q *  8 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (CGEMM_Q *  8)) - 15) & ~15;
616   zgemm_r = (((BUFFER_SIZE - ((ZGEMM_P * ZGEMM_Q * 16 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (ZGEMM_Q * 16)) - 15) & ~15;
617 #if defined(EXPRECISION) || defined(QUAD_PRECISION)
618   qgemm_r = (((BUFFER_SIZE - ((QGEMM_P * QGEMM_Q * 16 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (QGEMM_Q * 16)) - 15) & ~15;
619   xgemm_r = (((BUFFER_SIZE - ((XGEMM_P * XGEMM_Q * 32 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (XGEMM_Q * 32)) - 15) & ~15;
620 #endif
621
622   return;
623 }
624
625 #else
626
627 #define IA64_SYS_NAME  "/sys/devices/system/cpu/cpu0/cache/index3/size"
628 #define IA64_PROC_NAME "/proc/pal/cpu0/cache_info"
629
630 void blas_set_parameter(void){
631
632   BLASULONG cpuid3;
633   int size = 0;
634
635 #if 1
636   char buffer[128];
637   FILE *infile;
638
639   if ((infile = fopen(IA64_SYS_NAME, "r")) != NULL) {
640
641     fgets(buffer, sizeof(buffer), infile);
642     fclose(infile);
643
644     size = atoi(buffer) / 1536;
645   }
646
647   if (size <= 0) {
648     if ((infile = fopen(IA64_PROC_NAME, "r")) != NULL) {
649
650       while(fgets(buffer, sizeof(buffer), infile) != NULL) {
651         if ((!strncmp("Data/Instruction Cache level 3", buffer, 30))) break;
652       }
653
654       fgets(buffer, sizeof(buffer), infile);
655
656       fclose(infile);
657
658       *strstr(buffer, "bytes") = (char)NULL;
659
660       size = atoi(strchr(buffer, ':') + 1) / 1572864;
661     }
662   }
663 #endif
664
665   /* The last resort */
666
667   if (size <= 0) {
668     cpuid3 = cpuid(3);
669
670     size = BITMASK(cpuid3, 16, 0xff) + 1;
671   }
672
673   sgemm_p = 320 * size;
674   dgemm_p = 160 * size;
675   cgemm_p = 160 * size;
676   zgemm_p =  80 * size;
677 #ifdef EXPRECISION
678   qgemm_p =  80 * size;
679   xgemm_p =  40 * size;
680 #endif
681
682   sgemm_r = (((BUFFER_SIZE - ((SGEMM_P * SGEMM_Q *  4 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (SGEMM_Q *  4)) - 15) & ~15;
683   dgemm_r = (((BUFFER_SIZE - ((DGEMM_P * DGEMM_Q *  8 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (DGEMM_Q *  8)) - 15) & ~15;
684   cgemm_r = (((BUFFER_SIZE - ((CGEMM_P * CGEMM_Q *  8 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (CGEMM_Q *  8)) - 15) & ~15;
685   zgemm_r = (((BUFFER_SIZE - ((ZGEMM_P * ZGEMM_Q * 16 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (ZGEMM_Q * 16)) - 15) & ~15;
686 #ifdef EXPRECISION
687   qgemm_r = (((BUFFER_SIZE - ((QGEMM_P * QGEMM_Q * 16 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (QGEMM_Q * 16)) - 15) & ~15;
688   xgemm_r = (((BUFFER_SIZE - ((XGEMM_P * XGEMM_Q * 32 + GEMM_OFFSET_A + GEMM_ALIGN) & ~GEMM_ALIGN)) / (XGEMM_Q * 32)) - 15) & ~15;
689 #endif
690
691   return;
692 }
693
694 #endif
695
696 #endif
697
698 #if defined(ARCH_MIPS64)
699 void blas_set_parameter(void){
700 #if defined(LOONGSON3A)
701 #ifdef SMP
702   if(blas_num_threads == 1){
703 #endif
704     //single thread
705     dgemm_r = 1024;
706 #ifdef SMP
707   }else{
708     //multi thread
709     dgemm_r = 200;
710   }
711 #endif
712 #endif
713
714 #if defined(LOONGSON3B)
715 #ifdef SMP
716   if(blas_num_threads == 1 || blas_num_threads == 2){
717 #endif
718     //single thread
719     dgemm_r = 640;
720 #ifdef SMP
721   }else{
722     //multi thread
723     dgemm_r = 160;
724   }
725 #endif
726 #endif
727
728 }
729 #endif
730
731 #if defined(ARCH_ARM64)
732
733 #if defined(VULCAN) || defined(THUNDERX2T99) || defined(ARMV8)
734 unsigned long dgemm_prefetch_size_a;
735 unsigned long dgemm_prefetch_size_b;
736 unsigned long dgemm_prefetch_size_c;
737 #endif
738
739 void blas_set_parameter(void)
740 {
741 #if defined(VULCAN) || defined(THUNDERX2T99) || defined(ARMV8)
742   dgemm_p = 160;
743   dgemm_q = 128;
744   dgemm_r = 4096;
745
746   sgemm_p = 128;
747   sgemm_q = 352;
748   sgemm_r = 4096;
749
750   cgemm_p = 128;
751   cgemm_q = 224;
752   cgemm_r = 4096;
753
754   zgemm_p = 128;
755   zgemm_q = 112;
756   zgemm_r = 4096;
757
758   dgemm_prefetch_size_a = 3584;
759   dgemm_prefetch_size_b = 512;
760   dgemm_prefetch_size_c = 128;
761 #endif
762 }
763
764 #endif