Update Kokkos library to r2.6.00

This commit is contained in:
Stan Moore
2018-03-08 10:57:08 -07:00
parent 0c4c002f34
commit 39786b1740
694 changed files with 12261 additions and 6745 deletions

View File

@ -0,0 +1,5 @@
jenkins_test_driver is designed to be run through Jenkins as a
multiconfiguration job. It relies on a number of environment variables that will
only be set when run in that context. It is possible to override these if you
know the Jenkins job setup. It is not recommended that a non-expert try to run
this script directly.

View File

@ -0,0 +1,83 @@
#!/bin/bash -x
echo "Building for BUILD_TYPE = ${BUILD_TYPE}"
echo "Building with HOST_COMPILER = ${HOST_COMPILER}"
echo "Building in ${WORKSPACE}"
module use /home/projects/modulefiles
BUILD_TYPE=`echo $BUILD_TYPE | tr "~" " "`
build_options=""
for item in ${BUILD_TYPE}; do
build_options="$build_options --with-$item"
done
kokkos_path=${WORKSPACE}/kokkos
gtest_path=${WORKSPACE}/kokkos/tpls/gtest
echo ${WORKSPACE}
pwd
#extract information from the provided parameters.
host_compiler_brand=`echo $HOST_COMPILER | grep -o "^[a-zA-Z]*"`
cuda_compiler=`echo $BUILD_TYPE | grep -o "cuda_[^ ]*"`
host_compiler_module=`echo $HOST_COMPILER | tr "_" "/"`
cuda_compiler_module=`echo $cuda_compiler | tr "_" "/"`
build_path=`echo $BUILD_TYPE | tr " " "_"`
module load $host_compiler_module
module load $cuda_compiler_module
case $host_compiler_brand in
gcc)
module load nvcc-wrapper/gnu
compiler=g++
;;
intel)
module load nvcc-wrapper/intel
compiler=icpc
;;
*)
echo "Unrecognized compiler brand."
exit 1
;;
esac
#if cuda is on we need to set the host compiler for the
#nvcc wrapper and make the wrapper the compiler.
if [ $cuda_compiler != "" ]; then
export NVCC_WRAPPER_DEFAULT_COMPILER=$compiler
compiler=$kokkos_path/bin/nvcc_wrapper
fi
if [ $host_compiler_brand == "intel" -a $cuda_compiler != "" ]; then
echo "Intel compilers are not supported with cuda at this time."
exit 0
fi
rm -rf test-$build_path
mkdir test-$build_path
cd test-$build_path
/bin/bash $kokkos_path/generate_makefile.bash $build_options --kokkos-path="$kokkos_path" --with-gtest="$gtest_path" --compiler=$compiler 2>&1 |tee configure.out
if [ ${PIPESTATUS[0]} != 0 ]; then
echo "Configure failed."
exit 1
fi
make build-test 2>&1 | tee build.log
if [ ${PIPESTATUS[0]} != 0 ]; then
echo "Build failed."
exit 1
fi
make test 2>&1 | tee test.log
grep "FAIL" test.log
if [ $? == 0 ]; then
echo "Tests failed."
exit 1
fi

View File

