From 080e1be684e5ded94a868165dc71c55e79900044 Mon Sep 17 00:00:00 2001 From: Cedric Nugteren Date: Sat, 26 Nov 2016 16:38:17 +0100 Subject: Improved the default parameters for cases with non-common parameters across all devices --- scripts/database/database/defaults.py | 47 ++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) (limited to 'scripts') diff --git a/scripts/database/database/defaults.py b/scripts/database/database/defaults.py index 00405908..444c66df 100644 --- a/scripts/database/database/defaults.py +++ b/scripts/database/database/defaults.py @@ -5,6 +5,8 @@ # Author(s): # Cedric Nugteren +import ast +from collections import defaultdict import clblast import bests @@ -137,6 +139,10 @@ def get_smallest_best_parameters(group): return min_parameters +def get_parameter_names(section): + return [result["parameters"] for result in section["results"]] + + def get_common_best_parameters(group, group_identifier, verbose): """Sets defaults based on the best values of entries supported by all devices. This might cause a problem in case not every device was tuned with the same parameters. In that case it falls back to the above method to retrieve @@ -154,19 +160,48 @@ def get_common_best_parameters(group, group_identifier, verbose): result["relative_performance"] = minimum_time / result["time"] # Determine which parameters are available for all devices - common_parameters = [result["parameters"] for result in group[0]["results"]] # Parameters of the first section + common_parameters = get_parameter_names(group[0]) # Parameters of the first section for i in range(1, num_devices): - section_parameters = [result["parameters"] for result in group[i]["results"]] + section_parameters = get_parameter_names(group[i]) common_parameters = [p for p in section_parameters if p in common_parameters] # Intersection of the parameters # Fall back to another method in case there are no shared entries at all across devices if len(common_parameters) == 0: if verbose: - print("[database] No common kernels for: " + str(group_identifier) + " with devices: %d " % num_devices) - smallest_best_parameters = get_smallest_best_parameters(group) + print("[database] No common kernels for: " + str(group_identifier) + " across all %d devices " % num_devices) + + # Computes the amount of devices with shared parameters + parameters_count = defaultdict(int) + for i in range(0, num_devices): + for parameters in get_parameter_names(group[i]): + parameters_count[str(parameters)] += 1 + num_devices_common = max(parameters_count.values()) + + # Fall back method in case there are no shared entries at all across devices + if num_devices_common == 1: + print("[database] Warning: No common kernels for: " + str(group_identifier) + " at all") + smallest_best_parameters = get_smallest_best_parameters(group) + if verbose: + print("[database] " + str(group_identifier)) + return smallest_best_parameters + + # Checks if perhaps there are many more shared parameters with a bit fewer devices + num_parameters_common = defaultdict(int) + for count in parameters_count.values(): + if count != 1: + num_parameters_common[str(count)] += 1 + if num_parameters_common[str(num_devices_common - 1)] > num_parameters_common[str(num_devices_common)]: + num_devices_common -= 1 if verbose: - print("[database] " + str(group_identifier)) - return smallest_best_parameters + print("[database] Found %d common kernels for: " % num_parameters_common[str(num_devices_common)] + + str(group_identifier) + " across %d out of %d devices " % (num_devices_common, num_devices)) + + # Populates the common parameters + for parameters_string in parameters_count.keys(): + count = parameters_count[parameters_string] + if count == num_devices_common: + parameters = ast.literal_eval(parameters_string) + common_parameters.append(parameters) # Removes entries with parameters which are not common common_results = [] -- cgit v1.2.3