Subject: Re: Array boundry.

From: Zheng Gengbin <[email-masked]>
Date: Wed, 16 Apr 1997 10:03:54 +0800 (EAT)

On Tue, 15 Apr 1997, Guansong Zhang wrote:

> The alternative solution may be: caculating all the necessary boundaries in
> side the caller, and put them in argument list. Though DAD already have all
> those info, they can only be retrieved at run-time.
>

	I think Mr Carpenter is right , in f90 , when a subroutine is called,
while rempping the dummies it must have an explicit interface . The caller
can create the dad for callee , and pass the dad to the function. 

> In this case, every procedure call involved array section not only need to add
> a DAD as argument, but also the shape of the array.
>

	The DAD already contains the array shape information , doesn't it?

Now we have 2 method to deal with the dummy , first to create dummy dad
in the caller function , second is to create the dad inside the callee
function . We have to decide which one is better .

> Guansong
> 
> On Apr 15, 11:07am, Bryan Carpenter wrote:
> > Subject: Re: Array boundry.
> >
> > I don't know the specific compiler issues are, but
> >
> > 1) My reading of the HPF 2.0 standard is that it is now encouraged that
> >    remapping of array arguments at procedure boundaries occurs in the
> >    calling program.
> >
> >    I'm inferring this from the fact that any procedure call that requires
> >    argument remapping must now have an explicit interface, so the calling
> >    program is able to compute the mapping of the dummies.  Also from
> >    the fact that ``prescriptive'' and ``descriptive'' mappings of
> >    dummies are now required to be equivalent in all circumstances.  (In
> >    older specs a plausible interpretation seemed to be that remapping,
> >    if required by an explicity interface, of descriptively mapping
> >    dummies, would be done in the caller, and remapping of
> >    prescriptively mapped dummies would be done in the callee.  But we
> >    no longer seem to have that dichotomy.)
> >
> >    Under this interpretation, DAD's (with their associated templates)
> >    for dummy arguments would most likely be set up in the calling
> >    program (because you need to set up a DAD for the library remapping
> >    function, anyway) and passed into the function.  So creating a
> >    DAD/template/etc for an assumed size dummy probably wouldn't be an
> >    issue.
> >
> > 2) However, if you still want to set up a new DAD for `x' inside `fun',
> >    I don't see how that can be a problem for the library, whether or
> >    not you set up an explicit template.  If you give me some more
> >    details of the kind of code you are generating, I can probably tell
> >    you how to do it.
> >
> > Bryan
> >
> >
> > >
> > > Yan Mi once have the similiar problem when working on array assignment
> format.
> > > It is decide to use intrinsic functions in F90 to caculate the lower and
> upper
> > > bound of the array inside the procedure, so we can use it later.
> > >
> > > Now the problem is that if a template is added, it should be added before
> the
> > > execution statements, when boundary is not caculated out.
> > >
> > > Adlib Fortran interface provide support for an array to be distributed
> directly
> > > onto processors. I suggest we use those functions to solve the problem,
> though
> > > there is no effort to do so in trans0 at present time.
> > >
> > > If you agree, we should decide how to record a partitioned array without
> > > explicit template.
> > >
> > > Guansong
> > >
> > > On Apr 15,  2:55pm, Zheng Gengbin wrote:
> > > > Subject: Re: interesting thought
> > > >
> > > >
> > > > 	I found our current startegy encounters difficulty while creating
> > > > data mapping for assumed size dummy .
> > > > 	For example ,
> > > >
> > > > FUNCTION fun(x)
> > > >
> > > > real  x(:)
> > > >
> > > > END
> > > >
> > > > 	If x is not inherit , I must create a default template whose size
> > > > is the same as dummy x .  Then you will find the size of template cannot
> > > > be determined until runtime , so trans0 cannot got determined value to
> > > > caculate . Do you have any idea about this ? Can we modified our data
> mapping
> > > > strategy so that it can accept variable as well as constants boundries .
> > > > 	I remembered you said if an array is not explicit distributed ,
> > > > Adlib will perform a default data mapping . Can I assume this ?
> > > >
> > > >
> > > > Zheng
> > > >
> > > >-- End of excerpt from Zheng Gengbin
> > >
> > >
> > >
> >
> >-- End of excerpt from Bryan Carpenter
> 
> 
> 

***************************************************************************
*     Zheng Gengbin                 *                                     *
*                                   *                                     *
*  Dept. of Computer Science        *  Phone:  86-10-2585088              *
*         & Technology              *  Email:                             *
*                                   *      [email-masked]   *
*  Peking University P.R.China      *  Mail:                              *
*                                   *      Room 2106 ,Building 46,        *
*                                   *      Peking University, P.R.China   *
***************************************************************************

---

From: Zheng Gengbin <[email-masked]>
Date: Wed, 16 Apr 1997 11:31:21 +0800 (EAT)

I have check your Adlib-1.09 , and modified your configure.in ,
My major work is to decide the externel name of fortran and set the 
WDEF .  pcrc.C is modified also accroding to this macro variable.
Also I add the configure for Linux in it . So now this version can be
compiled on Liunx well , but the node program cannot run well while it
can run well on IBM RS6000 .  The old version work well  however .

Zheng
#! /bin/sh

# Guess values for system-dependent variables and create Makefiles.
# Generated automatically using autoconf version 2.12 
# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.

# Defaults:
ac_help=
ac_default_prefix=/usr/local
# Any additions from configure.in:
ac_default_prefix=`pwd`
ac_help="$ac_help

--with-MPI=mpich          Using mpich MPI (the defualt setting)
--with-MPI=chimp          Using chimp MPI 
--with-MPI=sp2            Using sp2 MPI from IBM "
ac_help="$ac_help
--enable-STRONG           Package building flag (default as disabled)"

# Initialize some variables set by options.
# The variables have the same names as the options, with
# dashes changed to underlines.
build=NONE
cache_file=./config.cache
exec_prefix=NONE
host=NONE
no_create=
nonopt=NONE
no_recursion=
prefix=NONE
program_prefix=NONE
program_suffix=NONE
program_transform_name=s,x,x,
silent=
site=
srcdir=
target=NONE
verbose=
x_includes=NONE
x_libraries=NONE
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datadir='${prefix}/share'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'
infodir='${prefix}/info'
mandir='${prefix}/man'

# Initialize some other variables.
subdirs=
MFLAGS= MAKEFLAGS=
# Maximum number of lines to put in a shell here document.
ac_max_here_lines=12

ac_prev=
for ac_option
do

  # If the previous option needs an argument, assign it.
  if test -n "$ac_prev"; then
    eval "$ac_prev=\$ac_option"
    ac_prev=
    continue
  fi

  case "$ac_option" in
  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
  *) ac_optarg= ;;
  esac

  # Accept the important Cygnus configure options, so we can diagnose typos.

  case "$ac_option" in

  -bindir | --bindir | --bindi | --bind | --bin | --bi)
    ac_prev=bindir ;;
  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
    bindir="$ac_optarg" ;;

  -build | --build | --buil | --bui | --bu)
    ac_prev=build ;;
  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
    build="$ac_optarg" ;;

  -cache-file | --cache-file | --cache-fil | --cache-fi \
  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
    ac_prev=cache_file ;;
  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
    cache_file="$ac_optarg" ;;

  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
    ac_prev=datadir ;;
  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
  | --da=*)
    datadir="$ac_optarg" ;;

  -disable-* | --disable-*)
    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
    # Reject names that are not valid shell variable names.
    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
    fi
    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
    eval "enable_${ac_feature}=no" ;;

  -enable-* | --enable-*)
    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
    # Reject names that are not valid shell variable names.
    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
    fi
    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
    case "$ac_option" in
      *=*) ;;
      *) ac_optarg=yes ;;
    esac
    eval "enable_${ac_feature}='$ac_optarg'" ;;

  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
  | --exec | --exe | --ex)
    ac_prev=exec_prefix ;;
  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
  | --exec=* | --exe=* | --ex=*)
    exec_prefix="$ac_optarg" ;;

  -gas | --gas | --ga | --g)
    # Obsolete; use --with-gas.
    with_gas=yes ;;

  -help | --help | --hel | --he)
    # Omit some internal or obsolete options to make the list less imposing.
    # This message is too long to be a string in the A/UX 3.1 sh.
    cat << EOF
Usage: configure [options] [host]
Options: [defaults in brackets after descriptions]
Configuration:
  --cache-file=FILE       cache test results in FILE
  --help                  print this message
  --no-create             do not create output files
  --quiet, --silent       do not print \`checking...' messages
  --version               print the version of autoconf that created configure
Directory and file names:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [$ac_default_prefix]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [same as prefix]
  --bindir=DIR            user executables in DIR [EPREFIX/bin]
  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
  --datadir=DIR           read-only architecture-independent data in DIR
                          [PREFIX/share]
  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
                          [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
  --includedir=DIR        C header files in DIR [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
  --infodir=DIR           info documentation in DIR [PREFIX/info]
  --mandir=DIR            man documentation in DIR [PREFIX/man]
  --srcdir=DIR            find the sources in DIR [configure dir or ..]
  --program-prefix=PREFIX prepend PREFIX to installed program names
  --program-suffix=SUFFIX append SUFFIX to installed program names
  --program-transform-name=PROGRAM
                          run sed PROGRAM on installed program names
EOF
    cat << EOF
Host type:
  --build=BUILD           configure for building on BUILD [BUILD=HOST]
  --host=HOST             configure for HOST [guessed]
  --target=TARGET         configure for TARGET [TARGET=HOST]
Features and packages:
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --x-includes=DIR        X include files are in DIR
  --x-libraries=DIR       X library files are in DIR
EOF
    if test -n "$ac_help"; then
      echo "--enable and --with options recognized:$ac_help"
    fi
    exit 0 ;;

  -host | --host | --hos | --ho)
    ac_prev=host ;;
  -host=* | --host=* | --hos=* | --ho=*)
    host="$ac_optarg" ;;

  -includedir | --includedir | --includedi | --included | --include \
  | --includ | --inclu | --incl | --inc)
    ac_prev=includedir ;;
  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
  | --includ=* | --inclu=* | --incl=* | --inc=*)
    includedir="$ac_optarg" ;;

  -infodir | --infodir | --infodi | --infod | --info | --inf)
    ac_prev=infodir ;;
  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
    infodir="$ac_optarg" ;;

  -libdir | --libdir | --libdi | --libd)
    ac_prev=libdir ;;
  -libdir=* | --libdir=* | --libdi=* | --libd=*)
    libdir="$ac_optarg" ;;

  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
  | --libexe | --libex | --libe)
    ac_prev=libexecdir ;;
  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
  | --libexe=* | --libex=* | --libe=*)
    libexecdir="$ac_optarg" ;;

  -localstatedir | --localstatedir | --localstatedi | --localstated \
  | --localstate | --localstat | --localsta | --localst \
  | --locals | --local | --loca | --loc | --lo)
    ac_prev=localstatedir ;;
  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
    localstatedir="$ac_optarg" ;;

  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
    ac_prev=mandir ;;
  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
    mandir="$ac_optarg" ;;

  -nfp | --nfp | --nf)
    # Obsolete; use --without-fp.
    with_fp=no ;;

  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
  | --no-cr | --no-c)
    no_create=yes ;;

  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
    no_recursion=yes ;;

  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
  | --oldin | --oldi | --old | --ol | --o)
    ac_prev=oldincludedir ;;
  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
    oldincludedir="$ac_optarg" ;;

  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
    ac_prev=prefix ;;
  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
    prefix="$ac_optarg" ;;

  -program-prefix | --program-prefix | --program-prefi | --program-pref \
  | --program-pre | --program-pr | --program-p)
    ac_prev=program_prefix ;;
  -program-prefix=* | --program-prefix=* | --program-prefi=* \
  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
    program_prefix="$ac_optarg" ;;

  -program-suffix | --program-suffix | --program-suffi | --program-suff \
  | --program-suf | --program-su | --program-s)
    ac_prev=program_suffix ;;
  -program-suffix=* | --program-suffix=* | --program-suffi=* \
  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
    program_suffix="$ac_optarg" ;;

  -program-transform-name | --program-transform-name \
  | --program-transform-nam | --program-transform-na \
  | --program-transform-n | --program-transform- \
  | --program-transform | --program-transfor \
  | --program-transfo | --program-transf \
  | --program-trans | --program-tran \
  | --progr-tra | --program-tr | --program-t)
    ac_prev=program_transform_name ;;
  -program-transform-name=* | --program-transform-name=* \
  | --program-transform-nam=* | --program-transform-na=* \
  | --program-transform-n=* | --program-transform-=* \
  | --program-transform=* | --program-transfor=* \
  | --program-transfo=* | --program-transf=* \
  | --program-trans=* | --program-tran=* \
  | --progr-tra=* | --program-tr=* | --program-t=*)
    program_transform_name="$ac_optarg" ;;

  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
  | -silent | --silent | --silen | --sile | --sil)
    silent=yes ;;

  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
    ac_prev=sbindir ;;
  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
  | --sbi=* | --sb=*)
    sbindir="$ac_optarg" ;;

  -sharedstatedir | --sharedstatedir | --sharedstatedi \
  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
  | --sharedst | --shareds | --shared | --share | --shar \
  | --sha | --sh)
    ac_prev=sharedstatedir ;;
  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
  | --sha=* | --sh=*)
    sharedstatedir="$ac_optarg" ;;

  -site | --site | --sit)
    ac_prev=site ;;
  -site=* | --site=* | --sit=*)
    site="$ac_optarg" ;;

  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
    ac_prev=srcdir ;;
  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
    srcdir="$ac_optarg" ;;

  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
  | --syscon | --sysco | --sysc | --sys | --sy)
    ac_prev=sysconfdir ;;
  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
    sysconfdir="$ac_optarg" ;;

  -target | --target | --targe | --targ | --tar | --ta | --t)
    ac_prev=target ;;
  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
    target="$ac_optarg" ;;

  -v | -verbose | --verbose | --verbos | --verbo | --verb)
    verbose=yes ;;

  -version | --version | --versio | --versi | --vers)
    echo "configure generated by autoconf version 2.12"
    exit 0 ;;

  -with-* | --with-*)
    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
    # Reject names that are not valid shell variable names.
    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
    fi
    ac_package=`echo $ac_package| sed 's/-/_/g'`
    case "$ac_option" in
      *=*) ;;
      *) ac_optarg=yes ;;
    esac
    eval "with_${ac_package}='$ac_optarg'" ;;

  -without-* | --without-*)
    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
    # Reject names that are not valid shell variable names.
    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
    fi
    ac_package=`echo $ac_package| sed 's/-/_/g'`
    eval "with_${ac_package}=no" ;;

  --x)
    # Obsolete; use --with-x.
    with_x=yes ;;

  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
  | --x-incl | --x-inc | --x-in | --x-i)
    ac_prev=x_includes ;;
  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
    x_includes="$ac_optarg" ;;

  -x-libraries | --x-libraries | --x-librarie | --x-librari \
  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
    ac_prev=x_libraries ;;
  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
    x_libraries="$ac_optarg" ;;

  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
    ;;

  *)
    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
      echo "configure: warning: $ac_option: invalid host type" 1>&2
    fi
    if test "x$nonopt" != xNONE; then
      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
    fi
    nonopt="$ac_option"
    ;;

  esac
done

if test -n "$ac_prev"; then
  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
fi

trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15

# File descriptor usage:
# 0 standard input
# 1 file creation
# 2 errors and warnings
# 3 some systems may open it to /dev/tty
# 4 used on the Kubota Titan
# 6 checking for... messages and results
# 5 compiler messages saved in config.log
if test "$silent" = yes; then
  exec 6>/dev/null
else
  exec 6>&1
fi
exec 5>./config.log

echo "\
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
" 1>&5

# Strip out --no-create and --no-recursion so they do not pile up.
# Also quote any args containing shell metacharacters.
ac_configure_args=
for ac_arg
do
  case "$ac_arg" in
  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
  | --no-cr | --no-c) ;;
  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
  esac
done

# NLS nuisances.
# Only set these to C if already set.  These must not be set unconditionally
# because not all systems understand e.g. LANG=C (notably SCO).
# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
# Non-C LC_CTYPE values break the ctype check.
if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi

# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -rf conftest* confdefs.h
# AIX cpp loses on an empty file, so make sure it contains at least a newline.
echo > confdefs.h

# A filename unique to this package, relative to the directory that
# configure is in, which we can look for to find out if srcdir is correct.
ac_unique_file=./configure

# Find the source files, if location was not specified.
if test -z "$srcdir"; then
  ac_srcdir_defaulted=yes
  # Try the directory containing this script, then its parent.
  ac_prog=$0
  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
  srcdir=$ac_confdir
  if test ! -r $srcdir/$ac_unique_file; then
    srcdir=..
  fi
else
  ac_srcdir_defaulted=no
fi
if test ! -r $srcdir/$ac_unique_file; then
  if test "$ac_srcdir_defaulted" = yes; then
    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
  else
    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
  fi
fi
srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`