@ -0,0 +1,287 @@
#! /usr/bin/env python
"""
Compute the size at which the current compiler will start to
significantly scale back optimization.
The CPP file being modified will need the following tags.
// JGF_DUPLICATE_BEGIN - Put before start of function to duplicate
// JGF_DUPLICATE_END - Put after end of function to duplcate
// JGF_DUPE function_name(args); - Put anywhere where it's legal to
put a function call but not in your timing section.
The program will need to output the string:
FOM: <number>
This will represent the program's performance
"""
import argparse, sys, os, doctest, subprocess, re, time
VERBOSE = False
###############################################################################
def parse_command_line(args, description):
###############################################################################
parser = argparse.ArgumentParser(
usage="""\n%s <cppfile> <build-command> <run-command> [--verbose]
OR
%s --help
OR
%s --test
\033[1mEXAMPLES:\033[0m
> %s foo.cpp 'make -j4' foo
""" % ((os.path.basename(args[0]), ) * 4),
description=description,
formatter_class=argparse.ArgumentDefaultsHelpFormatter
)
parser.add_argument("cppfile", help="Name of file to modify.")
parser.add_argument("buildcmd", help="Build command")
parser.add_argument("execmd", help="Run command")
parser.add_argument("-v", "--verbose", action="store_true",
help="Print extra information")
parser.add_argument("-s", "--start", type=int, default=1,
help="Starting number of dupes")
parser.add_argument("-e", "--end", type=int, default=1000,
help="Ending number of dupes")
parser.add_argument("-n", "--repeat", type=int, default=10,
help="Number of times to repeat an individial execution. Best value will be taken.")
parser.add_argument("-t", "--template", action="store_true",
help="Use templating instead of source copying to increase object size")
parser.add_argument("-c", "--csv", action="store_true",
help="Print results as CSV")
args = parser.parse_args(args[1:])
if (args.verbose):
global VERBOSE
VERBOSE = True
return args.cppfile, args.buildcmd, args.execmd, args.start, args.end, args.repeat, args.template, args.csv
###############################################################################
def verbose_print(msg, override=None):
###############################################################################
if ( (VERBOSE and not override is False) or override):
print msg
###############################################################################
def error_print(msg):
###############################################################################
print >> sys.stderr, msg
###############################################################################
def expect(condition, error_msg):
###############################################################################
"""
Similar to assert except doesn't generate an ugly stacktrace. Useful for
checking user error, not programming error.
"""
if (not condition):
raise SystemExit("FAIL: %s" % error_msg)
###############################################################################
def run_cmd(cmd, ok_to_fail=False, input_str=None, from_dir=None, verbose=None,
arg_stdout=subprocess.PIPE, arg_stderr=subprocess.PIPE):
###############################################################################
verbose_print("RUN: %s" % cmd, verbose)
if (input_str is not None):
stdin = subprocess.PIPE
else:
stdin = None
proc = subprocess.Popen(cmd,
shell=True,
stdout=arg_stdout,
stderr=arg_stderr,
stdin=stdin,
cwd=from_dir)
output, errput = proc.communicate(input_str)
output = output.strip() if output is not None else output
stat = proc.wait()
if (ok_to_fail):
return stat, output, errput
else:
if (arg_stderr is not None):
errput = errput if errput is not None else open(arg_stderr.name, "r").read()
expect(stat == 0, "Command: '%s' failed with error '%s'" % (cmd, errput))
else:
expect(stat == 0, "Command: '%s' failed. See terminal output" % cmd)
return output
###############################################################################
def build_and_run(source, cppfile, buildcmd, execmd, repeat):
###############################################################################
open(cppfile, 'w').writelines(source)
run_cmd(buildcmd)
best = None
for i in xrange(repeat):
wait_for_quiet_machine()
output = run_cmd(execmd)
current = None
fom_regex = re.compile(r'^FOM: ([0-9.]+)$')
for line in output.splitlines():
m = fom_regex.match(line)
if (m is not None):
current = float(m.groups()[0])
break
expect(current is not None, "No lines in output matched FOM regex")
if (best is None or best < current):
best = current
return best
###############################################################################
def wait_for_quiet_machine():
###############################################################################
while(True):
time.sleep(2)
# The first iteration of top gives garbage results
idle_pct_raw = run_cmd("top -bn2 | grep 'Cpu(s)' | tr ',' ' ' | tail -n 1 | awk '{print $5}'")
idle_pct_re = re.compile(r'^([0-9.]+)%id$')
m = idle_pct_re.match(idle_pct_raw)
expect(m is not None, "top not returning output in expected form")
idle_pct = float(m.groups()[0])
if (idle_pct < 95):
error_print("Machine is too busy, waiting for it to become free")
else:
break
###############################################################################
def add_n_dupes(curr_lines, num_dupes, template):
###############################################################################
function_name = None
function_invocation = None
function_lines = []
function_re = re.compile(r'^.* (\w+) *[(]')
function_inv_re = re.compile(r'^.*JGF_DUPE: +(.+)$')
# Get function lines
record = False
definition_insertion_point = None
invocation_insertion_point = None
for idx, line in enumerate(curr_lines):
if ("JGF_DUPLICATE_BEGIN" in line):
record = True
m = function_re.match(curr_lines[idx+1])
expect(m is not None, "Could not find function in line '%s'" % curr_lines[idx+1])
function_name = m.groups()[0]
elif ("JGF_DUPLICATE_END" in line):
record = False
definition_insertion_point = idx + 1
elif (record):
function_lines.append(line)
elif ("JGF_DUPE" in line):
m = function_inv_re.match(line)
expect(m is not None, "Could not find function invocation example in line '%s'" % line)
function_invocation = m.groups()[0]
invocation_insertion_point = idx + 1
expect(function_name is not None, "Could not find name of dupe function")
expect(function_invocation is not None, "Could not find function invocation point")
expect(definition_insertion_point < invocation_insertion_point, "fix me")
dupe_func_defs = []
dupe_invocations = ["int jgf_rand = std::rand();\n", "if (false) {}\n"]
for i in xrange(num_dupes):
if (not template):
dupe_func = list(function_lines)
dupe_func[0] = dupe_func[0].replace(function_name, "%s%d" % (function_name, i))
dupe_func_defs.extend(dupe_func)
dupe_invocations.append("else if (jgf_rand == %d) " % i)
if (template):
dupe_call = function_invocation.replace(function_name, "%s<%d>" % (function_name, i)) + "\n"
else:
dupe_call = function_invocation.replace(function_name, "%s%d" % (function_name, i)) + "\n"
dupe_invocations.append(dupe_call)
curr_lines[invocation_insertion_point:invocation_insertion_point] = dupe_invocations
curr_lines[definition_insertion_point:definition_insertion_point] = dupe_func_defs
###############################################################################
def report(num_dupes, curr_lines, object_file, orig_fom, curr_fom, csv=False, is_first_report=False):
###############################################################################
fom_change = (curr_fom - orig_fom) / orig_fom
if (csv):
if (is_first_report):
print "num_dupes, obj_byte_size, loc, fom, pct_diff"
print "%s, %s, %s, %s, %s" % (num_dupes, os.path.getsize(object_file), len(curr_lines), curr_fom, fom_change*100)
else:
print "========================================================"
print "For number of dupes:", num_dupes
print "Object file size (bytes):", os.path.getsize(object_file)
print "Lines of code:", len(curr_lines)
print "Field of merit:", curr_fom
print "Change pct:", fom_change*100
###############################################################################
def obj_size_opt_check(cppfile, buildcmd, execmd, start, end, repeat, template, csv=False):
###############################################################################
orig_source_lines = open(cppfile, 'r').readlines()
backup_file = "%s.orig" % cppfile
object_file = "%s.o" % os.path.splitext(cppfile)[0]
os.rename(cppfile, backup_file)
orig_fom = build_and_run(orig_source_lines, cppfile, buildcmd, execmd, repeat)
report(0, orig_source_lines, object_file, orig_fom, orig_fom, csv=csv, is_first_report=True)
i = start
while (i < end):
curr_lines = list(orig_source_lines)
add_n_dupes(curr_lines, i, template)
curr_fom = build_and_run(curr_lines, cppfile, buildcmd, execmd, repeat)
report(i, curr_lines, object_file, orig_fom, curr_fom, csv=csv)
i *= 2 # make growth function configurable?
os.remove(cppfile)
os.rename(backup_file, cppfile)
###############################################################################
def _main_func(description):
###############################################################################
if ("--test" in sys.argv):
test_results = doctest.testmod(verbose=True)
sys.exit(1 if test_results.failed > 0 else 0)
cppfile, buildcmd, execmd, start, end, repeat, template, csv = parse_command_line(sys.argv, description)
obj_size_opt_check(cppfile, buildcmd, execmd, start, end, repeat, template, csv)
###############################################################################
if (__name__ == "__main__"):
_main_func(__doc__)

