1 from itertools
import product
, chain
4 from exc
import IncompatibleUnits
, MemExceeded
6 def search(base_numbers
, ops
, cc
, max_round
=None, mem_limit
=2*1024**2):
9 # check if measurements do not mean anything directly
10 for m
in base_numbers
:
11 cc
.checkCandidate(m
, verbose
=True)
14 final_round
= max_round
== 0
17 while not final_round
:
18 final_round
= max_round
== round_count
21 print "ROUND %d started"%(round_count
,)
25 for op
in ops
.get(round_count
, ops
.get('default', None)):
28 raise NotImplementedError
31 sofar
= list(chain(*bf
))
33 pr
= [last
] + [sofar
]*(ar
-1)
37 if not op
.isCommutative() and ar
== 2:
38 i2
= product(chain(*(bf
[:-1])), last
)
40 for t
in chain(i1
, i2
):
41 if elem_count
% 10000 == 0 and not final_round
:
42 mem_used
= resource
.getrusage(resource
.RUSAGE_SELF
).ru_maxrss
43 if mem_used
> mem_limit
:
46 print "Limit %.1f MB, Used %.1f MB"%(mem_limit
/ 1024.0, mem_used
/ 1024.0)
47 print "FINAL ROUND FOLLOWS"
53 # we do not need to add if we are in the final round
54 # we save a lot of memory this way (and may even be able to compute one more round therefore
57 # register the result to see improving matches incrementaly
58 cc
.checkCandidate(res
, verbose
=True)
59 except IncompatibleUnits
:
61 except ZeroDivisionError:
65 # set the limit so that we end in the next iteration
66 max_round
= round_count
+ 1
70 print "ROUND %d ended, searched %d combinations in total"%(round_count
, elem_count
)
74 except KeyboardInterrupt:
83 # show what we have found