Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plumb in extra instrumentation mode iterations runners flags. #367

Merged
merged 1 commit into from
Feb 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions iterations_runners/iterations_runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,29 +111,40 @@ convert_str_to_int(char *s)
return ((int) r);
}

void
usage() {
printf("usage: iterations_runner_c <benchmark> <# of iterations> "
"<benchmark param>\n <debug flag> [instrumentation dir] "
"[key] [key pexec index]\n\n");
printf("Arguments in [] are for instrumentation mode only.\n");
exit(EXIT_FAILURE);
}

int
main(int argc, char **argv)
{
char *krun_benchmark = 0;
int krun_total_iters = 0, krun_param = 0, krun_iter_num = 0;
int krun_debug = 0, krun_num_cores = 0, krun_core;
int krun_debug = 0, krun_num_cores = 0, krun_core, krun_instrument = 0;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason behind not initialising krun_core?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can do, although it will be initialised before its first use in the loop header:

for (krun_core = 0; krun_core < krun_num_cores; krun_core++) {

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, it just seems weird to be the odd one out on that line.

void *krun_dl_handle = 0;
int (*krun_bench_func)(int); /* func ptr to benchmark entry */
double *krun_wallclock_times = NULL;
uint64_t **krun_cycle_counts = NULL, **krun_aperf_counts = NULL;
uint64_t **krun_mperf_counts = NULL;

if (argc != 6) {
printf("usage: iterations_runner_c "
"<benchmark> <# of iterations> <benchmark param> <debug flag> "
"<instrument flag>\n");
exit(EXIT_FAILURE);
if (argc < 5) {
usage();
}

krun_benchmark = argv[1];
krun_total_iters = convert_str_to_int(argv[2]);
krun_param = convert_str_to_int(argv[3]);
krun_debug = convert_str_to_int(argv[4]);
krun_instrument = argc >= 6;

if (krun_instrument && (argc != 8)) {
usage();
}

krun_init();
krun_num_cores = krun_get_num_cores();
Expand Down
23 changes: 17 additions & 6 deletions iterations_runners/iterations_runner.java
Original file line number Diff line number Diff line change
Expand Up @@ -201,20 +201,31 @@ private static void emitPerCoreResults(String name, int numCores, long[][] array
System.out.print("]");
}

public static void usage() {
System.out.println("usage: iterations_runner <benchmark> " +
"<# of iterations> <benchmark param>\n " +
"<debug flag> [instrumentation dir] [key] [key pexec index]\n");
System.out.println("Arguments in [] are for instrumentation mode only.\n");
System.exit(1);
}

public static void main(String args[]) throws
ClassNotFoundException, NoSuchMethodException, InstantiationException, IllegalAccessException, java.lang.reflect.InvocationTargetException {

if (args.length != 5) {
System.out.println("usage: iterations_runner <benchmark> " +
"<# of iterations> <benchmark param> <debug flag>" +
"<instrument flag>\n");
System.exit(1);
if (args.length < 4) {
usage();
}

String benchmark = args[0];
int iterations = Integer.parseInt(args[1]);
int param = Integer.parseInt(args[2]);
boolean debug = Integer.parseInt(args[3]) > 0;
boolean instrument = Integer.parseInt(args[4]) > 0;

// Note: JDK instrumentation is still using the old Krun interface.
boolean instrument = args.length >= 5;
if ((instrument) && (args.length != 7)) {
usage();
}

KrunJDKInstrumentation krunInst = null;
if (instrument) {
Expand Down
17 changes: 14 additions & 3 deletions iterations_runners/iterations_runner.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,26 @@ function emitPerCoreResults(name, num_cores, ary) {
write("]")
}

if (this.arguments.length != 5) {
throw "usage: iterations_runner.js <benchmark> <# of iterations> " +
"<benchmark param> <debug flag> <instrument flag>";
function usage() {
throw "\nusage: iterations_runner.js <benchmark> <# of iterations> " +
"<benchmark param>\n <debug flag> [instrumentation dir] [key] " +
"[key pexec index]\n\nArguments in [] are for" +
"instrumentation mode only.\n";
}

if (this.arguments.length < 4) {
usage();
}

var BM_entry_point = this.arguments[0];
var BM_n_iters = parseInt(this.arguments[1]);
var BM_param = parseInt(this.arguments[2]);
var BM_debug = parseInt(this.arguments[3]) > 0;
var BM_instrument = this.arguments.length >= 5;

if (BM_instrument && (this.arguments.length != 7)) {
usage();
}

load(BM_entry_point);

Expand Down
20 changes: 16 additions & 4 deletions iterations_runners/iterations_runner.lua
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ function emit_per_core_measurements(name, num_cores, tbl, tbl_len)
io.stdout:write("]")
end

function usage()
io.stderr:write("usage: iterations_runner.lua <benchmark> " ..
"<# of iterations> <benchmark param>\n " ..
"<debug flag> [instrumentation dir] [key] " ..
"[key pexec index]\n\n")
io.stderr:write("Arguments in [] are for instrumentation mode only.\n")
os.exit(1)
end

ffi.cdef[[
void krun_init(void);
void krun_done(void);
Expand All @@ -78,15 +87,18 @@ local krun_get_core_cycles_double = libkruntime.krun_get_core_cycles_double
local krun_get_aperf_double = libkruntime.krun_get_aperf_double
local krun_get_mperf_double = libkruntime.krun_get_mperf_double

if #arg < 4 then
usage()
end

local BM_benchmark = arg[1]
local BM_iters = tonumber(arg[2])
local BM_param = tonumber(arg[3])
local BM_debug = tonumber(arg[4]) > 0
local BM_instrument = #arg >= 5

if #arg ~= 5 then
io.stderr:write("usage: iterations_runner.lua <benchmark> <# of iterations> " ..
"<benchmark param> <debug flag> <instrument flag>")
os.exit(1)
if BM_instrument and #arg ~= 7 then
usage()
end

dofile(BM_benchmark)
Expand Down
15 changes: 13 additions & 2 deletions iterations_runners/iterations_runner.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,27 @@
* krun_get_{core_cycles,aperf,mperf}_double();
*/

if ($argc != 6) {
function usage() {
fwrite(STDERR, "usage: iterations_runner.php <benchmark> <# of iterations> " .
"<benchmark param> <debug flag> <instrument flag>\n");
"<benchmark param>\n <debug flag> [instrumentation dir] " .
"[key] [key pexec index]>\n\n");
fwrite(STDERR, "Arguments in [] are for instrumentation mode only.\n");
exit(1);
}

if ($argc < 5) {
usage();
}

$BM_benchmark = $argv[1];
$BM_iters = $argv[2];
$BM_param = (int) $argv[3];
$BM_debug = ((int) $argv[4]) > 0;
$BM_instrument = $argc >= 6;

if ($BM_instrument && ($argc != 8)) {
usage();
}

if (!file_exists($BM_benchmark)) {
throw new RuntimeException("Can't find $BM_benchmark");
Expand Down
30 changes: 18 additions & 12 deletions iterations_runners/iterations_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,13 @@

"""
Iterations runner for Python VMs.
Derived from iterations_runner.php.

Executes a benchmark many times within a single process.

In Kalibera terms, this script represents one executions level run.
"""
usage: iterations_runner.py <benchmark> <# of iterations> <benchmark param>
<debug flag> [instrumentation dir] [key] [key pexec index]

Arguments in [] are for instrumentation mode only."""

import cffi, sys, imp, os

Expand Down Expand Up @@ -70,20 +71,25 @@
krun_get_aperf = libkruntime.krun_get_aperf
krun_get_mperf = libkruntime.krun_get_mperf

def usage():
print(__doc__)
sys.exit(1)

# main
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this comment necessary?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably not :P

if __name__ == "__main__":
if len(sys.argv) != 6:
sys.stderr.write("usage: iterations_runner.py <benchmark> "
"<# of iterations> <benchmark param> <debug flag> "
"<instrument flag>\n")
sys.exit(1)
num_args = len(sys.argv)
if num_args < 5:
usage()

benchmark, iters, param, debug = sys.argv[1:5]
iters, param, debug = int(iters), int(param), int(debug) == 1
instrument = num_args >= 6

benchmark, iters, param, debug, instrument = sys.argv[1:]
iters, param, debug, instrument = \
int(iters), int(param), int(debug) == 1, int(instrument) == 1
if instrument and num_args != 8:
usage()

if instrument:
import pypyjit # instrumentation not supported on CPython yet anyway
import pypyjit # instrumentation not supported on CPython yet.

assert benchmark.endswith(".py")
bench_mod_name = os.path.basename(benchmark[:-3])
Expand Down
20 changes: 15 additions & 5 deletions iterations_runners/iterations_runner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,29 @@ def clock_gettime_monotonic()
end
end

def usage()
STDERR.puts "usage: iterations_runner.rb <benchmark> "\
"<# of iterations> <benchmark param>\n "\
"<debug flag> [instrumentation dir] [key] [key pexec index]>\n"
STDERR.puts "Arguments in [] are supplied for instrumentation mode only.\n"
Kernel.exit(1)
end

# main
if __FILE__ == $0
if ARGV.length != 5
STDERR.puts "usage: iterations_runner.rb <benchmark> "\
"<# of iterations> <benchmark param> <debug flag> "\
"<instrument flag>\n"
Kernel.exit(1)
if ARGV.length < 4
usage()
end

benchmark, iters, param, debug = ARGV
iters = Integer(iters)
param = Integer(param)
debug = Integer(debug) > 0
instrument = ARGV.length >= 5

if instrument and ARGV.length != 7 then
usage()
end

require("#{benchmark}")

Expand Down
8 changes: 8 additions & 0 deletions krun.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,14 @@ def inner_main(mailer, on_first_invocation, config, args):
platform.no_pstate_check = args.no_pstate_check
platform.hardware_reboots = args.hardware_reboots

# Create the instrumentation directory if required
if on_first_invocation:
# We only want make a dir if >=1 VM is in instrumentation mode.
for vm in config.VMS.itervalues():
if vm['vm_def'].instrument:
util.make_instr_dir(config)
break

debug("Checking platform preliminaries")
platform.check_preliminaries()

Expand Down
53 changes: 48 additions & 5 deletions krun/scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -309,16 +309,57 @@ def _write_new_manifest(self, config):
for item in manifest:
fh.write("%s\n" % item)

def next_exec_key_index(self):
"""Returns the sequential process execution index into the ordered list
of all process executions sharing the same 'bench:vm:variant' key.

Although this could have been done at `_parse()` time, it would require
a (variable sized) `dict` since we don't know which key we will be
counting for until we find the first outstanding (O) record.

Instead, this method does a pass over the manifest searching for
records whose key is `self.next_exec_key`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this very clear explanation!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. It took a while to get the wording right on this one!


This function assumes that there is at least one outstanding job (O
line) in the manifest. If there is not, it will raise `FatalKrunError`.
"""

fh = self._open()
lines = iter(fh)
count = 0

# Skip header
for line in lines:
strip_line = line.strip()
if strip_line == "keys":
break
else:
util.fatal("Manifest is missing a body")

# Now count the number of matching keys until the first 'O'
# (outstanding) record.
for line in lines:
flag, key = line.strip().split()
if key == self.next_exec_key:
if flag == "O":
break
count += 1
else:
util.fatal("Manifest ended unexpectedly")

return count


class ExecutionJob(object):
"""Represents a single executions level benchmark run"""

def __init__(self, sched, vm_name, vm_info, benchmark, variant, parameter):
def __init__(self, sched, vm_name, vm_info, benchmark, variant, parameter, key_pexec_idx):
self.sched = sched
self.vm_name, self.vm_info = vm_name, vm_info
self.benchmark = benchmark
self.variant = variant
self.parameter = parameter
self.key_pexec_idx = key_pexec_idx

# Used in results JSON and ETA dict
self.key = "%s:%s:%s" % (self.benchmark, self.vm_name, self.variant)
Expand Down Expand Up @@ -363,9 +404,10 @@ def run(self, mailer, dry_run=False):
stack_limit_kb = self.sched.config.STACK_LIMIT
in_proc_iters = self.vm_info["n_iterations"]

stdout, stderr, rc, envlog_filename = vm_def.run_exec(
entry_point, self.benchmark, in_proc_iters,
self.parameter, heap_limit_kb, stack_limit_kb)
stdout, stderr, rc, envlog_filename = \
vm_def.run_exec(entry_point, in_proc_iters, self.parameter,
heap_limit_kb, stack_limit_kb, self.key,
self.key_pexec_idx)

if not dry_run:
try:
Expand Down Expand Up @@ -497,8 +539,9 @@ def run(self):
self.platform.wait_for_temperature_sensors()

bench, vm, variant = self.manifest.next_exec_key.split(":")
key_pexec_idx = self.manifest.next_exec_key_index()
job = ExecutionJob(self, vm, self.config.VMS[vm], bench, variant,
self.config.BENCHMARKS[bench])
self.config.BENCHMARKS[bench], key_pexec_idx)

# Default to error state. This is the value the finally block will see
# if an exception is raised inside the try block, otherwise it is
Expand Down
Loading