darshan-gen-cxx.pl.in 6.39 KB
Newer Older
Philip Carns's avatar
Philip Carns committed
1 2 3 4 5 6
#!/usr/bin/perl -w
#
#  (C) 2009 by Argonne National Laboratory.
#      See COPYRIGHT in top-level directory.
#

7 8
# takes a standard mpicxx script as an argument and tried to generate a
# darshan-enabled mpicxx script to mimic it's behavior
Philip Carns's avatar
Philip Carns committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

use Getopt::Long;
use English;

$CP_WRAPPERS="@CP_WRAPPERS@";
$DARSHAN_LIB_PATH="@darshan_lib_path@";
$CP_ZLIB_LINK_FLAGS="@__CP_ZLIB_LINK_FLAGS@";

my $input_file = "";
my $output_file = "";

process_args();

# run original mpicc with -show argument to capture command line for
# compilation and linking
my $compile_cmd = `$input_file -show -c foo.c`;
if (!($compile_cmd))
{
    printf STDERR "Error: failed to invoke $input_file with -show\n";
    exit(1);
}

my $link_cmd = `$input_file -show foo.o -o foo`;
if (!($link_cmd))
{
    printf STDERR "Error: failed to invoke $input_file with -show\n";
    exit(1);
}

# check command lines for accuracy
if(!($compile_cmd =~ /-c foo.c/) || !($link_cmd =~ /foo.o -o foo/))
{
    printf STDERR "Error: faulty output from $input_file with -show.\n";
    exit(1);
}
chomp($compile_cmd);
chomp($link_cmd);

47 48 49 50 51 52 53 54 55 56 57 58 59 60
#
# Incomprehensible re to eat the leading path of the compiler command
# and only give the basename.
#
# /cmd -> cmd
# cmd -> cmd
# /x/y/x/z/cmd -> cmd
#
if($trim_exe_path)
{
    $compile_cmd =~ s/\/*([^\/ ]+\/)*//;
    $link_cmd =~ s/\/*([^\/ ]+\/)*//;
}

Philip Carns's avatar
Philip Carns committed
61 62 63 64 65
open (OUTPUT, ">$output_file") || die("Error opening output file: $!");

# substitute arguments and darshan options into commands
$base_link_cmd = $link_cmd;
$base_link_cmd =~ s/foo.o -o foo/"\$\{allargs\[\@\]\}"/g;
66
$link_cmd =~ s/foo.o -o foo/"\$\{newallargs\[\@\]\}" -L$DARSHAN_LIB_PATH $CP_ZLIB_LINK_FLAGS \$CXXMPICH -ldarshan-mpi-io -lz $CP_WRAPPERS/g;
Philip Carns's avatar
Philip Carns committed
67 68 69
$link_cmd =~ s/$/ -L$DARSHAN_LIB_PATH -ldarshan-posix/g;
$compile_cmd =~ s/-c foo.c/"\$\{allargs\[\@\]\}"/g;

70 71 72 73
# create link cmd with noshrargs variable
$link_cmd_no_shared = $base_link_cmd;
$link_cmd_no_shared =~ s/allargs/noshrargs/;

74
print OUTPUT<<'EOF';
Philip Carns's avatar
Philip Carns committed
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
#!/bin/bash
#
# Auto-generated mpicc script from darshan-gen-cc.pl
#
#
# Internal variables
# Show is set to echo to cause the compilation command to be echoed instead 
# of executed.
Show=

linking=yes
allargs=("$@")
argno=0
for arg in "$@" ; do
    # Set addarg to no if this arg should be ignored by the C compiler
    addarg=yes
    case "$arg" in 
 	# ----------------------------------------------------------------
	# Compiler options that affect whether we are linking or no
    -c|-S|-E|-M|-MM)
    # The compiler links by default
    linking=no
    ;;
    -show)
    addarg=no
    Show=echo
    ;;
    esac
    if [ $addarg = no ] ; then
	unset allargs[$argno]
    fi
    # Some versions of bash do not accept ((argno++))
    argno=`expr $argno + 1`
done
if [ "$linking" = yes ] ; then
    if [ -n "$C_LINKPATH_SHL" ] ; then
	# prepend the path for the shared libraries to the library list
	mpilibs="$C_LINKPATH_SHL$libdir $mpilibs"
    fi
EOF
115
print OUTPUT<<"EOF";
Philip Carns's avatar
Philip Carns committed
116 117 118 119 120 121 122 123
    # Trial run to generate a symbol listing.  We only enable Darshan if:
    # a) MPI is used
    # b) PMPI is _not_ used
    #
    # We want Darshan to get out of the way if the user is doing a runtime
    # test in configure (in which case MPI objects break the executable) or
    # if the user is using another PMPI based tool

124 125
    # if allargs includes any libraries, then we need to get 
    # -ldarshan-mpi-io in there first
