예제 #1
0
파일: mls.py 프로젝트: stijnh/kernel_tuner
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()
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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
예제 #6
0
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
예제 #7
0
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
예제 #8
0
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
예제 #9
0
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