@@ -66,6 +66,7 @@ PROGRAM PCLLTDRIVER
66
66
*
67
67
* =====================================================================
68
68
*
69
+ use,intrinsic :: ieee_arithmetic
69
70
* .. Parameters ..
70
71
INTEGER BLOCK_CYCLIC_2D, CSRC_, CTXT_, DLEN_, DTYPE_,
71
72
$ LLD_, MB_, M_, NB_, N_, RSRC_
@@ -137,6 +138,15 @@ PROGRAM PCLLTDRIVER
137
138
* ..
138
139
* .. Executable Statements ..
139
140
*
141
+ * Take command-line arguments if requested
142
+ CHARACTER * 80 arg
143
+ INTEGER numArgs, count
144
+ LOGICAL :: help_flag = .FALSE.
145
+ LOGICAL :: EX_FLAG = .FALSE. , RES_FLAG = .FALSE.
146
+ INTEGER :: INF_PERCENT = 0
147
+ INTEGER :: NAN_PERCENT = 0
148
+ DOUBLE PRECISION :: X
149
+ *
140
150
* Get starting information
141
151
*
142
152
#ifdef DYNAMIC_WORK_MEM_ALLOC
@@ -150,6 +160,35 @@ PROGRAM PCLLTDRIVER
150
160
$ NTESTS, NGRIDS, PVAL, NTESTS, QVAL, NTESTS,
151
161
$ THRESH, EST, MEM, IAM, NPROCS )
152
162
CHECK = ( THRESH.GE. 0.0E+0 )
163
+
164
+ * Get the number of command-line arguments
165
+ numArgs = command_argument_count()
166
+
167
+ * Process command-line arguments
168
+ do count = 1 , numArgs, 2
169
+ call get_command_argument(count, arg)
170
+ select case (arg)
171
+ case (" -h" , " --help" )
172
+ help_flag = .true.
173
+ exit
174
+ case (" -inf" )
175
+ call get_command_argument(count + 1 , arg)
176
+ read (arg, * ) INF_PERCENT
177
+ IF (INF_PERCENT .GT. 0 ) THEN
178
+ EX_FLAG = .TRUE.
179
+ END IF
180
+ case (" -nan" )
181
+ call get_command_argument(count + 1 , arg)
182
+ read (arg, * ) NAN_PERCENT
183
+ IF (NAN_PERCENT .GT. 0 ) THEN
184
+ EX_FLAG = .TRUE.
185
+ END IF
186
+ case default
187
+ print * , " Invalid option: " , arg
188
+ help_flag = .true.
189
+ exit
190
+ end select
191
+ end do
153
192
*
154
193
* Print headings
155
194
*
@@ -288,11 +327,20 @@ PROGRAM PCLLTDRIVER
288
327
GO TO 30
289
328
END IF
290
329
#else
291
- * If N < 0 in LLT.dat file then DESCINIT API sets IERR( 1 ) = -2
292
- IF ( N.LT. 0 .AND. IERR( 1 ).EQ. - 2 ) THEN
293
- * If DESCINIT is returning correct error code then
294
- * do nothing
330
+ IF (N .LT. 0 .AND. (IERR(1 ) .EQ. - 2 .OR.
331
+ $ IERR(1 ) .EQ. - 4 .OR. IERR(1 ) .EQ. - 8 .OR.
332
+ $ IERR(1 ) .EQ. - 3 .OR. IERR(1 ) .EQ. - 12 )) THEN
333
+ * DESCINIT returns the correct error code,
334
+ * -2, -3 incase of invalid M and N
335
+ * -4, -8 or -12 incase of incorrect grid info
336
+ * MAIN API can be validated.
337
+ * Do NOTHING
295
338
WRITE ( NOUT, FMT = 9984 ) ' N'
339
+ * disable extreme value case when N < 0
340
+ EX_FLAG = .FALSE.
341
+ ELSE IF (N .EQ. 0 ) THEN
342
+ * disable extreme value case when M < 0
343
+ EX_FLAG = .FALSE.
296
344
ELSE IF ( IERR( 1 ).LT. 0 ) THEN
297
345
IF ( IAM.EQ. 0 )
298
346
$ WRITE ( NOUT, FMT = 9997 ) ' descriptor'
@@ -370,7 +418,7 @@ PROGRAM PCLLTDRIVER
370
418
*
371
419
* Calculate inf-norm of A for residual error-checking
372
420
*
373
- IF ( CHECK ) THEN
421
+ IF ( CHECK .AND. N .GT. 0 ) THEN
374
422
CALL PCFILLPAD( ICTXT, NP, NQ, MEM( IPA- IPREPAD ),
375
423
$ DESCA( LLD_ ), IPREPAD, IPOSTPAD,
376
424
$ PADVAL )
@@ -397,7 +445,7 @@ PROGRAM PCLLTDRIVER
397
445
$ DESCA( LLD_ ), DESCA( RSRC_ ),
398
446
$ DESCA( CSRC_ ), IASEED, 0 , NP, 0 , NQ,
399
447
$ MYROW, MYCOL, NPROW, NPCOL )
400
- IF ( CHECK )
448
+ IF ( CHECK .AND. N .GT. 0 )
401
449
$ CALL PCFILLPAD( ICTXT, NP, NQ,
402
450
$ MEM( IPA0- IPREPAD ), DESCA( LLD_ ),
403
451
$ IPREPAD, IPOSTPAD, PADVAL )
@@ -419,27 +467,29 @@ PROGRAM PCLLTDRIVER
419
467
$ WRITE ( NOUT, FMT = * ) ' PCPOTRF INFO=' , INFO
420
468
* If N < 0 in LLT.dat file then PCPOTRF API sets INFO = -2
421
469
IF (N.LT. 0 .AND. INFO.EQ. - 2 ) THEN
422
- * If PCPOTRF is returning correct error
423
- * code we need to pass this case
470
+ * If PDPOTRF is returning correct error code, do nothing
424
471
WRITE ( NOUT, FMT = 9983 ) ' PCPOTRF'
425
- KPASS = KPASS + 1
472
+ ELSE IF (INFO.GT. 0 .AND. EX_FLAG) THEN
473
+ WRITE (* ,* ) ' PCPOTRF INFO=' , INFO
474
+ * do nothing, skip residual calculation
475
+ * Pass this case in INF/NAN residual calculation
426
476
ELSE
427
477
* For other error code we will mark test case as fail
428
478
KFAIL = KFAIL + 1
479
+ RCOND = ZERO
480
+ GO TO 60
429
481
END IF
430
- RCOND = ZERO
431
- GO TO 60
432
482
ELSE IF (N.EQ. 0 ) THEN
433
483
* If N = 0 this is the case of
434
484
* early return from ScaLAPACK API.
435
485
* If there is safe exit from API we need to pass this case
436
486
WRITE ( NOUT, FMT = 9982 ) ' PCPOTRF'
437
- KPASS = KPASS + 1
438
487
RCOND = ZERO
439
- GO TO 60
440
488
END IF
441
489
*
442
- IF ( CHECK ) THEN
490
+ *
491
+ IF ( CHECK .AND. .NOT. (EX_FLAG) .AND. INFO.EQ. 0 .AND.
492
+ $ N .GT. 0 ) THEN
443
493
*
444
494
* Check for memory overwrite in LLt factorization
445
495
*
@@ -481,7 +531,7 @@ PROGRAM PCLLTDRIVER
481
531
GO TO 60
482
532
END IF
483
533
*
484
- IF ( CHECK ) THEN
534
+ IF ( CHECK .AND. .NOT. (EX_FLAG) .AND. INFO .EQ. 0 ) THEN
485
535
CALL PCFILLPAD( ICTXT, LWORK, 1 ,
486
536
$ MEM( IPW- IPREPAD ), LWORK,
487
537
$ IPREPAD, IPOSTPAD, PADVAL )
@@ -493,11 +543,15 @@ PROGRAM PCLLTDRIVER
493
543
*
494
544
* Compute condition number of the matrix
495
545
*
496
- CALL PCPOCON( UPLO, N, MEM( IPA ), 1 , 1 , DESCA,
546
+
547
+ IF (.NOT. (EX_FLAG) .AND. N.GT. 0 ) THEN
548
+ CALL PCPOCON( UPLO, N, MEM( IPA ), 1 , 1 , DESCA,
497
549
$ ANORM1, RCOND, MEM( IPW ), LWORK,
498
550
$ MEM( IPW2 ), LRWORK, INFO )
551
+ END IF
499
552
*
500
- IF ( CHECK ) THEN
553
+ IF ( CHECK .AND. .NOT. (EX_FLAG) .AND.
554
+ $ N .GT. 0 ) THEN
501
555
CALL PCCHEKPAD( ICTXT, ' PCPOCON' , NP, NQ,
502
556
$ MEM( IPA- IPREPAD ), DESCA( LLD_ ),
503
557
$ IPREPAD, IPOSTPAD, PADVAL )
@@ -529,8 +583,9 @@ PROGRAM PCLLTDRIVER
529
583
$ IERR( 1 ) )
530
584
* If NRHS < 0 in LLT.dat file then
531
585
* DESCINIT API sets IERR( 1 ) = -3
532
- IF (NRHS.LT. 0 .AND. IERR( 1 ).EQ. - 3 ) THEN
533
- * If DESCINIT is returning correct error code then
586
+ IF (NRHS.LT. 0 .AND. IERR( 1 ).EQ. - 3 .OR.
587
+ $ IERR(1 ) .EQ. - 12 ) THEN
588
+ * If DESCINIT is returns correct error code
534
589
* do nothing
535
590
WRITE ( NOUT, FMT = 9984 ) ' NRHS'
536
591
END IF
@@ -598,7 +653,7 @@ PROGRAM PCLLTDRIVER
598
653
$ DESCB( CSRC_ ), IBSEED, 0 , NP, 0 ,
599
654
$ MYRHS, MYROW, MYCOL, NPROW, NPCOL )
600
655
*
601
- IF ( CHECK )
656
+ IF ( CHECK .AND. INFO .EQ. 0 )
602
657
$ CALL PCFILLPAD( ICTXT, NP, MYRHS,
603
658
$ MEM( IPB- IPREPAD ),
604
659
$ DESCB( LLD_ ),
@@ -613,7 +668,8 @@ PROGRAM PCLLTDRIVER
613
668
$ MYRHS, MYROW, MYCOL, NPROW,
614
669
$ NPCOL )
615
670
*
616
- IF ( CHECK ) THEN
671
+ IF ( CHECK .AND. .NOT. (EX_FLAG) .AND.
672
+ $ INFO .EQ. 0 ) THEN
617
673
CALL PCFILLPAD( ICTXT, NP, MYRHS,
618
674
$ MEM( IPB0- IPREPAD ),
619
675
$ DESCB( LLD_ ), IPREPAD,
@@ -645,19 +701,24 @@ PROGRAM PCLLTDRIVER
645
701
$ WRITE ( NOUT, FMT = * ) ' PCPOTRS INFO=' , INFO
646
702
* If NRHS < 0 in LLT.dat file then
647
703
* PCPOTRS API sets INFO = -3
648
- IF ( NRHS.LT. 0 .AND. INFO.EQ. - 3 ) THEN
649
- * If PCPOTRS is returning correct error code then
704
+ IF ( NRHS.LT. 0 .AND. INFO.EQ. - 3 .OR.
705
+ $ (N.LT. 0 .AND. INFO.EQ. - 2 ) ) THEN
706
+ * If PDPOTRS is returning correct error code then
650
707
* we need to pass this case
651
708
WRITE ( NOUT, FMT = 9983 ) ' PCPOTRS'
652
- KPASS = KPASS + 1
709
+ ELSE IF ( INFO .GT. 0 .AND. EX_FLAG) THEN
710
+ WRITE (* ,* ) ' PCPOTRS INFO=' , INFO
711
+ * Do Nothing, Pass this case in residual calculation
653
712
ELSE
654
713
* For other error code we will mark test case as fail
655
714
KFAIL = KFAIL + 1
715
+ GO TO 60
656
716
END IF
657
- GO TO 60
658
717
END IF
659
-
660
- IF ( CHECK ) THEN
718
+ *
719
+ IF ( CHECK .AND. .NOT. (EX_FLAG) .AND.
720
+ $ INFO .EQ. 0 .AND. N .GT. 0 .AND.
721
+ $ NRHS .GT. 0 ) THEN
661
722
*
662
723
* check for memory overwrite
663
724
*
@@ -707,10 +768,64 @@ PROGRAM PCLLTDRIVER
707
768
KFAIL = KFAIL + 1
708
769
PASSED = ' FAILED'
709
770
END IF
771
+ ELSE
772
+ IF ( NRHS.LT. 0 .AND. INFO.EQ. - 3 .OR.
773
+ $ (N.LT. 0 .AND. INFO.EQ. - 2 ) ) THEN
774
+ * If PDGETRS is returning correct error code
775
+ * we need to pass this case
776
+ SRESID = SRESID - SRESID
777
+ KPASS = KPASS + 1
778
+ IF (NAN_PERCENT .GT. 0 .OR.
779
+ $ INF_PERCENT .GT. 0 ) THEN
780
+ * RESET EX-FLAG
781
+ EX_FLAG = .TRUE.
782
+ END IF
783
+ ELSE IF ( N .EQ. 0 .AND. INFO .EQ. 0 ) THEN
784
+ * If PDGETRS is returning correct error code
785
+ * we need to pass this case
786
+ SRESID = SRESID - SRESID
787
+ KPASS = KPASS + 1
788
+ IF (NAN_PERCENT .GT. 0 .OR.
789
+ $ INF_PERCENT .GT. 0 ) THEN
790
+ * RESET EX-FLAG
791
+ EX_FLAG = .TRUE.
792
+ END IF
793
+ * Extreme value validation check
794
+ ELSE IF ( EX_FLAG) THEN
795
+ * Check presence of INF/NAN in output
796
+ * Pass the case if present
797
+ DO IK = 0 , M
798
+ DO JK = 1 , N
799
+ X = MEM(IK* N + JK)
800
+ IF (isnan(X)) THEN
801
+ * NAN DETECTED
802
+ RES_FLAG = .TRUE.
803
+ EXIT
804
+ ELSE IF (.NOT. ieee_is_finite(
805
+ $ X)) THEN
806
+ * INFINITY DETECTED
807
+ RES_FLAG = .TRUE.
808
+ EXIT
809
+ END IF
810
+ END DO
811
+ IF (RES_FLAG) THEN
812
+ EXIT
813
+ END IF
814
+ END DO
815
+ IF (.NOT. (RES_FLAG)) THEN
816
+ KFAIL = KFAIL + 1
817
+ PASSED = ' FAILED'
710
818
ELSE
711
819
KPASS = KPASS + 1
820
+ PASSED = ' PASSED'
821
+ * RESET RESIDUAL FLAG
822
+ RES_FLAG = .FALSE.
823
+ END IF
824
+ ELSE
712
825
SRESID = SRESID - SRESID
826
+ KPASS = KPASS + 1
713
827
PASSED = ' BYPASS'
828
+ END IF
714
829
END IF
715
830
*
716
831
IF ( EST ) THEN
@@ -744,7 +859,8 @@ PROGRAM PCLLTDRIVER
744
859
GO TO 10
745
860
END IF
746
861
*
747
- IF ( CHECK ) THEN
862
+ IF ( CHECK .AND. .NOT. (EX_FLAG) .AND.
863
+ $ INFO .EQ. 0 ) THEN
748
864
CALL PCFILLPAD( ICTXT, LWORK, 1 ,
749
865
$ MEM( IPW- IPREPAD ),
750
866
$ LWORK, IPREPAD, IPOSTPAD,
@@ -759,17 +875,21 @@ PROGRAM PCLLTDRIVER
759
875
* Use iterative refinement to improve the
760
876
* computed solution
761
877
*
762
- CALL PCPORFS( UPLO, N, NRHS, MEM( IPA0 ),
878
+ IF (INFO .EQ. 0 .AND. .NOT. (EX_FLAG) ) THEN
879
+ CALL PCPORFS( UPLO, N, NRHS, MEM( IPA0 ),
763
880
$ 1 , 1 , DESCA, MEM( IPA ), 1 , 1 ,
764
881
$ DESCA, MEM( IPB0 ), 1 , 1 ,
765
882
$ DESCB, MEM( IPB ), 1 , 1 , DESCB,
766
883
$ MEM( IPFERR ), MEM( IPBERR ),
767
884
$ MEM( IPW ), LWORK, MEM( IPW2 ),
768
885
$ LRWORK, INFO )
886
+ END IF
769
887
*
770
888
* check for memory overwrite
771
889
*
772
- IF ( CHECK ) THEN
890
+ IF ( CHECK .AND. INFO .EQ. 0 .AND.
891
+ $ .NOT. (EX_FLAG) .AND.
892
+ $ N .GT. 0 .AND. NRHS .GT. 0 ) THEN
773
893
CALL PCCHEKPAD( ICTXT, ' PCPORFS' , NP,
774
894
$ NQ, MEM( IPA0- IPREPAD ),
775
895
$ DESCA( LLD_ ), IPREPAD,
@@ -896,7 +1016,8 @@ PROGRAM PCLLTDRIVER
896
1016
10 CONTINUE
897
1017
20 END DO
898
1018
*
899
- IF ( CHECK .AND. SRESID.GT. THRESH ) THEN
1019
+ IF ( CHECK .AND. SRESID.GT. THRESH .AND. INFO .EQ. 0 .AND.
1020
+ $ .NOT. (EX_FLAG)) THEN
900
1021
*
901
1022
* Compute FRESID = ||A - LL'|| / (||A|| * N * eps)
902
1023
*
@@ -977,7 +1098,7 @@ PROGRAM PCLLTDRIVER
977
1098
9987 FORMAT ( ' END OF TESTS.' )
978
1099
9986 FORMAT ( ' ||A - ' , A4, ' || / (||A|| * N * eps) = ' , G25.7 )
979
1100
9985 FORMAT ( ' ||Ax-b||/(||x||*||A||*eps*N) ' , F25.7 )
980
- 9984 FORMAT ( A , ' < 0 case detected. ' ,
1101
+ 9984 FORMAT ( A4 , ' < 0 case detected. ' ,
981
1102
$ ' Instead of driver file, we will handle this case from ' ,
982
1103
$ ' ScaLAPACK API.' )
983
1104
9983 FORMAT ( A, ' returned correct error code. Passing this case.' )
0 commit comments