C
C --- Local label propagation (or "self-labeling") to do 
C --- global cluster labeling across processors.
C

      SUBROUTINE global_label
      INCLUDE "common.h"
      INCLUDE "cluster.h"
      INTEGER i,j,labeli,labeln,type,bytes
      INTEGER changed, how_many
      INTEGER  intadd
      EXTERNAL intadd

      how_many = 0
C --- Loop until nothing changes.
 123  CONTINUE
      changed = 0

C --- Get cluster labels and new spins from processors 
C --- in +ve i and j directions. 
      CALL get_edges

C --- i edge. 
      j=jsiz
      DO i=1,isiz
         labeli = Npoint(label(i,j))
         IF (jbond(i,j)) THEN
            labeln = recvi(i)
	    IF (labeln.LT.labeli) THEN
	       Npoint(label(i,j)) = labeln
	       new_spin(label(i,j)) = recvi(i+isiz)
	       changed = 1
	    ELSE
	      IF (labeln.GT.labeli) changed = 1
C ----------    Don't do anything since will send back Npoint(label(i,j)) 
C ----------    and new_spin(label(i,j)), which will be different.
C ----------  ELSE labeli = labeln so nothing changes.
	    END IF
	 END IF
      END DO

C --- j edge.
      i=isiz
      DO j=1,jsiz
	 labeli = Npoint(label(i,j))
	 IF (ibond(i,j)) THEN
	    labeln = recvj(j)
	    IF (labeln.LT.labeli) THEN
	       Npoint(label(i,j)) = labeln
	       new_spin(label(i,j)) = recvj(j+jsiz)
	       changed = 1
	    ELSE
	      IF (labeln.GT.labeli) changed = 1
C ----------    Don't do anything since will send back Npoint(label(i,j)) 
C ----------    and new_spin(label(i,j)), which will be different.
C ----------  ELSE labeli = labeln so nothing changes.
	    ENDIF
         ENDIF
      END DO

C --- Return cluster labels and new spins to processors 
C --- in +ve i and j dirs. 
      CALL return_edges

C --- Unpack first cluster then spin from recvi & recvj, and
C --- update N and new_spin if the new cluster labels are smaller.
      j = 1
      DO i=1,isiz
         IF (jbond(i,0) .AND. (recvi(i).LT.Npoint(label(i,j)))) THEN
            Npoint(label(i,j)) = recvi(i)
	    new_spin(label(i,j)) = recvi(i+isiz)
         ENDIF
      END DO
      i = 1
      DO j=1,jsiz
         IF (ibond(0,j) .AND. (recvj(j).LT.Npoint(label(i,j)))) THEN
            Npoint(label(i,j)) = recvj(j)
	    new_spin(label(i,j)) = recvj(j+jsiz) 
         ENDIF
      END DO

C --- Test for termination by combining changed's. Only start testing 
C --- after minits iterations, to save doing unnecessary broadcasts. 
      IF (how_many.GE.minits) THEN
        type = COMB
	bytes = 4
        CALL KXCOMB(changed,intadd,bytes,1,IALNOD,0,type)
      ELSE 
	changed = 1
      END IF

      how_many = how_many + 1
      IF (changed.GT.0) GOTO 123

C     WRITE(6,*) 'Iters to self-label clusters', how_many
      accept = how_many * globsites

      RETURN
      END


