Пример #1
0
 def test_with_only_line_charges_should_be_equal_to_original_results(self):
     charges = [
         LineCharge(1, [-1, -2], [-1, 2]),
         LineCharge(-1, [1, 2], [1, -2])
     ]
     original_electric_field = ElectricFieldWrapper(self._config, charges)
     original_result, _, __ = original_electric_field.calculate()
     sequential_electric_field = SequentialElectricField(
         self._config, charges)
     sequential_result, _, __ = sequential_electric_field.calculate()
     assert_array_almost_equal(original_result,
                               sequential_result,
                               decimal=5)
Пример #2
0
 def test_with_only_point_charges_should_be_equal_to_original_results(self):
     charges = [
         PointCharge(2, [0, 0]),
         PointCharge(-1, [2, 1]),
         PointCharge(1, [4, 0])
     ]
     original_electric_field = ElectricFieldWrapper(self._config, charges)
     original_result, _, __ = original_electric_field.calculate()
     sequential_electric_field = SequentialElectricField(
         self._config, charges)
     sequential_result, _, __ = sequential_electric_field.calculate()
     assert_array_almost_equal(original_result,
                               sequential_result,
                               decimal=5)
Пример #3
0
 def test_with_multiple_charge_types_should_be_equal_to_original_results(
         self):
     charges = [
         PointChargeFlatland(2, [0, 0]),
         PointCharge(-1, [2, 1]),
         LineCharge(1, [-1, -2], [-1, 2])
     ]
     original_electric_field = ElectricFieldWrapper(self._config, charges)
     original_result, _, __ = original_electric_field.calculate()
     sequential_electric_field = SequentialElectricField(
         self._config, charges)
     sequential_result, _, __ = sequential_electric_field.calculate()
     assert_array_almost_equal(original_result,
                               sequential_result,
                               decimal=5)
Пример #4
0
 def test_with_only_line_charges_should_be_equal_to_sequential_results(
         self):
     charges = [
         LineCharge(1, [-1, -2], [-1, 2]),
         LineCharge(-1, [1, 2], [1, -2])
     ]
     sequential_electric_field = SequentialElectricField(
         self._config, charges)
     sequential_result, _, __ = sequential_electric_field.calculate()
     parallel_electric_field = ParallelElectricField(
         self._config, charges, 16)
     parallel_result, _, __ = parallel_electric_field.calculate()
     assert_array_almost_equal(sequential_result,
                               parallel_result,
                               decimal=5)
Пример #5
0
 def test_with_multiple_charge_types_should_be_equal_to_sequential_results(
         self):
     charges = [
         PointChargeFlatland(2, [0, 0]),
         PointCharge(-1, [2, 1]),
         LineCharge(1, [-1, -2], [-1, 2])
     ]
     sequential_electric_field = SequentialElectricField(
         self._config, charges)
     sequential_result, _, __ = sequential_electric_field.calculate()
     parallel_electric_field = ParallelElectricField(
         self._config, charges, 16)
     parallel_result, _, __ = parallel_electric_field.calculate()
     assert_array_almost_equal(sequential_result,
                               parallel_result,
                               decimal=5)
Пример #6
0
 def test_with_only_point_charges_should_be_equal_to_sequential_results(
         self):
     charges = [
         PointCharge(2, [0, 0]),
         PointCharge(-1, [2, 1]),
         PointCharge(1, [4, 0])
     ]
     sequential_electric_field = SequentialElectricField(
         self._config, charges)
     sequential_result, _, __ = sequential_electric_field.calculate()
     parallel_electric_field = ParallelElectricField(
         self._config, charges, 16)
     parallel_result, _, __ = parallel_electric_field.calculate()
     assert_array_almost_equal(sequential_result,
                               parallel_result,
                               decimal=5)
Пример #7
0
 def __init__(self, config_option, charges):
     self._electric_field = SequentialElectricField(config_option, charges)
     self._parallel_electric_field = ParallelElectricField(
         config_option, charges)
     # To discard the compilation time.
     self._parallel_electric_field.time_it(sequential_time=0)