# Prefer explicitly selected file to automatically selected ones.
if test -z "$CONFIG_SITE"; then
  if test "x$prefix" != xNONE; then
    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
  else
    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
  fi
fi
for ac_site_file in $CONFIG_SITE; do
  if test -r "$ac_site_file"; then
    echo "loading site script $ac_site_file"
    . "$ac_site_file"
  fi
done

if test -r "$cache_file"; then
  echo "loading cache $cache_file"
  . $cache_file
else
  echo "creating cache $cache_file"
  > $cache_file
fi

ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross

if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
  # Stardent Vistra SVR4 grep lacks -e, says [email-masked].
  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
    ac_n= ac_c='
' ac_t='	'
  else
    ac_n=-n ac_c= ac_t=
  fi
else
  ac_n= ac_c='\c' ac_t=
fi

ac_aux_dir=
for ac_dir in ./config $srcdir/./config; do
  if test -f $ac_dir/install-sh; then
    ac_aux_dir=$ac_dir
    ac_install_sh="$ac_aux_dir/install-sh -c"
    break
  elif test -f $ac_dir/install.sh; then
    ac_aux_dir=$ac_dir
    ac_install_sh="$ac_aux_dir/install.sh -c"
    break
  fi
done
if test -z "$ac_aux_dir"; then
  { echo "configure: error: can not find install-sh or install.sh in ./config $srcdir/./config" 1>&2; exit 1; }
fi
ac_config_guess=$ac_aux_dir/config.guess
ac_config_sub=$ac_aux_dir/config.sub
ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.

# Do some error checking and defaulting for the host and target type.
# The inputs are:
#    configure --host=HOST --target=TARGET --build=BUILD NONOPT
#
# The rules are:
# 1. You are not allowed to specify --host, --target, and nonopt at the
#    same time.
# 2. Host defaults to nonopt.
# 3. If nonopt is not specified, then host defaults to the current host,
#    as determined by config.guess.
# 4. Target and build default to nonopt.
# 5. If nonopt is not specified, then target and build default to host.

# The aliases save the names the user supplied, while $host etc.
# will get canonicalized.
case $host---$target---$nonopt in
NONE---*---* | *---NONE---* | *---*---NONE) ;;
*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
esac

# Make sure we can run config.sub.
if $ac_config_sub sun4 >/dev/null 2>&1; then :
else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
fi

echo $ac_n "checking host system type""... $ac_c" 1>&6
echo "configure:583: checking host system type" >&5

host_alias=$host
case "$host_alias" in
NONE)
  case $nonopt in
  NONE)
    if host_alias=`$ac_config_guess`; then :
    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
    fi ;;
  *) host_alias=$nonopt ;;
  esac ;;
esac

host=`$ac_config_sub $host_alias`
host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$host" 1>&6

echo $ac_n "checking target system type""... $ac_c" 1>&6
echo "configure:604: checking target system type" >&5

target_alias=$target
case "$target_alias" in
NONE)
  case $nonopt in
  NONE) target_alias=$host_alias ;;
  *) target_alias=$nonopt ;;
  esac ;;
esac

target=`$ac_config_sub $target_alias`
target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$target" 1>&6

echo $ac_n "checking build system type""... $ac_c" 1>&6
echo "configure:622: checking build system type" >&5

build_alias=$build
case "$build_alias" in
NONE)
  case $nonopt in
  NONE) build_alias=$host_alias ;;
  *) build_alias=$nonopt ;;
  esac ;;
esac

build=`$ac_config_sub $build_alias`
build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
echo "$ac_t""$build" 1>&6

test "$host_alias" != "$target_alias" &&
  test "$program_prefix$program_suffix$program_transform_name" = \
    NONENONEs,x,x, &&
  program_prefix=${target_alias}-

if test "$program_transform_name" = s,x,x,; then
  program_transform_name=
else
  # Double any \ or $.  echo might interpret backslashes.
  cat <<\EOF_SED > conftestsed
s,\\,\\\\,g; s,\$,$$,g
EOF_SED
  program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
  rm -f conftestsed
fi
test "$program_prefix" != NONE &&
  program_transform_name="s,^,${program_prefix},; $program_transform_name"
# Use a double $ so make ignores it.
test "$program_suffix" != NONE &&
  program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"

# sed with no file args requires a program.
test "$program_transform_name" = "" && program_transform_name="s,x,x,"

echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
echo "configure:666: checking how to run the C preprocessor" >&5
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
  CPP=
fi
if test -z "$CPP"; then
if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
    # This must be in double quotes, not single quotes, because CPP may get
  # substituted into the Makefile and "${CC-cc}" will confuse make.
  CPP="${CC-cc} -E"
  # On the NeXT, cc -E runs the code through the compiler's parser,
  # not just through cpp.
  cat > conftest.$ac_ext <<EOF
#line 681 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:687: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
  :
else
  echo "$ac_err" >&5
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  CPP="${CC-cc} -E -traditional-cpp"
  cat > conftest.$ac_ext <<EOF
#line 698 "configure"
#include "confdefs.h"
#include <assert.h>
Syntax Error
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:704: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
  :
else
  echo "$ac_err" >&5
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  CPP=/lib/cpp
fi
rm -f conftest*
fi
rm -f conftest*
  ac_cv_prog_CPP="$CPP"
fi
  CPP="$ac_cv_prog_CPP"
else
  ac_cv_prog_CPP="$CPP"
fi
echo "$ac_t""$CPP" 1>&6

echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
echo "configure:727: checking for ANSI C header files" >&5
if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  cat > conftest.$ac_ext <<EOF
#line 732 "configure"
#include "confdefs.h"
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <float.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
{ (eval echo configure:740: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out`
if test -z "$ac_err"; then
  rm -rf conftest*
  ac_cv_header_stdc=yes
else
  echo "$ac_err" >&5
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  ac_cv_header_stdc=no
fi
rm -f conftest*

if test $ac_cv_header_stdc = yes; then
  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
#line 757 "configure"
#include "confdefs.h"
#include <string.h>
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  egrep "memchr" >/dev/null 2>&1; then
  :
else
  rm -rf conftest*
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat > conftest.$ac_ext <<EOF
#line 775 "configure"
#include "confdefs.h"
#include <stdlib.h>
EOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
  egrep "free" >/dev/null 2>&1; then
  :
else
  rm -rf conftest*
  ac_cv_header_stdc=no
fi
rm -f conftest*

fi

if test $ac_cv_header_stdc = yes; then
  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
if test "$cross_compiling" = yes; then
  :
else
  cat > conftest.$ac_ext <<EOF
#line 796 "configure"
#include "confdefs.h"
#include <ctype.h>
#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
int main () { int i; for (i = 0; i < 256; i++)
if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
exit (0); }

EOF
if { (eval echo configure:807: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
then
  :
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -fr conftest*
  ac_cv_header_stdc=no
fi
rm -fr conftest*
fi

fi
fi

echo "$ac_t""$ac_cv_header_stdc" 1>&6
if test $ac_cv_header_stdc = yes; then
  cat >> confdefs.h <<\EOF
#define STDC_HEADERS 1
EOF

fi

echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
echo "configure:833: checking for sys/wait.h that is POSIX.1 compatible" >&5
if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  cat > conftest.$ac_ext <<EOF
#line 838 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/wait.h>
#ifndef WEXITSTATUS
#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
#endif
#ifndef WIFEXITED
#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
#endif
int main() {
int s;
wait (&s);
s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
; return 0; }
EOF
if { (eval echo configure:854: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
  rm -rf conftest*
  ac_cv_header_sys_wait_h=yes
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  ac_cv_header_sys_wait_h=no
fi
rm -f conftest*
fi

echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
if test $ac_cv_header_sys_wait_h = yes; then
  cat >> confdefs.h <<\EOF
#define HAVE_SYS_WAIT_H 1
EOF

fi

# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:878: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$RANLIB"; then
  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
  for ac_dir in $PATH; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_RANLIB="ranlib"
      break
    fi
  done
  IFS="$ac_save_ifs"
  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
fi
fi
RANLIB="$ac_cv_prog_RANLIB"
if test -n "$RANLIB"; then
  echo "$ac_t""$RANLIB" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

VERSION=1.09
cat >> confdefs.h <<EOF
#define VERSION "$VERSION"
EOF

CWD=`pwd`

echo $ac_n "checking the MPI package""... $ac_c" 1>&6
echo "configure:918: checking the MPI package" >&5

MPI=

# Check whether --with-MPI or --without-MPI was given.
if test "${with_MPI+set}" = set; then
  withval="$with_MPI"
  MPI=${withval}
else
  MPI=mpich 
fi

if eval "test \"`echo '$''{'adlib_cv_mpipackage'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  adlib_cv_mpipackage=$MPI
fi

echo "$ac_t""as $adlib_cv_mpipackage" 1>&6

MPI=$adlib_cv_mpipackage

case "$MPI" in
  mpich )

    if test ! -x `which mpirun`
  then 
    echo "Please install mpich first ..."
    exit
  fi

  # Extract the first word of "mpCC", so it can be a program name with args.
set dummy mpCC; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:957: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_MPICC'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$MPICC"; then
  ac_cv_prog_MPICC="$MPICC" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
  for ac_dir in $PATH; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_MPICC="yes"
      break
    fi
  done
  IFS="$ac_save_ifs"
  test -z "$ac_cv_prog_MPICC" && ac_cv_prog_MPICC="no"
fi
fi
MPICC="$ac_cv_prog_MPICC"
if test -n "$MPICC"; then
  echo "$ac_t""$MPICC" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

  if [ "$MPICC" = "yes" ]
  then
    CXX=mpCC

    LIBKEY=
  else
        
    for ac_prog in $CCC c++ g++ gcc CC cxx cc++
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:998: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$CXX"; then
  ac_cv_prog_CXX="$CXX" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
  for ac_dir in $PATH; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_CXX="$ac_prog"
      break
    fi
  done
  IFS="$ac_save_ifs"
fi
fi
CXX="$ac_cv_prog_CXX"
if test -n "$CXX"; then
  echo "$ac_t""$CXX" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

test -n "$CXX" && break
done
test -n "$CXX" || CXX="gcc"

echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6
echo "configure:1029: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5

ac_ext=C
# CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='${CXX-g++} -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CXX-g++} -o conftest $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cxx_cross

cat > conftest.$ac_ext <<EOF
#line 1039 "configure"
#include "confdefs.h"
main(){return(0);}
EOF
if { (eval echo configure:1043: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
  ac_cv_prog_cxx_works=yes
  # If we can't run a trivial program, we are probably using a cross compiler.
  if (./conftest; exit) 2>/dev/null; then
    ac_cv_prog_cxx_cross=no
  else
    ac_cv_prog_cxx_cross=yes
  fi
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  ac_cv_prog_cxx_works=no
fi
rm -fr conftest*
ac_ext=c
# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
ac_cpp='$CPP $CPPFLAGS'
ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
cross_compiling=$ac_cv_prog_cc_cross

echo "$ac_t""$ac_cv_prog_cxx_works" 1>&6
if test $ac_cv_prog_cxx_works = no; then
  { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; }
fi
echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
echo "configure:1069: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5
echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6
cross_compiling=$ac_cv_prog_cxx_cross

echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6
echo "configure:1074: checking whether we are using GNU C++" >&5
if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  cat > conftest.C <<EOF
#ifdef __GNUC__
  yes;
#endif
EOF
if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:1083: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
  ac_cv_prog_gxx=yes
else
  ac_cv_prog_gxx=no
fi
fi

echo "$ac_t""$ac_cv_prog_gxx" 1>&6

if test $ac_cv_prog_gxx = yes; then
  GXX=yes
  ac_test_CXXFLAGS="${CXXFLAGS+set}"
  ac_save_CXXFLAGS="$CXXFLAGS"
  CXXFLAGS=
  echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6
echo "configure:1098: checking whether ${CXX-g++} accepts -g" >&5
if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  echo 'void f(){}' > conftest.cc
if test -z "`${CXX-g++} -g -c conftest.cc 2>&1`"; then
  ac_cv_prog_cxx_g=yes
else
  ac_cv_prog_cxx_g=no
fi
rm -f conftest*

fi

echo "$ac_t""$ac_cv_prog_cxx_g" 1>&6
  if test "$ac_test_CXXFLAGS" = set; then
    CXXFLAGS="$ac_save_CXXFLAGS"
  elif test $ac_cv_prog_cxx_g = yes; then
    CXXFLAGS="-g -O2"
  else
    CXXFLAGS="-O2"
  fi
else
  GXX=
  test "${CXXFLAGS+set}" = set || CXXFLAGS="-g"
fi

    if [ $CXX = c++ ]
    then
      LIBKEY="-lmpi"
    else
      case $target in

        *ibm* )
        LIBKEY="-lmpi"
        ;;

        *solaris* )
        LIBKEY="-lmpi -lsocket -lnsl" 
        ;;

        *dec* )
        LIBKEY="-lmpi -lcomplex -lm" 
        ;;

        * ) 
        echo "C++ compiler on $target is not supported yet"
        exit
        ;; 

      esac

    fi

  fi

  echo $ac_n "checking MPI include dir""... $ac_c" 1>&6
