def tune(runner, kernel_options, device_options, tuning_options): """ Find the best performing kernel configuration in the parameter space :params runner: A runner from kernel_tuner.runners :type runner: kernel_tuner.runner :param kernel_options: A dictionary with all options for the kernel. :type kernel_options: dict :param device_options: A dictionary with all options for the device on which the kernel should be tuned. :type device_options: dict :param tuning_options: A dictionary with all options regarding the tuning process. :type tuning_options: dict :returns: A list of dictionaries for executed kernel configurations and their execution times. And a dictionary that contains a information about the hardware/software environment on which the tuning took place. :rtype: list(dict()), dict() """ # MLS works with real parameter values and does not need scaling tuning_options["scaling"] = False tune_params = tuning_options.tune_params options = tuning_options.strategy_options max_fevals = options.get("max_fevals", 100) # limit max_fevals to max size of the parameter space parameter_space = itertools.product(*tune_params.values()) if tuning_options.restrictions is not None: parameter_space = filter(lambda p: util.check_restrictions(restrictions, p, tune_params.keys(), tuning_options.verbose), parameter_space) max_elems = len(list(parameter_space)) if max_elems < max_fevals: max_fevals = max_elems fevals = 0 max_threads = runner.dev.max_threads all_results = [] unique_results = {} #while searching while fevals < max_fevals: #get random starting position that is valid pos = [random.choice(v) for v in tune_params.values()] #if we have restrictions and config fails restrictions, try again #if restrictions and not util.check_restrictions(restrictions, pos, tune_params.keys(), False): if not util.config_valid(pos, tuning_options, max_threads): continue hillclimb(pos, max_fevals, all_results, unique_results, kernel_options, tuning_options, runner) fevals = len(unique_results) return all_results, runner.dev.get_environment()
def tune(runner, kernel_options, device_options, tuning_options): """ Tune a random sample of sample_fraction fraction in the parameter space :params runner: A runner from kernel_tuner.runners :type runner: kernel_tuner.runner :param kernel_options: A dictionary with all options for the kernel. :type kernel_options: kernel_tuner.interface.Options :param device_options: A dictionary with all options for the device on which the kernel should be tuned. :type device_options: kernel_tuner.interface.Options :param tuning_options: A dictionary with all options regarding the tuning process. :type tuning_options: kernel_tuner.interface.Options :returns: A list of dictionaries for executed kernel configurations and their execution times. And a dictionary that contains a information about the hardware/software environment on which the tuning took place. :rtype: list(dict()), dict() """ tune_params = tuning_options.tune_params fraction = tuning_options.strategy_options.get("fraction", 0.1) #compute cartesian product of all tunable parameters parameter_space = itertools.product(*tune_params.values()) #check for search space restrictions if tuning_options.restrictions is not None: parameter_space = filter( lambda p: util.check_restrictions(tuning_options.restrictions, p, tune_params.keys(), tuning_options.verbose), parameter_space) #reduce parameter space to a random sample using sample_fraction parameter_space = numpy.array(list(parameter_space)) size = len(parameter_space) fraction = int(numpy.ceil(size * fraction)) sample_indices = numpy.random.choice(range(size), size=fraction, replace=False) parameter_space = parameter_space[sample_indices] #call the runner results, env = runner.run(parameter_space, kernel_options, tuning_options) return results, env
def _cost_func(x, kernel_options, tuning_options, runner, results, cache): """ Cost function used by minimize """ error_time = 1e20 logging.debug('_cost_func called') logging.debug('x: ' + str(x)) x_key = ",".join([str(i) for i in x]) if x_key in cache: return cache[x_key] #snap values in x to nearest actual value for each parameter unscale x if needed if tuning_options.scaling: params = unscale_and_snap_to_nearest(x, tuning_options.tune_params, tuning_options.eps) else: params = snap_to_nearest_config(x, tuning_options.tune_params) logging.debug('params ' + str(params)) x_int = ",".join([str(i) for i in params]) if x_int in cache: return cache[x_int] #check if this is a legal (non-restricted) parameter instance if tuning_options.restrictions: legal = util.check_restrictions(tuning_options.restrictions, params, tuning_options.tune_params.keys(), tuning_options.verbose) if not legal: cache[x_int] = error_time cache[x_key] = error_time return error_time #compile and benchmark this instance res, _ = runner.run([params], kernel_options, tuning_options) #append to tuning results if res: results.append(res[0]) cache[x_int] = res[0]['time'] cache[x_key] = res[0]['time'] return res[0]['time'] cache[x_int] = error_time cache[x_key] = error_time return error_time
def tune(runner, kernel_options, device_options, tuning_options): """ Tune a random sample of sample_fraction fraction in the parameter space :params runner: A runner from kernel_tuner.runners :type runner: kernel_tuner.runner :param kernel_options: A dictionary with all options for the kernel. :type kernel_options: kernel_tuner.interface.Options :param device_options: A dictionary with all options for the device on which the kernel should be tuned. :type device_options: kernel_tuner.interface.Options :param tuning_options: A dictionary with all options regarding the tuning process. :type tuning_options: kernel_tuner.interface.Options :returns: A list of dictionaries for executed kernel configurations and their execution times. And a dictionary that contains a information about the hardware/software environment on which the tuning took place. :rtype: list(dict()), dict() """ tune_params = tuning_options.tune_params #compute cartesian product of all tunable parameters parameter_space = itertools.product(*tune_params.values()) #check for search space restrictions if tuning_options.restrictions is not None: parameter_space = filter(lambda p: util.check_restrictions(tuning_options.restrictions, p, tune_params.keys(), tuning_options.verbose), parameter_space) #reduce parameter space to a random sample using sample_fraction parameter_space = numpy.array(list(parameter_space)) size = len(parameter_space) fraction = int(numpy.ceil(size * float(tuning_options.sample_fraction))) sample_indices = numpy.random.choice(range(size), size=fraction, replace=False) parameter_space = parameter_space[sample_indices] #call the runner results, env = runner.run(parameter_space, kernel_options, tuning_options) return results, env
def _cost_func(x, kernel_options, tuning_options, runner, results): """ Cost function used by minimize """ error_time = 1e20 logging.debug('_cost_func called') logging.debug('x: ' + str(x)) # snap values in x to nearest actual value for each parameter unscale x if needed if tuning_options.snap: if tuning_options.scaling: params = unscale_and_snap_to_nearest(x, tuning_options.tune_params, tuning_options.eps) else: params = snap_to_nearest_config(x, tuning_options.tune_params) else: params = x logging.debug('params ' + str(params)) # we cache snapped values, since those correspond to results for an actual instance of the kernel x_int = ",".join([str(i) for i in params]) if x_int in tuning_options.cache: results.append(tuning_options.cache[x_int]) return tuning_options.cache[x_int]["time"] # check if this is a legal (non-restricted) parameter instance if tuning_options.restrictions: legal = util.check_restrictions(tuning_options.restrictions, params, tuning_options.tune_params.keys(), tuning_options.verbose) if not legal: error_result = OrderedDict( zip(tuning_options.tune_params.keys(), params)) error_result["time"] = error_time tuning_options.cache[x_int] = error_result return error_time # compile and benchmark this instance res, _ = runner.run([params], kernel_options, tuning_options) # append to tuning results if res: results.append(res[0]) return res[0]['time'] return error_time
def _cost_func(x, kernel_options, tuning_options, runner, results): """ Cost function used by the differential evolution optimizer """ #snap values in x to nearest actual value for each parameter params = minimize.snap_to_nearest_config(x, tuning_options.tune_params) #check if this is a legal (non-restricted) parameter instance if tuning_options.restrictions: legal = util.check_restrictions(tuning_options.restrictions, params, tuning_options.tune_params.keys(), tuning_options.verbose) if not legal: return 1e20 #compile and benchmark this instance res, _ = runner.run([params], kernel_options, tuning_options) #append to tuning results if len(res) > 0: results.append(res[0]) return res[0]['time'] return 1e20
def tune(runner, kernel_options, device_options, tuning_options): """ Tune all instances in the parameter space :params runner: A runner from kernel_tuner.runners :type runner: kernel_tuner.runner :param kernel_options: A dictionary with all options for the kernel. :type kernel_options: kernel_tuner.interface.Options :param device_options: A dictionary with all options for the device on which the kernel should be tuned. :type device_options: kernel_tuner.interface.Options :param tuning_options: A dictionary with all options regarding the tuning process. :type tuning_options: kernel_tuner.interface.Options :returns: A list of dictionaries for executed kernel configurations and their execution times. And a dictionary that contains a information about the hardware/software environment on which the tuning took place. :rtype: list(dict()), dict() """ tune_params = tuning_options.tune_params restrictions = tuning_options.restrictions verbose = tuning_options.verbose # compute cartesian product of all tunable parameters parameter_space = itertools.product(*tune_params.values()) # check for search space restrictions if restrictions is not None: parameter_space = filter(lambda p: util.check_restrictions(restrictions, p, tune_params.keys(), verbose), parameter_space) results, env = runner.run(parameter_space, kernel_options, tuning_options) return results, env
def tune(runner, kernel_options, device_options, tuning_options): """ Tune all instances in the parameter space :params runner: A runner from kernel_tuner.runners :type runner: kernel_tuner.runner :param kernel_options: A dictionary with all options for the kernel. :type kernel_options: kernel_tuner.interface.Options :param device_options: A dictionary with all options for the device on which the kernel should be tuned. :type device_options: kernel_tuner.interface.Options :param tuning_options: A dictionary with all options regarding the tuning process. :type tuning_options: kernel_tuner.interface.Options :returns: A list of dictionaries for executed kernel configurations and their execution times. And a dictionary that contains a information about the hardware/software environment on which the tuning took place. :rtype: list(dict()), dict() """ tune_params = tuning_options.tune_params restrictions = tuning_options.restrictions verbose = tuning_options.verbose #compute cartesian product of all tunable parameters parameter_space = itertools.product(*tune_params.values()) #check for search space restrictions if restrictions is not None: parameter_space = filter(lambda p: util.check_restrictions(restrictions, p, tune_params.keys(), verbose), parameter_space) results, env = runner.run(parameter_space, kernel_options, tuning_options) return results, env