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