GitLab maintenance scheduled for Today, 2020-02-27, from 17:00 to 18:00 CT - Services will be unavailable during this time.

darshan-gen-cc.pl.in 7.73 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12
#!/usr/bin/perl -w
#
#  (C) 2009 by Argonne National Laboratory.
#      See COPYRIGHT in top-level directory.
#

# takes a standard mpicc script as an argument and tried to generate a
# darshan-enabled mpicc script to mimic it's behavior

use Getopt::Long;
use English;

13 14 15 16
$CP_WRAPPERS="@CP_WRAPPERS@";
$DARSHAN_LIB_PATH="@darshan_lib_path@";
$CP_ZLIB_LINK_FLAGS="@__CP_ZLIB_LINK_FLAGS@";

17 18
my $input_file = "";
my $output_file = "";
19
my $trim_exe_path = 0;
20
my $xl_check=0;
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

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);
}

40 41 42 43 44 45 46 47 48
# we just want the first line of output from the mpi script's -v argument;
# the rest we assume will be generated by the underlying compiler
my $version_out = `$input_file -v 2>/dev/null |head -n 1`;
if (!($version_out))
{
    printf STDERR "Error: failed to invoke $input_file with -v\n";
    exit(1);
}

49 50 51 52 53 54
# 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);
}
55 56
chomp($compile_cmd);
chomp($link_cmd);
57
chomp($version_out);
58

59 60 61 62 63 64 65 66 67 68 69 70 71 72
#
# 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/\/*([^\/ ]+\/)*//;
}

73 74
open (OUTPUT, ">$output_file") || die("Error opening output file: $!");

75
# substitute arguments and darshan options into commands
76 77
$base_link_cmd = $link_cmd;
$base_link_cmd =~ s/foo.o -o foo/"\$\{allargs\[\@\]\}"/g;
78
$link_cmd =~ s/foo.o -o foo/"\$\{newallargs\[\@\]\}" -L$DARSHAN_LIB_PATH $CP_ZLIB_LINK_FLAGS -ldarshan-mpi-io -lz $CP_WRAPPERS/g;
79
$link_cmd =~ s/$/ -L$DARSHAN_LIB_PATH -ldarshan-posix/g;
80
$compile_cmd =~ s/-c foo.c/"\$\{allargs\[\@\]\}"/g;
81

82 83 84 85
# create link cmd with noshrargs variable
$link_cmd_no_shared = $base_link_cmd;
$link_cmd_no_shared =~ s/allargs/noshrargs/;

86
print OUTPUT<<'EOF';
Philip Carns's avatar
Philip Carns committed
87
#!/bin/bash
88 89 90 91 92 93 94 95
#
# 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=
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
EOF

if ($xl_check == 1)
{
print OUTPUT<<'EOF';
#
# Check for IBM XL Linker Parameters
#
# If IPA linker is used, we must disable darshan
# because the IPA linker doesn't support -wrap.
#
function check_XL()
{
    arg=$1;
    ipa_enabled=0;

    if [ "$arg" = "-O5" ]; then
        ipa_enabled=1;
    fi 
    if [ "$arg" = "-O4" ]; then
        ipa_enabled=1;
    fi 
    if [ "$arg" = "-qipa" ]; then
        ipa_enabled=1;
    fi

    return $ipa_enabled;
}
EOF
}
126

127
print OUTPUT<<'EOF';
128 129 130 131 132 133 134 135 136 137 138 139 140
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
    ;;
141 142 143 144 145 146 147 148 149 150 151 152
    -v)
    # Pass this argument to the compiler as well.
EOF
print OUTPUT<<"EOF";
    echo "$version_out"
EOF
print OUTPUT<<'EOF';
    # if there is only 1 argument, it must be -v.
    if [ "$#" -eq "1" ] ; then
        linking=no
    fi
    ;;
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
    -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
169
EOF
170
print OUTPUT<<"EOF";
171 172 173 174 175 176 177 178
    # 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

179 180
    # if allargs includes any libraries, then we need to get 
    # -ldarshan-mpi-io in there first
181 182
    argno=0;
    once=0;
183
    compiler_check=0;
184 185
    newallargs=\("\$\{allargs\[\@\]\}"\);
    for arg in "\$\{newallargs\[\@\]\}"; do
186
        res=`expr match "\$arg" "-l"`;
187 188 189 190 191 192 193 194
        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
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
EOF

#
# Add any functional tests for linker parameters
#
       if ($xl_check)
       {
print OUTPUT<<"EOF";
           check_XL "\$arg";
           if [ \$? -ne 0 ]; then
               compiler_check=1;
           fi
EOF
       }

print OUTPUT<<"EOF";
211 212
        argno=`expr \$argno + 1`
    done
213

214 215 216 217 218 219
    used_darshan=0

    # create a temporary file
    tmpfile=`mktemp`
    # generate a map of the symbol names
    # don't use -shared for this step
220 221 222 223 224 225 226 227 228 229
    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

230 231 232
    # is MPI in there?
    grep MPI \$tmpfile >& /dev/null
    rc_mpi=\$?
233 234
    # 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
235 236 237 238 239 240 241 242
    rc_pmpi=\$?
    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
243
        if [ \$rc_pmpi -ne 0 ] && [ \$compiler_check -eq 0 ]; then
Philip Carns's avatar
Philip Carns committed
244
            \$Show $link_cmd
245 246 247 248 249 250
            used_darshan=1
        fi
    fi

    # otherwise use the normal command line
    if [ "\$used_darshan" = "0" ] ; then
Philip Carns's avatar
Philip Carns committed
251
        \$Show $base_link_cmd
252 253
    fi
    rc=\$?
254
else
255 256
    \$Show $compile_cmd
    rc=\$?
257 258
fi

259
exit \$rc
260 261 262 263 264 265 266 267 268 269
EOF

close(OUTPUT);

chmod(0755, $output_file); 

exit(0);

sub process_args
{
270
    use vars qw( $opt_help $opt_output $opt_trim $opt_xl );
271 272 273

    Getopt::Long::Configure("no_ignore_case", "bundling");
    GetOptions( "help",
274
        "output=s",
275 276
        "trim",
        "xl");
277 278 279 280 281 282 283

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

284 285 286 287 288
    if($opt_trim)
    {
        $trim_exe_path=1;
    }

289 290 291 292 293
    if($opt_xl)
    {
        $xl_check=1;
    }

294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
    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
{
318
    print<<"EOF";
319 320 321 322 323

Usage: $PROGRAM_NAME <stock mpicc> --output <modified mpicc>

    --help          Prints this help message
    --output        Specifies name of output script
324
    --trim          Trim the compilers path
325 326
    --xl            Disables darshan if certain linker parameters are used
                    (Intended for IBM XL Compilers)
327 328 329 330 331 332 333 334 335 336

Purpose:

    This script takes an existing mpicc script as input and generates a
    modified version that includes Darshan support.

EOF
    return;
}