def tune_kernel(kernel_name, kernel_string, problem_size, arguments, tune_params, grid_div_x=None, grid_div_y=None, grid_div_z=None, restrictions=None, answer=None, atol=1e-6, verify=None, verbose=False, lang=None, device=0, platform=0, cmem_args=None, num_threads=1, use_noodles=False, sample_fraction=False, compiler=None, compiler_options=None, log=None, iterations=7, times=False, block_size_names=None, quiet=False, strategy=None, method=None): if log: logging.basicConfig(filename=kernel_name + datetime.now().strftime('%Y%m%d-%H:%M:%S') + '.log', level=log) _check_user_input(kernel_name, kernel_string, arguments, block_size_names) # check for forbidden names in tune parameters util.check_tune_params_list(tune_params) # check whether block_size_names are used as expected util.check_block_size_params_names_list(block_size_names, tune_params) if iterations < 1: raise ValueError("Iterations should be at least one!") #sort all the options into separate dicts opts = locals() kernel_options = Options([(k, opts[k]) for k in _kernel_options.keys()]) tuning_options = Options([(k, opts[k]) for k in _tuning_options.keys()]) device_options = Options([(k, opts[k]) for k in _device_options.keys()]) logging.debug('tune_kernel called') logging.debug('kernel_options: %s', util.get_config_string(kernel_options)) logging.debug('tuning_options: %s', util.get_config_string(tuning_options)) logging.debug('device_options: %s', util.get_config_string(device_options)) #select strategy based on user options if sample_fraction and not strategy in [None, 'sample_fraction']: raise ValueError("It's not possible to use both sample_fraction in combination with other strategies. " \ 'Please set strategy=None or strategy="random_sample", when using sample_fraction') if strategy in [None, 'sample_fraction', 'brute_force']: if sample_fraction: use_strategy = random_sample else: use_strategy = brute_force elif strategy in ["minimize", "basinhopping"]: if method: if not (method in [ "Nelder-Mead", "Powell", "CG", "BFGS", "L-BFGS-B", "TNC", "COBYLA", "SLSQP" ] or callable(method)): raise ValueError("method option not recognized") else: method = "L-BFGS-B" if strategy == "minimize": use_strategy = minimize else: use_strategy = basinhopping elif strategy == "diff_evo": use_strategy = diff_evo if method: if not method in [ "best1bin", "best1exp", "rand1exp", "randtobest1exp", "best2exp", "rand2exp", "randtobest1bin", "best2bin", "rand2bin", "rand1bin" ]: raise ValueError("method option not recognized") else: raise ValueError("strategy option not recognized") strategy = use_strategy #select runner based on user options if num_threads == 1 and not use_noodles: from kernel_tuner.runners.sequential import SequentialRunner runner = SequentialRunner(kernel_options, device_options, iterations) elif num_threads > 1 and not use_noodles: raise ValueError( "Using multiple threads requires the Noodles runner, use use_noodles=True" ) elif use_noodles: #check if Python version matches required by Noodles if sys.version_info[0] < 3 or (sys.version_info[0] == 3 and sys.version_info[1] < 5): raise ValueError( "Using multiple threads requires Noodles, Noodles requires Python 3.5 or higher" ) #check if noodles is installed in a way that works with Python 3.4 or newer noodles_installed = importlib.util.find_spec("noodles") is not None if not noodles_installed: raise ValueError( "Using multiple threads requires Noodles, please use 'pip install noodles'" ) #import the NoodlesRunner from kernel_tuner.runners.noodles import NoodlesRunner runner = NoodlesRunner(device_options, num_threads) else: raise ValueError( "Somehow no runner was selected, this should not happen, please file a bug report" ) #call the strategy to execute the tuning process results, env = strategy.tune(runner, kernel_options, device_options, tuning_options) #finished iterating over search space if not device_options.quiet: if results: #checks if results is not empty best_config = min(results, key=lambda x: x['time']) units = getattr(runner, "units", None) print("best performing configuration:", util.get_config_string(best_config, units=units)) else: print("no results to report") del runner.dev return results, env
def tune_kernel(kernel_name, kernel_string, problem_size, arguments, tune_params, grid_div_x=None, grid_div_y=None, grid_div_z=None, restrictions=None, answer=None, atol=1e-6, verify=None, verbose=False, lang=None, device=0, platform=0, cmem_args=None, texmem_args=None, compiler=None, compiler_options=None, log=None, iterations=7, block_size_names=None, quiet=False, strategy=None, strategy_options=None, cache=None): if log: logging.basicConfig(filename=kernel_name + datetime.now().strftime('%Y%m%d-%H:%M:%S') + '.log', level=log) kernel_source = core.KernelSource(kernel_string, lang) _check_user_input(kernel_name, kernel_source, arguments, block_size_names) # check for forbidden names in tune parameters util.check_tune_params_list(tune_params) # check whether block_size_names are used as expected util.check_block_size_params_names_list(block_size_names, tune_params) if iterations < 1: raise ValueError("Iterations should be at least one!") #sort all the options into separate dicts opts = locals() kernel_options = Options([(k, opts[k]) for k in _kernel_options.keys()]) tuning_options = Options([(k, opts[k]) for k in _tuning_options.keys()]) device_options = Options([(k, opts[k]) for k in _device_options.keys()]) logging.debug('tune_kernel called') logging.debug('kernel_options: %s', util.get_config_string(kernel_options)) logging.debug('tuning_options: %s', util.get_config_string(tuning_options)) logging.debug('device_options: %s', util.get_config_string(device_options)) if strategy: if strategy in strategy_map: strategy = strategy_map[strategy] else: raise ValueError("Strategy %s not recognized" % strategy) #make strategy_options into an Options object if tuning_options.strategy_options: if not isinstance(strategy_options, Options): tuning_options.strategy_options = Options(strategy_options) #select strategy based on user options if "fraction" in tuning_options.strategy_options and not tuning_options.strategy == 'random_sample': raise ValueError('It is not possible to use fraction in combination with strategies other than "random_sample". ' \ 'Please set strategy="random_sample", when using "fraction" in strategy_options') #check if method is supported by the selected strategy if "method" in tuning_options.strategy_options: method = tuning_options.strategy_options.method if not method in strategy.supported_methods: raise ValueError('Method %s is not supported for strategy %s' % (method, tuning_options.strategy)) #if no strategy_options dict has been passed, create empty dictionary else: tuning_options.strategy_options = Options({}) #if no strategy selected else: strategy = brute_force runner = SequentialRunner(kernel_source, kernel_options, device_options, iterations) #the user-specified function may or may not have an optional atol argument; #we normalize it so that it always accepts atol. tuning_options.verify = util.normalize_verify_function(tuning_options.verify) #process cache if cache: if cache[-5:] != ".json": cache += ".json" util.process_cache(cache, kernel_options, tuning_options, runner) else: tuning_options.cache = {} tuning_options.cachefile = None #call the strategy to execute the tuning process results, env = strategy.tune(runner, kernel_options, device_options, tuning_options) #finished iterating over search space if not device_options.quiet: if results: #checks if results is not empty best_config = min(results, key=lambda x: x['time']) units = getattr(runner, "units", None) print("best performing configuration:", util.get_config_string(best_config, list(tune_params.keys()) + ['time'], units=units)) else: print("no results to report") if cache: util.close_cache(cache) del runner.dev return results, env