#!/bin/sh
# Do a little magic to run perl from anywhere in your path.

lines=`cat $0 | wc -l`
lines=`expr $lines - 10`
tail -$lines $0 > /tmp/meshtvperl$$
echo "__END__" >> /tmp/meshtvperl$$
echo "$0 $*" >> /tmp/meshtvperl$$
exec perl /tmp/meshtvperl$$ $0 ${1+"$@"}

unlink $0;
$0 = shift @ARGV;

###############################################################################
#
#         Run MeshTV on various architectures
#
# Programmer:  Sean Ahern (adopted from a script that Jeremy Meredith wrote)
# Date      :  Aug 12, 1999
#
# Modifications:
#
#    Jeremy Meredith, Fri Mar 24 11:42:48 PST 2000
#    Added partition argument for parallel MeshTV.
#
#    Brad Whitlock, Mon Mar 27 17:39:37 PST 2000
#    Added tflops o/s.
#
#    Lisa J. Roberts, Fri May 12 14:42:33 PDT 2000
#    Changed luke to oak, since luke no longer exists. [HYPer01812]
#    I also appended our path info to the user's path so more
#    machines can find Netscape when they need it. [HYPer01801]
#
#    Eric Brugger, Fri Sep  1 16:14:32 PDT 2000
#    I added "-DFS" to the psub command line so that jobs running in batch
#    can access dfs.
#
###############################################################################

# Set a secure and reasonable path
$ENV{PATH} = join ':' , ("$ENV{PATH}","/bin","/usr/bin","/usr/sbin",
                         "/usr/local/bin", "/usr/bsd","/usr/ucb" );

# Determine OS and set binary directory "meshtvbindir"

# set base directory
chomp( $progdir = `dirname $0` );
chomp( $cwd = `pwd`        );

for ($progdir) {
    /^\//  && do { $tmpdir = $progdir; last; }; # starts with `/'
    /^\.$/ && do { $tmpdir = $cwd; last; };     # is exactly  `.'
    $tmpdir = "$cwd/$progdir";
}
chomp( $meshtvdir = `dirname $tmpdir` );

$use_psub = 0;
$use_yod = 0;
$meshtvbindir = "unsupported";
chomp( $os = `uname -s` );
$os =~ tr/[A-Z]/[a-z]/;
for ($os) {
    /irix/ && do {
        $version = `uname -r`;
        $version =~ s/(^[456])\..*/irix$1/ ;
        for ($version) {
            /irix4/ && do {
                $meshtvbindir = "$meshtvdir/bin/sgi-irix4-mips";
                last;
            };
            /irix5/ && do {
                $meshtvbindir = "$meshtvdir/bin/sgi-irix5-mips";
                last;
            };
            /irix6/ && do {
                $meshtvbindir = "$meshtvdir/bin/sgi-irix6-mips2";
                last;
            };
        }
        last;
    };
    /sunos/ && do {
        chomp( $mach    = `uname -m` );
        chomp( $version = `uname -r` );
        $version =~ s/([45])\..*/sunos$1/ ;
        if ($mach =~ /^sun4/) {
            $meshtvbindir = "$meshtvdir/bin/sun4-$version-sparc";
        }
        last;
    };
    /hp-ux/ && do {
        if (`uname -m` =~ /9000\/[78]/) {
            $meshtvbindir = "$meshtvdir/bin/hp-hpux-pa";
        }
        last;
    };
    /aix/ && do {
        $meshtvbindir = "$meshtvdir/bin/ibm-aix-pwr";
        $use_psub = 1;
        last;
    };
    /osf/ && do {
        $meshtvbindir = "$meshtvdir/bin/dec-osf1-alpha";
        last;
    };
    /linux/ && do {
        $meshtvbindir = "$meshtvdir/bin/linux";
        last;
    };
    /tflops/ && do {
        $meshtvbindir = "$meshtvdir/bin/intel-tflops-ppro";
        $use_yod = 1;
        last;
    };
}

# Set some defaults.
$parallel_usage = "
    Optional parallel arguments:
        -np #           The number of processors to use (required)
";
if (! $use_psub && ! $use_yod)
{
    $parallel_usage .= "
        -p partition    Partition to run in (required to launch using prun)
";
}
if ($use_psub)
{
    $parallel_usage .= "
        -r name         The parallel job name (optional)
        -c pool         Constraints used to determine the set of hosts on
                            which the job must run (optional)
        -b bank         Bank from which permitted resources are to be
                            drawn (optional)
        -tM time        Maximum job run time (optional)
        -a acct         Account that is to be charged (optional)
";
}
$usage = "
USAGE:
    meshtv [parallel arguments] [-i Silo_file] [-x meshtvx_name]
           [-geometry spec]

    Normal arguments:
        -i Silo_file        A Silo file to open upon startup
        -x meshtvx_name     The pathname of the meshtvx binary to use
        -geometry spec      What portion of the screen to use.  This is a
                            standard X Windows geometry specification
";

$parallel = 0;
$want_version = 0;
$np   = 0;
$name = "meshtv";
$bank = "";
$time = "";
$acct = "";
($node) = split /\./,`hostname`;
($sector = $node) =~ tr/[0-9]//d;
$pool = "pbatch,$sector";
$part = "";

