------- Comment #2 from Herve dot Chapuis at tours dot inra dot fr  2006-03-14 
15:14 -------
Subject: Re:  internal compiler error

pinskia at gcc dot gnu dot org a écrit :
> ------- Comment #1 from pinskia at gcc dot gnu dot org  2006-03-14 14:59 
> -------
> Can you attach fspak90.f90 (if it is legal to do so)?
>
>
>   
I think (hope) it is legal to do so. These programs are free of use for 
research purpose.

module sparseop
! sparse matrix operations including fspak90
  use sparsem
  implicit none

   interface fspak90
      module procedure fspak90r8,fspak90r4
   end interface

! matrix by vector multiplication   
   interface mult
       module procedure mult_densem_vec,mult_hashm_vec,mult_ija_vec,&
                        mult_vec_densem,mult_vec_hashm,mult_vec_ija
   end interface

! matrix by scalar multiplication   
   interface multmatscal                
        module procedure mult_densem_scal, mult_hashm_scal,mult_ija_scal
   end interface    


  contains



subroutine fspak90r4(operation,ija,rs4,sol4,det,msglev,maxmem,rank,rs8,sol8)
! interface to fspak; most parameters above optional and memory
! allocation dynamic

  interface
    subroutine fspak(mode,n,ia,ja,a,sol,flag,io1,io2,memory,&
                 mem_needed,work,i1,i2,i3,i4,i5,i6,rank)
    use kinds
    integer :: mode,n,ia(1),ja(1), flag,io1,io2,memory,&
                 mem_needed,i1,i2,i3,i4,i5,i6,rank 
    real (r8) :: a(1),sol(1),work(1)                       
    end subroutine
  end interface  

  character (len=*)  :: operation
  type (sparse_ija):: ija
  real(r8),optional :: rs8(:),sol8(:),det
  real(r4),optional :: rs4(:),sol4(:)
  real (r8), allocatable:: sol(:)
 !optional parameters
  integer,optional::rank,msglev,maxmem
  integer :: msglev_o,maxmem_o,i
  integer,save :: rank_o,status=-1,last_n=0
        ! status = -1 (initial), 1 (ordering done), 2 (factorization done)
  integer,save :: memory=100        !initial memory, modified by later programs
  real (r8),save,pointer :: work(:)=>null()
  real , external:: second


  if (last_n /= ija%n) then
        status=min(status,0)     !redo everything if dimension changes
        last_n=ija%n
  endif
!
  if (.not. present(msglev)) then
        msglev_o=0   ! default message level = minimal
      else
        msglev_o=msglev
  endif
  if (.not. present(maxmem)) then
        maxmem_o=huge(maxmem)         ! infinite memory limit if maxmem missing
     else
        maxmem_o=maxmem
  endif
  select case (operation(1:3))
       case ('fac')             !factorization
            status=min(status,1)        !nullify factorization if done
            call do_fact
       case('sol')            !solution
            allocate(sol(ija%n))
            if (present(sol8) .and. present(rs8)) then
               ! sol=rs8
                do i = 1, ija%n 
                   sol(i) = rs8(i)
                enddo 
                call do_fact
                call run_fspak('solve')
                ! sol8=sol
                do i = 1, ija%n
                   sol8(i) = sol(i)
                enddo
            elseif (present(sol4) .and. present(rs4)) then
                !sol=rs4
                do i = 1, ija%n 
                   sol(i) = rs4(i)
                enddo 
                call do_fact
                call run_fspak('solve') 
                !sol4=sol
                do i = 1, ija%n
                   sol4(i) = sol(i)
                enddo
              else
                print*,'FSPAK90: optional parameter SOL or RS missing'
                stop
            endif
            deallocate(sol)
       case('inv')           !sparse inversion
            call do_fact
            call run_fspak('inverse')
            status=1            !factorization lost
       case('res')            !reset storage
            if (status > -1) deallocate(work)
            status=-1
            memory=100
       case('det')              !determinant
            if (.not. present(det)) then
                print*,'FSPAK90: optional parameter DET missing'
              else
                call do_fact
                call run_fspak('det')
             endif
       case('lde')             !log determinant
            if (.not. present(det)) then
                print*,'FSPAK90: optional parameter DET misiing'
              else
                call do_fact
                call run_fspak('ldet')
            endif
       case('sta')             !print statistics
            call run_fspak('statistics')
       case default
          print*,'FSPAK90 operation ',operation,' unknown'
  end select


  contains

 subroutine do_fact
 ! executes all stages of fspak so that the factorization is available

 if (status == -1) then                
    allocate(work(memory/2+1))  ! real(r8) needed as integer
    status=0
 endif

 if (status == 0) then
    call run_fspak('ordering')
    call run_fspak('symbolic_fact')
    status=1
 endif

 if (status == 1) then
    call run_fspak('numeric_fact')
    status=2
 endif
 end subroutine do_fact


 subroutine run_fspak(op)
 ! runs operation op of fspak, adding more memory if necessary
 character (len=*) :: op
 real(r8),pointer,save::work1(:)=>null()
 real(r8) :: sc(2)   !scratch
 integer :: mem_needed,i,flag

! print*,op
 do
   select case(op)
      case ('ordering')
            open(99,file='fspak90.ord')
            call fspak(10,ija%n,ija%ia,ija%ja,ija%a,sc,flag,6,99,memory,&
                 mem_needed,work,i,i,i,i,i,i,rank_o)
            close (99)
            if (msglev_o > 2) then
               print*,'FSPAK90: size=',ija%n,'  #nonzeroes=',ija%nel
            endif
            if (msglev_o > 1) print*,'ordering time =',second()
      case('symbolic_fact')
            call fspak(20,ija%n,ija%ia,ija%ja,ija%a,sc,flag,6,99,memory,&
                 mem_needed,work,i,i,i,i,i,i,rank_o)
            if (msglev_o > 1) print*,'symbolic factorization time=',second()
      case('numeric_fact')
            call fspak(40,ija%n,ija%ia,ija%ja,ija%a,sc,flag,6,99,memory,&
                    mem_needed,work,i,i,i,i,i,i,rank_o)
            if (msglev_o > 1) print*,'numerical factorization time=',second()
      case('solve')
            call fspak(50,ija%n,ija%ia,ija%ja,ija%a,sol,flag,6,99,memory,&
                    mem_needed,work,i,i,i,i,i,i,rank_o)
      case('det')
            call fspak(54,ija%n,ija%ia,ija%ja,ija%a,sc,flag,6,99,memory,&
                    mem_needed,work,i,i,i,i,i,i,rank_o)
            det=sc(1)
      case('ldet')
            call fspak(55,ija%n,ija%ia,ija%ja,ija%a,sc,flag,6,99,memory,&
                    mem_needed,work,i,i,i,i,i,i,rank_o)
            det=sc(1)
      case('inverse')
            call fspak(61,ija%n,ija%ia,ija%ja,ija%a,sc,flag,6,99,memory,&
                 mem_needed,work,i,i,i,i,i,i,rank_o)
             if (msglev_o >1) print*,'inversion time=',second()
      case('statistics')
            call fspak(80,ija%n,ija%ia,ija%ja,ija%a,sc,flag,6,99,memory,&
                    mem_needed,work,i,i,i,i,i,i,rank_o)
   end select
   if (flag == 0) then
          exit
      elseif (flag >= 4000000) then
        print*,'FSPAK: Zero or negative pivot for row ROW',&
            'during numerical factorization in row:',flag-4000000
        stop
     ! if memory insufficient, assign more
      elseif (flag > 100) then
        if (mem_needed > maxmem_o) then
            print*,'FSPAK90: memory needed:',mem_needed
            print*,'         maxmimum memory allowed:',maxmem
          else
            if (msglev_o>0) print*,'memory increased from:',memory,' to:',&
                                                          mem_needed
            allocate(work1(mem_needed/2+1))    !create new memory
            work1(1:memory/2+1)=work           !copy old data
            deallocate(work)           !release old memory
            work=>work1                !let work point to memory of work1
            memory=mem_needed
        endif
      else
        print*,'fspak: unknown error flag: ',flag
        stop
   endif
 enddo
 if (present(rank)) rank=rank_o

 end subroutine

end subroutine fspak90r4


!-------------------------------------------------------------------------
! Overloading of fspak90 so that it works with real*8 solutions and RHS
!-------------------------------------------------------------------------

subroutine fspak90r8(operation1,ija1,rs1,sol1) !,msglev1,maxmem1,rank1)
! overloaded fspak90 so that solutions and right hand sides can be 
! double precision without using optional parameters 

  character (len=*)  :: operation1
  type (sparse_ija):: ija1
  real(r8):: rs1(:),sol1(:)
 !optional parameters
 ! integer,optional::rank1,msglev1,maxmem1
  call fspak90r4(operation1,ija1,rs8=rs1,sol8=sol1)
end subroutine fspak90r8


!--------------------------------------
! Multiplication of matrix by vector
!--------------------------------------

function mult_densem_vec(A,y) result (z)
! z = A * y for A in densem format
type (densem)::A
real (r8)::y(a%n),z(a%n)
!
z=matmul(A%x,y) 
end function


function mult_vec_densem(yy,A) result (z)
! z = y' * A  for A in densem format
type (densem)::A
real (r8)::yy(a%n),z(a%n)
!
z=matmul(yy,A%x) 
end function


function mult_hashm_vec(A,y) result (z)
! z = A * y for A in sparse_hashm form.
type (sparse_hashm)::A
real (r8)::y(a%n ),z(a%n)
integer::i,j,k
!
 z=0
 do j=1,a%nel
   if (a%x(1,j) /=0) then
      i=a%x(1,j); k=a%x(2,j)
     if (i == k) z(i)=z(i)+a%x(3,j)*y(k)
     if (i < k)  then
        z(i)=z(i)+a%x(3,j)*y(k)
        z(k)=z(k)+a%x(3,j)*y(i)
     endif    
   endif
 end do
end function


 function mult_vec_hashm(yy,A) result (z)
! z = y' * A for A in sparse_hashm form.
type (sparse_hashm)::A
real (r8)::yy(a%n ),z(a%n)
integer::i,j,k
!
 z=0
 do j=1,a%nel
   if (a%x(1,j) /=0) then
     i=a%x(1,j); k=a%x(2,j)
     if (i == k) z(i)=z(i)+a%x(3,j)*yy(k)
     if (i < k)  then
        z(i)=z(i)+a%x(3,j)*yy(k)
        z(k)=z(k)+a%x(3,j)*yy(i)
     endif    
   endif
 end do
end function



function mult_ija_vec(A,y) result (z)
! z = A * y for A in sparse_ija form.
type (sparse_ija)::A
real (r8)::y(a%n),z(a%n)
integer::i,j,k
!
   z=0
   do i=1,a%n
     do j=a%ia(i),a%ia(i+1)-1
        k=a%ja(j)
        if (i == k) z(i)=z(i)+a%a(j)*y(k)
        if (i < k)  then
            z(i)=z(i)+a%a(j)*y(k)
            z(k)=z(k)+a%a(j)*y(i)
        endif    
     end do
  end do  
end function


function mult_vec_ija(yy,A) result (z)
! z = y' * A for A in sparse_ija form.
type (sparse_ija)::A
real (r8)::yy(a%n),z(a%n)
integer::i,j,k
!
   z=0
   do i=1,a%n
     do j=a%ia(i),a%ia(i+1)-1
        k=a%ja(j)
        if (i == k) z(i)=z(i)+a%a(j)*yy(k)
        if (i < k)  then
            z(i)=z(i)+a%a(j)*yy(k)
            z(k)=z(k)+a%a(j)*yy(i)
        endif    
     end do
  end do  
end function


! -----------------------------------
!  Multiplication of matrix by scalar
!-------------------------------------

subroutine mult_densem_scal(A,y)
! A = A * y for A in densem format
type (densem)::A
real (r8)::y
!
A%x=A%x*y  
end subroutine

subroutine mult_hashm_scal(A,y)
! A = A * y for A in sparse_hashm form.
type (sparse_hashm)::A
real (r8)::y
!
 A%x(3,:)=A%x(3,:)*y

end subroutine


subroutine mult_ija_scal(A,y)
! A = A * y for A in sparse_ija form.
type (sparse_ija)::A
real (r8)::y
!
   A%a=A%a*y

end subroutine

end module


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26681

Reply via email to