001:       INTEGER FUNCTION PLASMA_ILAENV( ISPEC, NAME, OPTS, N1, N2, N3, 
002:      $                                N4 )
003: *
004: *  -- LAPACK auxiliary routine (version 3.2) --
005: *     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
006: *     January 2007
007: *
008: *     .. Scalar Arguments ..
009:       CHARACTER*( * )    NAME, OPTS
010:       INTEGER            ISPEC, N1, N2, N3, N4
011: *     ..
012: *
013: *  Purpose
014: *  =======
015: *
016: *  PLASMA_ILAENV is called from the LAPACK routines to choose problem-dependent
017: *  parameters for the local environment.  See ISPEC for a description of
018: *  the parameters.
019: *
020: *  PLASMA_ILAENV returns an INTEGER
021: *  if PLASMA_ILAENV >= 0: ILAENV returns the value of the parameter specified by ISPEC
022: *  if PLASMA_ILAENV < 0:  if ILAENV = -k, the k-th argument had an illegal value.
023: *
024: *  This version provides a set of parameters which should give good,
025: *  but not optimal, performance on many of the currently available
026: *  computers.  Users are encouraged to modify this subroutine to set
027: *  the tuning parameters for their particular machine using the option
028: *  and problem size information in the arguments.
029: *
030: *  This routine will not function correctly if it is converted to all
031: *  lower case.  Converting it to all upper case is allowed.
032: *
033: *  Arguments
034: *  =========
035: *
036: *  ISPEC   (input) INTEGER
037: *          Specifies the parameter to be returned as the value of
038: *          PLASMA_ILAENV.
039: *          = 1: the optimal blocksize; if this value is 1, an unblocked
040: *               algorithm will give the best performance.
041: *          = 2: the minimum block size for which the block routine
042: *               should be used; if the usable block size is less than
043: *               this value, an unblocked routine should be used.
044: *          = 3: the crossover point (in a block routine, for N less
045: *               than this value, an unblocked routine should be used)
046: *          = 4: the number of shifts, used in the nonsymmetric
047: *               eigenvalue routines (DEPRECATED)
048: *          = 5: the minimum column dimension for blocking to be used;
049: *               rectangular blocks must have dimension at least k by m,
050: *               where k is given by PLASMA_ILAENV(2,...) and m by ILAENV(5,...)
051: *          = 6: the crossover point for the SVD (when reducing an m by n
052: *               matrix to bidiagonal form, if max(m,n)/min(m,n) exceeds
053: *               this value, a QR factorization is used first to reduce
054: *               the matrix to a triangular form.)
055: *          = 7: the number of processors
056: *          = 8: the crossover point for the multishift QR method
057: *               for nonsymmetric eigenvalue problems (DEPRECATED)
058: *          = 9: maximum size of the subproblems at the bottom of the
059: *               computation tree in the divide-and-conquer algorithm
060: *               (used by xGELSD and xGESDD)
061: *          =10: ieee NaN arithmetic can be trusted not to trap
062: *          =11: infinity arithmetic can be trusted not to trap
063: *          12 <= ISPEC <= 16:
064: *               xHSEQR or one of its subroutines,
065: *               see IPARMQ for detailed explanation
066: *
067: *  NAME    (input) CHARACTER*(*)
068: *          The name of the calling subroutine, in either upper case or
069: *          lower case.
070: *
071: *  OPTS    (input) CHARACTER*(*)
072: *          The character options to the subroutine NAME, concatenated
073: *          into a single character string.  For example, UPLO = 'U',
074: *          TRANS = 'T', and DIAG = 'N' for a triangular routine would
075: *          be specified as OPTS = 'UTN'.
076: *
077: *  N1      (input) INTEGER
078: *  N2      (input) INTEGER
079: *  N3      (input) INTEGER
080: *  N4      (input) INTEGER
081: *          Problem dimensions for the subroutine NAME; these may not all
082: *          be required.
083: *
084: *  Further Details
085: *  ===============
086: *
087: *  The following conventions have been used when calling PLASMA_ILAENV from the
088: *  LAPACK routines:
089: *  1)  OPTS is a concatenation of all of the character options to
090: *      subroutine NAME, in the same order that they appear in the
091: *      argument list for NAME, even if they are not used in determining
092: *      the value of the parameter specified by ISPEC.
093: *  2)  The problem dimensions N1, N2, N3, N4 are specified in the order
094: *      that they appear in the argument list for NAME.  N1 is used
095: *      first, N2 second, and so on, and unused problem dimensions are
096: *      passed a value of -1.
097: *  3)  The parameter value returned by PLASMA_ILAENV is checked for validity in
098: *      the calling subroutine.  For example, PLASMA_ILAENV is used to retrieve
099: *      the optimal blocksize for STRTRI as follows:
100: *
101: *      NB = PLASMA_ILAENV( 1, 'STRTRI', UPLO // DIAG, N, -1, -1, -1 )
102: *      IF( NB.LE.1 ) NB = MAX( 1, N )
103: *
104: *  =====================================================================
105: *
106: *     .. Local Scalars ..
107:       INTEGER            I, IC, IZ, NB, NBMIN, NX
108:       LOGICAL            CNAME, SNAME
109:       CHARACTER          C1*1, C2*2, C4*2, C3*3, SUBNAM*6
110: *     ..
111: *     .. Intrinsic Functions ..
112:       INTRINSIC          CHAR, ICHAR, INT, MIN, REAL
113: *     ..
114: *     .. External Functions ..
115:       INTEGER            IEEECK, IPARMQ
116:       EXTERNAL           IEEECK, IPARMQ
117: *     ..
118: *     .. Executable Statements ..
119: *
120:       GO TO ( 10, 10, 10, 80, 90, 100, 110, 120,
121:      $        130, 140, 150, 160, 160, 160, 160, 160 )ISPEC
122: *
123: *     Invalid value for ISPEC
124: *
125:       PLASMA_ILAENV = -1
126:       RETURN
127: *
128:    10 CONTINUE
129: *
130: *     Convert NAME to upper case if the first character is lower case.
131: *
132:       PLASMA_ILAENV = 1
133:       SUBNAM = NAME
134:       IC = ICHAR( SUBNAM( 1: 1 ) )
135:       IZ = ICHAR( 'Z' )
136:       IF( IZ.EQ.90 .OR. IZ.EQ.122 ) THEN
137: *
138: *        ASCII character set
139: *
140:          IF( IC.GE.97 .AND. IC.LE.122 ) THEN
141:             SUBNAM( 1: 1 ) = CHAR( IC-32 )
142:             DO 20 I = 2, 6
143:                IC = ICHAR( SUBNAM( I: I ) )
144:                IF( IC.GE.97 .AND. IC.LE.122 )
145:      $            SUBNAM( I: I ) = CHAR( IC-32 )
146:    20       CONTINUE
147:          END IF
148: *
149:       ELSE IF( IZ.EQ.233 .OR. IZ.EQ.169 ) THEN
150: *
151: *        EBCDIC character set
152: *
153:          IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.
154:      $       ( IC.GE.145 .AND. IC.LE.153 ) .OR.
155:      $       ( IC.GE.162 .AND. IC.LE.169 ) ) THEN
156:             SUBNAM( 1: 1 ) = CHAR( IC+64 )
157:             DO 30 I = 2, 6
158:                IC = ICHAR( SUBNAM( I: I ) )
159:                IF( ( IC.GE.129 .AND. IC.LE.137 ) .OR.
160:      $             ( IC.GE.145 .AND. IC.LE.153 ) .OR.
161:      $             ( IC.GE.162 .AND. IC.LE.169 ) )SUBNAM( I:
162:      $             I ) = CHAR( IC+64 )
163:    30       CONTINUE
164:          END IF
165: *
166:       ELSE IF( IZ.EQ.218 .OR. IZ.EQ.250 ) THEN
167: *
168: *        Prime machines:  ASCII+128
169: *
170:          IF( IC.GE.225 .AND. IC.LE.250 ) THEN
171:             SUBNAM( 1: 1 ) = CHAR( IC-32 )
172:             DO 40 I = 2, 6
173:                IC = ICHAR( SUBNAM( I: I ) )
174:                IF( IC.GE.225 .AND. IC.LE.250 )
175:      $            SUBNAM( I: I ) = CHAR( IC-32 )
176:    40       CONTINUE
177:          END IF
178:       END IF
179: *
180:       C1 = SUBNAM( 1: 1 )
181:       SNAME = C1.EQ.'S' .OR. C1.EQ.'D'
182:       CNAME = C1.EQ.'C' .OR. C1.EQ.'Z'
183:       IF( .NOT.( CNAME .OR. SNAME ) )
184:      $   RETURN
185:       C2 = SUBNAM( 2: 3 )
186:       C3 = SUBNAM( 4: 6 )
187:       C4 = C3( 2: 3 )
188: *
189:       GO TO ( 50, 60, 70 )ISPEC
190: *
191:    50 CONTINUE
192: *
193: *     ISPEC = 1:  block size
194: *
195: *     In these examples, separate code is provided for setting NB for
196: *     real and complex.  We assume that NB will take the same value in
197: *     single or double precision.
198: *
199:       NB = 1
200: *
201:       IF( C2.EQ.'GE' ) THEN
202:          IF( C3.EQ.'TRF' ) THEN
203:             IF( SNAME ) THEN
204:                NB = 64
205:             ELSE
206:                NB = 64
207:             END IF
208:          ELSE IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR.
209:      $            C3.EQ.'QLF' ) THEN
210:             IF( SNAME ) THEN
211:                NB = 32
212:             ELSE
213:                NB = 32
214:             END IF
215:          ELSE IF( C3.EQ.'HRD' ) THEN
216:             IF( SNAME ) THEN
217:                NB = 32
218:             ELSE
219:                NB = 32
220:             END IF
221:          ELSE IF( C3.EQ.'BRD' ) THEN
222:             IF( SNAME ) THEN
223:                NB = 32
224:             ELSE
225:                NB = 32
226:             END IF
227:          ELSE IF( C3.EQ.'TRI' ) THEN
228:             IF( SNAME ) THEN
229:                NB = 64
230:             ELSE
231:                NB = 64
232:             END IF
233:          END IF
234:       ELSE IF( C2.EQ.'PO' ) THEN
235:          IF( C3.EQ.'TRF' ) THEN
236:             IF( SNAME ) THEN
237:                NB = 64
238:             ELSE
239:                NB = 64
240:             END IF
241:          END IF
242:       ELSE IF( C2.EQ.'SY' ) THEN
243:          IF( C3.EQ.'TRF' ) THEN
244:             IF( SNAME ) THEN
245:                NB = 64
246:             ELSE
247:                NB = 64
248:             END IF
249:          ELSE IF( SNAME .AND. C3.EQ.'TRD' ) THEN
250:             NB = 32
251:          ELSE IF( SNAME .AND. C3.EQ.'GST' ) THEN
252:             NB = 64
253:          END IF
254:       ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN
255:          IF( C3.EQ.'TRF' ) THEN
256:             NB = 64
257:          ELSE IF( C3.EQ.'TRD' ) THEN
258:             NB = 32
259:          ELSE IF( C3.EQ.'GST' ) THEN
260:             NB = 64
261:          END IF
262:       ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN
263:          IF( C3( 1: 1 ).EQ.'G' ) THEN
264:             IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
265:      $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
266:      $           THEN
267:                NB = 32
268:             END IF
269:          ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN
270:             IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
271:      $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
272:      $           THEN
273:                NB = 32
274:             END IF
275:          END IF
276:       ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN
277:          IF( C3( 1: 1 ).EQ.'G' ) THEN
278:             IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
279:      $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
280:      $           THEN
281:                NB = 32
282:             END IF
283:          ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN
284:             IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
285:      $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
286:      $           THEN
287:                NB = 32
288:             END IF
289:          END IF
290:       ELSE IF( C2.EQ.'GB' ) THEN
291:          IF( C3.EQ.'TRF' ) THEN
292:             IF( SNAME ) THEN
293:                IF( N4.LE.64 ) THEN
294:                   NB = 1
295:                ELSE
296:                   NB = 32
297:                END IF
298:             ELSE
299:                IF( N4.LE.64 ) THEN
300:                   NB = 1
301:                ELSE
302:                   NB = 32
303:                END IF
304:             END IF
305:          END IF
306:       ELSE IF( C2.EQ.'PB' ) THEN
307:          IF( C3.EQ.'TRF' ) THEN
308:             IF( SNAME ) THEN
309:                IF( N2.LE.64 ) THEN
310:                   NB = 1
311:                ELSE
312:                   NB = 32
313:                END IF
314:             ELSE
315:                IF( N2.LE.64 ) THEN
316:                   NB = 1
317:                ELSE
318:                   NB = 32
319:                END IF
320:             END IF
321:          END IF
322:       ELSE IF( C2.EQ.'TR' ) THEN
323:          IF( C3.EQ.'TRI' ) THEN
324:             IF( SNAME ) THEN
325:                NB = 64
326:             ELSE
327:                NB = 64
328:             END IF
329:          END IF
330:       ELSE IF( C2.EQ.'LA' ) THEN
331:          IF( C3.EQ.'UUM' ) THEN
332:             IF( SNAME ) THEN
333:                NB = 64
334:             ELSE
335:                NB = 64
336:             END IF
337:          END IF
338:       ELSE IF( SNAME .AND. C2.EQ.'ST' ) THEN
339:          IF( C3.EQ.'EBZ' ) THEN
340:             NB = 1
341:          END IF
342:       END IF
343:       PLASMA_ILAENV = NB
344:       RETURN
345: *
346:    60 CONTINUE
347: *
348: *     ISPEC = 2:  minimum block size
349: *
350:       NBMIN = 2
351:       IF( C2.EQ.'GE' ) THEN
352:          IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. C3.EQ.
353:      $       'QLF' ) THEN
354:             IF( SNAME ) THEN
355:                NBMIN = 2
356:             ELSE
357:                NBMIN = 2
358:             END IF
359:          ELSE IF( C3.EQ.'HRD' ) THEN
360:             IF( SNAME ) THEN
361:                NBMIN = 2
362:             ELSE
363:                NBMIN = 2
364:             END IF
365:          ELSE IF( C3.EQ.'BRD' ) THEN
366:             IF( SNAME ) THEN
367:                NBMIN = 2
368:             ELSE
369:                NBMIN = 2
370:             END IF
371:          ELSE IF( C3.EQ.'TRI' ) THEN
372:             IF( SNAME ) THEN
373:                NBMIN = 2
374:             ELSE
375:                NBMIN = 2
376:             END IF
377:          END IF
378:       ELSE IF( C2.EQ.'SY' ) THEN
379:          IF( C3.EQ.'TRF' ) THEN
380:             IF( SNAME ) THEN
381:                NBMIN = 8
382:             ELSE
383:                NBMIN = 8
384:             END IF
385:          ELSE IF( SNAME .AND. C3.EQ.'TRD' ) THEN
386:             NBMIN = 2
387:          END IF
388:       ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN
389:          IF( C3.EQ.'TRD' ) THEN
390:             NBMIN = 2
391:          END IF
392:       ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN
393:          IF( C3( 1: 1 ).EQ.'G' ) THEN
394:             IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
395:      $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
396:      $           THEN
397:                NBMIN = 2
398:             END IF
399:          ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN
400:             IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
401:      $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
402:      $           THEN
403:                NBMIN = 2
404:             END IF
405:          END IF
406:       ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN
407:          IF( C3( 1: 1 ).EQ.'G' ) THEN
408:             IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
409:      $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
410:      $           THEN
411:                NBMIN = 2
412:             END IF
413:          ELSE IF( C3( 1: 1 ).EQ.'M' ) THEN
414:             IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
415:      $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
416:      $           THEN
417:                NBMIN = 2
418:             END IF
419:          END IF
420:       END IF
421:       PLASMA_ILAENV = NBMIN
422:       RETURN
423: *
424:    70 CONTINUE
425: *
426: *     ISPEC = 3:  crossover point
427: *
428:       NX = 0
429:       IF( C2.EQ.'GE' ) THEN
430:          IF( C3.EQ.'QRF' .OR. C3.EQ.'RQF' .OR. C3.EQ.'LQF' .OR. C3.EQ.
431:      $       'QLF' ) THEN
432:             IF( SNAME ) THEN
433:                NX = 128
434:             ELSE
435:                NX = 128
436:             END IF
437:          ELSE IF( C3.EQ.'HRD' ) THEN
438:             IF( SNAME ) THEN
439:                NX = 128
440:             ELSE
441:                NX = 128
442:             END IF
443:          ELSE IF( C3.EQ.'BRD' ) THEN
444:             IF( SNAME ) THEN
445:                NX = 128
446:             ELSE
447:                NX = 128
448:             END IF
449:          END IF
450:       ELSE IF( C2.EQ.'SY' ) THEN
451:          IF( SNAME .AND. C3.EQ.'TRD' ) THEN
452:             NX = 32
453:          END IF
454:       ELSE IF( CNAME .AND. C2.EQ.'HE' ) THEN
455:          IF( C3.EQ.'TRD' ) THEN
456:             NX = 32
457:          END IF
458:       ELSE IF( SNAME .AND. C2.EQ.'OR' ) THEN
459:          IF( C3( 1: 1 ).EQ.'G' ) THEN
460:             IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
461:      $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
462:      $           THEN
463:                NX = 128
464:             END IF
465:          END IF
466:       ELSE IF( CNAME .AND. C2.EQ.'UN' ) THEN
467:          IF( C3( 1: 1 ).EQ.'G' ) THEN
468:             IF( C4.EQ.'QR' .OR. C4.EQ.'RQ' .OR. C4.EQ.'LQ' .OR. C4.EQ.
469:      $          'QL' .OR. C4.EQ.'HR' .OR. C4.EQ.'TR' .OR. C4.EQ.'BR' )
470:      $           THEN
471:                NX = 128
472:             END IF
473:          END IF
474:       END IF
475:       PLASMA_ILAENV = NX
476:       RETURN
477: *
478:    80 CONTINUE
479: *
480: *     ISPEC = 4:  number of shifts (used by xHSEQR)
481: *
482:       PLASMA_ILAENV = 6
483:       RETURN
484: *
485:    90 CONTINUE
486: *
487: *     ISPEC = 5:  minimum column dimension (not used)
488: *
489:       PLASMA_ILAENV = 2
490:       RETURN
491: *
492:   100 CONTINUE
493: *
494: *     ISPEC = 6:  crossover point for SVD (used by xGELSS and xGESVD)
495: *
496:       PLASMA_ILAENV = INT( REAL( MIN( N1, N2 ) )*1.6E0 )
497:       RETURN
498: *
499:   110 CONTINUE
500: *
501: *     ISPEC = 7:  number of processors (not used)
502: *
503:       PLASMA_ILAENV = 1
504:       RETURN
505: *
506:   120 CONTINUE
507: *
508: *     ISPEC = 8:  crossover point for multishift (used by xHSEQR)
509: *
510:       PLASMA_ILAENV = 50
511:       RETURN
512: *
513:   130 CONTINUE
514: *
515: *     ISPEC = 9:  maximum size of the subproblems at the bottom of the
516: *                 computation tree in the divide-and-conquer algorithm
517: *                 (used by xGELSD and xGESDD)
518: *
519:       PLASMA_ILAENV = 25
520:       RETURN
521: *
522:   140 CONTINUE
523: *
524: *     ISPEC = 10: ieee NaN arithmetic can be trusted not to trap
525: *
526: *     PLASMA_ILAENV = 0
527:       PLASMA_ILAENV = 1
528:       IF( PLASMA_ILAENV.EQ.1 ) THEN
529:          PLASMA_ILAENV = IEEECK( 1, 0.0, 1.0 )
530:       END IF
531:       RETURN
532: *
533:   150 CONTINUE
534: *
535: *     ISPEC = 11: infinity arithmetic can be trusted not to trap
536: *
537: *     PLASMA_ILAENV = 0
538:       PLASMA_ILAENV = 1
539:       IF( PLASMA_ILAENV.EQ.1 ) THEN
540:          PLASMA_ILAENV = IEEECK( 0, 0.0, 1.0 )
541:       END IF
542:       RETURN
543: *
544:   160 CONTINUE
545: *
546: *     12 <= ISPEC <= 16: xHSEQR or one of its subroutines. 
547: *
548:       PLASMA_ILAENV = IPARMQ( ISPEC, NAME, OPTS, N1, N2, N3, N4 )
549:       RETURN
550: *
551: *     End of PLASMA_ILAENV
552: *
553:       END
554: