Hi Thomas,

----- Mensaje original -----
> De: "Thomas Koenig" 
> Para: "Jorge D'Elia" , "Gfortran List" <fortran@gcc.gnu.org>
> CC: "Jorge D'Elia" 
> Enviado: MiƩrcoles, 29 de Septiembre 2021 3:02:46
> Asunto: Re: DGBSV: incorrect numerical results with -L/usr/lib64/atlas ?
>
> Hi Jorge,
> 
>> I do not know if this forum is the most appropriate, but as it based
>> using gfortran I will try to start here.
>> 
>> I usually build the ATLAS library in some beta version without any
>> numerical problem that I remember. In a circumstantial way, I have to
>> use the system ATLAS library and, today, I am getting some incorrect
>> numerical results with the DGBSV lapack fortran subroutine, which is
>> described below with a simple test.
>> 
>> Perhaps, I am not using the correct sintaxis in the interface, maybe
>> in the compiler flags or the link ones? Please, any ideas?
>> Thanks in advance.
> 
> I tried your code against the reference LAPACK and got the result below,
> which also has info=1 at the end.  There is no argument mismatch
> (at least) in the called routine, I checked that by including the
> refblas routine into the source.

Ok. Thanks for those checks.
 
> So, I don't know what's wrong.  Possibly something with the numerics,
> or a wrong size of an argument?  It would be possible to compile the
> reference LAPACK and BLAS with debugging and check with a debugger
> where the info flag is set.
> 
> If I may guess, it's probably an error in one of the array sizes -

Good catch! (see below).

> LAPACK is notorious that way.  I wish they would use modern 
> Fortran's array passing mechanism.

I agree. That update would be very welcome looking to the future.

> Best regards
> 
>         Thomas

Well. After a couple of coffees, it turns out that it 
was a false alarm because the end user wrongly used 
the lapack' subroutines. 

As often happens it was an oversight: in the test I forgot
to insert a call to some routine that converts the usual
representation of an array to the BLAS-General-Band Storage
format. Below I copy the corrected test and everything 
returned to normal. 

Sorry for the noise. Thus, atlas and gfortran work 
very well, as long as they are used correctly ...

Many thanks for your time in addressing this issue.


Best regards. 
Jorge.

!begin (fixed) test
! BLAS-general-band storage mode:
!   the storage mode packs the matrix elements by columns into
!   a two-dimensional array, such that each diagonal of the
!   matrix appears as a row in the packed array.
module m_interfase
  implicit none
  private
  public :: idp, iin, dgbsv, conversor_agb
  integer, parameter :: idp = kind (1.0d0)
  integer, parameter :: iin = kind (1)    
  !
  interface
    subroutine dgbsv (n, kl, ku, nrhs, ab, ldab, ipiv, b, ldb, info)
      integer           info, kl, ku, ldab, ldb, n, nrhs
      integer           ipiv (*)
      double precision  ab (ldab,*), b (ldb,*)
      external          dgbtrf, dgbtrs, xerbla
      intrinsic         max
    end subroutine dgbsv
  end interface
  !
contains
  !
  ! ................................................................
  ! A conversor from the general band matrix AAA (mm,nn) to
  ! the BLAS-general-band storage mode AGB (lda,nn) for dgbsv,
  ! where AGB has klo extra rows (i.e. lda = (ku + 1 + klo) + klo)
  ! needed for the dgbsv solution. Ref.
  !   https://www.ibm.com/docs/en/essl/
  !   /6.2?topic=representation-blas-general-band-storage-mode
  ! ................................................................
  subroutine conversor_agb (mm,nn,lda,kup,klo,aaa,agb)
    integer (iin), intent (in)  :: mm, nn, lda, kup, klo
    real    (idp), intent (in)  :: aaa (mm,nn)
    real    (idp), intent (out) :: agb (lda,nn)
    integer (iin) :: i, j, k, p
    agb = 0.0_idp
    do  j = 1, nn
      k = kup + 1 - j
      do  i = max (1,j-kup), min (mm,j+klo)
        p = klo + (k + i)
        agb (p,j) = aaa (i,j)
      end do
    end do
  end subroutine conversor_agb
  !