126 127 128 129
    argno=0;
    once=0;
    newallargs=\("\$\{allargs\[\@\]\}"\);
    for arg in "\$\{newallargs\[\@\]\}"; do
130
        res=`expr match "\$arg" "-l"`;
131 132 133 134 135 136 137 138 139 140
        if [ \$res -gt 0 -a \$once -lt 1 ]; then
            newallargs[\$argno]=-ldarshan-mpi-io
            argno=`expr \$argno + 1`
            newallargs[\$argno]=\$arg;
            once=1;
        else
            newallargs[\$argno]=\$arg;
        fi
        argno=`expr \$argno + 1`
    done
141

Philip Carns's avatar
Philip Carns committed
142 143 144 145 146 147
    used_darshan=0

    # create a temporary file
    tmpfile=`mktemp`
    # generate a map of the symbol names
    # don't use -shared for this step
148 149 150 151 152 153 154 155 156 157
    argno=0
    noshrargs=\("\$\{allargs\[\@\]\}");
    for arg in "\$\{noshrargs\[\@\]\}"; do
        if [ "\$arg" = "-shared" ]; then
            unset noshrarg[\$argno];
        fi
        argno=`expr \$argno + 1`
    done
    $link_cmd_no_shared -Wl,-Map,\$tmpfile \$LDFLAGS -o /dev/null >& /dev/null

Philip Carns's avatar
Philip Carns committed
158 159 160 161 162 163 164 165 166
    # is MPI in there?
    grep MPI \$tmpfile >& /dev/null
    rc_mpi=\$?

    # is PMPI being used for any init, finalize, or mpi-io calls?
    grep -E \\(PMPI_File_\\)\\|\\(PMPI_Init\\)\\|\\(PMPI_Finalize\\) \$tmpfile | grep -v -E \\(mpich.cnk.a\\|mpich.a\\) |grep \\(PMPI >& /dev/null
    rc_pmpi=\$?

    # normal or cnk libraries?
167
    grep -E mpich\\.cnk \$tmpfile >& /dev/null
Philip Carns's avatar
Philip Carns committed
168 169
    rc_cnk_check=\$?
    if [ \$rc_cnk_check -eq 0 ] ; then
170 171 172
        CXXMPICH=-lcxxmpich.cnk
    else
        CXXMPICH=-lcxxmpich
Philip Carns's avatar
Philip Carns committed
173 174 175 176 177 178 179 180 181 182
    fi

    rm \$tmpfile >& /dev/null

    # disable darshan if the executable is not an MPI program (this feature
    # mainly allows runtime configure tests to work
    if [ \$rc_mpi -eq 0 ] ; then
        # disable darshan if something else is already using PMPI; we don't
        # want to cause any symbol conflicts
        if [ \$rc_pmpi -ne 0 ] ; then
183
            \$Show $link_cmd
Philip Carns's avatar
Philip Carns committed
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
            used_darshan=1
        fi
    fi

    # otherwise use the normal command line
    if [ "\$used_darshan" = "0" ] ; then
        \$Show $base_link_cmd
    fi
    rc=\$?
else
    \$Show $compile_cmd
    rc=\$?
fi

exit \$rc
EOF

close(OUTPUT);

chmod(0755, $output_file); 

exit(0);

sub process_args
{
209
    use vars qw( $opt_help $opt_output $opt_trim );
Philip Carns's avatar
Philip Carns committed
210 211 212

    Getopt::Long::Configure("no_ignore_case", "bundling");
    GetOptions( "help",
213 214
        "output=s",
        "trim");
Philip Carns's avatar
Philip Carns committed
215 216 217 218 219 220 221

    if($opt_help)
    {
        print_help();
        exit(0);
    }

222 223 224 225 226
    if($opt_trim)
    {
        $trim_exe_path=1;
    }

Philip Carns's avatar
Philip Carns committed
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
    if($opt_output)
    {
        $output_file = $opt_output;
    }
    else
    {
        print_help();
        exit(1);
    }

    # there should only be one remaining argument: the input file 
    if($#ARGV != 0)
    {
        print "Error: invalid arguments.\n";
        print_help();
        exit(1);
    }
    $input_file = $ARGV[0];

    return;
}

sub print_help
{
251
    print<<"EOF";
Philip Carns's avatar
Philip Carns committed
252

253
Usage: $PROGRAM_NAME <stock mpicxx> --output <modified mpicc>
Philip Carns's avatar
Philip Carns committed
254 255 256

    --help          Prints this help message
    --output        Specifies name of output script
257
    --trim          Trim the compilers path
Philip Carns's avatar
Philip Carns committed
258 259 260

Purpose:

261
    This script takes an existing mpicxx script as input and generates a
Philip Carns's avatar
Philip Carns committed
262 263 264 265 266 267
    modified version that includes Darshan support.

EOF
    return;
}