Пример #8
0
class TimeEvaluator():
    def __init__(self, config_option, charges):
        self._electric_field = SequentialElectricField(config_option, charges)
        self._parallel_electric_field = ParallelElectricField(
            config_option, charges)
        # To discard the compilation time.
        self._parallel_electric_field.time_it(sequential_time=0)

    def process(self, times, max_number_of_cores=1024):
        report = {}
        report.update(self._process_sequential_execution(times))
        report.update(
            self._process_parallel_execution(times, report['sequential_time'],
                                             max_number_of_cores))
        self._save_as_json_file(report)
        self.plot(report)

        return report

    def _process_sequential_execution(self, times):
        partial_report = {}
        partial_report['sequential_time'] = 0
        partial_report['sequential_samples'] = []
        for _ in range(times):
            sample = self._electric_field.time_it()
            partial_report['sequential_time'] += sample['total_time'] / times
            partial_report['sequential_samples'].append(sample)
        return partial_report

    def _process_parallel_execution(self,
                                    times,
                                    sequential_time,
                                    max_number_of_cores=1024):
        partial_report = {}
        partial_report['parallel_time'] = []
        partial_report['parallel_speedup'] = []
        partial_report['parallel_efficiency'] = []
        partial_report['parallel_samples'] = []
        n = 0
        number_of_cores = 2**n
        while number_of_cores <= max_number_of_cores:
            time = 0
            speedup = 0
            # efficiency = 0
            samples = []
            for _ in range(times):
                self._parallel_electric_field.number_of_cores = number_of_cores
                sample = self._parallel_electric_field.time_it(
                    sequential_time=sequential_time)
                time += sample['total_time'] / times
                speedup += sample['speedup'] / times
                # efficiency += sample['efficiency']/times
                samples.append(sample)
            partial_report['parallel_time'].append(time)
            partial_report['parallel_speedup'].append(speedup)
            # partial_report['parallel_efficiency'].append(efficiency)
            partial_report['parallel_samples'].append(samples)
            n += 1
            number_of_cores = 2**n
        return partial_report

    @staticmethod
    def _save_as_json_file(report):
        f = open("tests.json", "w")
        json.dump(report, f)
        f.close()

    @staticmethod
    def plot(report):
        x = [f'A{n}' for n in range(11)]

        TimeEvaluator._generic_plot(
            ['S'] + x, [report['sequential_time']] + report['parallel_time'],
            'Tempo de execução X Threads per block', 'Tempo', 'Grid X Blocks',
            'time_plot.png')

        TimeEvaluator._generic_plot(x, report['parallel_speedup'],
                                    'Speedup X Threads per block', 'Tempo',
                                    'Grid X Blocks', 'speedup_plot.png')

        # I didn't find a way to limit the number of cores used by GPU. So, I can't calculate the
        # efficiency of parallel execution.
        # TimeEvaluator._generic_plot(
        #     x, report['parallel_efficiency'],
        #     'Eficiência X Threads per block', 'Tempo', 'Grid X Blocks', 'efficiency_plot.png')

    @staticmethod
    def _generic_plot(x, y, title_value, y_label, x_label, file_name):
        figure()
        scatter(x, y)
        title(title_value)
        ylabel(y_label)
        xlabel(x_label)
        grid(True)
        savefig(file_name)
Пример #9
0
# %%
# Original version
XMIN, XMAX = -40, 40
YMIN, YMAX = -30, 30
ZOOM = 6
XOFFSET = 2
init(XMIN, XMAX, YMIN, YMAX, ZOOM, XOFFSET)
field = ElectricField(charges)
f = pyplot.figure(figsize=(6, 4.5))
field.plot(-1.7, 0.8)
for charge in charges:
    charge.plot()
finalize_plot()
pyplot.savefig('image.png')

# %%
# Sequential version
electric_field = SequentialElectricField(config, charges)
electric_field.draw(n_min=-1.7, n_max=0.8, n_step=0.2)
# electric_field.time_it()
# electric_field.calculate()

# %%
# Parallel version
electric_field = ParallelElectricField(config, charges, 16)
electric_field.draw(n_min=-1.7, n_max=0.8, n_step=0.2)
# electric_field.time_it()
# electric_field.calculate()

# %%