View File

@ -0,0 +1,66 @@
#!/bin/bash
. /etc/profile.d/modules.sh
echo "build-dir $1"
echo "backend $2"
echo "module $3"
echo "compiler $4"
echo "cxxflags $5"
echo "architecrure $6"
echo "debug $7"
echo "kokkos-options $8"
echo "kokkos-cuda-options $9"
echo "hwloc $9"
NOW=`date "+%Y%m%d%H%M%S"`
BASEDIR="$1-$NOW"
mkdir $BASEDIR
cd $BASEDIR
module load $2
if [ $9 == "yes" ]; then
if [ $7 == "debug" ]; then
../generate_makefile.sh --with-devices=$2 \
--compiler=$4 \
--cxxflags=$5 \
--arch=$6 \
--debug \
--with-options=$8 \
--with-cuda-options=$9
--with-hwloc=${HWLOC_ROOT}
else
../generate_makefile.sh --with-devices=$2 \
--compiler=$4 \
--cxxflags=$5 \
--arch=$6 \
--debug \
--with-options=$8 \
--with-cuda-options=$9
--with-hwloc=${HWLOC_ROOT}
fi
else
if [ $7 == "debug" ]; then
../generate_makefile.sh --with-devices=$2 \
--compiler=$4 \
--cxxflags=$5 \
--arch=$6 \
--debug \
--with-options=$8 \
--with-cuda-options=$9
else
../generate_makefile.sh --with-devices=$2 \
--compiler=$4 \
--cxxflags=$5 \
--arch=$6 \
--debug \
--with-options=$8 \
--with-cuda-options=$9
fi
fi
make test
return $?