2016-11-15 5 views
0

У меня возникла проблема с отправкой и получением данных в цикле do. Проверьте код ниже:Как отправлять и получать данные в цикле

include 'mpif.h' 
    parameter (NRA = 4) 
    parameter (NCA = 4) 
    parameter (MASTER = 0) 
    parameter (FROM_MASTER = 1) 
    parameter (FROM_WORKER = 2) 

    integer numtasks,taskid,numworkers,source,dest,mtype, 
&   cols,avecol,extra, offset,i,j,k,ierr,rc 
    integer status(MPI_STATUS_SIZE) 
    real*8 a(NRA,NCA) 

    call MPI_INIT(ierr) 
    call MPI_COMM_RANK(MPI_COMM_WORLD, taskid, ierr) 
    call MPI_COMM_SIZE(MPI_COMM_WORLD, numtasks, ierr) 
    numworkers = numtasks-1 
    print *, 'task ID= ',taskid 
C *************************** master task ************************************* 
    if (taskid .eq. MASTER) then 
    if (numworkers .NE. 2) then 
    print *, 'Please use 3 processors' 
    print *,'Quitting...' 
    call MPI_ABORT(MPI_COMM_WORLD,rc,ierr) 
    endif 
C  Initialize A and B 
    do 30 i=1, NRA 
     do 30 j=1, NCA 
     a(i,j) = (i-1)+(j-1) 
30  continue 
C  Send matrix data to the worker tasks 
    avecol = NCA/numworkers 
    extra = mod(NCA,numworkers) 
    offset = 1 
    mtype = FROM_MASTER 
    do 50 dest=1, numworkers 
     if (dest .le. extra) then 
     cols = avecol + 1 
     else 
     cols = avecol 
     endif 
     write(*,*)' sending',cols,' cols to task',dest 
     call MPI_SEND(offset,1,MPI_INTEGER,dest,mtype, 
&     MPI_COMM_WORLD,ierr) 
     call MPI_SEND(cols,1,MPI_INTEGER,dest,mtype, 
&     MPI_COMM_WORLD,ierr) 
     call MPI_SEND(a(1,offset),cols*NRA,MPI_DOUBLE_PRECISION, 
&     dest,mtype,MPI_COMM_WORLD,ierr) 
     offset = offset + cols 
50  continue 
C  Receive results from worker tasks 
    mtype = FROM_WORKER 
    do 60 i=1, numworkers 
     source = i 
     call MPI_RECV(offset,1,MPI_INTEGER,source, 
&     mtype,MPI_COMM_WORLD,status,ierr) 
     call MPI_RECV(cols,1,MPI_INTEGER,source, 
&     mtype,MPI_COMM_WORLD,status,ierr) 
     call MPI_RECV(a(1,offset),cols*NRA,MPI_DOUBLE_PRECISION, 
&     source,mtype,MPI_COMM_WORLD,status,ierr) 
60  continue 
C  Print results 
    do 90 i=1, NRA 
     do 80 j = 1, NCA 
     write(*,70)a(i,j) 
70  format(2x,f8.2,$) 
80  continue 
     print *, ' ' 
90 continue 
    endif 
C *************************** worker task ************************************* 
    if (taskid > MASTER) then 
C  Receive matrix data from master task 
    mtype = FROM_MASTER 
    call MPI_RECV(offset,1,MPI_INTEGER,MASTER, 
&     mtype,MPI_COMM_WORLD,status,ierr) 
    call MPI_RECV(cols,1,MPI_INTEGER,MASTER, 
&     mtype,MPI_COMM_WORLD,status,ierr) 
    call MPI_RECV(a(1,offset),cols*NCA,MPI_DOUBLE_PRECISION,MASTER, 
&     mtype,MPI_COMM_WORLD,status,ierr) 
start0 = offset 
end0 = offset+cols-1 
C  Do matrix multiply 
    do t=1,5 
     do i=1, NRA 
     do j=start0,end0 
      a(i,j) = a(i,j)*t 
     enddo 
     enddo 
C  Send results back to master task 
    mtype = FROM_WORKER 
    call MPI_SEND(offset,1,MPI_INTEGER,MASTER,mtype, 
&     MPI_COMM_WORLD,ierr) 
    call MPI_SEND(cols,1,MPI_INTEGER,MASTER,mtype, 
&     MPI_COMM_WORLD,ierr) 
    call MPI_SEND(a(1,offset),cols*NCA,MPI_DOUBLE_PRECISION,MASTER, 
&     mtype,MPI_COMM_WORLD,ierr) 
enddo 
    endif 
    call MPI_FINALIZE(ierr) 
    end 

Я хочу напечатать матрицу a, каждый раз, когда на экране, который находится внутри сделать петлю. Когда я выполняю код, он печатается только один раз, т. Е. В первый раз цикла do (t = 1). Как изменить этот код, чтобы я мог получить матрицу a, распечатанную каждый раз на экране, как только она будет подсчитана.

+0

