From 69f2911e04ffb1b19eef1fafb8c040af271f656e Mon Sep 17 00:00:00 2001 From: Tor Aamodt Date: Thu, 15 Jul 2010 18:09:46 -0800 Subject: creating branch for adding support for CUDA 3.x and Fermi [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 6829] --- benchmarks/CUDA/CP/driver/__init__.py | 33 +++ benchmarks/CUDA/CP/driver/actions.py | 109 ++++++++++ benchmarks/CUDA/CP/driver/benchmark.py | 374 +++++++++++++++++++++++++++++++++ benchmarks/CUDA/CP/driver/futures.py | 14 ++ benchmarks/CUDA/CP/driver/globals.py | 16 ++ benchmarks/CUDA/CP/driver/options.py | 208 ++++++++++++++++++ benchmarks/CUDA/CP/driver/process.py | 181 ++++++++++++++++ benchmarks/CUDA/CP/driver/text.py | 75 +++++++ 8 files changed, 1010 insertions(+) create mode 100644 benchmarks/CUDA/CP/driver/__init__.py create mode 100644 benchmarks/CUDA/CP/driver/actions.py create mode 100644 benchmarks/CUDA/CP/driver/benchmark.py create mode 100644 benchmarks/CUDA/CP/driver/futures.py create mode 100644 benchmarks/CUDA/CP/driver/globals.py create mode 100644 benchmarks/CUDA/CP/driver/options.py create mode 100644 benchmarks/CUDA/CP/driver/process.py create mode 100644 benchmarks/CUDA/CP/driver/text.py (limited to 'benchmarks/CUDA/CP/driver') diff --git a/benchmarks/CUDA/CP/driver/__init__.py b/benchmarks/CUDA/CP/driver/__init__.py new file mode 100644 index 0000000..3b6c38a --- /dev/null +++ b/benchmarks/CUDA/CP/driver/__init__.py @@ -0,0 +1,33 @@ +# (c) 2007 The Board of Trustees of the University of Illinois. + +import sys +import os +from itertools import imap + +import globals +import actions +import options + +def run(): + # Print a banner message + print "Parboil parallel benchmark suite, version 0.1" + print + + # Global variable setup + root_path = os.getcwd() + python_path = (os.path.join(root_path,'common','python') + + ":" + + os.environ.get('PYTHONPATH',"")) + + globals.root = root_path + globals.benchmarks = benchmark.find_benchmarks() + globals.program_env = {'PARBOIL_ROOT':root_path, + 'PYTHONPATH':python_path, + } + + # Parse options + act = options.parse_options(sys.argv) + + # Perform the specified action + if act: act() + diff --git a/benchmarks/CUDA/CP/driver/actions.py b/benchmarks/CUDA/CP/driver/actions.py new file mode 100644 index 0000000..8525028 --- /dev/null +++ b/benchmarks/CUDA/CP/driver/actions.py @@ -0,0 +1,109 @@ +# (c) 2007 The Board of Trustees of the University of Illinois. + +# These are the main actions that the driver may take. The actions +# call lower-level routines from the process or benchmark modules. + +import os +from itertools import imap + +import process +import benchmark +import globals +from text import format_columns + +def benchmark_iter(): + """Iterate over the benchmarks in 'bmks'.""" + # bmks is a dictionary from str to Future(Benchmark) + return imap(lambda x: x.get(), globals.benchmarks.itervalues()) + +def list_benchmarks(): + """List all benchmarks on standard output.""" + print "Benchmarks:" + for bmk in benchmark_iter(): print " " + bmk.name + +def describe_benchmarks(): + """Print descriptions of all benchmarks to standard output.""" + for bmk in benchmark_iter(): describe_benchmark(bmk) + +def describe_benchmark(bmk): + """Print a description of one benchmark to standard output.""" + + print " " + bmk.name + print format_columns(bmk.describe(), 4) + +def lookup_benchmark(name): + """Find a benchmark, given its name. Returns None if no benchmark + is found with the given name or if the benchmark is invalid. + If the benchmark cannot be found, an error is printed.""" + b = globals.benchmarks.get(name) + if b is not None: + bmk = b.get() + if bmk.invalid is None: + return bmk + else: + print "Error in benchmark:" + print str(bmk.invalid) + return None + else: + print "Cannot find benchmark" + return None + +def with_benchmark_named(name, action): + """Look up the benchmark named 'name'. If found, apply the action + to it. Otherwise, print an error message and return None.""" + + bmk = lookup_benchmark(name) + if bmk is not None: action(bmk) + +def compile_benchmark(bmk, version_name): + """Compile the benchmark 'bmk'.""" + try: impl = bmk.impls[version_name] + except KeyError: + print "Cannot find benchmark version" + return + + impl.build(bmk) + +def clean_benchmark(bmk, version_name=None): + """Remove the compiled code for one implementation of 'bmk'. If + no version is given, clean all versions.""" + + if version_name: + try: impl = bmk.impls[version_name] + except KeyError: + print "Cannot find benchmark version" + return + + impl.clean(bmk) + else: + # Clean all versions + for impl in bmk.impls.itervalues(): + impl.clean(bmk) + +def run_benchmark(bmk, version_name, input_name, check=True, extra_opts=[]): + """Run the benchmark 'bmk'.""" + try: impl = bmk.impls[version_name] + except KeyError: + print "Cannot find benchmark version" + return + + try: data = bmk.datas[input_name] + except KeyError: + print "Cannot find data set" + return + + # Run the benchmark + success = impl.run(bmk, data, check, extra_opts=extra_opts) + + if not success: + print "Run failed!" + return + + # Verify the output + if check: + success = impl.check(bmk, data) + + if not success: + print "Output checking tool detected a mismatch" + else: + print "Output was not checked for correctness" diff --git a/benchmarks/CUDA/CP/driver/benchmark.py b/benchmarks/CUDA/CP/driver/benchmark.py new file mode 100644 index 0000000..43d7852 --- /dev/null +++ b/benchmarks/CUDA/CP/driver/benchmark.py @@ -0,0 +1,374 @@ +# (c) 2007 The Board of Trustees of the University of Illinois. + +import sys +import os +from os import path +import re +from itertools import imap, repeat, chain + +import globals +import process +from futures import Future + +class Benchmark(object): + """A benchmark. + + If the benchmark is malformed or otherwise invalid, only the 'name' and + 'invalid' fields will be set. Otherwise all fields will be set. + + Fields: + name The name of the benchmark. This is also the benchmark + directory name. + invalid None if the benchmark is valid; otherwise, an exception + describing why the benchmark is invalid. + path Full path of the benchmark directory. + descr A description of the benchmark. + impls A dictionary of benchmark source implementations. + datas A dictionary of data sets used to run the benchmark.""" + + def __init__(self, name, path = None, impls = [], datasets = [], + description=None, invalid=None): + self.name = name + self.invalid = invalid + + if invalid is None: + self.path = path + self.impls = dict(imap(lambda i: (i.name, i), impls)) + self.datas = dict(imap(lambda i: (i.name, i), datasets)) + self.descr = description + + def createFromName(name): + """Scan the benchmark directory for the benchmark named 'name' + and create a benchmark object for it.""" + bmkpath = path.join(globals.root, 'benchmarks', name) + descr = process.read_description_file(bmkpath) + + try: + # Scan implementations of the benchmark + impls = [BenchImpl.createFromName(name, impl) + for impl in process.scan_for_benchmark_versions(bmkpath)] + + # Scan data sets of the benchmark + datas = [BenchDataset.createFromName(name, data) + for data in process.scan_for_benchmark_datasets(bmkpath)] + + # If no exception occurred, the benchmark is valid + return Benchmark(name, bmkpath, impls, datas, descr) + except Exception, e: + return Benchmark(name, invalid=e) + + createFromName = staticmethod(createFromName) + + def describe(self): + """Return a string describing this benchmark.""" + + if self.invalid: + return "Error in benchmark:\n" + str(self.invalid) + + if self.descr is None: + header = "Benchmark '" + self.name + "'" + else: + header = self.descr + + impls = " ".join([impl.name for impl in self.impls.itervalues()]) + datas = " ".join([data.name for data in self.datas.itervalues()]) + + return header + "\nVersions: " + impls + "\nData sets: " + datas + + def instance_check(x): + if not isinstance(x, Benchmark): + raise TypeError, "argument must be an instance of Benchmark" + + instance_check = staticmethod(instance_check) + +class BenchImpl(object): + """An implementation of a benchmark.""" + + def __init__(self, name, description=None): + if not isinstance(name, str): + raise TypeError, "name must be a string" + + self.name = name + self.descr = description + + def createFromName(name, impl): + """Scan the directory containing a benchmark implementation + and create a BenchImpl object from it.""" + + # Path to the implementation + impl_path = path.join(globals.root, 'benchmarks', name, 'src', impl) + + # Get the description from a file, if provided + descr = process.read_description_file(impl_path) + + return BenchImpl(impl, descr) + + createFromName = staticmethod(createFromName) + + def makefile(self, benchmark, target=None, action=None): + """Run this implementation's makefile.""" + + Benchmark.instance_check(benchmark) + + def perform(): + srcdir = path.join('src', self.name) + builddir = path.join('build', self.name) + + env={'SRCDIR':srcdir, + 'BUILDDIR':builddir, + 'BIN':path.join(builddir,benchmark.name), + 'PARBOIL_ROOT':globals.root} + + # Run the makefile to build the benchmark + return process.makefile(target=target, + action=action, + filepath=path.join(srcdir, "Makefile"), + env=env) + + # Go to the benchmark directory before building + return process.with_path(benchmark.path, perform) + + def build(self, benchmark): + """Build an executable of this benchmark implementation.""" + return self.makefile(benchmark) + + def isBuilt(self, benchmark): + """Determine whether the executable is up to date.""" + return self.makefile(benchmark, action='q') + + def clean(self, benchmark): + """Remove build files for this benchmark implementation.""" + return self.makefile(benchmark, 'clean') + + def run(self, benchmark, dataset, do_output=True, extra_opts=[]): + """Run this benchmark implementation. + + Return True if the benchmark terminated normally or False + if there was an error.""" + + # Ensure that the benchmark has been built + if not self.isBuilt(benchmark): + rc = self.build(benchmark) + + # Stop if 'make' failed + if not rc: return False + + def perform(): + # Run the program + exename = path.join('build', self.name, benchmark.name) + args = [exename] + extra_opts + dataset.getCommandLineArguments(do_output) + rc = process.spawnwaitv(exename, args) + + # Program exited with error? + if rc != 0: return False + return True + + return process.with_path(benchmark.path, perform) + + def check(self, benchmark, dataset): + """Check the output from the last run of this benchmark + implementation. + + Return True if the output checks successfully or False + otherwise.""" + + def perform(): + output_file = dataset.getTemporaryOutputPath() + reference_file = dataset.getReferenceOutputPath() + + compare = os.path.join('tools', 'compare-output') + rc = process.spawnwaitl(compare, + compare, reference_file, output_file) + + # Program exited with error, or mismatch in output? + if rc != 0: return False + return True + + return process.with_path(benchmark.path, perform) + + def __str__(self): + return "" + +class BenchDataset(object): + """Data sets for running a benchmark.""" + + def __init__(self, name, in_files=[], out_files=[], parameters=[], + description=None): + if not isinstance(name, str): + raise TypeError, "name must be a string" + + self.name = name + self.inFiles = in_files + self.outFiles = out_files + self.parameters = parameters + self.descr = description + + def createFromName(name, dset): + """Scan the directory containing a dataset + and create a BenchDataset object from it.""" + + # Identify the paths where files may be found + benchmark_path = path.join(globals.root, 'benchmarks', name) + + if path.exists(path.join(benchmark_path, 'input')): + input_path = path.join(benchmark_path, 'input', dset) + else: + input_path = None + + output_path = path.join(benchmark_path, 'output', dset) + + # Look for input files + + def check_default_input_files(): + # This function is called to see if the input file set + # guessed by scanning the input directory can be used + if invalid_default_input_files: + raise ValueError, "Cannot infer command line when there are multiple input files in a data set\n(Fix by adding an input DESCRIPTION file)" + + if input_path: + input_descr = process.read_description_file(input_path) + input_files = list(process.scan_for_files(input_path, + boring=['DESCRIPTION','.svn'])) + + # If more than one input file was found, cannot use the default + # input file list produced by scanning the directory + invalid_default_input_files = len(input_files) > 1 + else: + # If there's no input directory, assume the benchmark + # takes no input + input_descr = None + input_files = [] + invalid_default_input_files = False + + # Read the text of the input description file + if input_descr is not None: + (parameters, input_files1, input_descr) = \ + unpack_dataset_description(input_descr, input_files=None) + + if input_files1 is None: + # No override vaule given; use the default + check_default_input_files() + else: + input_files = input_files1 + else: + check_default_input_files() + parameters = [] + + # Look for output files + output_descr = process.read_description_file(output_path) + output_files = list(process.scan_for_files(output_path, + boring=['DESCRIPTION','.svn'])) + if len(output_files) > 1: + raise ValueError, "Multiple output files not supported" + + # Concatenate input and output descriptions + if input_descr and output_descr: + descr = input_descr + "\n\n" + output_descr + else: + descr = input_descr or output_descr + + return BenchDataset(dset, input_files, output_files, parameters, descr) + + createFromName = staticmethod(createFromName) + + def getTemporaryOutputPath(self): + """Get the name of a file used to hold the output of a benchmark run. + This function should always return the same name if its parameters + are the same. The output path is not the path where the reference + output is stored.""" + + return path.join('run', self.name, self.outFiles[0]) + + def getReferenceOutputPath(self): + """Get the name of the reference file, to which the output of a + benchmark run should be compared.""" + + return path.join('output', self.name, self.outFiles[0]) + + def getCommandLineArguments(self, do_output=True): + """Get the command line arguments that should be passed to the + executable to run this data set. If 'output' is True, then + the executable will be passed flags to save its output to a file. + + Directories to hold ouptut files are created if they do not exist.""" + args = [] + + # Add arguments to pass input files to the benchmark + if self.inFiles: + in_files = ",".join([path.join('input', self.name, x) + for x in self.inFiles]) + args.append("-i") + args.append(in_files) + + # Add arguments to store the output somewhere, if output is + # desired + if do_output and self.outFiles: + if len(self.outFiles) != 1: + raise ValueError, "only one output file is supported" + + out_path = self.getTemporaryOutputPath() + args.append("-o") + args.append(out_path) + + # Ensure that a directory exists for the output + process.touch_directory(path.dirname(out_path)) + + args += self.parameters + return args + + def __str__(self): + return "" + +def unpack_dataset_description(descr, parameters=[], input_files=[]): + """Read information from the raw contents of a data set description + file. Optional 'parameters' and 'input_files' arguments may be + given, which will be retained unless overridden by the description + file.""" + leftover = [] + split_at_colon = re.compile(r"^\s*([a-zA-Z]+)\s*:(.*)$") + + # Initialize these to default empty strings + parameter_text = None + input_file_text = None + + # Scan the description line by line + for line in descr.split('\n'): + m = split_at_colon.match(line) + if m is None: continue + + # This line appears to declare something that should be + # interpreted + keyword = m.group(1) + if keyword == "Parameters": + parameter_text = m.group(2) + elif keyword == "Inputs": + input_file_text = m.group(2) + # else, ignore the line + + # Split the strings into (possibly) multiple arguments, discarding + # whitespace + if parameter_text is not None: parameters = parameter_text.split() + if input_file_text is not None: input_files = input_file_text.split() + return (parameters, input_files, descr) + +def find_benchmarks(): + """Find benchmarks in the repository. The benchmarks are + identified, but their contents are not scanned immediately. A + dictionary is returned mapping benchmark names to futures + containing the benchmarks.""" + + if not globals.root: + raise ValueError, "root directory has not been set" + + # Scan all benchmarks in the 'benchmarks' directory and + # lazily create benchmark objects. + db = {} + try: + for bmkname in process.scan_for_benchmarks(globals.root): + bmk = Future(lambda bmkname=bmkname: Benchmark.createFromName(bmkname)) + db[bmkname] = bmk + except OSError, e: + sys.stdout.write("Benchmark directory not found!\n\n") + return {} + + return db diff --git a/benchmarks/CUDA/CP/driver/futures.py b/benchmarks/CUDA/CP/driver/futures.py new file mode 100644 index 0000000..2e0b94b --- /dev/null +++ b/benchmarks/CUDA/CP/driver/futures.py @@ -0,0 +1,14 @@ +# (c) 2007 The Board of Trustees of the University of Illinois. + +class Future: + def __init__(self, thunk): + self.evaluated = 0 + self.value = thunk + + def get(self): + if self.evaluated: + return self.value + else: + self.value = self.value() + self.evaluated = 1 + return self.value diff --git a/benchmarks/CUDA/CP/driver/globals.py b/benchmarks/CUDA/CP/driver/globals.py new file mode 100644 index 0000000..9e14c23 --- /dev/null +++ b/benchmarks/CUDA/CP/driver/globals.py @@ -0,0 +1,16 @@ +# (c) 2007 The Board of Trustees of the University of Illinois. + +# This file holds global variables used by the driver. + +# Root directory of the repository (str) +root = None + +# Benchmarks in the repository ({str:Future(Benchmark)}) +benchmarks = None + +# Environment variables to use when spawning subprograms ({str:str}) +program_env = None + +# True if verbose output is desired. This may be set during +# option parsing. +verbose = False diff --git a/benchmarks/CUDA/CP/driver/options.py b/benchmarks/CUDA/CP/driver/options.py new file mode 100644 index 0000000..c044ef8 --- /dev/null +++ b/benchmarks/CUDA/CP/driver/options.py @@ -0,0 +1,208 @@ +# (c) 2007 The Board of Trustees of the University of Illinois. + +# This module takes care of parsing options for the Parboil driver. +# +# The main option parsing routine is parse_options(). Option parsing +# may print messages and terminate the program, but should not cause +# any other action to be taken. + +from sys import stdout +from optparse import OptionParser + +import actions +import globals + +def invalid_option_message(progname, cmd, args): + print "Unrecognized command '" + cmd + "'" + print "'" + progname + " help' for options" + +# Parsers for each mode. These take the command line as parameters +# and return an OptionGetter. +# +# The 'help' field prints a help message. +# +# The 'run' field does the actual parsing. If there is an error in +# the command line, it prints an error message and returns None; +# otherwise, it returns an action which will carry out the commands. + +class OptionGetter: + def __init__(self, help, run): + self.help = help + self.run = run + +def help_options(progname, cmd, args): + help_string = "usage: " + progname + " help [COMMAND]\nWithout parameters: list commands\nWith a parameter: Get help on COMMAND\n" + get_help = lambda: stdout.write(help_string) + + def run(): + if args: + try: helpcmd = parse_mode_options[args[0]] + except KeyError: + print "No help available for unrecognized command '" + args[0] + "'" + return None + + helpcmd(progname, cmd, args).help() + else: + print "Commands: " + print " help Display this help message" + print " list List benchmarks" + print " describe Show details on a benchmark" + print " clean Clean up generated files in a benchmark" + print " compile Compile a benchmark" + print " run Run a benchmark" + print "" + print "To get help on a command: " + progname + " help COMMAND" + + return None + + return OptionGetter(get_help, run) + +def list_options(progname, cmd, args): + help_string = "usage: " + progname + " list\nList available benchmarks\n" + get_help = lambda: stdout.write(help_string) + + def run(): + if args: + print "Unexpected parameter or option after 'list'" + return None + else: + return actions.list_benchmarks + + return OptionGetter(get_help, run) + +def describe_options(progname, cmd, args): + usage_string = progname + " describe [BENCHMARK]\nWithout parameters: describe all benchmarks in detail\nWith a parameter: describe BENCHMARK in detail" + parser = OptionParser(usage=usage_string) + + def run(): + (opts, pos) = parser.parse_args(args) + if len(pos) > 1: + print "Too many parameters after 'describe'" + return None + elif len(pos) == 0: + return actions.describe_benchmarks + else: + bmkname = pos[0] + return lambda: actions.with_benchmark_named(bmkname, + actions.describe_benchmark) + + return OptionGetter(parser.print_help, run) + +def clean_options(progname, cmd, args): + usage_string = progname + " clean BENCHMARK [VERSION]\nDelete the object code and executable of BENCHMARK version VERSION;\nif no version is given, remove the object code and executable of all versions" + parser = OptionParser(usage=usage_string) + parser.add_option('-v', "--verbose", + action="store_true", dest="verbose", default=False, + help="Produce verbose status messages") + + def run(): + (opts, pos) = parser.parse_args(args) + globals.verbose = opts.verbose + + if len(pos) == 0: + print "Expecting one or two parameters after 'clean'" + return None + elif len(pos) == 1: + bmkname = pos[0] + return lambda: actions.with_benchmark_named(bmkname, actions.clean_benchmark) + elif len(pos) == 2: + bmkname = pos[0] + ver = pos[1] + return lambda: actions.with_benchmark_named(bmkname, lambda b: actions.clean_benchmark(b, ver)) + else: + print "Too many parameters after 'clean'" + return None + + return OptionGetter(parser.print_help, run) + +def compile_options(progname, cmd, args): + help_string = "usage :" + progname + " compile BENCHMARK VERSION\nCompile version VERSION of BENCHMARK" + parser = OptionParser(usage = help_string) + parser.add_option('-v', "--verbose", + action="store_true", dest="verbose", default=False, + help="Produce verbose status messages") + + def run(): + (opts, pos) = parser.parse_args(args) + globals.verbose = opts.verbose + + if len(pos) != 2: + print "Expecting two parameters after 'compile'" + return None + else: + bmkname = pos[0] + ver = pos[1] + return lambda: actions.with_benchmark_named(bmkname, lambda b: actions.compile_benchmark(b, ver)) + + return OptionGetter(parser.print_help, run) + +def run_options(progname, cmd, args): + usage_string = progname + " run BENCHMARK VERSION INPUT\nRun version VERSION of BENCHMARK with data set INPUT" + parser = OptionParser(usage=usage_string) + parser.add_option('-C', "--no-check", + action="store_false", dest="check", default=True, + help="Skip the output check for this benchmark") + parser.add_option('-S', "--synchronize", + action="store_true", dest="synchronize", default=False, + help="Synchronize after GPU calls; necessary for accurate run time accounting on CUDA benchmarks") + parser.add_option('-v', "--verbose", + action="store_true", dest="verbose", default=False, + help="Produce verbose status messages") + + def run(): + (opts, pos) = parser.parse_args(args) + globals.verbose = opts.verbose + if len(pos) != 3: + print "Expecting three parameters after 'run'" + return None + else: + bmkname = pos[0] + ver = pos[1] + inp = pos[2] + ck=opts.check + extra_opts = [] + if opts.synchronize: + extra_opts.append('-S') + return lambda: actions.with_benchmark_named(bmkname, lambda b: actions.run_benchmark(b, ver, inp, check=ck, extra_opts=extra_opts)) + + return OptionGetter(parser.print_help, run) + +# Dictionary from option name to function from command-line parameters +# to pair of help thunk and option processor thunk +parse_mode_options = { + 'help' : help_options, + '-h' : help_options, + '--help' : help_options, + 'list' : list_options, + 'describe' : describe_options, + 'clean' : clean_options, + 'compile' : compile_options, + 'run' : run_options + } + +def parse_options(args): + """Parse a list of command-line options. If there is an error in + the options, then the function will print a message and either call + sys.exit() or return None. If options were parsed successfully + then it will return a thunk which represents the action to take, + or None if no action need be taken. + + Generally, the caller should call the return value, unless None is + returned.""" + # Parse arguments; skip the program name + prog_name = args[0] + + # Get the command name + try: cmd = args[1] + except IndexError: cmd = 'help' + + # Dispatch + try: mode = parse_mode_options[cmd] + except KeyError: + invalid_option_message(prog_name, cmd, args[2:]) + return + + # Set up and run the option parser + return mode(prog_name, cmd, args[2:]).run() + + diff --git a/benchmarks/CUDA/CP/driver/process.py b/benchmarks/CUDA/CP/driver/process.py new file mode 100644 index 0000000..56e7e98 --- /dev/null +++ b/benchmarks/CUDA/CP/driver/process.py @@ -0,0 +1,181 @@ +# (c) 2007 The Board of Trustees of the University of Illinois. + +# Process-management and directory management routines are collected here. + +import os +import os.path as path +import stat +from itertools import imap, ifilter, chain + +import globals + +def scan_for_files(topdir, directory=False, boring=[]): + """Scan the contents of the directory 'topdir'. If 'directory' is + True, return a sequence of all directories found in that directory; + otherwise, return a sequence of all files found in that directory. + Directories whose names are found in the 'boring' list are excluded.""" + + # Look for directories or regular files, depending on the 'directory' + # parameter + if directory: valid_test = path.isdir + else: valid_test = path.isfile + + def interesting(fname): + # True if 'dirname' is not a boring name, and it is a directory + if fname in boring: return False + + fpath = path.join(topdir, fname) + try: return valid_test(fpath) + except OSError: return False # Ignore file-not-found errors + + if not path.isdir(topdir): + raise OSError, "Cannot access '" + str(topdir) + "' as a directory" + + # Return names of all directories found + return ifilter(interesting, os.listdir(topdir)) + +def scan_for_benchmarks(topdir): + """Scan subdirectories of the benchmark repository to find + benchmarks. Return a sequence containing all benchmark + directory names.""" + + return scan_for_files(path.join(topdir, "benchmarks"), True, boring=['_darcs','.svn']) + +def scan_for_benchmark_versions(bmkdir): + """Scan subdirectories of a benchmark directory 'bmkdir' to find + benchmark versions. Return a sequence containing all benchmark + version names.""" + + return scan_for_files(path.join(bmkdir, "src"), True, boring=['.svn']) + +def scan_for_benchmark_datasets(bmkdir): + """Scan subdirectories of a benchmark directory 'bmkdir' to find + data sets. Return a sequence containing all data set names.""" + + # Get input and output subdirectories + inp_dir = path.join(bmkdir, "input") + if path.exists(inp_dir): + inp_dirs = scan_for_files(path.join(bmkdir, "input"), True, boring=['.svn']) + else: + # Assume no input files are found because the benchmark + # doesn't need input + inp_dirs = [] + + out_dirs = scan_for_files(path.join(bmkdir, "output"), True, boring=['.svn']) + + # Return the union of the dataset directories + return dict(imap(lambda x: (x, None), chain(inp_dirs, out_dirs))).keys() + +def read_description_file(dirpath): + """Read the contents of a file in 'dirpath' called DESCRIPTION, + if one exists. This returns the file text as a string, or None + if no description was found.""" + + descr_path = os.path.join(dirpath, 'DESCRIPTION') + if os.access(descr_path, os.R_OK): + descr_file = file(descr_path, 'r') + descr = descr_file.read() + descr_file.close() + return descr + + # else, return None + +def touch_directory(dirpath): + """Ensures that the directory 'dirpath' and its parent directories + exist. If they do not exist, they will be created. It is an + error if the path exists but is not a directory.""" + if path.isdir(dirpath): + return + elif path.exists(dirpath): + raise OSError, "Path exists but is not a directory" + else: + (head, tail) = path.split(dirpath) + if head: touch_directory(head) + os.mkdir(dirpath) + +def with_path(wd, action): + """Executes an action in a separate working directory. The action + should be a callable object.""" + cwd = os.getcwd() + os.chdir(wd) + try: result = action() + finally: os.chdir(cwd) + return result + +def makefile(target=None, action=None, filepath=None, env={}): + """Run a makefile. An optional command, makefile path, and dictionary of + variables to define on the command line may be defined. The return code + value is the return code returned by the makefile. + + If no action is given, 'make' is invoked. Returns True if make was + successful and False otherwise. + + A 'q' action queries whether the target needs to be rebuilt. True is + returned if the target is up to date.""" + + args = ["make"] + + if action is None: + def run(): + rc = os.spawnvp(os.P_WAIT, "make", args) + return rc == 0 + elif action in ['q']: + args.append('-q') + + def run(): + rc = os.spawnvp(os.P_WAIT, "make", args) + if rc == 0: + # Up-to-date + return True + elif rc == 1: + # Needs remake + return False + else: + # Error + return False + else: + raise ValueError, "invalid action" + + # Pass the target as the second argument + if target: args.append(target) + + # Pass the path the the makefile + if filepath: + args.append('-f') + args.append(filepath) + + # Pass variables + for (k,v) in env.iteritems(): + args.append(k + "=" + v) + + # Print a status message, if running in verbose mode + if globals.verbose: + + print "Running '" + " ".join(args) + "' in " + os.getcwd() + + # Run the makefile and return result info + return run() + +def spawnwaitv(prog, args): + """Spawn a program and wait for it to complete. The program is + spawned in a modified environment.""" + + env = dict(os.environ) + env.update(globals.program_env) + + # Print a status message if running in verbose mode + if globals.verbose: + print "Running '" + " ".join(args) + "' in " + os.getcwd() + + # Check that the program is runnable + if not os.access(prog, os.X_OK): + raise OSError, "Cannot execute '" + prog + "'" + + # Run the program + return os.spawnve(os.P_WAIT, prog, args, env) + +def spawnwaitl(prog, *argl): + """Spawn a program and wait for it to complete. The program is + spawned in a modified environment.""" + + return spawnwaitv(prog, argl) diff --git a/benchmarks/CUDA/CP/driver/text.py b/benchmarks/CUDA/CP/driver/text.py new file mode 100644 index 0000000..b8e1097 --- /dev/null +++ b/benchmarks/CUDA/CP/driver/text.py @@ -0,0 +1,75 @@ +#! /usr/bin/env python + +from itertools import imap +import re + +TOKEN = re.compile(r"(?:^|(?<=\s))[^\s]+|(?:^|(? COLUMNS: break + n += 1 + n = max(n, 1) + + # Concatenate the tokens and prepend spaces for indentation + outls.append(' ' * inl_indent + "".join(tokens[:n])) + + # Continue with tokens + tokens = tokens[n:] + + return "\n".join(outls) + + -- cgit v1.3