end module m_interfase
!
program extrouble
  use  m_interfase, only: iin, idp, dgbsv, conversor_agb
  implicit none
  !
  real (idp), parameter :: cero = 0.0_idp
  real (idp), parameter :: uno  = 1.0_idp
  real (idp), parameter :: dos  = 2.0_idp
  real (idp), parameter :: tres = 3.0_idp
  real (idp), parameter :: cuat = 4.0_idp
  real (idp), parameter :: cinc = 5.0_idp
  real (idp), parameter :: seis = 6.0_idp
  real (idp), parameter :: siet = 7.0_idp
  real (idp), parameter :: ocho = 8.0_idp
  real (idp), parameter :: nuev = 9.0_idp
  real (idp), dimension (9,9), parameter :: &
    ccc = reshape ( [ &
      uno,  dos, tres, cero, cero, cero, cero, cero, cero, & ! 1
      dos,  uno,  dos, tres, cero, cero, cero, cero, cero, & ! 2
     tres,  dos,  uno,  dos, tres, cero, cero, cero, cero, & ! 3
     cuat, tres,  dos,  uno,  dos, tres, cero, cero, cero, & ! 4
     cero, cuat, tres,  dos,  uno,  dos, tres, cero, cero, & ! 5
     cero, cero, cuat, tres,  dos,  uno,  dos, tres, cero, & ! 6
     cero, cero, cero, cuat, tres,  dos,  uno,  dos, tres, & ! 7
     cero, cero, cero, cero, cuat, tres,  dos,  uno,  dos, & ! 8
     cero, cero, cero, cero, cero, cuat, tres,  dos,  uno  & ! 9
     ], [9,9])
  !
  real (idp), dimension (9,3), parameter :: &
    vvv = reshape ( [ &
      uno,  uno,  uno,  uno,  uno,  uno,  uno,  uno,  uno, & ! 1
      uno, -uno,  uno, -uno,  uno, -uno,  uno, -uno,  uno, & ! 2
      uno,  dos, tres, cuat, cinc, seis, siet, ocho, nuev  & ! 3
      ], [9,3])
  !
  real    (idp), dimension (8,9) :: aaa
  real    (idp), dimension (9,3) :: bbb
  integer (iin), dimension (9)   :: ipiv
  integer (iin) :: mm, nn, klo, kup, nrhs, lda, ldb, info
  integer (iin) :: i
  !
  nn   = size (aaa,2)
  mm   = nn
  klo  = 2
  kup  = 3
  nrhs = size (bbb,2)
  lda  = 2 * klo + kup + 1
  ldb  = nn
  !
  call conversor_agb (mm,nn,lda,kup,klo,ccc,aaa)
  bbb  = vvv
  ipiv = 0
  !
  write (*,*)
  write (*,*)" dgbsv (General Band Side) test "
  write (*,*)
  write (*,*)" system matrix: aaa (lda,n) "
  do  i = 1, lda
  write (*,*) real (aaa (i,:))
  end do
  write (*,*)
  write (*,*)" source: bbb (ldb,nrhs) "
  do  i = 1, ldb
  write (*,*) real (bbb (i,:))
  end do
  write (*,*)" nn   = ", nn
  write (*,*)" klo  = ", klo
  write (*,*)" kup  = ", kup
  write (*,*)" nrhs = ", nrhs
  write (*,*)" lda  = ", lda
  write (*,*)" ldb  = ", ldb
  !           N  KL   KU   NRHS   A   LDA   IPIV  B    LDB  INFO)
  !           |   |    |    |     |    |    |     |      |     |
 !call dgbsv (9 , 2  , 3  , 3   , aaa, 8  , ipiv, bbb,   9, info)
  call dgbsv (nn, klo, kup, nrhs, aaa, lda, ipiv, bbb, ldb, info)
  !
  write (*,*)
  write (*,*)" output aaa: "
  do  i = 1, lda
  write (*,*) real (aaa (i,:))
  end do
  write (*,*)
  write (*,*)" output bbb: "
  do  i = 1, ldb
  write (*,*) real (bbb (i,:))
  end do 
  write (*,*)
  write (*,*)" output ipiv: ", ipiv
  write (*,*)
  write (*,*)" info = ", info
end program extrouble
!end fixed test

Reply via email to