diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /devtools/bin/vmpi_test.pl | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'devtools/bin/vmpi_test.pl')
| -rw-r--r-- | devtools/bin/vmpi_test.pl | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/devtools/bin/vmpi_test.pl b/devtools/bin/vmpi_test.pl new file mode 100644 index 0000000..4fe22d2 --- /dev/null +++ b/devtools/bin/vmpi_test.pl @@ -0,0 +1,385 @@ +#!/usr/bin/perl -w +use Getopt::Long; +use Pod::Usage; +use Sys::Hostname; +use File::Copy; +use File::Path; +use Time::HiRes qw(gettimeofday tv_interval); +use Cwd; +use strict; + +use vars qw(%TESTS %STATS $ABORT_RUN $MPI_GRAPHICS); + +# To add a new test, just create a new hash entry that has code +# references for the Prep, Run and Clean stages of the test. +# The new test can be selected using the -test option. + +%TESTS = ( + 'vrad' => { + 'PREP' => \&VRADPrep, + 'RUN' => \&VRADRun, + 'CLEAN' => \&VRADClean, + }, + + 'vvis' => { + 'PREP' => \&VVISPrep, + 'RUN' => \&VVISRun, + 'CLEAN' => \&VVISClean, + }, + + 'shadercompile' => { + 'PREP' => \&ShaderPrep, + 'RUN' => \&ShaderRun, + 'CLEAN' => \&ShaderClean, + } + ); + +%STATS = (); +$ABORT_RUN = 0; +$MPI_GRAPHICS = 0; + +local $SIG{INT} = sub { + $ABORT_RUN = 1; +}; + +my $start = 4; +my $stop = 32; +my $step = 4; +my $test = "vrad"; +my $list = undef; +my $help = 0; +my $man = 0; + +my @work_list = (); +GetOptions("file=s" => \$list, + "test=s" => \$test, + "workerlist=s" => sub { + shift; local $_ = shift; + @work_list = split(',', $_) + }, + "start|s=i" => \$start, + "stop|e=i" => \$stop, + "step=i" => \$step, + "graphics" => \$MPI_GRAPHICS, + "help|?" => \$help, + "man" => \$man) or pod2usage(2); +pod2usage(1) if $help; +pod2usage(-exitstatus => 0, -verbose => 2) if $man; + +my @extra_args = @ARGV; + +unless (@work_list) { + for (my $workers = $stop; $workers >= $start; $workers -= $step) { + push @work_list, $workers; + } +} + +if (defined($list)) { + @work_list = ReadMachineList($list, \@work_list); +} + +unless (@work_list) { + die "No workers in list\n"; +} + +my $logfile = "$test-$$.log"; +print "Testing: ", join(", ", @work_list), "\n"; +print "Logging to $logfile\n"; + +# Redirect console to log file and unbuffer the output +open STDOUT, ">$logfile"; +open STDERR, ">>$logfile"; +my $oldfh = select(STDOUT); $| = 1; +select(STDERR); $| = 1; +select($oldfh); + +# Lock the list of machines if given +# Prepare for the test +# Run the test over the work list +# Clean up after the test +# Release lock on list of machines if given + +my $pass = defined($list) ? ReserveMachines($list, $test) : ''; +TestPrep($test, @extra_args); +for my $workers (@work_list) { + last if $ABORT_RUN; + TestRun($test, $workers, $pass, @extra_args); +} +TestClean($test, @extra_args); +ReleaseMachines($list) if defined($list); + +sub ReadMachineList +{ + my $list = shift; + my $work_list = shift; + + my @machines = (); + + if (open(my $listfh, $list)) { + while(my $line = <$listfh>) { + chomp($line); + next unless $line =~ /\S/; + push @machines, $line; + } + } + + my @capped_list = grep { $_ <= scalar(@machines) } @{$work_list}; + if ($#{$work_list} > $#capped_list) { + print "Not enough machines to run test\n"; + print "Reducing max workers\n\n"; + } + return @capped_list; +} + +sub SetVMPIPass { + my $machines = shift; + my $pass = shift; + + system("vmpi_chpass.pl", "-p", $pass, "-f", $machines); +} + +sub ReserveMachines +{ + my $list = shift; + my $pass = shift; + + my $host = lc hostname(); + $pass .= "-test-$host-$$"; + SetVMPIPass($list, $pass); + return $pass; +} + +sub ReleaseMachines +{ + my $machines = shift; + SetVMPIPass($machines, ''); +} + +sub DoTestFunc +{ + my $test = shift; + my $func = shift; + my $workers = $_[0]; + + if (exists($TESTS{$test}{$func})) { + my $start = [gettimeofday]; + &{$TESTS{$test}{$func}}(@_); + my $stop = [gettimeofday]; + my $time = tv_interval($start, $stop); + $STATS{$func}{$workers} = $time / 60; + } + else { + die "Failed to locate test function for: $test($func)\n"; + } +} + +sub TestPrep +{ + my $test = shift; + DoTestFunc($test, 'PREP', 0, '', @_); +} + +sub TestRun +{ + my $test = shift; + DoTestFunc($test, 'RUN', @_); +} + +sub TestClean +{ + my $test = shift; + DoTestFunc($test, 'CLEAN', 0, '', @_); +} + +sub GetMPIArgs +{ + my $n_workers = shift; + my $pass = shift; + + my @args = ("-mpi"); + push(@args, "-mpi_workercount", $n_workers) if $n_workers > 0; + push(@args, "-mpi_pw", $pass) if $pass; + push(@args, "-mpi_graphics", "-mpi_trackevents") if $MPI_GRAPHICS; + return @args; +} + + +sub VRADPrep +{ + my $n_workers = shift; + my $pass = shift; + my $basename = shift; + my @extra_args = @_; + my @mpi_args = GetMPIArgs($n_workers, $pass); + + system("vbsp", $basename); + system("vvis", @mpi_args, @extra_args, $basename); + copy("$basename.bsp", "$basename-$$.bsp"); +} + +sub VRADRun +{ + my $n_workers = shift; + my $pass = shift; + my $basename = shift; + my @extra_args = @_; + my @mpi_args = GetMPIArgs($n_workers, $pass); + + copy("$basename-$$.bsp", "$basename.bsp"); + system("vrad", "-final", "-staticproppolys", "-staticproplighting", + @mpi_args, @extra_args, $basename); + +} + +sub VRADClean +{ + my $n_workers = shift; + my $pass = shift; + my $basename = shift; + + unlink("$basename.bsp", "$basename-$$.bsp"); +} + + +sub VVISPrep +{ + my $n_workers = shift; + my $pass = shift; + my $basename = shift; + my @mpi_args = GetMPIArgs($n_workers, $pass); + + system("vbsp", $basename); + copy("$basename.bsp", "$basename-$$.bsp"); +} + +sub VVISRun +{ + my $n_workers = shift; + my $pass = shift; + my $basename = shift; + my @extra_args = @_; + my @mpi_args = GetMPIArgs($n_workers, $pass); + + copy("$basename-$$.bsp", "$basename.bsp"); + system("vvis", @mpi_args, $pass, @extra_args, $basename); +} + +sub VVISClean +{ + my $n_workers = shift; + my $pass = shift; + my $basename = shift; + + unlink("$basename.bsp", "$basename-$$.bsp"); +} + +sub ShaderPrep +{ + my $n_workers = shift; + my $pass = shift; + my $basename = shift; + + $ENV{DIRECTX_SDK_VER}='pc09.00'; + $ENV{DIRECTX_SDK_BIN_DIR}='dx9sdk\\utilities'; + $ENV{PATH} .= ";..\\..\\devtools\\bin"; + + my $src_base = "../.."; + my $dos_base = $src_base; + $dos_base =~ s|/|\\|g; + + unlink("makefile.$basename"); + unlink(qw(filelist.txt filestocopy.txt filelistgen.txt inclist.txt vcslist.txt)); + rmtree("shaders"); + mkpath(["shaders/fxc", "shaders/vsh", "shaders/psh"]); + + print "Update Shaders\n"; + system("updateshaders.pl", "-source", $dos_base, $basename); + + print "Prep Shaders\n"; + system("nmake", "/S", "/C", "-f", "makefile.$basename"); + if (open(my $fh, ">>filestocopy.txt")) { + print $fh "$dos_base\\$ENV{DIRECTX_SDK_BIN_DIR}\\dx_proxy.dll\n"; + print $fh "$dos_base\\..\\game\\bin\\shadercompile.exe\n"; + print $fh "$dos_base\\..\\game\\bin\\shadercompile_dll.dll\n"; + print $fh "$dos_base\\..\\game\\bin\\vstdlib.dll\n"; + print $fh "$dos_base\\..\\game\\bin\\tier0.dll\n"; + } + + print "Uniqify List\n"; + system("uniqifylist.pl < filestocopy.txt > uniquefilestocopy.txt"); + copy("filelistgen.txt", "filelist.txt"); + print "Done Prep\n"; +} + +sub ShaderRun +{ + my $n_workers = shift; + my $pass = shift; + my $basename = shift; + my @extra_args = @_; + my @mpi_args = GetMPIArgs($n_workers, $pass); + + my $old_dir = getcwd(); + my $dos_dir = $old_dir; + $dos_dir =~ s|/|\\|g; + + system("shadercompile", "-allowdebug", "-shaderpath", $dos_dir, @mpi_args, @extra_args); +} + +sub ShaderClean +{ + my $n_workers = shift; + my $pass = shift; + my $basename = shift; + + unlink("makefile.$basename"); + unlink(qw(filelist.txt filestocopy.txt filelistgen.txt inclist.txt vcslist.txt)); + mkpath(["shaders/fxc", "shaders/vsh", "shaders/psh"]); +} + +END { + if (%STATS) { + print "\n\n", "-"x70, "\n\n"; + for my $func (qw(PREP RUN CLEAN)) { + print "$func\n"; + print "="x length($func), "\n"; + for my $workers (sort {$a <=> $b} keys %{$STATS{$func}}) { + printf("%3d, %6.3f\n", $workers, $STATS{$func}{$workers}); + } + print "\n"; + } + } +} + +__END__ + +=head1 NAME + +vmpi_test.pl - Test utility to automate execution of VMPI tools + +=head1 SYNOPSIS + +vmpi_test.pl [-test <test name>] [-file <host file>] [-start <num>] [-stop <num>] [-step <num>] [-workerlist <list>] [-graphics] [-help|-?] [-man] + + Options: + -test The name of the test to run + -file A file that contains the names of machines to use + -start Lowest worker count to test + -stop Highest worker count to test + -step Interval to increment worker count + -workerlist A comma separated list of worker counts to test + -graphics Enable MPI visual work unit tracker + -help|-? Display command line usage + -man Display full documentation + +=head1 DESCRIPTION + +B<vmpi_test.pl> executes a specified test for each number of worker +counts given on the command line. The worker counts can be provided as +a start, stop and step relationship, or it can be specified using a +comma separated list. An optional host list file can be provided to +restrict the test to a given set of machines. These machines will have +a VMPI password applied to them so that you will get exclusive access +to them. + +=cut |