summaryrefslogtreecommitdiff
path: root/scripts/database
diff options
context:
space:
mode:
authorCedric Nugteren <web@cedricnugteren.nl>2016-08-07 16:25:38 +0200
committerCedric Nugteren <web@cedricnugteren.nl>2016-08-07 16:25:38 +0200
commit3f5401d4c8947945c4770fb1dfd354892702195f (patch)
tree0f580501c735948fa1bc8e9291093a876b5d8c7b /scripts/database
parent35623cd98d798173661c8d86c84fb48261a2493e (diff)
Added a first version of the database's common-best default calculation
Diffstat (limited to 'scripts/database')
-rwxr-xr-xscripts/database/database.py3
-rw-r--r--scripts/database/database/defaults.py70
2 files changed, 64 insertions, 9 deletions
diff --git a/scripts/database/database.py b/scripts/database/database.py
index e115d68c..0ce89d03 100755
--- a/scripts/database/database.py
+++ b/scripts/database/database.py
@@ -98,7 +98,8 @@ def main(argv):
database_best_results = bests.get_best_results(database)
# Determines the defaults for other vendors and per vendor
- database_defaults = defaults.calculate_defaults(database_best_results)
+ print("[database] Calculating the default values...")
+ database_defaults = defaults.calculate_defaults(database)
database_best_results = db.concatenate_database(database_best_results, database_defaults)
# Outputs the database as a C++ database
diff --git a/scripts/database/database/defaults.py b/scripts/database/database/defaults.py
index 357c3a3a..fca793ea 100644
--- a/scripts/database/database/defaults.py
+++ b/scripts/database/database/defaults.py
@@ -6,7 +6,9 @@
# Cedric Nugteren <www.cedricnugteren.nl>
import pandas as pd
+
import clblast
+import bests
def set_default_device(database_entry):
@@ -23,16 +25,18 @@ def set_default_time(database_entry):
return database_entry
-def calculate_defaults(df):
- """# Sets defaults for devices of the same type/vendor based on the smallest values of all known entries. The average
- might be better for performance but some parameters might not be supported on other devices."""
+def calculate_defaults(database, calculate_common_best=True):
+ """Sets defaults for devices of the same type/vendor. An option determines how to compute the defaults."""
database_defaults = pd.DataFrame()
# Defaults per combination of device vendors and device types (e.g. AMD GPU)
- database_type_vendor = df.groupby(clblast.DEVICE_TYPE_ATTRIBUTES + clblast.KERNEL_ATTRIBUTES + ["kernel"] +
- clblast.ARGUMENT_ATTRIBUTES)
+ database_type_vendor = database.groupby(clblast.DEVICE_TYPE_ATTRIBUTES + clblast.KERNEL_ATTRIBUTES + ["kernel"] +
+ clblast.ARGUMENT_ATTRIBUTES)
for group_name, database_group in database_type_vendor:
- default_values = database_group.min(axis=0)
+ if calculate_common_best:
+ default_values = get_common_best(database_group, group_name)
+ else:
+ default_values = get_smallest_best(database_group)
default_values = set_default_device(default_values)
default_values = set_default_time(default_values)
database_defaults = database_defaults.append(default_values, ignore_index=True)
@@ -45,9 +49,9 @@ def calculate_defaults(df):
print("[WARNING] Entries for a single kernel with multiple argument values: " + description)
# Defaults over all device types and vendors
- groups = df.groupby(clblast.KERNEL_ATTRIBUTES + ["kernel"] + clblast.ARGUMENT_ATTRIBUTES)
+ groups = database.groupby(clblast.KERNEL_ATTRIBUTES + ["kernel"] + clblast.ARGUMENT_ATTRIBUTES)
for group_name, database_group in groups:
- default_values = database_group.min(axis=0)
+ default_values = get_smallest_best(database_group)
default_values["device_vendor"] = clblast.VENDOR_DEFAULT
default_values["device_type"] = clblast.DEVICE_TYPE_DEFAULT
default_values = set_default_device(default_values)
@@ -56,3 +60,53 @@ def calculate_defaults(df):
# Database with both types of defaults only
return database_defaults
+
+
+def get_smallest_best(database):
+ """Sets defaults based on the smallest values of all known entries. The average might be better for performance but
+ some parameters might not be supported on other devices."""
+ database_best_results = bests.get_best_results(database)
+ return database_best_results.min(axis=0)
+
+
+def get_common_best(database, group_name):
+ """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."""
+ # TODO: Quite a bit slower than the above `get_smallest_best` method
+
+ # Counts the number of devices in this group
+ num_devices = len(database.groupby(clblast.DEVICE_ATTRIBUTES))
+
+ # Removes columns without any values
+ database = database.dropna(axis=1, how='all')
+
+ # Retrieves the parameter names for this kernel
+ all_column_names = list(database.columns.values)
+ parameter_column_names = [c for c in all_column_names if "parameters." in c]
+
+ # Removes entries which are not available for all devices
+ database_common = pd.DataFrame()
+ database_by_parameters = database.groupby(parameter_column_names)
+ for parameter_values, database_parameters in database_by_parameters:
+ num_entries = database_parameters.shape[0]
+ if num_entries == num_devices:
+ database_common = database_common.append(database_parameters)
+
+ # Fall back to another method in case there are no shared entries at all across devices
+ if database_common.shape[0] == 0:
+ # print("Skipping: " + str(group_name) + " with devices: " + str(num_devices) + " " + str(database.shape[0]))
+ return get_smallest_best(database)
+
+ # Computes the sum of the execution times over the different devices
+ database_common['time'] = database_common.groupby(parameter_column_names)['time'].transform(sum)
+
+ # Retrieves the entries with the best execution time
+ best_time = database_common["time"].min()
+ database_bests = database_common[database_common["time"] == best_time]
+
+ # Retrieves one example only (the parameters are the same anyway)
+ database_bests = database_bests.drop_duplicates(["time"])
+ # print(str(group_name) + " with num devices: " + str(num_devices) + " " + str(database_bests.shape))
+ assert database_bests.shape[0] == 1
+
+ return database_bests