echo "configure:1160: checking MPI include dir" >&5

  MPI_PREFIX=`which mpirun | sed 's%/bin/mpirun%%'`
  if [ ! -f $MPI_PREFIX/include/mpi.h ]
  then 
    echo "Please input the mpich install prefix:"
  read MPI_PREFIX
  fi  

  if [ ! -f $MPI_PREFIX/include/mpi.h ]
  then 
    echo "Please install mpich first ..."
    exit
  fi

  MPI_INC=$MPI_PREFIX/include/

  if eval "test \"`echo '$''{'adlib_cv_mpi_inc'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  adlib_cv_mpi_inc=$MPI_INC
fi

  echo "$ac_t""$adlib_cv_mpi_inc" 1>&6

  MPI_INC=-I$adlib_cv_mpi_inc

  echo $ac_n "checking MPI lib dir""... $ac_c" 1>&6
echo "configure:1192: checking MPI lib dir" >&5

  ARCH=`tarch`

  DEVICE=`tdevice $ARCH`

    MPI_LIB=$MPI_PREFIX/lib/$ARCH/$DEVICE

  if eval "test \"`echo '$''{'adlib_cv_mpi_lib'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  adlib_cv_mpi_lib=$MPI_LIB
fi

  echo "$ac_t""$adlib_cv_mpi_lib" 1>&6

  MPI_LIB=-L$adlib_cv_mpi_lib

  ;;

  chimp )

  echo Not supported 
  ;;

  sp2 )

  # Extract the first word of "mpCC", so it can be a program name with args.
set dummy mpCC; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1227: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_MPICC'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$MPICC"; then
  ac_cv_prog_MPICC="$MPICC" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
  for ac_dir in $PATH; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_MPICC="yes"
      break
    fi
  done
  IFS="$ac_save_ifs"
  test -z "$ac_cv_prog_MPICC" && ac_cv_prog_MPICC="no"
fi
fi
MPICC="$ac_cv_prog_MPICC"
if test -n "$MPICC"; then
  echo "$ac_t""$MPICC" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

  if [ "$MPICC" = "yes" ]
  then 
    CXX=mpCC
  fi

  if [ "$CXX" = "" ]
  then
    echo "Please install SP2 mpCC first ..."
    exit
  fi

  MPI_INC=

  MPI_LIB=

  LIBKEY=
  
  ;;

  * )

  echo The package does not support MPI=$MPI.
  exit
  ;;

esac

echo $ac_n "checking compiler option""... $ac_c" 1>&6
echo "configure:1285: checking compiler option" >&5

COMPILER_OPT=

# Check whether --enable-STRONG or --disable-STRONG was given.
if test "${enable_STRONG+set}" = set; then
  enableval="$enable_STRONG"
  COMPILER_OPT=-Dstrong
else
  COMPILER_OPT= 
fi

echo "$ac_t""as $COMPILER_OPT" 1>&6

case $target in
	
  *ibm* )

  if [ $MPICC = yes ]
  then
    # Extract the first word of "mpxlf", so it can be a program name with args.
set dummy mpxlf; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1313: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_FCL'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$FCL"; then
  ac_cv_prog_FCL="$FCL" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
  for ac_dir in $PATH; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_FCL="mpxlf"
      break
    fi
  done
  IFS="$ac_save_ifs"
fi
fi
FCL="$ac_cv_prog_FCL"
if test -n "$FCL"; then
  echo "$ac_t""$FCL" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

  fi
  if [ "$FCL" = "" ]
  then 
    # Extract the first word of "xlf", so it can be a program name with args.
set dummy xlf; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1344: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_FCL'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$FCL"; then
  ac_cv_prog_FCL="$FCL" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
  for ac_dir in $PATH; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_FCL="xlf"
      break
    fi
  done
  IFS="$ac_save_ifs"
fi
fi
FCL="$ac_cv_prog_FCL"
if test -n "$FCL"; then
  echo "$ac_t""$FCL" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

  fi
  if [ "$FCL" = "" ]
  then 
    # Extract the first word of "f77", so it can be a program name with args.
set dummy f77; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1375: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_FCL'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$FCL"; then
  ac_cv_prog_FCL="$FCL" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
  for ac_dir in $PATH; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_FCL="f77"
      break
    fi
  done
  IFS="$ac_save_ifs"
fi
fi
FCL="$ac_cv_prog_FCL"
if test -n "$FCL"; then
  echo "$ac_t""$FCL" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

  fi
  if [ "$FCL" != "" ]
  then 
    FC_OPT=-qextname
  fi

  PLATFORM=AIX

  ;;

  *dec* )
  # Extract the first word of "f90", so it can be a program name with args.
set dummy f90; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1414: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_FCL'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$FCL"; then
  ac_cv_prog_FCL="$FCL" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
  for ac_dir in $PATH; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_FCL="f90"
      break
    fi
  done
  IFS="$ac_save_ifs"
fi
fi
FCL="$ac_cv_prog_FCL"
if test -n "$FCL"; then
  echo "$ac_t""$FCL" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

  if [ "$FCL" = "" ]
  then 
    # Extract the first word of "f77", so it can be a program name with args.
set dummy f77; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1444: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_FCL'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$FCL"; then
  ac_cv_prog_FCL="$FCL" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
  for ac_dir in $PATH; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_FCL="f77"
      break
    fi
  done
  IFS="$ac_save_ifs"
fi
fi
FCL="$ac_cv_prog_FCL"
if test -n "$FCL"; then
  echo "$ac_t""$FCL" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

  fi

  PLATFORM=DEC

  ;;

  *linux* )
  # Extract the first word of "g77", so it can be a program name with args.
set dummy g77; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1479: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_FCL'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$FCL"; then
  ac_cv_prog_FCL="$FCL" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
  for ac_dir in $PATH; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_FCL="g77"
      break
    fi
  done
  IFS="$ac_save_ifs"
fi
fi
FCL="$ac_cv_prog_FCL"
if test -n "$FCL"; then
  echo "$ac_t""$FCL" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

  if [ "$FCL" = "" ]
  then 
    # Extract the first word of "fort77", so it can be a program name with args.
set dummy fort77; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1509: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_FCL'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$FCL"; then
  ac_cv_prog_FCL="$FCL" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
  for ac_dir in $PATH; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_FCL="fort77"
      break
    fi
  done
  IFS="$ac_save_ifs"
fi
fi
FCL="$ac_cv_prog_FCL"
if test -n "$FCL"; then
  echo "$ac_t""$FCL" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

  fi
  PLATFORM=EPC

  ;;

  * ) 
  # Extract the first word of "f77", so it can be a program name with args.
set dummy f77; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
echo "configure:1543: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_prog_FCL'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  if test -n "$FCL"; then
  ac_cv_prog_FCL="$FCL" # Let the user override the test.
else
  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
  for ac_dir in $PATH; do
    test -z "$ac_dir" && ac_dir=.
    if test -f $ac_dir/$ac_word; then
      ac_cv_prog_FCL="f77"
      break
    fi
  done
  IFS="$ac_save_ifs"
fi
fi
FCL="$ac_cv_prog_FCL"
if test -n "$FCL"; then
  echo "$ac_t""$FCL" 1>&6
else
  echo "$ac_t""no" 1>&6
fi

  ;; 

esac

echo $ac_n "checking for main in -lC""... $ac_c" 1>&6
echo "configure:1574: checking for main in -lC" >&5
ac_lib_var=`echo C'_'main | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  ac_save_LIBS="$LIBS"
LIBS="-lC  $LIBS"
cat > conftest.$ac_ext <<EOF
#line 1582 "configure"
#include "confdefs.h"

int main() {
main()
; return 0; }
EOF
if { (eval echo configure:1589: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=yes"
else
  echo "configure: failed program was:" >&5
  cat conftest.$ac_ext >&5
  rm -rf conftest*
  eval "ac_cv_lib_$ac_lib_var=no"
fi
rm -f conftest*
LIBS="$ac_save_LIBS"

fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
  echo "$ac_t""yes" 1>&6
  CXXLIBKEY="-lC"
else
  echo "$ac_t""no" 1>&6
CXXLIBKEY=""
fi

if  ! test "$FCL" = "" -a -d ./src/pcrcFortran 
then
  pcrcFortran=pcrcFortran
else
  pcrcFortran=
fi

echo $ac_n "checking Fortran externels name""... $ac_c" 1>&6
echo "configure:1619: checking Fortran externels name" >&5
if eval "test \"`echo '$''{'ac_fort_name_flag'+set}'`\" = set"; then
  echo $ac_n "(cached) $ac_c" 1>&6
else
  ac_fort_name_flag=
(cd src/pcrcFortran ; /bin/rm -f pcrc_stack.o ; \
        $FCL $FC_OPT -c pcrc_stack.f > /dev/null 2>&1 )
nameform1=`strings -a src/pcrcFortran/pcrc_stack.o | grep pcrc_integer_alloc_  | head -1`
nameform2=`strings -a src/pcrcFortran/pcrc_stack.o | grep PCRC_INTEGER_ALLOC   | head -1`
nameform3=`strings -a src/pcrcFortran/pcrc_stack.o | grep pcrc_integer_alloc   | head -1`
nameform4=`strings -a src/pcrcFortran/pcrc_stack.o | grep pcrc_integer_alloc__ | head -1`

/bin/rm -f src/pcrcFortran/pcrc_stack.o
if test -n "$nameform4" ; then
	WDEF='-DFORT2UNDERSCORE'
elif test -n "$nameform1" ; then
        WDEF='-DFORT1UNDERSCORE'
elif test -n "$nameform2" ; then
	WDEF='-DFORTCAPS'
elif test -n "$nameform3" ; then
        WDEF='-DFORT0UNDERSCORE'
else
	echo "Unable to determine the form of Fortran external names"
fi
ac_fort_name_flag=$WDEF

fi

echo "$ac_t""$WDEF" 1>&6
case "$WDEF" in
-DFORT2UNDERSCORE)    
	echo "Fortran externals are lower case and have 1 or 2 trailing underscores" 
	;;
-DFORT1UNDERSCORE)
	echo "Fortran externals have a trailing underscore and are lowercase"
	;;
-DFORTCAPS)
	echo "Fortran externals are uppercase"
	;;
-DFORT0UNDERSCORE)
	echo "Fortran externals are lower case"
	;;
esac

trap '' 1 2 15
cat > confcache <<\EOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs.  It is not useful on other systems.
# If it contains results you don't want to keep, you may remove or edit it.
#
# By default, configure uses ./config.cache as the cache file,
# creating it if it does not exist already.  You can give configure
# the --cache-file=FILE option to use a different cache file; that is
# what configure does when it calls configure scripts in
# subdirectories, so they share the cache.
# Giving --cache-file=/dev/null disables caching, for debugging configure.
# config.status only pays attention to the cache file if you give it the
# --recheck option to rerun configure.
#
EOF
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, don't put newlines in cache variables' values.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(set) 2>&1 |
  case `(ac_space=' '; set) 2>&1` in
  *ac_space=\ *)
    # `set' does not quote correctly, so add quotes (double-quote substitution
    # turns \\\\ into \\, and sed turns \\ into \).
    sed -n \
      -e "s/'/'\\\\''/g" \
      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
    ;;
  *)
    # `set' quotes correctly as required by POSIX, so do not add quotes.
    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
    ;;
  esac >> confcache
