2013-02-26 3 views
0

Я пытаюсь решить ax = b с итерацией jacobi, мой серийный код работает отлично, но версия MPI даже не запускается. Может кто-нибудь мне помочь?Якоби Итерация в Фортране и MPI

Серийное

program jacobis 

implicit none 

integer, parameter :: n=10 
integer :: i,j,k,ni,s,seed 
double precision :: tol,t1,t2,sig 
double precision, dimension(0:n-1,0:n-1) :: A 
double precision, dimension(0:n-1) :: B, x, xb, buff 

ni=1000 

seed=time() 
call srand(seed) 

do i=0, n-1 
    do j=0, n-1 
    A(i,j)=rand(0) 
    B(i)=rand(0) 
    end do 
end do 

do i = 0, n-1 
A(i,i) = sum(A(i,:)) + 1 
enddo 

!do i=0,n-1 
!A(i,i)=4 
!end do 

print *, "a", A 
print *, "b", B 

x=B 
call cpu_time(t1) 
do k=1,ni 
xb=x 
do i=0,n-1 
    s=0 
    do j=0,n-1 
    if (j/=i) then 
     s=s+A(i,j)*xb(j) 
     endif 
    end do 
    x(i)=(B(i)-s)/A(i,i) 

    sig=(x(i)-xb(i))*(x(i)-xb(i)) 
    tol=tol+sig 
    tol=sqrt(tol) 
end do 


print *, "x", x 

!print *, "tol=", tol 

print *, "iter =",k 

if (tol<1.000001) EXIT 
if (k==(ni-1)) then 
    print *, "Numero Maximo de Iteracoes" 
    EXIT 
endif 
end do 

call cpu_time(t2) 
print *, "t=",t2-t1 


end 

MPI версия

program jacobis 

use mpi 
implicit none 

integer, parameter :: n=2 
integer :: i_local,i_global,j,k,ni,s,m 
double precision :: tol,t,t2,sig 
double precision, dimension(:,:), ALLOCATABLE :: A_local 
double precision, dimension(:), ALLOCATABLE :: B_local, x_local, x_temp1,x_temp2,x_old,x_new, buff 
INTEGER, DIMENSION (MPI_STATUS_SIZE) :: STATUS 
integer :: rank,procs,tag,ierror 


CALL MPI_INIT(ierror) 
CALL MPI_COMM_RANK(MPI_COMM_WORLD,rank,ierror) 
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,procs,ierror) 

ni=100 
m=n/procs 

ALLOCATE (A_local(0:n-1,0:n-1)) 
ALLOCATE (B_local(0:m-1)) 
ALLOCATE (x_temp1(0:m-1)) 
ALLOCATE (x_temp2(0:m-1)) 

A_local=0 
B_local=2 

do i_global=0,n-1 
A_local(i_global,i_global)=2 
end do 

CALL MPI_ALLGATHER(B_local, m, MPI_DOUBLE, x_temp1, m, MPI_DOUBLE, MPI_COMM_WORLD,ierror) 

x_new=x_temp1 
x_old=x_temp2 

print *, "a", A_local 
print *, "b", B_local 


t=mpi_wtime() 
do k=1,ni 
x_old=x_new 
do i_local=0,m-1 
    i_global=i_local+rank*m 
    !x_local(i_local)=b_local(i_local) 
    s=0 
    do j=0,n-1 
    if (j/=i_local) then 
     s=s+A_local(i_local,j)*x_old(j) 
     endif 
    end do 
    x_local(i_local)=(B_local(i_local)-s)/A_local(i_local,i_global) 

end do 
CALL MPI_ALLGATHER(x_local,m, MPI_DOUBLE, x_new, m, MPI_DOUBLE, MPI_COMM_WORLD,ierror) 

do i_global=0,n-1 
    sig=(x_new(i_global)-x_old(i_global))*(x_new(i_global)-x_old(i_global)) 
    tol=tol+sig 
    tol=sqrt(tol) 
end do 

print *, "x", x_local 

print *, "tol=", tol 

print *, "iter =",k 

if (tol<1.000001) EXIT 
if (k==(ni-1)) then 
    print *, "Numero Maximo de Iteracoes" 
    EXIT 
endif 
end do 

t2=mpi_wtime()-t; 
print *, "t=",t2 

CALL MPI_FINALIZE(ierror) 
end 

кто может указать на то, что я делаю не так? Это проблема индекса? Пожалуйста, мне действительно нужно решить это сегодня, или я убью курс. Я потратил бесчисленные часы на это и не могу заставить его работать.

ОК, вы были правы! Теперь у меня ошибка сегментации, но я не могу ее найти! заменили код на новую версию

+0

У вас все еще есть выделенные массивы на LHS выражений присваивания. Какой компилятор вы используете? Скомпилируйте флаги '-O0 -g -C', чтобы получить сообщения об ошибках с большим количеством подсказок о том, что не так. Поскольку это назначение класса, мы не можем отлаживать ваш код, но можем давать только подсказки о том, что не так и как действовать. Удачи. – milancurcic

