<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run(self, parameter_space, kernel_options, tuning_options):
 """ Tune all instances in parameter_space using a multiple threads :param parameter_space: The parameter space as an iterable. :type parameter_space: iterable :param kernel_options: A dictionary with all options for the kernel. :type kernel_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() """

        workflow = self._parameter_sweep(parameter_space, kernel_options, self.device_options,
                                         tuning_options)
        if tuning_options.verbose:
            with NCDisplay(_error_filter) as display:
                answer = run_parallel_with_display(workflow, self.max_threads, display)
        else:
            answer = run_parallel(workflow, self.max_threads)

        if answer is None:
            print("Tuning did not return any results, did an error occur?")
            return None

        # Filter out None times
        result = []
        for chunk in answer:
            result += [d for d in chunk if d['time']]

        return result, {}