if cmp -s $cache_file confcache; then
  :
else
  if test -w $cache_file; then
    echo "updating cache $cache_file"
    cat confcache > $cache_file
  else
    echo "not updating unwritable cache $cache_file"
  fi
fi
rm -f confcache

trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15

test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'

# Any assignment to VPATH causes Sun make to only execute
# the first set of double-colon rules, so remove it if not needed.
# If there is a colon in the path, we need to keep it.
if test "x$srcdir" = x.; then
  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
fi

trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15

DEFS=-DHAVE_CONFIG_H

# Without the "./", some shells look in PATH for config.status.
: ${CONFIG_STATUS=./config.status}

echo creating $CONFIG_STATUS
rm -f $CONFIG_STATUS
cat > $CONFIG_STATUS <<EOF
#! /bin/sh
# Generated automatically by configure.
# Run this file to recreate the current configuration.
# This directory was configured as follows,
# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
#
# $0 $ac_configure_args
#
# Compiler output produced by configure, useful for debugging
# configure, is in ./config.log if it exists.

ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
for ac_option
do
  case "\$ac_option" in
  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
    echo "$CONFIG_STATUS generated by autoconf version 2.12"
    exit 0 ;;
  -help | --help | --hel | --he | --h)
    echo "\$ac_cs_usage"; exit 0 ;;
  *) echo "\$ac_cs_usage"; exit 1 ;;
  esac
done

ac_given_srcdir=$srcdir

trap 'rm -fr `echo "Makefile 
src/Makefile 
src/include/Makefile src/kernel/Makefile src/script/Makefile src/pcrcFortran/Makefile
man/Makefile
man/man1/Makefile
test/Makefile test/kernel/Makefile test/pcrcFortran/Makefile
src/script/ad++:src/script/ad++.in
src/script/prun:src/script/prun.in
src/pcrcFortran/pcrcf:src/pcrcFortran/pcrcf.in 
test/kernel/runtests:test/kernel/runtests.in
test/pcrcFortran/runtests:test/pcrcFortran/runtests.in
 ./src/include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
EOF
cat >> $CONFIG_STATUS <<EOF

# Protect against being on the right side of a sed subst in config.status.
sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
 s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
$ac_vpsub
$extrasub
s%@CFLAGS@%$CFLAGS%g
s%@CPPFLAGS@%$CPPFLAGS%g
s%@CXXFLAGS@%$CXXFLAGS%g
s%@DEFS@%$DEFS%g
s%@LDFLAGS@%$LDFLAGS%g
s%@LIBS@%$LIBS%g
s%@exec_prefix@%$exec_prefix%g
s%@prefix@%$prefix%g
s%@program_transform_name@%$program_transform_name%g
s%@bindir@%$bindir%g
s%@sbindir@%$sbindir%g
s%@libexecdir@%$libexecdir%g
s%@datadir@%$datadir%g
s%@sysconfdir@%$sysconfdir%g
s%@sharedstatedir@%$sharedstatedir%g
s%@localstatedir@%$localstatedir%g
s%@libdir@%$libdir%g
s%@includedir@%$includedir%g
s%@oldincludedir@%$oldincludedir%g
s%@infodir@%$infodir%g
s%@mandir@%$mandir%g
s%@host@%$host%g
s%@host_alias@%$host_alias%g
s%@host_cpu@%$host_cpu%g
s%@host_vendor@%$host_vendor%g
s%@host_os@%$host_os%g
s%@target@%$target%g
s%@target_alias@%$target_alias%g
s%@target_cpu@%$target_cpu%g
s%@target_vendor@%$target_vendor%g
s%@target_os@%$target_os%g
s%@build@%$build%g
s%@build_alias@%$build_alias%g
s%@build_cpu@%$build_cpu%g
s%@build_vendor@%$build_vendor%g
s%@build_os@%$build_os%g
s%@CPP@%$CPP%g
s%@RANLIB@%$RANLIB%g
s%@VERSION@%$VERSION%g
s%@CWD@%$CWD%g
s%@MPI@%$MPI%g
s%@MPICC@%$MPICC%g
s%@CXX@%$CXX%g
s%@LIBKEY@%$LIBKEY%g
s%@MPI_INC@%$MPI_INC%g
s%@MPI_LIB@%$MPI_LIB%g
s%@COMPILER_OPT@%$COMPILER_OPT%g
s%@FCL@%$FCL%g
s%@WDEF@%$WDEF%g
s%@FC_OPT@%$FC_OPT%g
s%@PLATFORM@%$PLATFORM%g
s%@CXXLIBKEY@%$CXXLIBKEY%g
s%@pcrcFortran@%$pcrcFortran%g

CEOF
EOF

cat >> $CONFIG_STATUS <<\EOF

# Split the substitutions into bite-sized pieces for seds with
# small command number limits, like on Digital OSF/1 and HP-UX.
ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
ac_file=1 # Number of current file.
ac_beg=1 # First line for current file.
ac_end=$ac_max_sed_cmds # Line after last line for current file.
ac_more_lines=:
ac_sed_cmds=""
while $ac_more_lines; do
  if test $ac_beg -gt 1; then
    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
  else
    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
  fi
  if test ! -s conftest.s$ac_file; then
    ac_more_lines=false
    rm -f conftest.s$ac_file
  else
    if test -z "$ac_sed_cmds"; then
      ac_sed_cmds="sed -f conftest.s$ac_file"
    else
      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
    fi
    ac_file=`expr $ac_file + 1`
    ac_beg=$ac_end
    ac_end=`expr $ac_end + $ac_max_sed_cmds`
  fi
done
if test -z "$ac_sed_cmds"; then
  ac_sed_cmds=cat
fi
EOF

cat >> $CONFIG_STATUS <<EOF

CONFIG_FILES=\${CONFIG_FILES-"Makefile 
src/Makefile 
src/include/Makefile src/kernel/Makefile src/script/Makefile src/pcrcFortran/Makefile
man/Makefile
man/man1/Makefile
test/Makefile test/kernel/Makefile test/pcrcFortran/Makefile
src/script/ad++:src/script/ad++.in
src/script/prun:src/script/prun.in
src/pcrcFortran/pcrcf:src/pcrcFortran/pcrcf.in 
test/kernel/runtests:test/kernel/runtests.in
test/pcrcFortran/runtests:test/pcrcFortran/runtests.in
"}
EOF
cat >> $CONFIG_STATUS <<\EOF
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
  case "$ac_file" in
  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
  *) ac_file_in="${ac_file}.in" ;;
  esac

  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.

  # Remove last slash and all that follows it.  Not all systems have dirname.
  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
    # The file is in a subdirectory.
    test ! -d "$ac_dir" && mkdir "$ac_dir"
    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
    # A "../" for each directory in $ac_dir_suffix.
    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
  else
    ac_dir_suffix= ac_dots=
  fi

  case "$ac_given_srcdir" in
  .)  srcdir=.
      if test -z "$ac_dots"; then top_srcdir=.
      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
  *) # Relative path.
    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
    top_srcdir="$ac_dots$ac_given_srcdir" ;;
  esac

  echo creating "$ac_file"
  rm -f "$ac_file"
  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
  case "$ac_file" in
  *Makefile*) ac_comsub="1i\\
# $configure_input" ;;
  *) ac_comsub= ;;
  esac

  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
  sed -e "$ac_comsub
s%@configure_input@%$configure_input%g
s%@srcdir@%$srcdir%g
s%@top_srcdir@%$top_srcdir%g
" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
fi; done
rm -f conftest.s*

# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
# NAME is the cpp macro being defined and VALUE is the value it is being given.
#
# ac_d sets the value in "#define NAME VALUE" lines.
ac_dA='s%^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
ac_dB='\([ 	][ 	]*\)[^ 	]*%\1#\2'
ac_dC='\3'
ac_dD='%g'
# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
ac_uA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
ac_uB='\([ 	]\)%\1#\2define\3'
ac_uC=' '
ac_uD='\4%g'
# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
ac_eA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
ac_eB='$%\1#\2define\3'
ac_eC=' '
ac_eD='%g'

if test "${CONFIG_HEADERS+set}" != set; then
EOF
cat >> $CONFIG_STATUS <<EOF
  CONFIG_HEADERS="./src/include/config.h"
EOF
cat >> $CONFIG_STATUS <<\EOF
fi
for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
  case "$ac_file" in
  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
  *) ac_file_in="${ac_file}.in" ;;
  esac

  echo creating $ac_file

  rm -f conftest.frag conftest.in conftest.out
  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
  cat $ac_file_inputs > conftest.in

EOF

