Skip to content

Commit b92b4fb

Browse files
Merge pull request #588 from ICB-DCM/develop
* Ignore B027 empty method in an abstract base class (#587) * Ignore B027 empty method in an abstract base class * Refactor EPSMixin * Fix EPSMixin for ConcurrentFutureSampler * restrict distributed, see dask/distributed#7227 * tmp add bokeh for tests to avoid restrictions * version+releasenotes 0.12.7
2 parents c52091e + 9c86cc2 commit b92b4fb

File tree

10 files changed

+189
-161
lines changed

10 files changed

+189
-161
lines changed

.flake8

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ extend-ignore =
1111
E203
1212
# Don't be crazy if line too long
1313
E501
14+
# Empty method in an abstract base class
15+
B027
1416

1517
per-file-ignores =
1618
# Imported but unused

CHANGELOG.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ Release Notes
88
...........
99

1010

11+
0.12.7 (2022-10-30)
12+
-------------------
13+
14+
Minor:
15+
16+
* Ignore B027 empty method in an abstract base class
17+
* Refactor EPSMixin
18+
* Fix EPSMixin for ConcurrentFutureSampler
19+
* Temporarily add bokeh to test due to dask error
20+
1121
0.12.6 (2022-08-30)
1222
-------------------
1323

pyabc/population.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,10 @@ def __init__(self, particles: List[Particle]):
104104
raise AssertionError(
105105
"A population should only consist of accepted particles"
106106
)
107-
if not np.isclose(sum(p.weight for p in particles), 1):
107+
108+
if not np.isclose(total_weight := sum(p.weight for p in particles), 1):
108109
raise AssertionError(
109-
"The population total weight is not normalized."
110+
f"The population total weight {total_weight} is not normalized."
110111
)
111112

112113
self.calculate_model_probabilities()

pyabc/sampler/concurrent_future.py

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Sample via the python concurrent futures executor interface."""
2+
13
from .base import Sampler
24
from .eps_mixin import EPSMixin
35

@@ -11,66 +13,49 @@ class ConcurrentFutureSampler(EPSMixin, Sampler):
1113
1214
Parameters
1315
----------
14-
15-
cfuture_executor: concurrent.futures.Executor, required
16+
cfuture_executor: "concurrent.futures.Executor"
1617
Configured object that implements the concurrent.futures.Executor
1718
interface
18-
1919
client_max_jobs:
2020
Maximum number of jobs that can submitted to the client at a time.
2121
If this value is smaller than the maximum number of cores provided by
2222
the distributed infrastructure, the infrastructure will not be utilized
2323
fully.
24-
2524
default_pickle:
2625
Specify if the sampler uses pythons default pickle function to
2726
communicate the submit function to python; if this is the case, a
2827
cloud-pickle based workaround is used to pickle the simulate and
2928
evaluate functions. This allows utilization of locally defined
3029
functions, which can not be pickled using default pickle, at the cost
3130
of an additional pickling overhead.
32-
33-
batch_size: int, optional
31+
batch_size:
3432
Number of parameter samples that are evaluated in one remote execution
3533
call. Batch submission can be used to reduce the communication overhead
3634
for fast (ms-s) model evaluations. Large batch sizes can result in un-
3735
necessary model evaluations. By default, batch_size=1, i.e. no batching
3836
is done.
39-
4037
"""
4138

4239
def __init__(
4340
self,
4441
cfuture_executor=None,
45-
client_max_jobs=200,
46-
default_pickle=True,
47-
batch_size=1,
42+
client_max_jobs: int = 200,
43+
default_pickle: bool = True,
44+
batch_size: int = 1,
4845
):
49-
super().__init__()
50-
51-
# Assign Client
52-
self.my_client = cfuture_executor
53-
54-
# Client options
55-
self.client_max_jobs = client_max_jobs
56-
57-
# Job state
58-
self.jobs_queued = 0
59-
60-
# Empty functions
61-
self.simulate_one = None
62-
self.accept_one = None
63-
64-
# Option pickling
65-
self.default_pickle = default_pickle
66-
67-
# Batchsize
68-
self.batch_size = batch_size
46+
EPSMixin.__init__(
47+
self,
48+
client=cfuture_executor,
49+
client_max_jobs=client_max_jobs,
50+
default_pickle=default_pickle,
51+
batch_size=batch_size,
52+
)
53+
Sampler.__init__(self)
6954

7055
def __getstate__(self):
7156
d = dict(self.__dict__)
72-
del d['my_client']
57+
del d['client']
7358
return d
7459

75-
def client_cores(self):
60+
def client_cores(self) -> int:
7661
return self.client_max_jobs

pyabc/sampler/dask_sampler.py

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"""Sample via dask."""
2+
13
import numpy as np
24
from dask.distributed import Client
35

@@ -13,7 +15,7 @@ class DaskDistributedSampler(EPSMixin, Sampler):
1315
1416
Parameters
1517
----------
16-
dask_client: dask.Client, optional
18+
dask_client:
1719
The configured dask Client.
1820
If none is provided, then a local dask distributed cluster is created.
1921
client_max_jobs:
@@ -22,14 +24,14 @@ class DaskDistributedSampler(EPSMixin, Sampler):
2224
the distributed infrastructure, the infrastructure will not be utilized
2325
fully.
2426
default_pickle:
25-
Specify if the sampler uses pythons default pickle function to
27+
Specify if the sampler uses python's default pickle function to
2628
communicate the submit function to python; if this is the case, a
2729
cloud-pickle based workaround is used to pickle the simulate and
2830
evaluate functions. This allows utilization of locally defined
2931
functions, which can not be pickled using default pickle, at the cost
3032
of an additional pickling overhead. For dask, this workaround should
3133
not be necessary and it should be save to use default_pickle=false.
32-
batch_size: int, optional
34+
batch_size:
3335
Number of parameter samples that are evaluated in one remote execution
3436
call. Batchsubmission can be used to reduce the communication overhead
3537
for fast (ms-s) model evaluations. Large batch sizes can result in un-
@@ -39,41 +41,35 @@ class DaskDistributedSampler(EPSMixin, Sampler):
3941

4042
def __init__(
4143
self,
42-
dask_client=None,
43-
client_max_jobs=np.inf,
44-
default_pickle=False,
45-
batch_size=1,
44+
dask_client: Client = None,
45+
client_max_jobs: int = np.inf,
46+
default_pickle: bool = False,
47+
batch_size: int = 1,
4648
):
47-
super().__init__()
48-
4949
# Assign Client
5050
if dask_client is None:
5151
dask_client = Client()
52-
self.my_client = dask_client
53-
54-
# Client options
55-
self.client_max_jobs = client_max_jobs
56-
57-
# Job state
58-
self.jobs_queued = 0
59-
60-
# For dask, we use cloudpickle by default
61-
self.default_pickle = default_pickle
6252

63-
# Batchsize
64-
self.batch_size = batch_size
53+
EPSMixin.__init__(
54+
self,
55+
client=dask_client,
56+
client_max_jobs=client_max_jobs,
57+
default_pickle=default_pickle,
58+
batch_size=batch_size,
59+
)
60+
Sampler.__init__(self)
6561

6662
def __getstate__(self):
6763
d = dict(self.__dict__)
68-
del d['my_client']
64+
del d['client']
6965
return d
7066

71-
def client_cores(self):
72-
return sum(self.my_client.ncores().values())
67+
def client_cores(self) -> int:
68+
return sum(self.client.ncores().values())
7369

7470
def shutdown(self):
7571
"""Shutdown the dask client.
7672
If it was started without arguments, the
7773
local cluster that was started at the same time is also closed.
7874
"""
79-
self.my_client.close()
75+
self.client.close()

0 commit comments

Comments
 (0)