      subroutine m4_func_NGA_GATHER(m4_test_type, m4_ndim)
      implicit none
#include "mafdecls.fh"
#include "global.fh"
c     
      integer n,m
      integer ndim
      parameter (n = m4_n)
      parameter (m = (m4_n**m4_ndim)/100)
      parameter (ndim = m4_ndim)
      m4_data_type a(substr(m4_array, 1, eval(m4_ndim*2-1)))
      m4_data_type b(substr(m4_array, 1, eval(m4_ndim*2-1)))
      integer lo(ndim),hi(ndim),dims(ndim),ld(ndim)
      integer g_a
      integer chunk(ndim)
      integer i, j, total, loop
      integer elems, count_elems
      m4_data_type v(m)
      integer d(ndim, m)
      double precision drand
      integer unique,unique_index
      integer nproc, me
      logical status
c     
      nproc = ga_nnodes()
      me    = ga_nodeid()
c     
c---------------------- initialize the GA -----------------------
c     initialize the chunk, dims, ld, and calculate the number 
c     of elements
      total=1
      do i = 1,ndim
         chunk(i) = 0
         dims(i) = n
         ld(i) = n
         total = total * dims(i)
      enddo
c
c***  Create global arrays
      if (.not. nga_create(m4_MT, ndim, dims, 'a', chunk, g_a))
     $     call ga_error(' ga_create failed ',1)
c     
      call ga_sync()
c
c------------------------------- NGA_GATHER ----------------------------
      m4_print_info(nga_gather)
c
c     initialize GA
      call m4_util_init_array(m4_test_type)(a,total)
      call nga_distribution(g_a, me, lo, hi)
      elems = count_elems(lo, hi, ndim)
      if(elems.gt.0) call nga_put(g_a,lo,hi,
     $     a(substr(m4_lo_all, 1, eval(m4_ndim*6-1))),dims)
c
      do loop = 1, MAXLOOP 
         call ga_sync()
c        initialize the index array
         do i = 1, m
c           generate indices
            unique_index = 0
            do while(unique_index.eq.0)
               do j=1,ndim
                  d(j,i) = int(drand(0)*real(n)) + 1
               enddo
c              
               unique_index = unique(d,ndim,m,i)
            enddo
         enddo
c
c        gather from global array
         call nga_gather(g_a, v, d, m)
c     
c        collect each elements and compare
         do i = 1, m
            do j=1, ndim
               lo(j) = d(j,i)
            enddo
            call nga_get(g_a,lo,lo,
     $           b(substr(m4_lo_all, 1, eval(m4_ndim*6-1))),ld)
c
c           compare the results
            if(v(i).ne.
     $           b(substr(m4_lo_all, 1, eval(m4_ndim*6-1)))) then
               call ga_error('bye', 0)
            endif
         enddo
      enddo
c
      call ga_sync()
      if(me.eq.0)then
         print *, 'OK'
         print *, ' '
         call ffflush(6)
      endif
c---------------------------
c     
      status= ga_destroy(g_a)
      end