# Transform confdefs.h into a sed script conftest.vals that substitutes
# the proper values into config.h.in to produce config.h.  And first:
# Protect against being on the right side of a sed subst in config.status.
# Protect against being in an unquoted here document in config.status.
rm -f conftest.vals
cat > conftest.hdr <<\EOF
s/[\\&%]/\\&/g
s%[\\$`]%\\&%g
s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
s%ac_d%ac_u%gp
s%ac_u%ac_e%gp
EOF
sed -n -f conftest.hdr confdefs.h > conftest.vals
rm -f conftest.hdr

# This sed command replaces #undef with comments.  This is necessary, for
# example, in the case of _POSIX_SOURCE, which is predefined and required
# on some systems where configure will not decide to define it.
cat >> conftest.vals <<\EOF
s%^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
EOF

# Break up conftest.vals because some shells have a limit on
# the size of here documents, and old seds have small limits too.

rm -f conftest.tail
while :
do
  ac_lines=`grep -c . conftest.vals`
  # grep -c gives empty output for an empty file on some AIX systems.
  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
  # Write a limited-size here document to conftest.frag.
  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
  echo 'CEOF
  sed -f conftest.frag conftest.in > conftest.out
  rm -f conftest.in
  mv conftest.out conftest.in
' >> $CONFIG_STATUS
  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
  rm -f conftest.vals
  mv conftest.tail conftest.vals
done
rm -f conftest.vals

cat >> $CONFIG_STATUS <<\EOF
  rm -f conftest.frag conftest.h
  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
  cat conftest.in >> conftest.h
  rm -f conftest.in
  if cmp -s $ac_file conftest.h 2>/dev/null; then
    echo "$ac_file is unchanged"
    rm -f conftest.h
  else
    # Remove last slash and all that follows it.  Not all systems have dirname.
      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
      # The file is in a subdirectory.
      test ! -d "$ac_dir" && mkdir "$ac_dir"
    fi
    rm -f $ac_file
    mv conftest.h $ac_file
  fi
fi; done

EOF
cat >> $CONFIG_STATUS <<EOF

EOF
cat >> $CONFIG_STATUS <<\EOF

exit 0
EOF
chmod +x $CONFIG_STATUS
rm -fr confdefs* $ac_clean_files
test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1

chmod a+x src/script/ad++
chmod a+x src/script/prun
chmod a+x test/kernel/runtests
chmod a+x test/pcrcFortran/runtests
if [ "$pcrcFortran" != "" ]
then
  chmod a+x src/pcrcFortran/pcrcf
fi

echo Done!

#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

#include "ad++.h"
#include "pcrc.h"

//#include "platform.h"

#ifdef FORT2UNDERSCORE
#define pcrc_init_  pcrc_init__
#define pcrc_finalize_ pcrc_finalize__
#define pcrc_new_group_grid_ pcrc_new_group_grid__
#define pcrc_delete_group_ pcrc_delete_group__
#define pcrc_new_range_distribute_ pcrc_new_range_distribute__
#define pcrc_new_range_collapse_ pcrc_new_range_collapse__
#define pcrc_new_range_align_ pcrc_new_range_align__
#define pcrc_new_range_copy_  pcrc_new_range_copy__
#define pcrc_new_range_loop_  pcrc_new_range_loop__
#define pcrc_delete_range_ pcrc_delete_range__
#define pcrc_new_array_data_  pcrc_new_array_data__
#define pcrc_set_array_distribute_  pcrc_set_array_distribute__
#define pcrc_set_array_collapse_ pcrc_set_array_collapse__
#define pcrc_set_array_align_  pcrc_set_array_align__
#define pcrc_set_array_copy_  pcrc_set_array_copy__
#define pcrc_set_array_loop_  pcrc_set_array_loop__
#define pcrc_new_array_section_  pcrc_new_array_section__
#define pcrc_set_array_triplet_  pcrc_set_array_triplet__
#define pcrc_set_array_scalar_ pcrc_set_array_scalar__
#define pcrc_new_array_copy_  pcrc_new_array_copy__
#define pcrc_delete_array_ pcrc_delete_array__
#define pcrc_grp_  pcrc_grp__
#define pcrc_rng_  pcrc_rng__
#define pcrc_size_  pcrc_size__
#define pcrc_str_  pcrc_str__
#define pcrc_reset_array_bounds_  pcrc_reset_array_bounds__
#define pcrc_reset_array_base_  pcrc_reset_array_base__
#define pcrc_on_  pcrc_on__
#define pcrc_glob_  pcrc_glob__
#define pcrc_loc_  pcrc_loc__
#define pcrc_loop_bounds_  pcrc_loop_bounds__
#define pcrc_shift_  pcrc_shift__
#define pcrc_tshift_  pcrc_tshift__
#define pcrc_remap_  pcrc_remap__
#define pcrc_detect_communication_  pcrc_detect_communication__
#define pcrc_coef_  pcrc_coef__
#define pcrc_reset_push_bounds_  pcrc_reset_push_bounds__
#define pcrc_reset_pop_bounds_  pcrc_reset_pop_bounds__
#define pcrc_print_dad_  pcrc_print_dad__
#elif defined(FORT0UNDERSCORE)
#define pcrc_init_  pcrc_init
#define pcrc_finalize_ pcrc_finalize
#define pcrc_new_group_grid_ pcrc_new_group_grid
#define pcrc_delete_group_ pcrc_delete_group
#define pcrc_new_range_distribute_ pcrc_new_range_distribute
#define pcrc_new_range_collapse_ pcrc_new_range_collapse
#define pcrc_new_range_align_ pcrc_new_range_align
#define pcrc_new_range_copy_  pcrc_new_range_copy
#define pcrc_new_range_loop_  pcrc_new_range_loop
#define pcrc_delete_range_ pcrc_delete_range
#define pcrc_new_array_data_  pcrc_new_array_data
#define pcrc_set_array_distribute_  pcrc_set_array_distribute
#define pcrc_set_array_collapse_ pcrc_set_array_collapse
#define pcrc_set_array_align_  pcrc_set_array_align
#define pcrc_set_array_copy_  pcrc_set_array_copy
#define pcrc_set_array_loop_  pcrc_set_array_loop
#define pcrc_new_array_section_  pcrc_new_array_section
#define pcrc_set_array_triplet_  pcrc_set_array_triplet
#define pcrc_set_array_scalar_ pcrc_set_array_scalar
#define pcrc_new_array_copy_  pcrc_new_array_copy
#define pcrc_delete_array_ pcrc_delete_array
#define pcrc_grp_  pcrc_grp
#define pcrc_rng_  pcrc_rng
#define pcrc_size_  pcrc_size
#define pcrc_str_  pcrc_str
#define pcrc_reset_array_bounds_  pcrc_reset_array_bounds
#define pcrc_reset_array_base_  pcrc_reset_array_base
#define pcrc_on_  pcrc_on
#define pcrc_glob_  pcrc_glob
#define pcrc_loc_  pcrc_loc
#define pcrc_loop_bounds_  pcrc_loop_bounds
#define pcrc_shift_  pcrc_shift
#define pcrc_tshift_  pcrc_tshift
#define pcrc_remap_  pcrc_remap
#define pcrc_detect_communication_  pcrc_detect_communication
#define pcrc_coef_  pcrc_coef
#define pcrc_reset_push_bounds_  pcrc_reset_push_bounds
#define pcrc_reset_pop_bounds_  pcrc_reset_pop_bounds
#define pcrc_print_dad_  pcrc_print_dad
#endif

extern "C" {
  void pcrc_init_() ;
  void pcrc_finalize_() ;

  int pcrc_new_group_grid_(int* rank, int* shape) ;
  void pcrc_delete_group_(int* grp) ;

  int pcrc_new_range_distribute_(int* g_lb, int* g_ub,
                                 int* distribution, int* grp_grid, int *dim) ;
  int pcrc_new_range_collapse_(int* g_lb, int* g_ub) ;
  int pcrc_new_range_align_(int* g_lb, int* g_ub,
                            int* offset, int* stride, int* rng_parent) ;
  int pcrc_new_range_copy_(int* rng_parent) ;
  int pcrc_new_range_loop_(int* g_lb, int* g_ub, int* g_stride,
                           int* offset, int* stride, int* rng_parent) ;
  void pcrc_delete_range_(int* rng) ;

  int pcrc_new_array_data_(void* array,
                           int* element_type, int* element_size,
                           int* rank, int* grp) ;
  void pcrc_set_array_distribute_(int* dad, int* dim, int* g_lb, int* g_ub,
                                  int* distribution,
                                  int* grp_grid, int *grid_dim) ;
  void pcrc_set_array_collapse_(int* dad, int* dim,
                                int* g_lb, int* g_ub) ;
  void pcrc_set_array_align_(int* dad, int* dim,
                             int* g_lb, int* g_ub,
                             int* offset, int* stride, int* rng_parent) ;
  void pcrc_set_array_copy_(int* dad, int* dim, int* rng_parent) ;
  void pcrc_set_array_loop_(int* dad, int* dim,
                            int* g_lb, int* g_ub, int* g_stride,
                            int* offset, int* stride, int* rng_parent) ;
   
  int pcrc_new_array_section_(int* rank, int* dad_parent) ;
  void pcrc_set_array_triplet_(int* dad, int* dim,
                               int* lb, int* ub, int* stride,
                               int* dad_parent, int* dim_parent) ;
  void pcrc_set_array_scalar_(int* dad,
                              int* i,
                              int* dad_parent, int* dim_parent) ;

  int pcrc_new_array_copy_(void* data, int* dad_parent) ;

  void pcrc_delete_array_(int* dad) ;

  int pcrc_grp_(int* dad) ;
  int pcrc_rng_(int* dad, int* dim) ;
  int pcrc_size_(int* dad) ;
  int pcrc_str_(int* dad, int* dim) ;

  void pcrc_reset_array_bounds_(int* dad, int* dim,
                        int* lb, int* ub, int* stride,
                        int* lb_parent, int* ub_parent, int* stride_parent) ;
  void pcrc_reset_array_base_(int* dad, void* array) ;

  int pcrc_on_(int* grp) ;

  int pcrc_glob_(int* rng, int* l_i) ;
  int pcrc_loc_(int* rng, int* g_i) ;

  void pcrc_loop_bounds_(int* rng, int* l_lb, int* l_ub, int* l_stride) ;

  void pcrc_shift_(int* dad, int* dad_source, int* dim, int* amount) ;
  void pcrc_tshift_(void* data, int* dad_source, int* dim, int* amount) ;
  void pcrc_remap_(int* dad, int* dad_source) ;

  int pcrc_detect_communication_(int* dad, int* dad_source,
                                 int* dim, int* l, int* u, int* stride,
                                 int* a, int* b,
                                 float* m, float* c, int *amount) ;
  void pcrc_coef_(int * dad, int *dim, int *l, int *u, int *s, int *a, int *b,
					int *amount, int *m, int *c);
  void pcrc_reset_push_bounds_(int* dad, int* dim, int* lb, 
					int* lb_parent, int* ub_parent, int* stride_parent ) ;
  void pcrc_reset_pop_bounds_(int* dad, int* dim,
				int* lb, int* ub, int* stride ) ;
  void pcrc_print_dad_(int *dad, int *dim);
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//                                                                     //
// Global state.                                                       //
//                                                                     //
// Go straight into the Fortran run-time library to pick up the values //
// of `argc' and `argv'.                                               //
//                                                                     //
// There doesn't seem to be a sensible, portable alternative           //
// (this is probably a bug in the MPI definition).                     //
//                                                                     //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

#ifdef AIX

extern "C" {
  extern int p_xargc ;
  extern char** p_xargv ;
}

static void _AdlibInit() {
  AdlibInit(p_xargc, p_xargv) ;
}

#endif

#ifdef NAG

extern "C" {
  extern int f90_argc ;
  extern char** f90_argv ;
}

static void _AdlibInit() {
  AdlibInit(f90_argc, f90_argv) ;
}

#endif

#ifdef EPC

extern "C" {
  extern int xargc ;
  extern char** xargv ;
}

static void _AdlibInit() {
  AdlibInit(xargc, xargv) ;
}

#endif

#ifdef DEC

extern "C" {
  extern int for__l_argc ;
  extern char** for__a_argv ;
}

static void _AdlibInit() {
  AdlibInit(for__l_argc, for__a_argv) ;
}

#endif

static GRP* globPtr ;
static GRP* rootPtr ;

static int ad_FromPointer(void* ptr) ;
static Procs* getProcs(int rank, int shape []) ;

void pcrc_init_() {
  _AdlibInit() ;

  globPtr = new GRP ;
  globPtr->grp    = apg ;
  globPtr->handle = ad_FromPointer(globPtr) ;  // should be 1

  rootPtr = new GRP ;
  rootPtr->grp    = *getProcs(0, (int*) 0) ;
  rootPtr->handle = ad_FromPointer(rootPtr) ;  // should be 2
}

void pcrc_finalize_() {
  AdlibFinalize() ;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//                                                                     //
//  Routines to convert to and from pointers.                          //
//                                                                     //
//  This code is lifted, with minimal modification, from               //
//  `mpich/src/util/ptrcvt.c'.  It is a dirty fix for the fact that    //
//  pointers and int's are different lengths on the DEC Alpha.         //
//                                                                     //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

struct Ad_PtrToIdx {
  int idx;
  void *ptr;
  Ad_PtrToIdx *next;
} ;

#define MAX_PTRS 10000

static Ad_PtrToIdx PtrArray[MAX_PTRS];
static Ad_PtrToIdx *avail=0;
static int      DoInit = 1;

static void ad_InitPointer() {
  int  i;
  for (i=0; i<MAX_PTRS-1; i++) {
    PtrArray[i].next = PtrArray + i + 1;
    PtrArray[i].idx  = i;
  }
  PtrArray[MAX_PTRS-1].next = 0;
  /* Don't start with the first one, whose index is 0. That could
     break some code. */
  avail   = PtrArray + 1;
}

static void *ad_ToPointer(int idx) {
  if (DoInit) {
    DoInit = 0;
    ad_InitPointer();
  }
  if (idx < 0 || idx >= MAX_PTRS) {
    fprintf(stderr, "** RUNTIME ERROR **  "
            "Could not convert index %d into a pointer\n", idx );
    exit(1);
  }
  if (idx == 0) return (void *)0;
  return PtrArray[idx].ptr;
}

static int ad_FromPointer(void* ptr) {
  int      idx;
  Ad_PtrToIdx *newP;
  if(DoInit) {
    DoInit = 0;
    ad_InitPointer();
  }
  if(!ptr) return 0;
  if(avail) {
    newP	      = avail;
    avail	      = avail->next;
    newP->next	      = 0;
    idx		      = newP->idx;
    PtrArray[idx].ptr = ptr;
    return idx;
  }
  // This isn't the right thing to do, but it isn't too bad
  fprintf(stderr, "** RUNTIME ERROR **  Pointer conversions exhausted\n" );
  exit(1);
  // Some systems may complain here about the lack of a return.
  return 0;
}

static void ad_RmPointer(int idx) {
  int myrank;
  if (DoInit) {
    DoInit = 0;
    ad_InitPointer();
    }
  if(idx < 0 || idx >= MAX_PTRS) {
    fprintf(stderr, "** RUNTIME ERROR **  "
            "Could not convert index %d into a pointer\n", idx );
    exit(1);
    }
  if (idx == 0) return;
  if (PtrArray[idx].next) {
    /* In-use pointers NEVER have next set */
    MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
    fprintf(stderr, "** RUNTIME ERROR **  "
	    "[%d] Error in recovering Fortran pointer; already freed\n", 
	    myrank );
    exit(1);
  }
  PtrArray[idx].next = avail;
  PtrArray[idx].ptr  = 0;
  avail              = PtrArray + idx;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//                                                                     //
// Processor grid.                                                     //
//                                                                     //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

// `processArrays' table is used to ensure that if several process
// grids are defined with the same shape they refer to the same
// `Procs' structure.  It shouldn't be confused with the handle-to-pointer
// translation table `PtrArray'.

// Construction and destruction.

struct Ad_ProcessArrayRecord {
  int rank ;
  int shape [7] ;
  Procs* procs ;
} ;

#define MAX_PROCESS_ARRAYS 100

static Ad_ProcessArrayRecord processArrays [MAX_PROCESS_ARRAYS] ;
static int numProcessArrays = 0 ;

static Procs* getProcs(int rank, int shape []) {

  // Scan `processArrays' table for pre-existing process array of the
  // same shape.  Return that if it exists.

  for(int slot = 0 ; slot < numProcessArrays ; slot++) {
    Ad_ProcessArrayRecord& processArray = processArrays [slot] ;
    if(rank == processArray.rank) {
      int i = 0 ;
      while (i < rank && shape [i] == processArray.shape [i]) i++ ;
      if(i == rank) return processArray.procs;
    }
  }

  // Otherwise create a new `Procs'

  if(numProcessArrays == MAX_PROCESS_ARRAYS) {
    fprintf(stderr, "** RUNTIME ERROR **  Process array records exhausted\n") ;
    exit(1) ;
    return 0 ;
  }
  else {
    int i ;

    // Check size of processor array is number of available processors.

    int size = 1 ;
    for (i = 0 ; i < rank ; i++)
      size *= shape [i] ;

    int asize = apg.size() ;

    if(size != asize && size != 1) {
      fprintf(stderr, "** RUNTIME ERROR **  "
              "Processor array requires %d processes---only %d available\n",
              size, asize) ;
      exit(1) ;
    }

    // Create new process array, and add it to `processArrays' table.

    Ad_ProcessArrayRecord& processArray = processArrays [numProcessArrays] ;

    processArray.rank = rank ;
    for (i = 0 ; i < rank ; i++)
      processArray.shape [i] = shape [i] ;
    processArray.procs = new Procs(rank, shape) ;

    numProcessArrays++ ;

    return processArray.procs ;
  }
}

int pcrc_new_group_grid_(int* rank, int* shape) {
  GRP* grpPtr = new GRP ;
  grpPtr->grp    = *getProcs(*rank, shape) ;
  grpPtr->handle = ad_FromPointer(grpPtr) ;

  return grpPtr->handle ;
}

void pcrc_delete_group_(int* grp) {
  delete (GRP*) ad_ToPointer(*grp) ;

  ad_RmPointer(*grp) ;
}

int pcrc_on_(int* grp) {
  GRP* ptr = (GRP*) ad_ToPointer(*grp) ;
  Group p = ptr->grp ;

  int result = p.on() ;
  p.no() ;
  
  return result ;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//                                                                     //
// struct DIM.                                                         //
//                                                                     //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

void DIM :: setDistribute(int _g_lb, int _g_ub, int distribution,
                          GRP* grpPtr, int dim) {
  Dimension d = grpPtr->grp.dim(dim - 1) ;
  const int extent = _g_ub - _g_lb + 1 ;
  switch(distribution) {
    case 1 :
      rng = Range(extent, d, BLK) ;
      break ;
    case 2 :
      rng = Range(extent, d, CYC) ;
      break ;
  }

  g_lb = _g_lb ;
  g_ub = _g_ub ;
  g_stride = 1 ;

  loopBounds() ;

  distCode  = distribution ;
  ghostSize = 0 ;

  t_lb = g_lb ;
  t_ub = g_ub ;
  t_stride = 1 ;
  t_offset = 0 ;

  switch(distribution) {
    case 1 : {
      int numProcs = d.size() ;
      t_blockSize = (extent + numProcs - 1) / numProcs ;
      break ;
    }
    case 2 :
      t_blockSize = 1 ;
      break ;
  }

  handle = ad_FromPointer(this) ;
}

void DIM :: setCollapse(int _g_lb, int _g_ub) {
  const int extent = _g_ub - _g_lb + 1 ;
  rng = Range(extent) ;

  g_lb = _g_lb ;
  g_ub = _g_ub ;
  g_stride = 1 ;

  loopBounds() ;

  distCode  = 0 ;
  ghostSize = 0 ;

  t_lb = g_lb ;
  t_ub = g_ub ;
  t_stride = 1 ;
  t_offset = 0 ;

  t_blockSize = extent ;

  handle = ad_FromPointer(this) ;
}

void DIM :: setAlign(int _g_lb, int _g_ub, int a, int b, DIM* parent) {
  const int extent = _g_ub - _g_lb + 1 ;
  const int base   = (a * _g_lb + b - parent->g_lb) / parent->g_stride ;
  const int stride = a / parent->g_stride ;
  rng = parent->rng.subrng(extent, base, stride) ;

  g_lb = _g_lb ;
  g_ub = _g_ub ;
  g_stride = 1 ;

  loopBounds() ;

  distCode  = parent->distCode  ;
  ghostSize = parent->ghostSize ;

  t_lb = parent->t_lb ;
  t_ub = parent->t_ub ;
  t_stride = a * parent->t_stride ;
  t_offset = b * parent->t_stride + parent->t_offset ;

  t_blockSize = parent->t_blockSize ;

  handle = ad_FromPointer(this) ;
}

void DIM :: setLoop(int _g_lb, int _g_ub, int _g_stride,
                    int a, int b, DIM* parent) {
  const int extent = (_g_ub - _g_lb) / _g_stride + 1 ;
  const int base   = (a * _g_lb + b - parent->g_lb) / parent->g_stride ;
  const int stride = a * _g_stride / parent->g_stride ;
  rng = parent->rng.subrng(extent, base, stride) ;

  g_lb = _g_lb ;
  g_ub = _g_ub ;
  g_stride = _g_stride ;

  loopBounds() ;

  distCode  = parent->distCode  ;
  ghostSize = parent->ghostSize ;

  t_lb = parent->t_lb ;
  t_ub = parent->t_ub ;
  t_stride = a * parent->t_stride ;
  t_offset = b * parent->t_stride + parent->t_offset ;

  t_blockSize = parent->t_blockSize ;

  handle = ad_FromPointer(this) ;
}

void DIM :: setCopy(DIM* parent) {
  *this = *parent ;

  handle = ad_FromPointer(this) ;
}

void DIM :: setTriplet(int lb, int ub, int stride, DIM* parent) {
  int extent = (ub - lb) / stride + 1 ;
  int base   = (lb - parent->g_lb) / parent->g_stride ;
  int stride_ = stride / parent->g_stride ;
  rng = parent->rng.subrng(extent, base, stride_) ;

  g_lb     = lb ;
  g_ub     = ub ;
  g_stride = stride ;

  loopBounds() ;

  distCode  = parent->distCode  ;
  ghostSize = parent->ghostSize ;

  t_lb = parent->t_lb ;
  t_ub = parent->t_ub ;
  t_stride = parent->t_stride ;
//  t_offset = parent->t_stride ;
  t_offset = parent->t_offset ;

  t_blockSize = parent->t_blockSize ;

  handle = ad_FromPointer(this) ;
}

void DIM :: unset() {
  ad_RmPointer(handle) ;
}

void DIM :: loopBounds() {
  LocBlocksIndex i(rng) ;

  l_lb     = i.blockBaseSub ;
  l_stride = i.blockStepSub ;
  l_ub     = l_lb + l_stride * (i.blockCount - 1) ;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//                                                                     //
// Range creation.                                                     //
//                                                                     //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

int pcrc_new_range_distribute_(int* g_lb, int* g_ub,
                               int* distribution, int* grp_grid, int* dim) {
  DIM* ptr = new DIM ;

  GRP* grpPtr = (GRP*) ad_ToPointer(*grp_grid) ;
  ptr->setDistribute(*g_lb, *g_ub, *distribution, grpPtr, *dim) ;

  return ptr->handle ;
}

int pcrc_new_range_collapse_(int* g_lb, int* g_ub) {

  DIM* ptr = new DIM ;

  ptr->setCollapse(*g_lb, *g_ub) ;

  return ptr->handle ;
}

int pcrc_new_range_align_(int* g_lb, int* g_ub,
                          int* a, int* b, int* rng_parent) {
  DIM* ptr = new DIM ;

  ptr->setAlign(*g_lb, *g_ub, *a, *b, (DIM*) ad_ToPointer(*rng_parent)) ;

  return ptr->handle ;
}

int pcrc_new_range_loop_(int* g_lb, int* g_ub, int* g_stride,
                         int* a, int* b, int* rng_parent) {
  DIM* ptr = new DIM ;

  ptr->setLoop(*g_lb, *g_ub, *g_stride, *a, *b,
               (DIM*) ad_ToPointer(*rng_parent)) ;

  return ptr->handle ;
}

int pcrc_new_range_copy_(int* rng_parent) {
  DIM* ptr = new DIM ;

  ptr->setCopy((DIM*) ad_ToPointer(*rng_parent)) ;

  return ptr->handle ;
}

void pcrc_delete_range_(int* rng) {
  DIM* ptr = (DIM*) ad_ToPointer(*rng) ;

  ptr->unset() ;

  delete ptr ;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//                                                                     //
// Array creation.                                                     //
//                                                                     //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

int pcrc_new_array_data_(void* data,
                         int* element_type, int* element_size,
                         int* rank, int* grp) {
  DAD* ptr = new DAD ;
  ptr->handle    = ad_FromPointer(ptr) ;

  GRP* grpPtr = (GRP*) ad_ToPointer(*grp) ;

  ptr->elementType = *element_type ;
  ptr->grp         = *grpPtr ;
  ptr->grp.handle  = ad_FromPointer(&(ptr->grp)) ;
//  ptr->array       = Array((char*) data, grpPtr->grp, DimensionSet(),
//                           *rank, new Range [*rank], new Stride [*rank],
//                           *element_size) ;
  ptr->array       = Array((char*) data, grpPtr->grp, *rank, *element_size) ;
  ptr->size        = 1 ;

  return ptr->handle ;
}

void pcrc_set_array_distribute_(int* dad, int* dim, int* g_lb, int* g_ub,
                                int* distribution,
                                int* grp_grid, int *grid_dim) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;

  int d = *dim - 1 ;
  DIM* rngPtr = ptr->dims + d ;
  
  GRP* grpPtr = (GRP*) ad_ToPointer(*grp_grid) ;
  rngPtr->setDistribute(*g_lb, *g_ub, *distribution, grpPtr, *grid_dim) ;

  ptr->strs [d] = ptr->size ;
  ptr->array.shp() [d] = rngPtr->rng ;

  ptr->array.sig() += rngPtr->rng.dim() ;

  Stride str(rngPtr->rng.vector(ptr->size)) ;
  ptr->size *= str.volume() ;
  ptr->array.lay() [d] = str ;
}

void pcrc_set_array_collapse_(int* dad, int* dim, int* g_lb, int* g_ub) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;

  int d = *dim - 1 ;
  DIM* rngPtr = ptr->dims + d ;
  
  rngPtr->setCollapse(*g_lb, *g_ub) ;

  ptr->strs [d] = ptr->size ;
  ptr->array.shp() [d] = rngPtr->rng ;

  Stride str(rngPtr->rng.vector(ptr->size)) ;
  ptr->size *= str.volume() ;
  ptr->array.lay() [d] = str ;
}

void pcrc_set_array_align_(int* dad, int* dim,
                           int* g_lb, int* g_ub,
                           int* a, int* b, int* rng_parent) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;

  int d = *dim - 1 ;
  DIM* rngPtr = ptr->dims + d ;
  
  DIM* parPtr = (DIM*) ad_ToPointer(*rng_parent) ;
  rngPtr->setAlign(*g_lb, *g_ub, *a, *b, parPtr) ;

  ptr->strs [d] = ptr->size ;
  ptr->array.shp() [d] = rngPtr->rng ;

  ptr->array.sig() += rngPtr->rng.dim() ;

  Stride str(rngPtr->rng.vector(ptr->size)) ;
  ptr->size *= str.volume() ;
  ptr->array.lay() [d] = str ;
}

void pcrc_set_array_loop_(int* dad, int* dim,
                          int* g_lb, int* g_ub, int* g_stride,
                          int* a, int* b, int* rng_parent) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;

  int d = *dim - 1 ;
  DIM* rngPtr = ptr->dims + d ;
  
  DIM* parPtr = (DIM*) ad_ToPointer(*rng_parent) ;
  rngPtr->setLoop(*g_lb, *g_ub, *g_stride, *a, *b, parPtr) ;

  ptr->strs [d] = ptr->size ;
  ptr->array.shp() [d] = rngPtr->rng ;

  ptr->array.sig() += rngPtr->rng.dim() ;

  Stride str(rngPtr->rng.vector(ptr->size)) ;
  ptr->size *= str.volume() ;
  ptr->array.lay() [d] = str ;
}

void pcrc_set_array_copy_(int* dad, int* dim, int* rng_parent) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;

  int d = *dim - 1 ;
  DIM* rngPtr = ptr->dims + d ;
  
  DIM* parPtr = (DIM*) ad_ToPointer(*rng_parent) ;
  rngPtr->setCopy(parPtr) ;

  ptr->strs [d] = ptr->size ;
  ptr->array.shp() [d] = rngPtr->rng ;

  ptr->array.sig() += rngPtr->rng.dim() ;

  Stride str(rngPtr->rng.vector(ptr->size)) ;
  ptr->size *= str.volume() ;
  ptr->array.lay() [d] = str ;
}

void pcrc_delete_array_(int* dad) {
  DAD* ptr = (DAD*) ad_ToPointer(*dad) ;

//  delete [] ptr->array.shp() ;
//  delete [] ptr->array.lay() ;

  ad_RmPointer(ptr->grp.handle) ;
  for(int i = 0 ; i < ptr->array.rnk() ; i++)
    ptr->dims [i].unset() ;

  ad_RmPointer(ptr->handle) ;

  delete ptr ;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//                                                                     //
// Section creation.                                                   //
//                                                                     //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

int pcrc_new_array_section_(int* rank, int* dad_parent) {
  DAD* ptr = new DAD ;
  ptr->handle    = ad_FromPointer(ptr) ;

  DAD* parPtr = (DAD*) ad_ToPointer(*dad_parent) ;

  ptr->elementType = parPtr->elementType ;

  ptr->grp         = parPtr->grp ;
  ptr->grp.handle  = ad_FromPointer(&(ptr->grp)) ;

//  ptr->array       = Array(parPtr->array.dat(), ptr->grp.grp,
//                           parPtr->array.sig(), *rank, new Range [*rank],
//                           new Stride [*rank],
//		           parPtr->array.len()) ;
  ptr->array       = Array(parPtr->array.dat(), ptr->grp.grp,
                           *rank, parPtr->array.len()) ;

  ptr->size        = parPtr->size ;

  return ptr->handle ;
}

void pcrc_set_array_triplet_(int* dad, int* dim,
			     int *lb, int *ub, int *stride,
			     int* dad_parent, int* dim_parent) {

  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;
  DAD* parPtr = (DAD*) ad_ToPointer(*dad_parent) ;

  DIM* rngPtr    = ptr->dims + *dim - 1 ;
  DIM* parRngPtr = parPtr->dims + *dim_parent - 1 ;

  rngPtr->setTriplet(*lb, *ub, *stride, parRngPtr) ;

  ptr->strs [*dim - 1] = parPtr->strs [*dim_parent - 1] ;

  ptr->array.shp() [*dim - 1] = rngPtr->rng ;
  ptr->array.lay() [*dim - 1] = parPtr->array.lay() [*dim_parent - 1] ;

  ptr->array.sig() += rngPtr->rng.dim() ;
}

void pcrc_set_array_scalar_(int* dad,
		            int *i,
		            int* dad_parent, int* dim_parent) {

  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;
  DAD* parPtr = (DAD*) ad_ToPointer(*dad_parent) ;

  DIM* parRngPtr = parPtr->dims + *dim_parent - 1 ;

  int j = (*i - parRngPtr->g_lb) / parRngPtr->g_stride ;

  Subscript s((parRngPtr->rng)(j)) ;
  int    len = parPtr->array.len() ;
  Stride str = parPtr->array.str(*dim_parent - 1) ;

  (char*&) ptr->array.dat() += len * str.offset(s) ;
  ptr->array.grp() /= s ;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//                                                                     //
// Array copying.                                                      //
//                                                                     //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

int pcrc_new_array_copy_(void* data, int* dad_parent) {
  DAD* ptr = new DAD ;
  DAD* parPtr = (DAD*) ad_ToPointer(*dad_parent) ;

  int rank = parPtr->array.rnk() ;
//  Range*  rngs = new Range  [rank] ;
//  Stride* strs = new Stride [rank] ;

  *ptr = *parPtr ;
  ptr->handle     = ad_FromPointer(ptr) ;
  ptr->grp.handle = ad_FromPointer(&(ptr->grp)) ;

//  for(int i = 0 ; i < rank ; i++) {
//    DIM& rng = ptr->dims [i] ;
//    rng.handle   = ad_FromPointer(&rng) ;
//
//    rngs [i] = ptr->array.rng(i) ;
//    strs [i] = ptr->array.str(i) ;
//  }
//
//  ptr->array = Array((char*) data, ptr->grp.grp, ptr->array.sig(),
//                     rank, rngs, strs, ptr->array.len()) ;

  ptr->array = Array(data, ptr->grp.grp, rank, ptr->array.len()) ;
  ptr->array.sig() = parPtr->array.sig() ;
  for(int i = 0 ; i < rank ; i++) {
    DIM* rng = ptr->dims + i ;
    rng->handle   = ad_FromPointer(rng) ;

    ptr->array.shp() [i] = parPtr->array.rng(i) ;
    ptr->array.lay() [i] = parPtr->array.str(i) ;
  }

  ptr->size  = parPtr->size ;  // implicit in *ptr = *parPtr?

  return ptr->handle ;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//                                                                     //
// Misc operations on arrays.                                          //
//                                                                     //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

int pcrc_grp_(int* dad) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;

  return ptr->grp.handle ;
}

int pcrc_rng_(int* dad, int* dim) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;
  DIM* rngPtr = ptr->dims + *dim - 1 ;

  return rngPtr->handle ;
}

int pcrc_str_(int* dad, int* dim) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;

  return ptr->strs [*dim - 1] ;
}

int pcrc_size_(int* dad) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;

  return ptr->size ;
}

