'gfortran SIGABRT error: the zgesvd function from lapack

I am coding a fortran 90 subroutine that calls the lapack function zgesvd. Unfortunately I get this error:

    malloc(): corrupted top size
    Program received signal SIGABRT: Process abort signal.
    Backtrace for this error:
    #0  0x7f338321cd21 in ???
    #1  0x7f338321bef5 in ???
    #2  0x7f3382f0120f in ???
    #3  0x7f3382f0118b in ???
    #4  0x7f3382ee0858 in ???
    #5  0x7f3382f4b3ed in ???
    #6  0x7f3382f5347b in ???
    #7  0x7f3382f56839 in ???
    #8  0x7f3382f58418 in ???
    #9  0x560e60a94daf in ???
    #10  0x560e60a94b75 in ???
    #11  0x560e60a94bae in ???
    #12  0x7f3382ee20b2 in ???
    #13  0x560e60a9420d in ???
    #14  0xffffffffffffffff in ???
    Aborted (core dumped)

The minimal code containing the subroutine is written below. Since Lapack calls are rather elaborated, it has to be a bit lengthy to contain the details about every argument, I apologize for that:

module my_mod
    IMPLICIT NONE

    CONTAINS
    subroutine svd_gc(A,u,s,vt,info)
        integer, parameter :: pr = SELECTED_REAL_KIND(15,3)
        complex(pr), dimension (:,:), intent(in)  :: A
        integer :: M, N
        
        integer :: lda, ldu, ldvt

        real(pr), dimension (min(SIZE(A,1),SIZE(A,2))) :: s
        complex(pr), dimension (SIZE(A,1),SIZE(A,1)) :: u
        complex(pr), dimension (SIZE(A,2),SIZE(A,2)) :: vt
        integer lwork
        complex(pr), dimension (1) :: work1
        real, dimension (5*min(SIZE(A,1),SIZE(A,2))) :: rwork
        integer :: info
        complex(pr), allocatable, dimension(:) :: work2
        
        external zgesvd

        M = SIZE(A,1)
        N = SIZE(A,2)
        lda = M
        ldu = M
        ldvt = N

        ! initialization step
        call zgesvd('All', 'All', M, N, A, lda, s, u, ldu, vt, ldvt, work1, -1, rwork, info )
        lwork = min(1000, int( work1(1) ))
        allocate( work2(lwork) )

        call zgesvd('All', 'All', M, N, A, lda, s, u, ldu, vt, ldvt, work2, lwork, rwork, info )

    end subroutine svd_gc
end module my_mod

which is called here:

program main
    use my_mod

    implicit none
    
    integer, parameter :: pr = SELECTED_REAL_KIND(15,3)
    real(pr), dimension (5,3) :: MR, MI
    complex(pr), dimension (5,3) :: M

    complex(pr), dimension(5,5) :: u
    complex(pr), dimension(3,3) :: vt
    real(pr), dimension(3) :: s
    integer i, j, info
    
    call random_vec(5,3,MR) ! generates an array of real numbers
    call random_vec(5,3,MI)
    
    M = cmplx(MR,MI)
    
    call svd_gc(M,u,s,vt,info)

    do j=1,3
        print '("---------")'
        print*,s(j)
        
        do i=1,3
            print*,vt(i,j)
        end do
        
        print '(" ")'
    end do

end program main

and I compile with gfortran... to finally run the produced file

Unfortunately this call returns a SIGABRT error, so I found a working example of zgesvd call and I took that one from Intel website: https://www.intel.com/content/www/us/en/develop/documentation/onemkl-lapack-examples/top/least-squares-and-eigenvalue-problems/singular-value-decomposition/gesvd-function/zgesvd-example/zgesvd-example-fortran.html

basically you dont need work2, you set the size of work1 to 1000, and you call:

    call zgesvd('All', 'All', M, N, A, lda, s, u, ldu, vt, ldvt, work1, -1, rwork, info )
    lwork = min(1000, int( work1(1) ))

    call zgesvd('All', 'All', M, N, A, lda, s, u, ldu, vt, ldvt, work1, lwork, rwork, info )

ok it works thank you Intel!

HOWEVER now if I dare using the 'allocate' command in any code that calls my zgesvd subroutine (svd_gc), then I get again a SIGABRT error. I am wondering, I am doing anything wrong ? or is the zgesvd function still not stable, maybe with some 'free()' calls misplaced or ill defined ? Do you see any correction or workaround ? maybe another Fortran library ?

I saw a very similar thread: gfortran error: zgesvd in lapack however, I am not using this kind of 'USV' type definition so I don't think it is related

Thanks in advance! Jee

edit: In this edit, I did change the "double" assignement 'REAL*8' to another one which I hope is more clean. Also, I added the minimal code for the main program that calls the subroutine !



Solution 1:[1]

Ok I got the error thanks to Ian Bush comment about the 'rwork' variable. 'rwork' has to be double precision as it is stated in the prototype here: http://www.netlib.org/lapack/explore-html/d3/da8/group__complex16_g_esing_gad6f0c85f3cca2968e1ef901d2b6014ee.html

Thus, replacing: real, dimension (5*min(SIZE(A,1),SIZE(A,2))) :: rwork
by: real(pr), dimension (5*min(SIZE(A,1),SIZE(A,2))) :: rwork
seems to solve the issue. Thank you for constructive comments and critics, it helped to improve !

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jee