      SUBROUTINE puv_driver(mv_begin,mv_end,NumMinVols,
     &                      lu,ld,fcerr,data,nobs)
      include 'params.h'
c.....................................................................c
C     NASA/DAO OPTIMUM INTERPOLATION ANALYSIS  -  VERSION 1.4         :
c.....................................................................c
C**********************************************************************
C  This is a new driver interface for the data parallel version       *
C  It includes SEARCH routine, which stores its results in arrays     *
C  indexed by mini-volume label (igp). These are then passed to       *
C  local drivers via SOLVEDRV.                                        *
C**********************************************************************
C  Data parallel implementation (CM Fortran) : M. Makivic (NPAC)      *
C  Date:       4/94                                                   *
C**********************************************************************
c
c
c
      integer max_batch_size
      integer NumMinVols,mv_begin,mv_end
      INTEGER nreps (NumMinVols,50), augment
      LOGICAL first, final, onestage, qobs, offlev, solved
      logical unislp
      EXTERNAL cov
      common /obs/      maxdex,  nfgge,   lun,
     &                  vhc(13,13,20),    vcorox(18,18,4),
     &                  obserr(200,4,19), ww(13,13,20),
     &                  qobs(200,5),  offlev(200)
      common / obschar / dataname (5), obsname(200)


      REAL 
     &clam (144), datalist (NumMinVols,150,50),data (nobs,NRECORDS),
     & fcerr (im , jnp ), slam (144), 
     &delta (150),
     &gp (600), 
     &npd_mark, aug (3)
      CHARACTER * 8 dataname, obsname
      logical mv_done
      integer mv_start
      real crscov
      COMMON /PUV/ CRSCOV


!hpf$ distribute datalist(block,block,block)
!hpf$ distribute aug(block)
!hpf$ distribute clam(block)
!hpf$ distribute data(block,block)
!hpf$ distribute delta(block)
!hpf$ distribute fcerr(block,block)
!hpf$ distribute glatup(block)
!hpf$ distribute glonup(block)
!hpf$ distribute gp(block)
!hpf$ distribute kq(block)
!hpf$ distribute nh(block)
!hpf$ distribute nreps(block,block)
!hpf$ distribute obserr(block,block,block)
!hpf$ distribute offlev(block)
!hpf$ distribute qobs(block,block)
!hpf$ distribute reg(block)
!hpf$ distribute slam(block)
!hpf$ distribute vcorox(block,block,block)
!hpf$ distribute vhc(block,block,block)
!hpf$ distribute volcentre_x(block)
!hpf$ distribute volcentre_y(block)
!hpf$ distribute ww(block,block,block)
      DATA aug / 1.01, 1.1, 10. /
      integer nfact

      COMMON / gridxx / im, jnp, mlev
      COMMON / region / reg (13104)
      COMMON / scan / maxobs, rscan, onestage, MaxData
      COMMON / sparam / lsolve, ns, nr, nv, nh (13104), nq, kq (3), volc
     &entre_x (13104), ngv, volcentre_y (13104), glatup (13104), glonup 
     &(13104)

      COMMON / CORTABS / HCORFE (1000, 3, 20, 2)
!hpf$ distribute hcorfe(block,block,block,block)
      real,dimension(1000,3):: hcorfemm
!hpf$ distribute hcorfemm(block,block)


      integer handle_hcorfemm
      integer handle_obserr
      integer,parameter:: SIZE_OF_HCORFEMM=(1000*3*4)
      integer,parameter:: SIZE_OF_OBSERR=(200*4*19*4)

      COMMON / sfcdrag / drag (imr,jmr+1), iwater(13104)
!hpf$ distribute drag(block,block)
!hpf$ distribute  iwater(block)

      integer,dimension(NumMinVols,700):: gplat,gplon
!hpf$ distribute gplat(block,block)
!hpf$ distribute gplon(block,block)
      integer,dimension(NumMinVols,50):: npd_flag
!hpf$ distribute npd_flag(block,block)

      real,dimension(NumMinVols,700):: plat,plon,pstd,
     &     gstd,pdel,pkx,wlat,wlon,wstd,wkx,plst,wlst,glat,
     &     glon, udel,vdel,wdrg

!hpf$ distribute     udel(block,block)
!hpf$ distribute     vdel(block,block)
!hpf$ distribute     wdrg(block,block)
!hpf$ distribute     plat(block,block)
!hpf$ distribute     plon(block,block)
!hpf$ distribute     pstd(block,block)
!hpf$ distribute     gstd(block,block)
!hpf$ distribute     pdel(block,block)
!hpf$ distribute     pkx(block,block)
!hpf$ distribute     wlat(block,block)
!hpf$ distribute     wlon(block,block)
!hpf$ distribute     wstd(block,block)
!hpf$ distribute     wkx(block,block)
!hpf$ distribute     plst(block,block)
!hpf$ distribute     wlst(block,block)
!hpf$ distribute     glat(block,block)
!hpf$ distribute     glon(block,block)

      integer,dimension(NumMinVols)::np,nw,nhgp,nreports
!hpf$ distribute np(block)
!hpf$ distribute nw(block)
!hpf$ distribute nhgp(block)
!hpf$ distribute nreports(block)

      integer,dimension(NumMinVols)::testing_loc1
!hpf$ distribute testing_loc1(block)

      real,dimension(NumMinVols)::region,water
!hpf$ distribute region(block)
!hpf$ distribute water(block)
      if(mv_end.ne.(mv_begin+NumMinVols-1)) then
         print *, 'MV indices messed up!'
         stop
      end if

      do i=1,1000
      do j=1,3
          hcorfemm(i,j)=hcorfe(i,j,1,1)
      end do
      end do

      WRITE( 6,'(" Now beginning the search.....")' ) 
      mv_start=1
c      write(6,*) 'Enter batch factor..'
c      read(5,*) nfact
       nfact=1000
c      max_batch_size=ngv*nfact
      max_batch_size=100*nfact
      write(6,*) 'from driver.. ',max_batch_size

111   continue
      CALL search(mv_begin,mv_end,NumMinVols,
     &     mv_start,max_batch_size,lu,ld,datalist,
     &     nreps,data,nobs,mv_done)
      if(.not.mv_done) goto 111

      print *, 'finished search'
      call getconh('PI180   ', pi180 )
      call getconh('DLAT    ',dlat)
      call getconh('DLON    ',dlon)
      CALL GETCONH('RADE    ',RADE  )
      CALL GETCONH('RADEI   ',RADEI )
      CALL GETCONH('RADEI2  ',RADEI2)
      cALL GETCONH('OMEGA2  ',OMEGA2)
      CALL GETCONH('RHOBAR  ',RHOBAR)
      CALL GETCONI('MAXREP  ',MAXREP)
      CALL GETCONL('SLP     ',UNISLP)
      zero=0.0
      one=1.0
         IF(     UNISLP) THEN
            CRSCOV = ZERO
         ELSE
            CRSCOV = ONE
         END IF


      nhgp(1:NumMinVols)=nh(mv_begin:mv_end)
      water(1:NumMinVols)=iwater(mv_begin:mv_end)
      region(1:NumMinVols)=reg(mv_begin:mv_end)
    
c      handle_hcorfemm= CMGL_BROADCAST_SERIAL_ARRAY
c     &                 (hcorfemm,SIZE_OF_HCORFEMM)
c      handle_obserr= CMGL_BROADCAST_SERIAL_ARRAY
c     &                 (obserr,SIZE_OF_OBSERR)

      do levels = lu, ld, nv

!  Prepare arrays needed to compute covariance matrices.
        if( any(nreps(:,levels).ne.0) ) then

        print *, 'ready to call puv_prep_cov'
           call puv_prep_cov(mv_begin,mv_end,NumMinVols,
     &             nobs,datalist(:,:,levels),
     &             nreps(:,levels),data,fcerr,
     &             glatup,glonup,nh,volcentre_x,volcentre_y,
     &             gplat,gplon,plat,plon,pstd,gstd,pdel,pkx,wlat,wlon,
     &             wstd,udel,vdel,wkx,glat,glon,np,nw)
        endif
        nreports(1:NumMinVols)=nreps(1:NumMinVols,levels)

!  Call a local driver to compute and solve covariance matrices
c          call solvedrvl ( im,jnp,mlev,levels,dlon,nq,nr,region,
c     &              nreports, nhgp, np, nw, water, crscov, 
c     &              handle_obserr,
c     &              handle_hcorfe, radei, pi180, rhobar, omega2,plon,
c     &              plat, pstd, wlat, wlon, wstd, wdrg, udel,
c     &              vdel, pdel, pkx, wkx, testing_loc1)

        print *, 'ready to call solvedrvl'
          call solvedrvl ( mv_begin,mv_end,NumMinVols,
     &              im,jnp,mlev,levels,dlon,nq,nr,nv,region,
     &              nreports,nhgp,np,nw, water,crscov,
     &              obserr,hcorfemm,
     &              radei, pi180, rhobar, omega2, plon,
     &              plat, pstd, wlat, wlon, wstd, wdrg, udel,
     &              vdel, pdel, pkx, wkx, testing_loc1, npd_flag)

!  Store covariance matrices locally
!        call storel()

      end do

      write(6,'("...matrix solutions complete.")')
      write(6,'(//)')
      write(6,*) 'testing_loc1'
      write(6,*) testing_loc1
      write(6,*) 'nreports'
      write(6,*) nreports

!  Average the wind increments at the poles.

!      if( nq.eq.3 ) then

!        do levels = lu, ld

!         call avguvinc ( im, clam, slam,
!     &        aquan(1,jnp,levels,2), aquan(1,jnp,levels,3),
!     &        aquan(1,  1,levels,2), aquan(1,  1,levels,3)    )
!
!        end do

!      endif

      clam=1.0
      RETURN
      END