ответ

0

Я решил проблему, теперь она правильно вычисляет итерацию, проверенную серийной программой, используя ту же матрицу. Это была проблема распределения и индекса. Благодаря предыдущему ответу, было очень полезно.

program jacobis 

use mpi 
implicit none 

integer, parameter :: n=1000 
integer :: i_local,i_global,j,k,ni,s,m,seed 
double precision :: tol,t,t2,sig 
double precision, dimension(:,:), ALLOCATABLE :: A_local 
double precision, dimension(:), ALLOCATABLE :: B_local, x_local, x_temp1,x_old,x_new, buff 
INTEGER, DIMENSION (MPI_STATUS_SIZE) :: STATUS 
integer :: rank,procs,tag,ierror 


CALL MPI_INIT(ierror) 
CALL MPI_COMM_RANK(MPI_COMM_WORLD,rank,ierror) 
CALL MPI_COMM_SIZE(MPI_COMM_WORLD,procs,ierror) 

ni=1000 
m=n/procs 

ALLOCATE (A_local(0:n-1,0:n-1)) 
ALLOCATE (B_local(0:n-1)) 
ALLOCATE (x_local(0:n-1)) 
ALLOCATE (x_temp1(0:n-1)) 
ALLOCATE (x_new(0:n-1)) 

!A_local=23 
!B_local=47 

seed=time() 
call srand(seed) 

do k=0, n-1 
do j=0, n-1 
    A_local(k,j)=rand(0) 
    B_local(k)=rand(0) 
end do 
end do 

do i_global = 0, m-1 
A_local(i_global,i_global) = sum(A_local(i_global,:)) + n 
enddo 

CALL MPI_ALLGATHER(B_local, m, MPI_DOUBLE, x_temp1, m, MPI_DOUBLE, MPI_COMM_WORLD,ierror) 

x_new=x_temp1 

print *, "a", A_local 
print *, "b", B_local 


t=mpi_wtime() 
do k=1,ni 
x_old=x_new 
do i_local=0,m-1 
    i_global=i_local+rank*m 
    !x_local(i_local)=b_local(i_local) 
    s=0 
    do j=0,n-1 
    if (j/=i_local) then 
     s=s+A_local(i_local,j)*x_old(j) 
     endif 
    end do 
    x_local(i_local)=(B_local(i_local)-s)/A_local(i_local,i_global) 
end do 
CALL MPI_ALLGATHER(x_local,m, MPI_DOUBLE, x_new, m, MPI_DOUBLE, MPI_COMM_WORLD,ierror) 
do j=0,n-1 
    sig=(x_new(j)-x_old(j))*(x_new(j)-x_old(j)) 
    tol=tol+sig 
    tol=sqrt(tol) 
end do 

print *, "x", x_local 

print *, "tol=", tol 

print *, "iter =",k 

if (tol<1.01) EXIT 
if (k==(ni-1)) then 
    print *, "Numero Maximo de Iteracoes" 
    EXIT 
endif 
end do 

t2=mpi_wtime()-t; 
print *, "t=",t2 

CALL MPI_FINALIZE(ierror) 
end 
+0

Рад, что вы решили свою проблему. Обратите внимание, что вы можете нажать на галочку, чтобы принять ответ как правильный. – milancurcic

+1

Подумайте о нажатии галочки на ответ от @ IRO-bot, который помог вам решить проблему (а не ваше собственное решение, основанное на его предложении). – bcumming

2

В вашей программе есть несколько проблем, которые я вижу. Сообщение об ошибке, что вы включили указует нераспределенный буфер приема в этом вызове:

CALL MPI_ALLGATHER(B_local, m, MPI_DOUBLE, x_temp1, m, MPI_DOUBLE, MPI_COMM_WORLD) 

массива x_temp1, буфер приема, должно быть выделено перед использованием в этом контексте.

Фиксация этого приведет только к вам, и вы получите менее информативную ошибку сегментации. Будет полезно найти правильное использование для MPI_AllGather в вашей реализации MPI. Большинство подпрограмм MPI имеют целочисленный аргумент состояния ошибки в конце:

MPI_ALLGATHER(SENDBUF, SENDCOUNT, SENDTYPE, RECVBUF, RECVCOUNT, 
     RECVTYPE, COMM, IERROR) 
    <type> SENDBUF (*), RECVBUF (*) 
    INTEGER SENDCOUNT, SENDTYPE, RECVCOUNT, RECVTYPE, COMM, 
    INTEGER IERROR 

Это должно заставить вас идти с вашим заданием. Обязательно выделите все используемые вами allocatable массивы и используйте соответствующую документацию для вашего руководства по реализации MPI и компилятора.

0

У вашей программы серьезная проблема, и возможно, вы ошибаетесь. Переменная s объявляется как целое, а ей назначаются нецелые значения. Обновите его как двойную точность, чтобы получить правильные результаты. (Отправлено для тех, кто когда-либо копировал этот код)

Смежные вопросы