mirror of
https://github.com/CNugteren/CLBlast.git
synced 2024-08-21 20:42:28 +02:00
Added a first version of the database's common-best default calculation
This commit is contained in:
parent
35623cd98d
commit
3f5401d4c8
|
@ -98,7 +98,8 @@ def main(argv):
|
||||||
database_best_results = bests.get_best_results(database)
|
database_best_results = bests.get_best_results(database)
|
||||||
|
|
||||||
# Determines the defaults for other vendors and per vendor
|
# 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)
|
database_best_results = db.concatenate_database(database_best_results, database_defaults)
|
||||||
|
|
||||||
# Outputs the database as a C++ database
|
# Outputs the database as a C++ database
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
# Cedric Nugteren <www.cedricnugteren.nl>
|
# Cedric Nugteren <www.cedricnugteren.nl>
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
|
|
||||||
import clblast
|
import clblast
|
||||||
|
import bests
|
||||||
|
|
||||||
|
|
||||||
def set_default_device(database_entry):
|
def set_default_device(database_entry):
|
||||||
|
@ -23,16 +25,18 @@ def set_default_time(database_entry):
|
||||||
return database_entry
|
return database_entry
|
||||||
|
|
||||||
|
|
||||||
def calculate_defaults(df):
|
def calculate_defaults(database, calculate_common_best=True):
|
||||||
"""# Sets defaults for devices of the same type/vendor based on the smallest values of all known entries. The average
|
"""Sets defaults for devices of the same type/vendor. An option determines how to compute the defaults."""
|
||||||
might be better for performance but some parameters might not be supported on other devices."""
|
|
||||||
database_defaults = pd.DataFrame()
|
database_defaults = pd.DataFrame()
|
||||||
|
|
||||||
# Defaults per combination of device vendors and device types (e.g. AMD GPU)
|
# 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"] +
|
database_type_vendor = database.groupby(clblast.DEVICE_TYPE_ATTRIBUTES + clblast.KERNEL_ATTRIBUTES + ["kernel"] +
|
||||||
clblast.ARGUMENT_ATTRIBUTES)
|
clblast.ARGUMENT_ATTRIBUTES)
|
||||||
for group_name, database_group in database_type_vendor:
|
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_device(default_values)
|
||||||
default_values = set_default_time(default_values)
|
default_values = set_default_time(default_values)
|
||||||
database_defaults = database_defaults.append(default_values, ignore_index=True)
|
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)
|
print("[WARNING] Entries for a single kernel with multiple argument values: " + description)
|
||||||
|
|
||||||
# Defaults over all device types and vendors
|
# 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:
|
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_vendor"] = clblast.VENDOR_DEFAULT
|
||||||
default_values["device_type"] = clblast.DEVICE_TYPE_DEFAULT
|
default_values["device_type"] = clblast.DEVICE_TYPE_DEFAULT
|
||||||
default_values = set_default_device(default_values)
|
default_values = set_default_device(default_values)
|
||||||
|
@ -56,3 +60,53 @@ def calculate_defaults(df):
|
||||||
|
|
||||||
# Database with both types of defaults only
|
# Database with both types of defaults only
|
||||||
return database_defaults
|
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
|
||||||
|
|
Loading…
Reference in a new issue