Добро пожаловать в Переполнение стека. Постарайтесь, чтобы ваш вопрос был кратким. Избегайте введения о себе и избегайте приветствия и благодарности заранее. Хорошо показать результаты программы и объяснить, что вы хотите получить. –

+0

@VladimirF matrix a is [0 1 2 3; 1 2 3 4; 2 3 4 5; ]. В цикле он умножается на 1 - 5. Я ожидаю результат 1 * a, 2 * a, ..5 * a матрицу, которая будет напечатана на экране. Но с настоящим только 1 * a печатается. –

ответ

0

У меня есть. Я должен поставить петлю в мастер, получая данные от ведомого. Измененный код.

include 'mpif.h' 

    parameter (NRA = 4) 
    parameter (NCA = 4) 
    parameter (MASTER = 0) 
    parameter (FROM_MASTER = 1) 
    parameter (FROM_WORKER = 2) 

    integer numtasks,taskid,numworkers,source,dest,mtype, 
&   cols,avecol,extra, offset,i,j,k,ierr,rc 
    integer status(MPI_STATUS_SIZE) 
    real*8 a(NRA,NCA) 

    call MPI_INIT(ierr) 
    call MPI_COMM_RANK(MPI_COMM_WORLD, taskid, ierr) 
    call MPI_COMM_SIZE(MPI_COMM_WORLD, numtasks, ierr) 
    numworkers = numtasks-1 
    print *, 'task ID= ',taskid 

    C *************************** master task ************************************* 
    if (taskid .eq. MASTER) then 
    if (numworkers .NE. 2) then 
    print *, 'Please use 3 processors' 
    print *,'Quitting...' 
    call MPI_ABORT(MPI_COMM_WORLD,rc,ierr) 
    endif 
    C  Initialize A and B 
    do 30 i=1, NRA 
     do 30 j=1, NCA 
     a(i,j) = (i-1)+(j-1) 
30  continue 

C  Send matrix data to the worker tasks 
    avecol = NCA/numworkers 
    extra = mod(NCA,numworkers) 
    offset = 1 
    mtype = FROM_MASTER 
    do 50 dest=1, numworkers 
     if (dest .le. extra) then 
     cols = avecol + 1 
     else 
     cols = avecol 
     endif 
     write(*,*)' sending',cols,' cols to task',dest 
     call MPI_SEND(offset,1,MPI_INTEGER,dest,mtype, 
&     MPI_COMM_WORLD,ierr) 
     call MPI_SEND(cols,1,MPI_INTEGER,dest,mtype, 
&     MPI_COMM_WORLD,ierr) 
     call MPI_SEND(a(1,offset),cols*NRA,MPI_DOUBLE_PRECISION, 
&     dest,mtype,MPI_COMM_WORLD,ierr) 
     offset = offset + cols 
50  continue 

C  Receive results from worker tasks 
    do t = 1,5 
    mtype = FROM_WORKER 
    do 60 i=1, numworkers 
     source = i 
     call MPI_RECV(offset,1,MPI_INTEGER,source, 
&     mtype,MPI_COMM_WORLD,status,ierr) 
     call MPI_RECV(cols,1,MPI_INTEGER,source, 
&     mtype,MPI_COMM_WORLD,status,ierr) 
     call MPI_RECV(a(1,offset),cols*NRA,MPI_DOUBLE_PRECISION, 
&     source,mtype,MPI_COMM_WORLD,status,ierr) 
60  continue 
C  Print results 
    do 90 i=1, NRA 
     do 80 j = 1, NCA 
     write(*,70)a(i,j) 
70  format(2x,f8.2,$) 
80  continue 
     print *, ' ' 
90 continue 
    end do 


    endif 

C *************************** worker task ************************************* 
    if (taskid > MASTER) then 
C  Receive matrix data from master task 
    mtype = FROM_MASTER 
    call MPI_RECV(offset,1,MPI_INTEGER,MASTER, 
&     mtype,MPI_COMM_WORLD,status,ierr) 
    call MPI_RECV(cols,1,MPI_INTEGER,MASTER, 
&     mtype,MPI_COMM_WORLD,status,ierr) 
    call MPI_RECV(a(1,offset),cols*NCA,MPI_DOUBLE_PRECISION,MASTER, 
&     mtype,MPI_COMM_WORLD,status,ierr) 
start0 = offset 
end0 = offset+cols-1 

C  Do matrix multiply 
    do t=1,5 
     do i=1, NRA 
     do j=start0,end0 
      a(i,j) = a(i,j)*t 
     enddo 
     enddo  
C  Send results back to master task 
    mtype = FROM_WORKER 
    call MPI_SEND(offset,1,MPI_INTEGER,MASTER,mtype, 
&     MPI_COMM_WORLD,ierr) 
    call MPI_SEND(cols,1,MPI_INTEGER,MASTER,mtype, 
&     MPI_COMM_WORLD,ierr) 
    call MPI_SEND(a(1,offset),cols*NCA,MPI_DOUBLE_PRECISION,MASTER, 
&     mtype,MPI_COMM_WORLD,ierr) 
enddo 
    endif 
    call MPI_FINALIZE(ierr) 
    end