      PROGRAM GLUPOTKA     
c     GLUPOTKA BO GLUPI PROBLEM
c     TYLKO DO OBJASNIENIA JAK DZIALA
c     PRYMITYWNY PROGRAMIK NA KLASTRZE

c     TU ZACZYNA SIE PROGRAM GLOWNY
c     NIE WOLNO W NIM  DEKLAOWAC WYMIARÓW PRZY POMOCY ZMIENNYCH
c     ALE MOZNA TO ROBIC W PODPRPGRAMACH

      implicit none
      include 'mpif.h'
c     INFORMACJA, ZE WSZYSTKIE ZMIENNE BEDA DEKLAROWANE
c     INFORMACJA DLA KOMPILATORA, ZE BEDZIE UZYTY MPI
      integer ierr,size,rank,R,s,lp,bd
      real*8 Z
c     DEKLARACJE ZMIENNYCH
      
      call MPI_Init(ierr)
c     URUCHOMIENIE MPI      
      call MPI_Comm_Size(MPI_Comm_World,size,ierr)
c     SIZE LICZBA PROCESOROW (ZADEKLAROWANA W SKRYPCIE KOLEJKOWYM)      
      call MPI_Comm_Rank(MPI_Comm_World,rank,ierr)
c     RANK NUMER PROCESORA
c     UWAGA, TU WSZYSTKO NUMERUJE  SIE OD ZERA!
      
      lp=size
       s=rank
c     DLA UŁTWIENIA ZAPISU: lp=LICZBA "ZAMÓWIONYCH" PROCESORÓW
c     s=NUMER PROCESORA W KTÓRYM JEST AKTUALNIE TEN PROGRAM       
c     ZATEM s=0,1,2,....lp-1
      bd=MPI_Bsend_Overhead+1000
c     ZADEKLAROWANY WYMIAR BUFORA W BAJTACH      

c     CONTROL       
c      write(*,*)'size=',lp 
c      write(*,*)'rank=',s
c     JEŚLI SKASUJEMY DWA POWYŻSZE "c" TO W PLIKU wynik
c     WYPISZE SIĘ WARTOŚĆ lp I WARTÓŚĆ s, ORAZ KOMENTARZ 
c     PODANY MIĘDZY ' '

               
       
           
      open(unit=10,file='GLUPDATA')
      rewind(10)
      read(10,*) R
      close(10)
c     CZYTANIE Z DYSKU DANYCH
c     W PLIKU 'GLUPDATA' JEST JEDYNA DANA DO PROGRAMU: 
c     ICZBA CAŁKOWITA R 
     
      call GLUP(lp,s,R,bd,Z)
c     WOLANIE PODPROGRAMU LICZĄCEGO

      if(s.eq.0)then
      open(unit=20,file='Z')
      rewind(20)
      write(20,*)'GOTOWE R=',R,' Z=',Z
      endif
      close(20)
c     WYPISANIE WYNIKU NA DYSK DO PLIKU Z
c     WARTOŚCI ZMIENNEJ R I Z WRAZ Z KOMENTARZEM      

      call MPI_Finalize(ierr)
      
c     WYŁACZENIE MPI       
      stop 100
      end
c     KONIEC Z WYPISANIEM INFORMACJI '100' Z KAŻDEGO PROCESORA


      subroutine GLUP(lp,s,R,bd,Z)
c     ZADANIE GLUPOTKI POLEGA NA UTWORZENIU W KAŻDYM Z UŻYTYCH
c     PROCESORÓW SUMY ELEMENTÓW UTWORZONEGO TU ZBIORU X WYMIARU X(0:R):
c     X(0)=real(s)
c     X(1)=X(0)+real(1)   
c     X(2)=X(0)+real(2)
c     ITD. DO R      
c     I NASTĘNIE ZSUMOWANIE WYNIKÓW ZE WSZYSTKICH PROCESORÓW W PROCESORZE NR s=0 
c     
      implicit none
      include 'mpif.h'
      integer lp,s,bd,R,k,ierr

      real*8 BUFF,O,E,X,Y,Z
      dimension BUFF(bd),X(0:R)
      
c     CONTROL
c      write(*,*)'GLUP IN  s=',s


      O=real(0)
      E=real(1)
c     ZERO REAL
c     JEDYNKA REAL
c     NA WSZELKI WYPADEK      
      call MPI_Buffer_Attach(BUFF,bd,ierr)
c     PODŁĄCZENIE BUFORA (TU TEŻ TYLKO NA WSZELKI WYPADEK)
c     I NA POKAZ      
     
      do k=0,R,1
      X(k)=real(k)+real(s)
      enddo
c     TWORZENIE ZBIORU X O WYMIARZE 0:R 
c     X(0),X(1),...,X(R): R+1 ELEMENTOW
      Y=O
      do k=0,R,1
      Y=Y+X(k)
      enddo
c     SUMOWANIE ELEMENTÓW ZBIORU X 
c     WYNIK DLA PROCESORA NR s BĘDZIE W ZMIENNEJ Y
      
      call MPI_Reduce(Y,Z,1,MPI_Real8,MPI_sum,0,MPI_Comm_World,ierr)

c     TU ZOSTŁA UŻYTA KOMENDA MPI KTÓRA POWODUJE ZSUMOWANIE W PROCESORZE NR s=0
c     W ZMIENNEJ Z, WARTOŚCI ZMIENNYCH Y Z KAŻDEGO PROCESORA
c           
      call MPI_Buffer_Detach(BUFF,bd,ierr)

c     ODŁĄCZENIE BUFORA 
c     CONTROL
c      write(*,*)'GLUP OUT s=',s
      

c     WYJŚCIE Z PODPROGRAMU      
      return
      end