void pcrc_reset_array_bounds_(int* dad, int* dim,
                      int* lb, int* ub, int* stride,
                      int* lb_parent, int* ub_parent, int* stride_parent) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;
  DIM* rngPtr = ptr->dims + *dim - 1 ;

  *lb_parent     = rngPtr->g_lb ;
  *ub_parent     = rngPtr->g_ub ;
  *stride_parent = rngPtr->g_stride ;

  rngPtr->g_lb     = *lb ;
  rngPtr->g_ub     = *ub ;
  rngPtr->g_stride = *stride ;

  int t_stride_parent = rngPtr->t_stride ;

  rngPtr->t_stride *= *stride_parent / *stride ;
  rngPtr->t_offset += t_stride_parent * *lb_parent - rngPtr->t_stride * *lb ;
}

void pcrc_reset_push_bounds_(int* dad, int* dim, int* lb, 
					int* lb_parent, int* ub_parent, int* stride_parent ) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;
  DIM* rngPtr = ptr->dims + *dim - 1 ;

	int stride = 1;
	int ub = (rngPtr->g_ub - rngPtr->g_lb) / rngPtr->g_stride + 1 ;

  *lb_parent     = rngPtr->g_lb ;
  *ub_parent     = rngPtr->g_ub ;
  *stride_parent = rngPtr->g_stride ;

  rngPtr->g_lb     = *lb ;
  rngPtr->g_ub     = ub ;
  rngPtr->g_stride = stride ;

  int t_stride_parent = rngPtr->t_stride ;

  rngPtr->t_stride = rngPtr->t_stride * *stride_parent / stride ;
  rngPtr->t_offset += t_stride_parent * *lb_parent - rngPtr->t_stride * *lb ;
}

