CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C                                                                    C
C     THIS FILE CONTAINS THE SOURCE CODE FOR FORTRAN 90D INTRINSIC   C
C     FUNCTIONS.                                                     C
C                                                                    C
C     VERSION 1.00, 10/11/92                                         C
C                                                                    C
C     COPYRIGHT (C) NORTHEAST PARALLEL ARCHITECTURES CENTER,         C
C     SYRACUSE UNIVERSITY, SYRACUSE, NY 13244, USA.                  C
C                                                                    C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      integer function MAXVAL_1_I(A, a1, a2, A_INFO, proclist)
      integer a1, a2
      integer A(a1:a2), A_INFO(8,7), max, proclist(*)
      integer i, intsize, type, status, min_row, max_row
      data intsize, type /4, 23/
      integer findintmax
      external findintmax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      max = A(min_row)

      do i=min_row+1, max_row
         if (A(i) .GT. max) then
            max = A(i)
         end if
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(max,findintmax,intsize,1,IALNOD,0,type)
      else
         status = KXCOMB(max,findintmax,intsize,1,proclist(1),
     &                proclist(2),type)
      end if

      MAXVAL_1_I = max

      return
      end
      

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      integer function MAXVAL_1_I_M(A, a1, a2, A_INFO, mask, m1, 
     &      m2, MASK_INFO, proclist)
      integer a1, a2, m1, m2, A_INFO(8,7), max, proclist(*)
      integer A(a1:a2), MASK_INFO(8,7)
      logical mask(m1:m2)
      integer i, intsize, type, status, min_row, max_row
      data intsize, type /4, 23/
      integer findintmax
      external findintmax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      max = -21474836

      do i=min_row, max_row
         if ((A(i) .GT. max) .AND. mask(i)) then
            max = A(i)
         end if
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(max,findintmax,intsize,1,IALNOD,0,type)
      else
         status = KXCOMB(max,findintmax,intsize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MAXVAL_1_I_M = max

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      integer function MAXVAL_2_I_S(A, a1, a2, a3, a4, A_INFO, 
     &       proclist)
      integer a1, a2, a3, a4, A_INFO(8,7), max, proclist(*)
      integer A(a1:a2,a3:a4)
      integer min_row, max_row, min_col, max_col
      integer i, intsize, type, status
      data intsize, type /4, 23/
      integer findintmax
      external findintmax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      max = A(min_row,min_col)
      do j=min_col, max_col
         do i=min_row, max_row
            if (A(i,j) .GT. max) then
               max = A(i,j)
            end if
         end do
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(max,findintmax,intsize,1,IALNOD,0,type)
      else
         status = KXCOMB(max,findintmax,intsize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MAXVAL_2_I_S = max

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      integer function MAXVAL_2_I_S_M(A, a1, a2, a3, a4, A_INFO, 
     &   mask, m1, m2, m3, m4, MASK_INFO, proclist)
      integer a1, a2, a3, a4, m1, m2, m3, m4
      integer A_INFO(8,7), MASK_INFO(8,7)
      integer A(a1:a2,a3:a4), max, proclist(*)
      logical mask(m1:m2,m3:m4)
      integer min_row, max_row, min_col, max_col
      integer i, intsize, type, status
      data intsize, type /4, 23/
      integer findintmax
      external findintmax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      max = -21474836
      do j=min_col, max_col
         do i=min_row, max_row
            if ((A(i,j) .GT. max) .AND. mask(i,j)) then
               max = A(i,j)
            end if
         end do
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(max,findintmax,intsize,1,IALNOD,0,type)
      else
         status = KXCOMB(max,findintmax,intsize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MAXVAL_2_I_S_M = max

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      subroutine MAXVAL_2_I_V(A, a1, a2, a3, a4, A_INFO, dim, max, 
     &   s1, s2, MAX_INFO, proclist)
      integer a1, a2, a3, a4, s1, s2, A_INFO(8,7), MAX_INFO(8,7)
      integer A(a1:a2,a3:a4), dim, max(s1:s2), proclist(*)
      integer i, j, status, min_row, max_row, min_col, max_col
      integer intsize, type
      data intsize, type /4, 23/
      integer env(4), coord(2), nproc(2), size
      integer findintmax
      external findintmax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      if (dim .EQ. 2) then 
         size = max_row - min_row + 1
      else 
         size = max_col - min_col + 1
      end if

      if (dim .EQ. 2) then
         do i=min_row, max_row
            max(i) = A(i,min_col)
            do j=min_col+1, max_col
               if (A(i,j) .GT. max(i)) then
                  max(i) = A(i,j)
               end if
            end do
         end do
      else
         do i=min_col, max_col
            max(i) = A(min_row,i)
            do j=min_row+1, max_row
               if (A(j,i) .GT. max(i)) then
                  max(i) = A(j,i)
               end if
            end do
         end do
      end if


C     (BLOCK,*), (CYCLIC,*) AND REDUCTION ALONG COLUMN;   OR 
C     (*,BLOCK), (*,CYCLIC) AND REDUCTION ALONG ROW.


      if (((A_INFO(6,2) .EQ. 0) .AND. (dim .EQ. 1)) .OR. 
     & ((A_INFO(6,1) .EQ. 0) .AND. (dim .EQ. 2))) then
         nproc(1) = A_INFO(8,dim)
         status = KXGDIN(1, nproc)
         status = KXCOMB(max,findintmax,intsize,size,IALNOD,0,type)
      end if


C     ARRAY DECOMPOSED ALONG BOTH DIMENSIONS


      if ((A_INFO(6,1) .NE. 0) .AND. (A_INFO(6,2) .NE. 0)) then
         nproc(2) = A_INFO(8,1)
         nproc(1) = A_INFO(8,2)

         status = KXPARA(env)
         status = KXGDIN(2, nproc)
         status = KXGDCO(env(1), coord)

         if (dim .EQ. 2) then
            do i=0, nproc(1)-1
               coord(1) = i
               proclist(i+1) = KXGDPR(coord)
            end do
         else
            do i=0, nproc(2)-1
               coord(2) = i
               proclist(i+1) = KXGDPR(coord)
            end do 
         endif
         
         status = KXCOMB(max,findintmax,intsize,size,nproc(3-dim),
     &   proclist, type)
      end if

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      
      subroutine MAXVAL_2_I_V_M(A, a1, a2, a3, a4, A_INFO, dim, mask, 
     &  m1, m2, m3, m4, MASK_INFO, max, s1, s2, MAX_INFO, proclist)
      integer a1, a2, a3, a4, m1, m2, m3, m4, s1, s2
      integer A_INFO(8,7), MASK_INFO(8,7), MAX_INFO(8,7) 
      integer A(a1:a2,a3:a4), dim, max(s1:s2), proclist(*)
      logical mask(m1:m2,m3:m4)
      integer i, j, status, min_row, max_row, min_col, max_col
      integer intsize, type
      data intsize, type /4, 23/
      integer env(4), coord(2), nproc(2), size
      integer findintmax
      external findintmax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      if (dim .EQ. 2) then 
         size = max_row - min_row + 1
      else 
         size = max_col - min_col + 1
      end if

      if (dim .EQ. 2) then
         do i=min_row, max_row
            max(i) = -21474836
            do j=min_col, max_col
               if ((A(i,j) .GT. max(i)) .AND. mask(i,j)) then
                  max(i) = A(i,j)
               end if
            end do
         end do
      else
         do i=min_col, max_col
            max(i) = -21474836
            do j=min_row, max_row
               if ((A(j,i) .GT. max(i)) .AND. mask(j,i)) then
                  max(i) = A(j,i)
               end if
            end do
         end do
      end if


C     (BLOCK,*), (CYCLIC,*) AND REDUCTION ALONG COLUMN;   OR 
C     (*,BLOCK), (*,CYCLIC) AND REDUCTION ALONG ROW.


      if (((A_INFO(6,2) .EQ. 0) .AND. (dim .EQ. 1)) .OR. 
     & ((A_INFO(6,1) .EQ. 0) .AND. (dim .EQ. 2))) then
         nproc(1) = A_INFO(8,dim)
         status = KXGDIN(1, nproc)
         status = KXCOMB(max,findintmax,intsize,size,IALNOD,0,type)
      end if


C     ARRAY DECOMPOSED ALONG BOTH DIMENSIONS


      if ((A_INFO(6,1) .NE. 0) .AND. (A_INFO(6,2) .NE. 0)) then
         nproc(2) = A_INFO(8,1)
         nproc(1) = A_INFO(8,2)

         status = KXPARA(env)
         status = KXGDIN(2, nproc)
         status = KXGDCO(env(1), coord)

         if (dim .EQ. 2) then
            do i=0, nproc(1)-1
               coord(1) = i
               proclist(i+1) = KXGDPR(coord)
            end do
         else
            do i=0, nproc(2)-1
               coord(2) = i
               proclist(i+1) = KXGDPR(coord)
            end do 
         end if
         
         status = KXCOMB(max,findintmax,intsize,size,nproc(3-dim),
     &   proclist, type)
      end if

      return
      end



CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      
C     FOR REAL

      real function MAXVAL_1_R(A, a1, a2, A_INFO, proclist)
      integer a1, a2, A_INFO(8,7), proclist(*)
      real A(a1:a2), max
      integer i, realsize, type, status, min_row, max_row
      data realsize, type /4, 23/
      real findrealmax
      external findrealmax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      max = A(min_row)

      do i=min_row+1, max_row
         if (A(i) .GT. max) then
            max = A(i)
         end if
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(max,findrealmax,realsize,1,IALNOD,0,type)
      else
         status = KXCOMB(max,findrealmax,realsize,1,proclist(1),
     &                proclist(2),type)
      end if

      MAXVAL_1_R = max

      return
      end
      

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      real function MAXVAL_1_R_M(A, a1, a2, A_INFO, mask, m1, 
     &      m2, MASK_INFO, proclist)
      integer a1, a2, m1, m2, A_INFO(8,7), MASK_INFO(8,7)
      integer proclist(*)
      real A(a1:a2), max
      logical mask(m1:m2)
      integer i, realsize, type, status, min_row, max_row
      data realsize, type /4, 23/
      real findrealmax
      external findrealmax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      max = -21474836.0

      do i=min_row, max_row
         if ((A(i) .GT. max) .AND. mask(i)) then
            max = A(i)
         end if
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(max,findrealmax,realsize,1,IALNOD,0,type)
      else
         status = KXCOMB(max,findrealmax,realsize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MAXVAL_1_R_M = max

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      real function MAXVAL_2_R_S(A, a1, a2, a3, a4, A_INFO, 
     &       proclist)
      integer a1, a2, a3, a4, A_INFO(8,7), proclist(*)
      real A(a1:a2,a3:a4), max
      integer min_row, max_row, min_col, max_col
      integer i, realsize, type, status
      data realsize, type /4, 23/
      real findrealmax
      external findrealmax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      max = A(min_row,min_col)
      do j=min_col, max_col
         do i=min_row, max_row
            if (A(i,j) .GT. max) then
               max = A(i,j)
            end if
         end do
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(max,findrealmax,realsize,1,IALNOD,0,type)
      else
         status = KXCOMB(max,findrealmax,realsize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MAXVAL_2_R_S = max

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      real function MAXVAL_2_R_S_M(A, a1, a2, a3, a4, A_INFO, 
     &   mask, m1, m2, m3, m4, MASK_INFO, proclist)
      integer a1, a2, a3, a4, m1, m2, m3, m4
      integer A_INFO(8,7), MASK_INFO(8,7), proclist(*)
      real A(a1:a2,a3:a4), max
      logical mask(m1:m2,m3:m4)
      integer min_row, max_row, min_col, max_col
      integer i, realsize, type, status
      data realsize, type /4, 23/
      real findrealmax
      external findrealmax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      max = -21474836.0
      do j=min_col, max_col
         do i=min_row, max_row
            if ((A(i,j) .GT. max) .AND. mask(i,j)) then
               max = A(i,j)
            end if
         end do
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(max,findrealmax,realsize,1,IALNOD,0,type)
      else
         status = KXCOMB(max,findrealmax,realsize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MAXVAL_2_R_S_M = max

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      subroutine MAXVAL_2_R_V(A, a1, a2, a3, a4, A_INFO, dim, max, 
     &   s1, s2, MAX_INFO, proclist)
      integer a1, a2, a3, a4, s1, s2, A_INFO(8,7), MAX_INFO(8,7)
      real A(a1:a2,a3:a4), max(s1:s2)
      integer dim, proclist(*)
      integer i, j, status, min_row, max_row, min_col, max_col
      integer realsize, type
      data realsize, type /4, 23/
      integer env(4), coord(2), nproc(2), size
      real findrealmax
      external findrealmax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      if (dim .EQ. 2) then 
         size = max_row - min_row + 1
      else 
         size = max_col - min_col + 1
      end if

      if (dim .EQ. 2) then
         do i=min_row, max_row
            max(i) = A(i,min_col)
            do j=min_col+1, max_col
               if (A(i,j) .GT. max(i)) then
                  max(i) = A(i,j)
               end if
            end do
         end do
      else
         do i=min_col, max_col
            max(i) = A(min_row,i)
            do j=min_row+1, max_row
               if (A(j,i) .GT. max(i)) then
                  max(i) = A(j,i)
               end if
            end do
         end do
      end if


C     (BLOCK,*), (CYCLIC,*) AND REDUCTION ALONG COLUMN;   OR 
C     (*,BLOCK), (*,CYCLIC) AND REDUCTION ALONG ROW.


      if (((A_INFO(6,2) .EQ. 0) .AND. (dim .EQ. 1)) .OR. 
     & ((A_INFO(6,1) .EQ. 0) .AND. (dim .EQ. 2))) then
         nproc(1) = A_INFO(8,dim)
         status = KXGDIN(1, nproc)
         status = KXCOMB(max,findrealmax,realsize,size,IALNOD,0,type)
      end if


C     ARRAY DECOMPOSED ALONG BOTH DIMENSIONS


      if ((A_INFO(6,1) .NE. 0) .AND. (A_INFO(6,2) .NE. 0)) then
         nproc(2) = A_INFO(8,1)
         nproc(1) = A_INFO(8,2)

         status = KXPARA(env)
         status = KXGDIN(2, nproc)
         status = KXGDCO(env(1), coord)

         if (dim .EQ. 2) then
            do i=0, nproc(1)-1
               coord(1) = i
               proclist(i+1) = KXGDPR(coord)
            end do
         else
            do i=0, nproc(2)-1
               coord(2) = i
               proclist(i+1) = KXGDPR(coord)
            end do 
         endif
         
         status = KXCOMB(max,findrealmax,realsize,size,nproc(3-dim),
     &   proclist, type)
      end if

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      
      subroutine MAXVAL_2_R_V_M(A, a1, a2, a3, a4, A_INFO, dim, mask, 
     &  m1, m2, m3, m4, MASK_INFO, max, s1, s2, MAX_INFO, proclist)
      integer a1, a2, a3, a4, m1, m2, m3, m4, s1, s2
      integer A_INFO(8,7), MASK_INFO(8,7), MAX_INFO(8,7) 
      real A(a1:a2,a3:a4), max(s1:s2)
      integer dim, proclist(*)
      logical mask(m1:m2,m3:m4)
      integer i, j, status, min_row, max_row, min_col, max_col
      integer realsize, type
      data realsize, type /4, 23/
      integer env(4), coord(2), nproc(2), size
      real findrealmax
      external findrealmax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      if (dim .EQ. 2) then 
         size = max_row - min_row + 1
      else 
         size = max_col - min_col + 1
      end if

      if (dim .EQ. 2) then
         do i=min_row, max_row
            max(i) = -21474836.0
            do j=min_col, max_col
               if ((A(i,j) .GT. max(i)) .AND. mask(i,j)) then
                  max(i) = A(i,j)
               end if
            end do
         end do
      else
         do i=min_col, max_col
            max(i) = -21474836.0
            do j=min_row, max_row
               if ((A(j,i) .GT. max(i)) .AND. mask(j,i)) then
                  max(i) = A(j,i)
               end if
            end do
         end do
      end if


C     (BLOCK,*), (CYCLIC,*) AND REDUCTION ALONG COLUMN;   OR 
C     (*,BLOCK), (*,CYCLIC) AND REDUCTION ALONG ROW.


      if (((A_INFO(6,2) .EQ. 0) .AND. (dim .EQ. 1)) .OR. 
     & ((A_INFO(6,1) .EQ. 0) .AND. (dim .EQ. 2))) then
         nproc(1) = A_INFO(8,dim)
         status = KXGDIN(1, nproc)
         status = KXCOMB(max,findrealmax,realsize,size,IALNOD,0,type)
      end if


C     ARRAY DECOMPOSED ALONG BOTH DIMENSIONS


      if ((A_INFO(6,1) .NE. 0) .AND. (A_INFO(6,2) .NE. 0)) then
         nproc(2) = A_INFO(8,1)
         nproc(1) = A_INFO(8,2)

         status = KXPARA(env)
         status = KXGDIN(2, nproc)
         status = KXGDCO(env(1), coord)

         if (dim .EQ. 2) then
            do i=0, nproc(1)-1
               coord(1) = i
               proclist(i+1) = KXGDPR(coord)
            end do
         else
            do i=0, nproc(2)-1
               coord(2) = i
               proclist(i+1) = KXGDPR(coord)
            end do 
         end if
         
         status = KXCOMB(max,findrealmax,realsize,size,nproc(3-dim),
     &   proclist, type)
      end if

      return
      end



CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      

C     FOR DOUBLE


      double precision function MAXVAL_1_D(A, a1, a2, A_INFO, proclist)
      integer a1, a2, A_INFO(8,7), proclist(*)
      double precision A(a1:a2), max
      integer i, doublesize, type, status, min_row, max_row
      data doublesize, type /8, 23/
      double precision finddoublemax
      external finddoublemax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      max = A(min_row)

      do i=min_row+1, max_row
         if (A(i) .GT. max) then
            max = A(i)
         end if
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(max,finddoublemax,doublesize,1,IALNOD,0,type)
      else
         status = KXCOMB(max,finddoublemax,doublesize,1,proclist(1),
     &                proclist(2),type)
      end if

      MAXVAL_1_D = max

      return
      end
      

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      double precision function MAXVAL_1_D_M(A, a1, a2, A_INFO, mask, 
     &      m1, m2, MASK_INFO, proclist)
      integer a1, a2, m1, m2, A_INFO(8,7), MASK_INFO(8,7)
      integer proclist(*)
      double precision A(a1:a2), max
      logical mask(m1:m2)
      integer i, doublesize, type, status, min_row, max_row
      data doublesize, type /8, 23/
      double precision finddoublemax
      external finddoublemax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      max = -21474836.0

      do i=min_row, max_row
         if ((A(i) .GT. max) .AND. mask(i)) then
            max = A(i)
         end if
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(max,finddoublemax,doublesize,1,IALNOD,0,type)
      else
         status = KXCOMB(max,finddoublemax,doublesize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MAXVAL_1_D_M = max

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      double precision function MAXVAL_2_D_S(A, a1, a2, a3, a4, A_INFO, 
     &       proclist)
      integer a1, a2, a3, a4, A_INFO(8,7), proclist(*)
      double precision A(a1:a2,a3:a4), max
      integer min_row, max_row, min_col, max_col
      integer i, doublesize, type, status
      data doublesize, type /8, 23/
      double precision finddoublemax
      external finddoublemax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      max = A(min_row,min_col)
      do j=min_col, max_col
         do i=min_row, max_row
            if (A(i,j) .GT. max) then
               max = A(i,j)
            end if
         end do
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(max,finddoublemax,doublesize,1,IALNOD,0,type)
      else
         status = KXCOMB(max,finddoublemax,doublesize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MAXVAL_2_D_S = max

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      double precision function MAXVAL_2_D_S_M(A, a1, a2, a3, a4, 
     &   A_INFO, mask, m1, m2, m3, m4, MASK_INFO, proclist)
      integer a1, a2, a3, a4, m1, m2, m3, m4
      integer A_INFO(8,7), MASK_INFO(8,7), proclist(*)
      double precision A(a1:a2,a3:a4), max
      logical mask(m1:m2,m3:m4)
      integer min_row, max_row, min_col, max_col
      integer i, doublesize, type, status
      data doublesize, type /8, 23/
      double precision finddoublemax
      external finddoublemax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      max = -21474836.0
      do j=min_col, max_col
         do i=min_row, max_row
            if ((A(i,j) .GT. max) .AND. mask(i,j)) then
               max = A(i,j)
            end if
         end do
      end do

      if (proclist(1) .EQ. -1) then
         status = KXCOMB(max,finddoublemax,doublesize,1,IALNOD,0,type)
      else
         status = KXCOMB(max,finddoublemax,doublesize,1,proclist(1),
     &                   proclist(2),type)
      end if

      MAXVAL_2_D_S_M = max

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


      subroutine MAXVAL_2_D_V(A, a1, a2, a3, a4, A_INFO, dim, max, 
     &   s1, s2, MAX_INFO, proclist)
      integer a1, a2, a3, a4, s1, s2, A_INFO(8,7), MAX_INFO(8,7)
      double precision A(a1:a2,a3:a4), max(s1:s2)
      integer dim, proclist(*)
      integer i, j, status, min_row, max_row, min_col, max_col
      integer doublesize, type
      data doublesize, type /8, 23/
      integer env(4), coord(2), nproc(2), size
      double precision finddoublemax
      external finddoublemax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      if (dim .EQ. 2) then 
         size = max_row - min_row + 1
      else 
         size = max_col - min_col + 1
      end if

      if (dim .EQ. 2) then
         do i=min_row, max_row
            max(i) = A(i,min_col)
            do j=min_col+1, max_col
               if (A(i,j) .GT. max(i)) then
                  max(i) = A(i,j)
               end if
            end do
         end do
      else
         do i=min_col, max_col
            max(i) = A(min_row,i)
            do j=min_row+1, max_row
               if (A(j,i) .GT. max(i)) then
                  max(i) = A(j,i)
               end if
            end do
         end do
      end if


C     (BLOCK,*), (CYCLIC,*) AND REDUCTION ALONG COLUMN;   OR 
C     (*,BLOCK), (*,CYCLIC) AND REDUCTION ALONG ROW.


      if (((A_INFO(6,2) .EQ. 0) .AND. (dim .EQ. 1)) .OR. 
     & ((A_INFO(6,1) .EQ. 0) .AND. (dim .EQ. 2))) then
         nproc(1) = A_INFO(8,dim)
         status = KXGDIN(1, nproc)
         status = KXCOMB(max,finddoublemax,doublesize,size,IALNOD,0,
     &          type)
      end if


C     ARRAY DECOMPOSED ALONG BOTH DIMENSIONS


      if ((A_INFO(6,1) .NE. 0) .AND. (A_INFO(6,2) .NE. 0)) then
         nproc(2) = A_INFO(8,1)
         nproc(1) = A_INFO(8,2)

         status = KXPARA(env)
         status = KXGDIN(2, nproc)
         status = KXGDCO(env(1), coord)

         if (dim .EQ. 2) then
            do i=0, nproc(1)-1
               coord(1) = i
               proclist(i+1) = KXGDPR(coord)
            end do
         else
            do i=0, nproc(2)-1
               coord(2) = i
               proclist(i+1) = KXGDPR(coord)
            end do 
         endif
         
         status = KXCOMB(max,finddoublemax,doublesize,size,
     &       nproc(3-dim),proclist, type)
      end if

      return
      end


CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      
      subroutine MAXVAL_2_D_V_M(A, a1, a2, a3, a4, A_INFO, dim, mask, 
     &  m1, m2, m3, m4, MASK_INFO, max, s1, s2, MAX_INFO, proclist)
      integer a1, a2, a3, a4, m1, m2, m3, m4, s1, s2
      integer A_INFO(8,7), MASK_INFO(8,7), MAX_INFO(8,7) 
      double precision A(a1:a2,a3:a4), max(s1:s2)
      integer dim, proclist(*)
      logical mask(m1:m2,m3:m4)
      integer i, j, status, min_row, max_row, min_col, max_col
      integer doublesize, type
      data doublesize, type /8, 23/
      integer env(4), coord(2), nproc(2), size
      double precision finddoublemax
      external finddoublemax

      COMMON /XPRESS/ NOCARE, NORDER, NONODE, IHOST, IALNOD, IALPRC

      min_row = A_INFO(1,1)
      max_row = A_INFO(2,1)
      min_col = A_INFO(1,2)
      max_col = A_INFO(2,2)

      if (dim .EQ. 2) then 
         size = max_row - min_row + 1
      else 
         size = max_col - min_col + 1
      end if

      if (dim .EQ. 2) then
         do i=min_row, max_row
            max(i) = -21474836.0
            do j=min_col, max_col
               if ((A(i,j) .GT. max(i)) .AND. mask(i,j)) then
                  max(i) = A(i,j)
               end if
            end do
         end do
      else
         do i=min_col, max_col
            max(i) = -21474836.0
            do j=min_row, max_row
               if ((A(j,i) .GT. max(i)) .AND. mask(j,i)) then
                  max(i) = A(j,i)
               end if
            end do
         end do
      end if


C     (BLOCK,*), (CYCLIC,*) AND REDUCTION ALONG COLUMN;   OR 
C     (*,BLOCK), (*,CYCLIC) AND REDUCTION ALONG ROW.


      if (((A_INFO(6,2) .EQ. 0) .AND. (dim .EQ. 1)) .OR. 
     & ((A_INFO(6,1) .EQ. 0) .AND. (dim .EQ. 2))) then
         nproc(1) = A_INFO(8,dim)
         status = KXGDIN(1, nproc)
         status = KXCOMB(max,finddoublemax,doublesize,size,IALNOD,0,
     &         type)
      end if


C     ARRAY DECOMPOSED ALONG BOTH DIMENSIONS


      if ((A_INFO(6,1) .NE. 0) .AND. (A_INFO(6,2) .NE. 0)) then
         nproc(2) = A_INFO(8,1)
         nproc(1) = A_INFO(8,2)

         status = KXPARA(env)
         status = KXGDIN(2, nproc)
         status = KXGDCO(env(1), coord)

         if (dim .EQ. 2) then
            do i=0, nproc(1)-1
               coord(1) = i
               proclist(i+1) = KXGDPR(coord)
            end do
         else
            do i=0, nproc(2)-1
               coord(2) = i
               proclist(i+1) = KXGDPR(coord)
            end do 
         end if
         
         status = KXCOMB(max,finddoublemax,doublesize,size,
     &     nproc(3-dim),proclist, type)
      end if

      return
      end
