Skip to content

Instantly share code, notes, and snippets.

@grisuthedragon
Created October 20, 2017 08:51
Show Gist options
  • Save grisuthedragon/9847dce71b3dd129753d51a9d5db496f to your computer and use it in GitHub Desktop.
Save grisuthedragon/9847dce71b3dd129753d51a9d5db496f to your computer and use it in GitHub Desktop.
PROGRAM CRASH_DTRMV
IMPLICIT NONE
INTEGER N
PARAMETER( N = 64)
DOUBLE PRECISION, ALLOCATABLE :: A(:,:), X(:)
INTEGER J, LDA, INCX
LDA = N
INCX = 1
ALLOCATE(A(LDA, N), X(N))
CALL RANDOM_NUMBER(A)
CALL RANDOM_NUMBER(X)
DO J = 1, N
CALL DTRMV_COMPARE("Upper", "Nontrans", "Nounit", J, A, LDA, X, INCX)
END DO
DEALLOCATE (A, X)
END PROGRAM
SUBROUTINE DTRMV_COMPARE(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
IMPLICIT NONE
INTEGER INCX,LDA,N
CHARACTER DIAG,TRANS,UPLO
DOUBLE PRECISION A(LDA,*),X(*)
DOUBLE PRECISION, ALLOCATABLE :: X1(:), X2(:), X3(:), X4(:)
INTEGER J, ERRORS
DOUBLE PRECISION RES
ALLOCATE(X1(1 + ( N - 1 )*abs( INCX ) ), X2(1 + ( N - 1 )*abs( INCX ) ))
ALLOCATE(X3(N), X4(N))
CALL DCOPY(N, X, INCX, X1, INCX)
CALL DCOPY(N, X, INCX, X2, INCX)
CALL DTRMV(UPLO,TRANS,DIAG,N,A,LDA,X1,INCX)
CALL NLDTRMV(UPLO,TRANS,DIAG,N,A,LDA,X2,INCX)
CALL DCOPY(N, X1, INCX, X3, 1)
CALL DCOPY(N, X2, INCX, X4, 1)
ERRORS = 0
RES = 0
DO J = 1, N
RES = MAX (RES, DABS(X3(J)-X4(J)))
IF ( DABS(X3(J)-X4(J)) .GT. 1.0D-14) THEN
ERRORS = ERRORS + 1
! WRITE(*,'( I5 , 2X, D20.10 , 2X, D20.10, 2X, D20.10)') J, X3(J), X4(J), DABS(X3(J)-X4(J))
END IF
END DO
IF ( ERRORS .GT. 0 ) THEN
WRITE(*, '("Wrong RESULT : DTRMV(", A1, ",", A1, "," , A1, ",", I5, ", A,", I5, ", X, ", I5, ") MAXERR = ", D20.15)') &
& UPLO, TRANS, DIAG, N, LDA, INCX, RES
ELSE
WRITE(*, '("Correct RESULT: DTRMV(", A1, ",", A1, "," , A1, ",", I5, ", A,", I5, ", X, ", I5, ") MAXERR = ", D20.15)') &
& UPLO, TRANS, DIAG, N, LDA, INCX, RES
END IF
CALL DCOPY(N, X2, INCX, X, INCX)
DEALLOCATE (X1,X2,X3,X4)
END SUBROUTINE DTRMV_COMPARE
! Netlib DTRMV
SUBROUTINE NLDTRMV(UPLO,TRANS,DIAG,N,A,LDA,X,INCX)
!
! -- Reference BLAS level2 routine (version 3.7.0) --
! -- Reference BLAS is a software package provided by Univ. of Tennesse
! -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd
! December 2016
!
! .. Scalar Arguments ..
INTEGER INCX,LDA,N
CHARACTER DIAG,TRANS,UPLO
! ..
! .. Array Arguments ..
DOUBLE PRECISION A(LDA,*),X(*)
! ..
!
! =====================================================================
!
! .. Parameters ..
DOUBLE PRECISION ZERO
PARAMETER (ZERO=0.0D+0)
! ..
! .. Local Scalars ..
DOUBLE PRECISION TEMP
INTEGER I,INFO,IX,J,JX,KX
LOGICAL NOUNIT
! ..
! .. External Functions ..
LOGICAL LSAME
EXTERNAL LSAME
! ..
! .. External Subroutines ..
EXTERNAL XERBLA
! ..
! .. Intrinsic Functions ..
INTRINSIC MAX
! ..
!
! Test the input parameters.
!
INFO = 0
IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN
INFO = 1
ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND. &
& .NOT.LSAME(TRANS,'C')) THEN
INFO = 2
ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN
INFO = 3
ELSE IF (N.LT.0) THEN
INFO = 4
ELSE IF (LDA.LT.MAX(1,N)) THEN
INFO = 6
ELSE IF (INCX.EQ.0) THEN
INFO = 8
END IF
IF (INFO.NE.0) THEN
CALL XERBLA('DTRMV ',INFO)
RETURN
END IF
!
! Quick return if possible.
!
IF (N.EQ.0) RETURN
!
NOUNIT = LSAME(DIAG,'N')
!
! Set up the start point in X if the increment is not unity. This
! will be ( N - 1 )*INCX too small for descending loops.
!
IF (INCX.LE.0) THEN
KX = 1 - (N-1)*INCX
ELSE IF (INCX.NE.1) THEN
KX = 1
END IF
!
! Start the operations. In this version the elements of A are
! accessed sequentially with one pass through A.
!
IF (LSAME(TRANS,'N')) THEN
!
! Form x := A*x.
!
IF (LSAME(UPLO,'U')) THEN
IF (INCX.EQ.1) THEN
DO 20 J = 1,N
IF (X(J).NE.ZERO) THEN
TEMP = X(J)
DO 10 I = 1,J - 1
X(I) = X(I) + TEMP*A(I,J)
10 CONTINUE
IF (NOUNIT) X(J) = X(J)*A(J,J)
END IF
20 CONTINUE
ELSE
JX = KX
DO 40 J = 1,N
IF (X(JX).NE.ZERO) THEN
TEMP = X(JX)
IX = KX
DO 30 I = 1,J - 1
X(IX) = X(IX) + TEMP*A(I,J)
IX = IX + INCX
30 CONTINUE
IF (NOUNIT) X(JX) = X(JX)*A(J,J)
END IF
JX = JX + INCX
40 CONTINUE
END IF
ELSE
IF (INCX.EQ.1) THEN
DO 60 J = N,1,-1
IF (X(J).NE.ZERO) THEN
TEMP = X(J)
DO 50 I = N,J + 1,-1
X(I) = X(I) + TEMP*A(I,J)
50 CONTINUE
IF (NOUNIT) X(J) = X(J)*A(J,J)
END IF
60 CONTINUE
ELSE
KX = KX + (N-1)*INCX
JX = KX
DO 80 J = N,1,-1
IF (X(JX).NE.ZERO) THEN
TEMP = X(JX)
IX = KX
DO 70 I = N,J + 1,-1
X(IX) = X(IX) + TEMP*A(I,J)
IX = IX - INCX
70 CONTINUE
IF (NOUNIT) X(JX) = X(JX)*A(J,J)
END IF
JX = JX - INCX
80 CONTINUE
END IF
END IF
ELSE
!
! Form x := A**T*x.
!
IF (LSAME(UPLO,'U')) THEN
IF (INCX.EQ.1) THEN
DO 100 J = N,1,-1
TEMP = X(J)
IF (NOUNIT) TEMP = TEMP*A(J,J)
DO 90 I = J - 1,1,-1
TEMP = TEMP + A(I,J)*X(I)
90 CONTINUE
X(J) = TEMP
100 CONTINUE
ELSE
JX = KX + (N-1)*INCX
DO 120 J = N,1,-1
TEMP = X(JX)
IX = JX
IF (NOUNIT) TEMP = TEMP*A(J,J)
DO 110 I = J - 1,1,-1
IX = IX - INCX
TEMP = TEMP + A(I,J)*X(IX)
110 CONTINUE
X(JX) = TEMP
JX = JX - INCX
120 CONTINUE
END IF
ELSE
IF (INCX.EQ.1) THEN
DO 140 J = 1,N
TEMP = X(J)
IF (NOUNIT) TEMP = TEMP*A(J,J)
DO 130 I = J + 1,N
TEMP = TEMP + A(I,J)*X(I)
130 CONTINUE
X(J) = TEMP
140 CONTINUE
ELSE
JX = KX
DO 160 J = 1,N
TEMP = X(JX)
IX = JX
IF (NOUNIT) TEMP = TEMP*A(J,J)
DO 150 I = J + 1,N
IX = IX + INCX
TEMP = TEMP + A(I,J)*X(IX)
150 CONTINUE
X(JX) = TEMP
JX = JX + INCX
160 CONTINUE
END IF
END IF
END IF
!
RETURN
!
! End of DTRMV .
!
END
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment