|
@@ -1,6 +1,8 @@
|
|
program PCMRH
|
|
program PCMRH
|
|
!***************************************************************
|
|
!***************************************************************
|
|
! Parallel CMRH program with MPI
|
|
! Parallel CMRH program with MPI
|
|
|
|
+!
|
|
|
|
+! Created by S. Duminil sep. 2012
|
|
!***************************************************************
|
|
!***************************************************************
|
|
use mpi
|
|
use mpi
|
|
external SSWAP,DCOPY,DSCAL,DGEMV,DSWAP
|
|
external SSWAP,DCOPY,DSCAL,DGEMV,DSWAP
|
|
@@ -36,7 +38,6 @@ call MPI_COMM_RANK(MPI_COMM_WORLD,rang,code)
|
|
call MPI_COMM_SIZE(MPI_COMM_WORLD,Nprocs,code)
|
|
call MPI_COMM_SIZE(MPI_COMM_WORLD,Nprocs,code)
|
|
call MPI_BARRIER(MPI_COMM_WORLD,code)
|
|
call MPI_BARRIER(MPI_COMM_WORLD,code)
|
|
|
|
|
|
-
|
|
|
|
call itime(timearray) ! Get the current time
|
|
call itime(timearray) ! Get the current time
|
|
i = rand ( timearray(1)+timearray(2)+timearray(3) )
|
|
i = rand ( timearray(1)+timearray(2)+timearray(3) )
|
|
|
|
|
|
@@ -91,8 +92,6 @@ endif
|
|
call MPI_BCAST(solchoice,1,MPI_INTEGER,0,MPI_COMM_WORLD,code)
|
|
call MPI_BCAST(solchoice,1,MPI_INTEGER,0,MPI_COMM_WORLD,code)
|
|
call solution(AL,workl,sol,nl,n,solchoice)
|
|
call solution(AL,workl,sol,nl,n,solchoice)
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
call MPI_ALLGATHER(workl,nl,MPI_DOUBLE_PRECISION,b,nl,MPI_DOUBLE_PRECISION,MPI_COMM_WORLD,code)
|
|
call MPI_ALLGATHER(workl,nl,MPI_DOUBLE_PRECISION,b,nl,MPI_DOUBLE_PRECISION,MPI_COMM_WORLD,code)
|
|
|
|
|
|
!********************************************
|
|
!********************************************
|
|
@@ -132,32 +131,32 @@ D_inv = 1.d0/beta
|
|
! First permutation
|
|
! First permutation
|
|
!********************************************
|
|
!********************************************
|
|
if (indice .ne.1) then
|
|
if (indice .ne.1) then
|
|
-call dswap(1,b(indice),1,b(1),1)
|
|
|
|
-call dswap(nl,AL(1,indice),1,AL(1,1),1)
|
|
|
|
-call position(indice,nl,inl,inlp)
|
|
|
|
-if (inl==0) then
|
|
|
|
-if (rang==inl)then
|
|
|
|
-call dswap(n,AL(inlp,1),nl,AL(1,1),nl)
|
|
|
|
-end if
|
|
|
|
-else
|
|
|
|
-if (rang==inl) then
|
|
|
|
-call dcopy(n,AL(inlp,1),nl,temp,1)
|
|
|
|
-end if
|
|
|
|
-call MPI_BCAST(temp,n,MPI_DOUBLE_PRECISION,inl,MPI_COMM_WORLD,code)
|
|
|
|
-if (rang==0)then
|
|
|
|
-call dcopy(n,AL(1,1),nl,temp2,1)
|
|
|
|
-end if
|
|
|
|
-call MPI_BCAST(temp2,n,MPI_DOUBLE_PRECISION,0,MPI_COMM_WORLD,code)
|
|
|
|
-if (rang==inl)then
|
|
|
|
-call dcopy(n,temp2,1,AL(inlp,1),nl)
|
|
|
|
-end if
|
|
|
|
-if (rang==0)then
|
|
|
|
-call dcopy(n,temp,1,AL(1,1),nl)
|
|
|
|
-end if
|
|
|
|
-end if
|
|
|
|
-if (rang==0)then
|
|
|
|
-call sswap(1,p(indice),1,p(1),1)
|
|
|
|
-end if
|
|
|
|
|
|
+ call dswap(1,b(indice),1,b(1),1)
|
|
|
|
+ call dswap(nl,AL(1,indice),1,AL(1,1),1)
|
|
|
|
+ call position(indice,nl,inl,inlp)
|
|
|
|
+ if (inl==0) then
|
|
|
|
+ if (rang==inl)then
|
|
|
|
+ call dswap(n,AL(inlp,1),nl,AL(1,1),nl)
|
|
|
|
+ end if
|
|
|
|
+ else
|
|
|
|
+ if (rang==inl) then
|
|
|
|
+ call dcopy(n,AL(inlp,1),nl,temp,1)
|
|
|
|
+ end if
|
|
|
|
+ call MPI_BCAST(temp,n,MPI_DOUBLE_PRECISION,inl,MPI_COMM_WORLD,code)
|
|
|
|
+ if (rang==0)then
|
|
|
|
+ call dcopy(n,AL(1,1),nl,temp2,1)
|
|
|
|
+ end if
|
|
|
|
+ call MPI_BCAST(temp2,n,MPI_DOUBLE_PRECISION,0,MPI_COMM_WORLD,code)
|
|
|
|
+ if (rang==inl)then
|
|
|
|
+ call dcopy(n,temp2,1,AL(inlp,1),nl)
|
|
|
|
+ end if
|
|
|
|
+ if (rang==0)then
|
|
|
|
+ call dcopy(n,temp,1,AL(1,1),nl)
|
|
|
|
+ end if
|
|
|
|
+ end if
|
|
|
|
+ if (rang==0)then
|
|
|
|
+ call sswap(1,p(indice),1,p(1),1)
|
|
|
|
+ end if
|
|
end if
|
|
end if
|
|
|
|
|
|
!********************************************
|
|
!********************************************
|
|
@@ -225,14 +224,14 @@ do while((dnorm.gt.tol).and.(k.lt.n))
|
|
end if
|
|
end if
|
|
end if
|
|
end if
|
|
|
|
|
|
- !********************************************
|
|
|
|
- ! j Loop
|
|
|
|
- !********************************************
|
|
|
|
|
|
+!********************************************
|
|
|
|
+! j Loop
|
|
|
|
+!********************************************
|
|
do j=1,k
|
|
do j=1,k
|
|
- !********************************************
|
|
|
|
- ! A(j,k)=workl(j)
|
|
|
|
- ! workl(j)=0
|
|
|
|
- !********************************************
|
|
|
|
|
|
+!********************************************
|
|
|
|
+! A(j,k)=workl(j)
|
|
|
|
+! workl(j)=0
|
|
|
|
+!********************************************
|
|
call position(j,nl,knl,knlp)
|
|
call position(j,nl,knl,knlp)
|
|
if (rang==knl) then
|
|
if (rang==knl) then
|
|
AL(knlp,k)=workl(knlp)
|
|
AL(knlp,k)=workl(knlp)
|
|
@@ -240,9 +239,9 @@ do while((dnorm.gt.tol).and.(k.lt.n))
|
|
alpha=-AL(knlp,k)
|
|
alpha=-AL(knlp,k)
|
|
end if
|
|
end if
|
|
call MPI_BCAST(alpha,1,MPI_DOUBLE_PRECISION,knl,MPI_COMM_WORLD,code)
|
|
call MPI_BCAST(alpha,1,MPI_DOUBLE_PRECISION,knl,MPI_COMM_WORLD,code)
|
|
- !********************************************
|
|
|
|
- ! workl=workl - alpha A(:,j)
|
|
|
|
- !********************************************
|
|
|
|
|
|
+!********************************************
|
|
|
|
+! workl=workl - alpha A(:,j)
|
|
|
|
+!********************************************
|
|
call position(j+1,nl,knl,knlp)
|
|
call position(j+1,nl,knl,knlp)
|
|
if (rang >knl)then
|
|
if (rang >knl)then
|
|
call daxpy(nl,alpha,AL(1,j),1,workl,1)
|
|
call daxpy(nl,alpha,AL(1,j),1,workl,1)
|
|
@@ -251,19 +250,19 @@ do while((dnorm.gt.tol).and.(k.lt.n))
|
|
call daxpy(nl-knlp+1,alpha,AL(knlp,j),1,workl(knlp),1)
|
|
call daxpy(nl-knlp+1,alpha,AL(knlp,j),1,workl(knlp),1)
|
|
end if
|
|
end if
|
|
end do
|
|
end do
|
|
- !********************************************
|
|
|
|
- ! End j Loop
|
|
|
|
- !********************************************
|
|
|
|
|
|
+!********************************************
|
|
|
|
+! End j Loop
|
|
|
|
+!********************************************
|
|
if (k.lt.n)then
|
|
if (k.lt.n)then
|
|
call MPI_ALLGATHER(workl,nl,MPI_DOUBLE_PRECISION,b,nl,MPI_DOUBLE_PRECISION,MPI_COMM_WORLD,code)
|
|
call MPI_ALLGATHER(workl,nl,MPI_DOUBLE_PRECISION,b,nl,MPI_DOUBLE_PRECISION,MPI_COMM_WORLD,code)
|
|
- !********************************************
|
|
|
|
- ! Search indice i_0
|
|
|
|
- !********************************************
|
|
|
|
|
|
+!********************************************
|
|
|
|
+! Search indice i_0
|
|
|
|
+!********************************************
|
|
indice=k+idamax(n_k,b(k1),1)
|
|
indice=k+idamax(n_k,b(k1),1)
|
|
H_k1=b(indice)
|
|
H_k1=b(indice)
|
|
- !********************************************
|
|
|
|
- ! Permutation
|
|
|
|
- !********************************************
|
|
|
|
|
|
+!********************************************
|
|
|
|
+! Permutation
|
|
|
|
+!********************************************
|
|
if (indice.ne.k1) then
|
|
if (indice.ne.k1) then
|
|
if (rang==0) then
|
|
if (rang==0) then
|
|
call sswap(1,p(indice),1,p(k1),1)
|
|
call sswap(1,p(indice),1,p(k1),1)
|
|
@@ -294,13 +293,13 @@ do while((dnorm.gt.tol).and.(k.lt.n))
|
|
end if
|
|
end if
|
|
end if
|
|
end if
|
|
end if
|
|
end if
|
|
- !********************************************
|
|
|
|
- ! End Permutation
|
|
|
|
- !********************************************
|
|
|
|
|
|
+!********************************************
|
|
|
|
+! End Permutation
|
|
|
|
+!********************************************
|
|
if (H_k1.ne.0.d0)then
|
|
if (H_k1.ne.0.d0)then
|
|
- !********************************************
|
|
|
|
- ! b=b/(b)_(i_0)
|
|
|
|
- !********************************************
|
|
|
|
|
|
+!********************************************
|
|
|
|
+! b=b/(b)_(i_0)
|
|
|
|
+!********************************************
|
|
D_inv=1.d0/H_k1
|
|
D_inv=1.d0/H_k1
|
|
! call dcopy(n,work,1,b,1)
|
|
! call dcopy(n,work,1,b,1)
|
|
call dscal(n,D_inv,b,1)
|
|
call dscal(n,D_inv,b,1)
|
|
@@ -309,9 +308,9 @@ do while((dnorm.gt.tol).and.(k.lt.n))
|
|
H_k1=0.d0
|
|
H_k1=0.d0
|
|
call dscal(n,0.d0,b,1)
|
|
call dscal(n,0.d0,b,1)
|
|
end if
|
|
end if
|
|
- !********************************************
|
|
|
|
- ! Application of Givens rotations
|
|
|
|
- !********************************************
|
|
|
|
|
|
+!********************************************
|
|
|
|
+! Application of Givens rotations
|
|
|
|
+!********************************************
|
|
if (k.gt.1)then
|
|
if (k.gt.1)then
|
|
do i=2,k
|
|
do i=2,k
|
|
call position(i-1,nl,knl,knlp)
|
|
call position(i-1,nl,knl,knlp)
|
|
@@ -357,9 +356,9 @@ do while((dnorm.gt.tol).and.(k.lt.n))
|
|
AL(knlp,k)=c(k)*btemp+s(k)*H_k1
|
|
AL(knlp,k)=c(k)*btemp+s(k)*H_k1
|
|
end if
|
|
end if
|
|
end if
|
|
end if
|
|
- !********************************************
|
|
|
|
- ! End Givens rotations
|
|
|
|
- !********************************************
|
|
|
|
|
|
+!********************************************
|
|
|
|
+! End Givens rotations
|
|
|
|
+!********************************************
|
|
end do
|
|
end do
|
|
|
|
|
|
!********************************************
|
|
!********************************************
|
|
@@ -534,23 +533,23 @@ end subroutine matrice
|
|
! Solution Choice
|
|
! Solution Choice
|
|
!********************************************
|
|
!********************************************
|
|
subroutine solution(A,b,sol,nl,n,solchoice)
|
|
subroutine solution(A,b,sol,nl,n,solchoice)
|
|
-integer ::n,i,nl,solchoice
|
|
|
|
-real(kind=8),dimension(n,n) ::A
|
|
|
|
-real(kind=8),dimension(n) ::sol
|
|
|
|
-real(kind=8),dimension(nl) ::b
|
|
|
|
-real ::rand
|
|
|
|
-do i=1,n
|
|
|
|
-if (solchoice==1) then
|
|
|
|
-sol(i)=1.d0
|
|
|
|
-end if
|
|
|
|
-if (solchoice==2) then
|
|
|
|
-sol(i)=dble(n-i+1)
|
|
|
|
-end if
|
|
|
|
-if (solchoice==3)then
|
|
|
|
-sol(i)=rand(0)
|
|
|
|
-end if
|
|
|
|
-end do
|
|
|
|
-call dgemv('N',nl,n,1.d0,A,nl,sol,1,0.d0,b,1)
|
|
|
|
|
|
+ integer ::n,i,nl,solchoice
|
|
|
|
+ real(kind=8),dimension(n,n) ::A
|
|
|
|
+ real(kind=8),dimension(n) ::sol
|
|
|
|
+ real(kind=8),dimension(nl) ::b
|
|
|
|
+ real ::rand
|
|
|
|
+ do i=1,n
|
|
|
|
+ if (solchoice==1) then
|
|
|
|
+ sol(i)=1.d0
|
|
|
|
+ end if
|
|
|
|
+ if (solchoice==2) then
|
|
|
|
+ sol(i)=dble(n-i+1)
|
|
|
|
+ end if
|
|
|
|
+ if (solchoice==3)then
|
|
|
|
+ sol(i)=rand(0)
|
|
|
|
+ end if
|
|
|
|
+ end do
|
|
|
|
+ call dgemv('N',nl,n,1.d0,A,nl,sol,1,0.d0,b,1)
|
|
end subroutine solution
|
|
end subroutine solution
|
|
|
|
|
|
|
|
|
|
@@ -562,15 +561,3 @@ integer :: k,nl,knl,knlp
|
|
knl=(k-1)/nl
|
|
knl=(k-1)/nl
|
|
knlp=k-knl*nl
|
|
knlp=k-knl*nl
|
|
end subroutine position
|
|
end subroutine position
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|