Newsgroups: comp.parallel.pvm
From: zuniga@sirius.cerfacs.fr (Juan Zuniga)
Subject: Report bug on pvm3.3.3
Organization: CERFACS, Toulouse, France
Date: 16 Aug 1994 11:39:40 +0200
Message-ID: <32q1gs$31i@sirius.cerfacs.fr>


        Just to learn about pvm I have make some small examples.
      One of this examples is getting me crazy since I don't 
      know why it doesn't work.

      The example makes the following: there is a master who 
      spawn a number of slaves ( the number must be a power of 2).
      Then the master broads to each slave a real number. 
      If the slave is even , send this value to the previous one
      and leaves pvm. If the slave is odd wait for the 
      value coming from next slave. This is done till there is 
      only one slave ( number 1) who sends final result to the
      master.

        When the number of slaves is 2, everything works
      if I remove debugging prints on the slave code. 
      If the number of slaves is 4 then the master is waiting
      for results forever regardless there is debugging prints
      or not on the code. I have tried both
      in a RS6K and SUN cluster. The version of pvm
      is 3.3.3. Can anybody explain me where I am doing wrong?


  This is the code for the master:

      program master
      include '/usr/local/pvm/include/fpvm3.h'
      parameter ( max_slaves = 32)
      integer mytid,tids(1:max_slaves)
      integer info, msgtype,nb_slaves,nit
      real one, slaves

      call pvmfmytid(mytid) 
      write(*,*)' How many slaves will you used (1-32)'  
      write(*,*)' Must be a power of 2'
      read(*,*)nb_slaves
      exponent = log(float(nb_slaves))/log(2.)
      nit = int(exponent)
      call pvmfspawn('slavep',PVMDEFAULT,'*',nb_slaves,tids,numt) 
c
c --- Send  data to slaves
c
      one = 1.
      call pvmfinitsend( PVMDEFAULT, info)
      call pvmfpack( INTEGER4, nb_slaves, 1, 1, info)
      call pvmfpack( INTEGER4, nit , 1, 1, info)
      call pvmfpack( INTEGER4, tids, nb_slaves, 1, info)
      call pvmfpack( REAL4, one, 1, 1, info)
      msgtype = 1
      call pvmfmcast( nb_slaves, tids, msgtype, info)
c
c -- Collect the result
c
      msgtype = 2
      call pvmfrecv(tids(1), msgtype, info)
      call pvmfunpack(REAL4, slaves, 1, 1, info)
      write(*,*)'Total is', one,' master and ',slaves,'slaves'

      call shutdown(nb_slaves,tids)
      call pvmfexit(info)
      stop
      end
      subroutine shutdown( nproc, tids )
      integer nproc, tids(*)
      do 10 i=1, nproc
         call pvmfkill( tids(i), info )
  10  continue
      call pvmfexit( info )
      return
      end


   And this is the code for the slaves:


      program slavep
      include '/usr/local/pvm/include/fpvm3.h'
      integer mytid, info, msgtype, mtid
      integer tids(1:32)
      integer n_slaves
      real other, value 
      integer nit, dest, src 

      call pvmfmytid(mytid)
      call pvmfparent(mtid)
 
      msgtype = 1
      call pvmfrecv( mtid, msgtype, info)
      call pvmfunpack( INTEGER4, nb_slaves, 1, 1, info)
      call pvmfunpack( INTEGER4, nit, 1, 1, info)
      call pvmfunpack( INTEGER4, tids, nb_slaves, 1, info)
      call pvmfunpack( REAL4, other, 1, 1, info)
c
c --- Determines who am I
c
      do i=1, nb_slaves
          if (tids(i).eq.mytid) me = i
      enddo

      inst = me
      msgtype = 10
      do 100, i = 1, nit
         if (mod(inst,2).eq.0) then 
           call pvmfinitsend( PVMDEFAULT, info)
           call pvmfpack( REAL4, other, 1, 1, info)
           dest = me - 2**(i-1)
           call pvmfsend( tids(dest), msgtype+i, info)
           goto 9999
         endif
           src = me + 2**(i-1)
           call pvmfrecv (tids(src), msgtype+i, info)
           call pvmfunpack( REAL4, value, 1, 1, info)
           other = other + value          
           inst = (inst + 1) /2
100   continue
      call pvmfinitsend( PVMDEFAULT, info)
      call pvmfpack( REAL4, other, 1, 1, info)
      msgtype = 2
      call pvmfsend( mtid, msgtype, info)
9999  continue
      end



