-
Notifications
You must be signed in to change notification settings - Fork 21
/
threaded_count.py
75 lines (43 loc) · 2.29 KB
/
threaded_count.py
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#ParallelScreen.py
#Region: Imports
import itertools;
import time;
import smact
from multiprocessing import Pool;
#EndRegion
#Region: Functions
def _Kernel(elementList):
combinationCount = 0;
chargeNeutralCount = 0;
paulingSensibleCount = 0;
electronegativities = [element.pauling_eneg for element in elementList];
for oxidationStates in itertools.product(*[element.oxidation_states for element in elementList]):
combinationCount = combinationCount + 1;
ret1, ret2 = smact.charge_neutrality(oxidationStates, threshold = 1);
if ret1:
chargeNeutralCount = chargeNeutralCount + 1;
if smact.pauling_test(oxidationStates, electronegativities):
paulingSensibleCount = paulingSensibleCount + 1;
return (combinationCount, chargeNeutralCount, paulingSensibleCount);
#EndRegion
#Region: Main
#COMMENT: When using multiprocessing, the "main" code *must* be enclosed in this block - otherwise, bad things happen (at least, they do on Windows...).
if __name__ == "__main__":
elementList = smact.ordered_elements(1, 100);
startTime = time.time();
searchPrimitives = [smact.Element(element) for element in elementList];
threadPool = Pool(4);
#COMMENT: The mapping function returns a tuple of counts, and the list of these generated by Pool.map() needs to be summed at the end; this isn't great, but it's probably better than shared state.
result = threadPool.map(_Kernel, itertools.combinations(searchPrimitives, 4), 100);
#COMMENT: To see whether or not multithreading makes a difference, we can also try the equivalent single-thread code.
#result = [_Kernel(argument) for argument in itertools.combinations(searchPrimitives, 4)];
combinationCount = sum(count1 for count1, count2, count3 in result);
chargeNeutralCount = sum(count2 for count1, count2, count3 in result);
paulingSensibleCount = sum(count3 for count1, count2, count3 in result);
totalTime = time.time() - startTime;
print("Enumeration: {0:.2f} s".format(totalTime));
print("Combinations: {0}".format(combinationCount));
print("Charge neutral: {0}".format(chargeNeutralCount));
print("Pauling sensible: {0}".format(paulingSensibleCount));
print("");
#EndRegion