void pcrc_reset_pop_bounds_(int* dad, int* dim,
				int* lb, int* ub, int* stride ) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;
  DIM* rngPtr = ptr->dims + *dim - 1 ;

	int lb_parent, ub_parent, stride_parent;

	lb_parent	 = rngPtr->g_lb ;
	ub_parent     = rngPtr->g_ub ;
	stride_parent = rngPtr->g_stride ;

  rngPtr->g_lb     = *lb ;
  rngPtr->g_ub     = *ub ;
  rngPtr->g_stride = *stride ;

  int t_stride_parent = rngPtr->t_stride ;

  rngPtr->t_stride = rngPtr->t_stride * stride_parent / *stride ;
  rngPtr->t_offset += t_stride_parent * lb_parent - rngPtr->t_stride * *lb ;
}

void pcrc_reset_array_base_(int* dad, void* data) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;

  ptr->array.dat() = (char*) data ;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//                                                                     //
// Address translation.                                                //
//                                                                     //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

int pcrc_glob_(int* rng, int* l_i) {
  DIM* rngPtr = (DIM*) ad_ToPointer(*rng) ;

  Range x = rngPtr->rng ;
  Dimension dim = x.dim() ;

  Subscript s ;

  s.dim = dim ;
  s.crd = dim ? dim.crd() : 0 ;
  s.blk = 0 ;
  s.sub = *l_i ;

  return rngPtr->g_lb + x(s) * rngPtr->g_stride ;
}

int pcrc_loc_(int* rng, int* g_i) {
  DIM* rngPtr = (DIM*) ad_ToPointer(*rng) ;

  Range x = rngPtr->rng ;

  Subscript& s = x((*g_i - rngPtr->g_lb) / rngPtr->g_stride) ;

  return s.sub ;
}

void pcrc_loop_bounds_(int* rng, int* l_lb, int* l_ub, int* l_stride) {
  DIM* ptr = (DIM*) ad_ToPointer(*rng) ;

  *l_lb     = ptr->l_lb ;
  *l_ub     = ptr->l_ub ;
  *l_stride = ptr->l_stride ;
}

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //
//                                                                     //
// Communication.                                                      //
//                                                                     //
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //

void pcrc_shift_(int* dad, int* dad_source, int* dim, int* amount) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;
  DAD* srcPtr = (DAD*) ad_ToPointer(*dad_source) ;

  shift(ptr->array, srcPtr->array, *amount, *dim - 1, EDGE) ;
}

void pcrc_tshift_(void* data, int* dad_source, int* dim, int* amount) {

  // This implementation is valid because PCRC arrays use Adlib
  // `STANDARD' layout---data segments are laid out following the
  // the template, or primitive range.

  DAD* srcPtr = (DAD*) ad_ToPointer(*dad_source) ;
  Array src = srcPtr->array ;

  int rank = src.rnk() ;
  int d = *dim - 1 ;

  // Create `Array' records containing a primitive range in
  // place of the actual source array range.

  Range* rngs = new Range [rank] ;
  for(int i = 0 ; i < rank ; i++)
    if(i == d)
      rngs [i] = src.rng(i).prm() ;
    else
      rngs [i] = src.rng(i) ;

  Array tmpSrc(src.dat(), src.grp(), src.sig(), rank, rngs,
               src.lay(), src.len()) ;
  Array tmpDst((char*) data, src.grp(), src.sig(), rank, rngs,
               src.lay(), src.len()) ;

  // Do the shift.

  shift(tmpDst, tmpSrc, *amount, d, EDGE) ;

  delete [] rngs ;
}

void pcrc_remap_(int* dad, int* dad_source) {
  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;
  DAD* srcPtr = (DAD*) ad_ToPointer(*dad_source) ;

  remap(ptr->array, srcPtr->array) ;
}

int pcrc_detect_communication_(int* dad, int* dad_source,
                               int* dim, int* l, int* u, int* stride,
                               int* a, int* b,
                               float* m, float* c, int *amount) {
  *m = 1.0 ;
  *c = 0.0 ;

  DAD* ptr    = (DAD*) ad_ToPointer(*dad) ;
  DAD* srcPtr = (DAD*) ad_ToPointer(*dad_source) ;

   int devide(int s1,int s2);
   int shift_detect(DAD *ptr, DAD *srcPtr, int l, int u, int s,
					int a, int b, int d);
   int no_communication_detect(DAD *ptr, DAD *srcPtr,int d, int l, int u, int s,
							int a, int b,float *m, float *c);
   void shift_amount(DAD *ptr, DAD *srcPtr,int p,int lx,int a,int b,int s,int d,
						int tx, int ty, float *u, float *v, int *amount);
   int d=*dim-1;

  int numProcs = (ptr->dims[d].rng.dim()!=NULL) ? 
			ptr->dims[d].rng.dim().size() : 1;
  int srcNumprocs = (srcPtr->dims[d].rng.dim()!=NULL) ?
			srcPtr->dims[d].rng.dim().size() : 1;

	*amount = 0;

  if (numProcs != srcNumprocs) return 2;
  if (ptr->dims[d].distCode != srcPtr->dims[d].distCode) return 2;

	int tx = devide(ptr->dims[d].t_ub-ptr->dims[d].t_lb+1,numProcs); 
	int ty = devide(srcPtr->dims[d].t_ub-srcPtr->dims[d].t_lb+1,numProcs);

  switch(ptr->dims[d].distCode) {
		case 0: 		// Collapse Distribution
				*amount = 0;
				*m = (float)srcPtr->dims[d].t_stride * (*a) /
							ptr->dims[d].t_stride;
				*c = (float)(srcPtr->dims[d].t_stride*(*a*
						(float)(1-ptr->dims[d].t_offset)/ptr->dims[d].t_stride
						+*b)+srcPtr->dims[d].t_offset-1);
				
				return 0;
			break;
		case 1 : {		// BLOCK Distribution
			int t1=ptr->dims[d].t_stride * ty;				// ax * ty
		    int t2=srcPtr->dims[d].t_stride*(*a)*tx;		// ay * a * tx
			if (t1 == t2) { 
//				int shift = shift_detect(ptr,srcPtr,*l,*u,*stride,*a,*b,d);
				if (!no_communication_detect(ptr,
							srcPtr,d,*l,*u,*stride,*a,*b,m,c)) return 0;

				shift_amount(ptr,srcPtr,numProcs,*l,*a,*b,*stride,d,
								tx,ty,m,c,amount);
//				if (shift == 0) { *c += *amount; return 0; }
//				else return 1;
				return 1;
			}
			break;
			}
		case 2 : {		// CYCLIC Distribution
			int t=(srcPtr->dims[d].t_stride*(*a)*(*stride)) % numProcs;
						//  ay * a * s (mod p)
			if (t == (ptr->dims[d].t_stride * (*stride) % numProcs)) {
						// ax * a (mod p)
//				int shift = shift_detect(ptr,srcPtr,*l,*u,*stride,*a,*b,d);
				shift_amount(ptr,srcPtr,numProcs,*l,*a,*b,*stride,d,
								tx,ty,m,c,amount);
				if (*amount == 0) return 0;
				else return 1;
			}
			break;
			}
	}

  return 2 ;
}

