-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparallel_euler_number.py
More file actions
61 lines (51 loc) · 2.29 KB
/
Copy pathparallel_euler_number.py
File metadata and controls
61 lines (51 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import concurrent.futures
import sys
import math
import time
import os
from decimal import Decimal, getcontext
from argument_parser import ArgumentParser
from general_utils import get_commands_arguments_dict
import multiprocessing as mp
from functools import reduce
from operator import mul
def factorial(start, end):
start = start if start > 0 else 1
fact = Decimal(reduce(mul, range(start, (end + 1)), 1))
return fact
def calculate_euler_number_with_precision(start_idx, end_idx, d):
getcontext().prec = 100000
sum = Decimal(0)
print(f'Starting execution of [{start_idx},{end_idx}] by process {os.getpid()}')
for k in range(start_idx, end_idx+1):
print(f'Executing process {os.getpid()} for index {k}')
max_computed_value = max(key for key in d.keys() if key <= 2*k)
d[2 * k] = d[max_computed_value]*factorial(max_computed_value + 1, 2*k)
next_sum = Decimal(2*k + 1) / Decimal(d[2*k])
sum = sum + next_sum
return sum
def _helper(partial_sum_arguments):
return calculate_euler_number_with_precision(partial_sum_arguments[0], partial_sum_arguments[1], partial_sum_arguments[2])
def parrale_sum(n, num_processes, granularity, quiet_output=False):
delimeter = num_processes*granularity
step = math.ceil(n / delimeter)
with mp.Manager() as manager:
d = manager.dict()
d[1] = 1
#Adding the shared dict to every partial interval
parts = [[start+1, start+step, d] for start in range(0, n, step)]
parts[-1] = [parts[-1][0], n, d]
with concurrent.futures.ProcessPoolExecutor(max_workers=num_processes) as executor:
partial_sums = executor.map(_helper, parts)
return Decimal(1) + sum(partial_sums)
if __name__ == '__main__':
commands_dict = get_commands_arguments_dict(sys.argv)
commands = ArgumentParser(**commands_dict)
getcontext().prec = 100000
start = time.perf_counter()
euler_number = parrale_sum(commands.precision, commands.num_processors, commands.granularity, commands.quiet_output)
end = time.perf_counter()
print(f'Time took for execution {int((end - start)*1000)}ms with '
f'{commands.num_processors} processors and granularity {commands.granularity}')
with open(commands.save_to_file, 'w+') as f:
f.write(str(euler_number))