# Parse the arguments
@meshtvargs = ();
while ($arg = shift @ARGV) {
    if    ($arg eq "-np")   { $np   = shift; $parallel = 1; }
    elsif ($arg eq "-r" )   { $name = shift; $name_set = 1; }
    elsif ($arg eq "-c" )   { $pool = shift; $pool_set = 1; }
    elsif ($arg eq "-b" )   { $bank = shift; $bank_set = 1; }
    elsif ($arg eq "-tM")   { $time = shift; $time_set = 1; }
    elsif ($arg eq "-a" )   { $acct = shift; $acct_set = 1; }
    elsif ($arg eq "-p" )   { $part = shift; $part_set = 1; }
    elsif ($arg eq "-help") { print "$usage\n$parallel_usage\n"; exit(0); }
    elsif ($arg eq "-version") { $want_version = 1; }
    else                    { push @meshtvargs, $arg; }
}

# Check for sanity
if ((!$parallel)
    and ($name_set or $pool_set or $bank_set or $time_set or $acct_set or $part_set)
   )
{
    print STDERR <<"EOF";
You specified a parallel argument without using -np to specify the number of
processors.  Please add an -np argument.
EOF
    print STDERR $usage;
    print STDERR $parallel_usage;
    exit(1);
}

if (($parallel) and ($np < 2))
{
    print STDERR <<"EOF";
You must specify more than one processor to execute parallel MeshTV.
You specified \"$np\" processors.
EOF
    exit 1;
}

# Check for errors
if ($meshtvbindir eq "unsupported")
{
    print STDERR <<"EOF";
This hardware platform is not supported by MeshTV.
EOF
    exit 1;
}

if (! -d $meshtvbindir)
{
    print STDERR <<"EOF";
The executables for this hardware platform have not been installed.
EOF
    exit 1;
}


# Set required environment variables
$ENV{TRAP_FPE} = "";
$ENV{MESHTVHOME}     = "$meshtvdir";
$ENV{MESHTVHELPHOME} = "$meshtvdir/help";
$ENV{MESHTVURLHOME}  = "file:/usr/lib/meshtv/";
#    gethostbyname("oak.scf.cln") ? "http://oak.scf.cln/" : "http://www.llnl.gov/";

# Find the executables
$gui_name = "meshtv";
$cli_name = $gui_name."x";
if ($parallel)
{
    $gui_name .= "p";
    $cli_name .= "p";
}
@gui = grep(/$gui_name[\d\.]+$/,<$meshtvbindir/$gui_name*>);

$msg = "";
if (scalar(@gui) == 0)
{
    $msg = "parallel " if ($parallel);
    print STDERR <<"EOF";
No versions of ${msg}MeshTV have been installed for this hardware platform.
EOF
    exit(1);
}

@guiversions = @gui;
@guiversions = grep( s/^.*$gui_name//, @guiversions);
$max = 0;
foreach $num (@guiversions)
{
    $version = $num;
    $num =~ s/(\d\.\d)\.(\d)/$1$2/;
    if ($num > $max)
    {
        $max = $num;
        $max_version = $version;
    }
}

if ($want_version)
{
    print STDERR <<"EOF";
The latest version of MeshTV installed on this platform is $max_version.
EOF
    exit(0);
}

# Check to see if we have a meshtvx of the same version number
if (! -x "$meshtvbindir/$cli_name$max_version")
{
    print STDERR <<"EOF";
MeshTV has not been installed properly.  Version $max_version of the GUI is 
installed, but no corresponding CLI is installed.
EOF
    exit(1);
}

@meshtvcmd = ("$meshtvbindir/$gui_name$max_version",
              "-x","$meshtvbindir/$cli_name$max_version",
              @meshtvargs);

# Run it!
if ($parallel)
{
    if ($use_psub) {
        @psubcmd = ("psub");
        push @psubcmd, "-x";
        push @psubcmd, "-DFS";
        push @psubcmd, "-ln", int(($np+3)/4);
        push @psubcmd, "-g",  $np;
        push @psubcmd, "-r",  $name  if $name;
        push @psubcmd, "-c",  $pool  if $pool;
        push @psubcmd, "-b",  $bank  if $bank;
        push @psubcmd, "-tM", $time  if $time;
        push @psubcmd, "-a",  $acct  if $acct;
        push @psubcmd, "-i", "cd $cwd ; setenv DISPLAY $ENV{DISPLAY} ; ".
                             "@meshtvcmd";

        @psubnicecmd = @psubcmd;
        push @psubnicecmd, ("\"".(pop @psubnicecmd)."\"");
        print "Running: @psubnicecmd\n";
        exec @psubcmd or die "Can't execute psub: $!\n";
    }
    elsif ($use_yod) {
        # The GUI cannot run the CLI on the red machine in parallel.
        # Just run the CLI.
        @meshtvxcmd = ("$meshtvbindir/$cli_name$max_version", @meshtvargs);
        @yodcmd = ("/cougar/bin/yod");
        push @yodcmd,"-sz",$np;
        push @yodcmd,@meshtvxcmd;

        @printcmd = @meshtvxcmd;
        chomp($printcmd[0] = `basename $printcmd[0]`);
        print "Running: yod -sz $np @printcmd\n";
        exec @yodcmd or die "Can't execute yod: $!\n";
    }
    else {
        push @meshtvcmd, "-np",$np;
        push @meshtvcmd, "-p", $part  if $part;
        @printcmd = @meshtvcmd;
        chomp($printcmd[0] = `basename $printcmd[0]`);
        chomp($printcmd[2] = `basename $printcmd[2]`);
        print "Running: @printcmd\n";
        exec @meshtvcmd or die "Can't execute meshtv: $!\n";
    }
} else {
    @printcmd = @meshtvcmd;
    chomp($printcmd[0] = `basename $printcmd[0]`);
    chomp($printcmd[2] = `basename $printcmd[2]`);
    print "Running: @printcmd\n";
    exec @meshtvcmd or die "Can't execute meshtv: $!\n";
}