int shift_detect(DAD *ptr, DAD *srcPtr, int l, int u, int s,
					int a, int b, int d)
{
	int i,j;
	int number_x=0,number_y=0;

	for (i=l; i<=u; i+=s) {

//		DIM * rngPtr = &ptr->dims[d] ;

//		Range x = rngPtr.rng ;
		Range x = ptr->dims[d].rng;
		int i_a = (i - ptr->dims[d].g_lb) / ptr->dims[d].g_stride ;

        j = a * i + b ;

//		DIM* srcRngPtr = srcPtr->dims [d] ;

//		Range y = srcRngPtr.rng ;
		Range y = srcPtr->dims[d].rng ;
		int j_a = (j - srcPtr->dims[d].g_lb) / srcPtr->dims[d].g_stride ;

		if( x(i_a).crd != y(j_a).crd ) return 1;

    }
		return 0;

//	for (i=l; i<=u; i+=s) {
//		if (i>=ptr->dims[d].l_lb && i<=ptr->dims[d].l_ub) number_x++;
//		if (i>ptr->dims[d].l_ub) break;
//	}

//	for (i=a*l+b; i<=a*u+b; i+=a*s) {
//		if (i>=srcPtr->dims[d].l_lb && i<=srcPtr->dims[d].l_ub) number_y++;
//		if (i>srcPtr->dims[d].l_ub) break;
//	}
	
// if each processor has the same number of x array elements and y array
// elements, it does not need shift communication ( X array and Y array
// have the same distribution mode)

//	if (number_x == number_y) return 0;
//	else return 1;
}

void shift_amount(DAD *ptr, DAD *srcPtr,int p,int lx,int a, int b, int s, int d,
						int tx, int ty, float *u, float *v, int *amount)
{
   int devide(int s1,int s2);
   int lower_index(DAD *ptr, int d);
   int kx,ky_f,ky,kx_each,ky_each;

	int localCoord = ptr->dims[d].rng.dim().crd();

  switch(ptr->dims[d].distCode) {
		case 1 : 		// BLOCK Distribution
		    kx = ptr->dims[d].t_stride * lx + ptr->dims[d].t_offset;
	   	    ky_f = srcPtr->dims[d].t_stride*(a*lx+b)+srcPtr->dims[d].t_offset;
// debug ..............
	kx = kx - ptr->dims[d].t_lb + 1;
	ky_f = ky_f - srcPtr->dims[d].t_lb + 1;
// ..........   debug

			ky = devide(kx*ty,tx);
			*amount = ky_f - ky;
			*u = (float)a*srcPtr->dims[d].t_stride/ptr->dims[d].t_stride;
		
		//	int kx_each = kx + localCoord * ptr->dims[d].t_blockSize;

			if (kx>=lower_index(ptr,d) && 
					kx<=lower_index(ptr,d)+ptr->dims[d].t_blockSize)
				kx_each = kx;
			else kx_each = kx + s*ptr->dims[d].t_stride * 
					devide(lower_index(ptr,d)-kx, s*ptr->dims[d].t_stride);

//	int l_tlb = lower_index(ptr,d);
//	int kx_each;
//	if (l_tlb > kx) kx_each = l_tlb + s*ptr->dims[d].t_stride - 
//								(l_tlb - kx) % (s*ptr->dims[d].t_stride);
//	else kx_each = kx;

			ky_each = devide(kx_each * ty, tx);

			if (ky>=lower_index(srcPtr,d) && 
					ky<=lower_index(srcPtr,d)+srcPtr->dims[d].t_blockSize)
				ky_each = ky;
			else ky_each = ky + a*s*srcPtr->dims[d].t_stride * 
		devide(lower_index(srcPtr,d)-ky+*amount, a*s*srcPtr->dims[d].t_stride);

			*v = (ky_each-lower_index(srcPtr,d)-*amount) - 
					(kx_each-lower_index(ptr,d))*(*u);

// .... debug
int m,lkx,lky;
int blockSize, l_tlbx,l_tlby;
	m = s*ptr->dims[d].t_stride;
		localCoord = ptr->dims[d].rng.dim().crd();
        blockSize = devide(ptr->dims[d].t_ub-ptr->dims[d].t_lb+1, p);
        l_tlbx = ptr->dims[d].t_lb + localCoord * blockSize;
		    kx = ptr->dims[d].t_stride * lx + ptr->dims[d].t_offset;
        if (kx >= l_tlbx && kx <= l_tlbx + blockSize)
            lkx = kx;
        else
            lkx = kx + m * devide(l_tlbx-kx, m);

	m = a*s*srcPtr->dims[d].t_stride;
		localCoord = ptr->dims[d].rng.dim().crd();
        blockSize = devide(srcPtr->dims[d].t_ub-srcPtr->dims[d].t_lb+1, p);
        l_tlby = srcPtr->dims[d].t_lb + localCoord * blockSize;
	   	    ky = srcPtr->dims[d].t_stride*(a*lx+b)+srcPtr->dims[d].t_offset;
        if (ky >= l_tlby && ky <= l_tlby + blockSize)
            lky = ky;
        else
            lky = ky + m * devide(l_tlby-ky+*amount, m);

        *v = (float)((lky-l_tlby-*amount) - (float)(lkx-l_tlbx)*(*u));

// debug ....

printf("u = %f v = %f amount = %d\n",*u,*v,*amount);

			break;

		case 2 : 		// CYCLIC Distribution
		    kx = ptr->dims[d].t_stride * lx + ptr->dims[d].t_offset;
	   	    ky_f = srcPtr->dims[d].t_stride*(a*lx+b)+srcPtr->dims[d].t_offset;
			int px = (kx - ptr->dims[d].t_lb) % p;
			int py = (ky_f - srcPtr->dims[d].t_lb) %p;
			if (px == py) *amount = 0;
			else if (px > py && (ky_f/p) > (kx/p))  
						*amount = py + (p - px);
				else		*amount = py - px;

			*u = (float)a*srcPtr->dims[d].t_stride/ptr->dims[d].t_stride;
			*v = (float)((srcPtr->dims[d].t_stride*((a*(localCoord
				+ptr->dims[d].t_lb-ptr->dims[d].t_offset)/ptr->dims[d].t_stride)
				+b)+srcPtr->dims[d].t_offset-localCoord
				-srcPtr->dims[d].t_lb-(*amount))/p);

			break;
  }

}

int lower_index(DAD *ptr, int d)
{
	int l_tlb_a;

	int localCoord = ptr->dims[d].rng.dim().crd();
	switch (ptr->dims[d].distCode) {
		case 1 : {						// BLOCK Distribution
				l_tlb_a = localCoord * ptr->dims[d].t_blockSize;
				break;
			}
		case 2 : {						// CYCLIC Distribution
				l_tlb_a = localCoord;
				break;
			}
	}
	return l_tlb_a + ptr->dims[d].t_lb;
}

int devide(int s1,int s2)
{
	int s = s1 / s2;
	int q = s1 % s2;
	if (q>0) s++;
	else if (q<0) s--;
	return s;
}

int no_communication_detect(DAD *ptr, DAD *srcPtr,int d, int l, int u, int s,
							int a, int b,float *m, float *c)
{
	int sx = ptr->dims[d].t_stride * s;
	int sy = srcPtr->dims[d].t_stride * s * a;
  	int numProcs=ptr->dims[d].rng.dim().size();
	int wx = devide(ptr->dims[d].t_ub-ptr->dims[d].t_lb+1,numProcs); 
	int wy = devide(srcPtr->dims[d].t_ub-srcPtr->dims[d].t_lb+1,numProcs);

	int l_tlbx[16], l_tubx[16], lkx[16], ukx[16];
	int l_tlby[16], l_tuby[16], lky[16], uky[16];
	int i;

	int ltx = ptr->dims[d].t_lb;
	int lty = srcPtr->dims[d].t_lb;

	for (i=0;i<=numProcs;i++) {
		l_tlbx[i] = ltx + i* wx;
		l_tubx[i] = ltx + (i+1) * wx -1;
		l_tlby[i] = lty + i * wy;
		l_tuby[i] = lty + (i+1) * wy -1;
	}

	int kx = ptr->dims[d].t_stride * l + ptr->dims[d].t_offset;
    int ky = srcPtr->dims[d].t_stride*(a*l+b)+srcPtr->dims[d].t_offset;

	for (i=0; i<=numProcs; i++) {
		if (l_tlbx[i] > ptr->dims[d].t_stride * u + ptr->dims[d].t_offset ||
			l_tubx[i] < kx)
			lkx[i] = ltx -1;
		else if (l_tlbx[i] > kx)
				lkx[i] = kx + devide(l_tlbx[i] - kx, sx) * sx;
			 else lkx[i] = kx;
		
		if (l_tubx[i] < ptr->dims[d].t_stride * u + ptr->dims[d].t_offset)
			ukx[i] = kx + (l_tubx[i] - kx) / sx * sx;
		else ukx[i] = ptr->dims[d].t_stride * u + ptr->dims[d].t_offset;

		if (l_tlby[i]>srcPtr->dims[d].t_stride*(a*u+b)+srcPtr->dims[d].t_offset
					 || l_tuby[i] < ky)
			lky[i] = lty -1;
		else if (l_tlby[i] > ky)
				lky[i] = ky + devide(l_tlby[i] - ky, sy) * sy;
			 else lky[i] = ky;
		
		if (l_tuby[i]<srcPtr->dims[d].t_stride*(a*u+b)+srcPtr->dims[d].t_offset)
			uky[i] = ky + (l_tuby[i] - ky) / sy * sy;
		else uky[i]=srcPtr->dims[d].t_stride*(a*u+b)+ srcPtr->dims[d].t_offset;

		*m = (float)a*srcPtr->dims[d].t_stride/ptr->dims[d].t_stride;

		if (lkx[i] != ltx-1) {
			int ex = (ukx[i] - lkx[i]) / sx;
			int ey = (uky[i] - lky[i]) / sy;
			*c = (float)(lky[i] - l_tlby[i] - (float)((*m)*(lkx[i]-l_tlbx[i])));
			if (ex != ey) return 1;
		}
	}
	return 0;
}

void pcrc_coef_(int * dad, int *dim, int *l, int *u, int *s, int *a, int *b,
					int *amount, int *m, int *c)
{
	int kx, ky;
	int localCoord, blockSize, l_tlb, lkx;
	int devide(int s1,int s2);
	int gcd(int s1, int s2);

	DAD* ptr  = (DAD*) ad_ToPointer(*dad) ;

	int d = *dim - 1;
	int p = (ptr->dims[d].rng.dim()!=NULL) ?
            ptr->dims[d].rng.dim().size() : 1;

	switch(ptr->dims[d].distCode) {
		case 0 :					// Collapse Distribution
			*m = ptr->dims[d].t_stride * *a * *s;		// u = ax*a*s
			kx = ptr->dims[d].t_stride * (*a**l+*b) + ptr->dims[d].t_offset;
			*c = kx - ptr->dims[d].t_lb;
			break;

		case 1 :					// BLOCK distribution
			*m = ptr->dims[d].t_stride * *a * *s;		// u = ax*a*s
			localCoord = ptr->dims[d].rng.dim().crd();
			blockSize = devide(ptr->dims[d].t_ub-ptr->dims[d].t_lb+1, p);
			kx = ptr->dims[d].t_stride * (*a**l+*b) + ptr->dims[d].t_offset;
			l_tlb = ptr->dims[d].t_lb + localCoord * blockSize;
			if (kx >= l_tlb && kx <= l_tlb + blockSize)
				lkx = kx;
			else 
				lkx = kx + *m * devide(l_tlb-kx+*amount, *m);
			*c = lkx - l_tlb - *amount;
			break;

		case 2 :					// CYCLIC distribution
			int sx =  ptr->dims[d].t_stride * *a * *s;
			int g = gcd(sx, p);
			kx = ptr->dims[d].t_stride * (*a**l+*b) + ptr->dims[d].t_offset;
			localCoord = ptr->dims[d].rng.dim().crd();
			int i;
			
			for (i=0; i<p/g; i++) {
				lkx = kx + i * sx - ptr->dims[d].t_lb - *amount;
				if (localCoord == lkx % p) {
					*c = lkx / p;
					break;
				}
			}
			*m = sx / g;
			break;
	}
}

int gcd(int s1, int s2)
{
	int i, gcd;
	int j = s1<s2 ? s1 : s2;
	for (i=1; i<=j; i++)
		if (s1%i==0 && s2%i==0) gcd = i;
	return gcd;
}

void pcrc_print_dad_(int *dad, int *dim)
{
	int d = *dim - 1;
    DAD* ptr  = (DAD*) ad_ToPointer(*dad) ;
	printf("Dad is : t_lb = %d\tt_ub = %d\tt_stride = %d\tt_offset = %d\n",
			ptr->dims[d].t_lb,ptr->dims[d].t_ub,
			ptr->dims[d].t_stride,ptr->dims[d].t_offset);
}