Skip to content

Commit 2068558

Browse files
Merge pull request #319 from qdev-dk/feature/remove_mp
Feat: Default to no multiprocessing.
2 parents a476f61 + 3ef83bc commit 2068558

13 files changed

Lines changed: 82 additions & 63 deletions

File tree

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ install:
1818
- python setup.py develop
1919
# command to run tests
2020
script:
21-
- python qcodes/test.py --skip-coverage
22-
- python qcodes/test.py --mp-spawn
21+
- python qcodes/test.py --skip-coverage -f
22+
- python qcodes/test.py --mp-spawn -f
2323
after_success:
2424
# install codacy coverage plugin only on traivs
2525
- pip install codacy-coverage

docs/examples/Tutorial.ipynb

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -475,10 +475,10 @@
475475
"# If you leave these out, you get a new timestamped DataSet each time.\n",
476476
"\n",
477477
"loop = qc.Loop(c0.sweep(0,20,0.1), delay=0.001).each(meter.amplitude)\n",
478-
"data = loop.get_data_set(data_manager=False)\n",
478+
"data = loop.get_data_set()\n",
479479
"plot = qc.QtPlot()\n",
480480
"plot.add(data.meter_amplitude)\n",
481-
"_ = loop.with_bg_task(plot.update, 0.0005).run(name='testsweep',background=False)"
481+
"_ = loop.with_bg_task(plot.update, 0.0005).run(name='testsweep')"
482482
]
483483
},
484484
{
@@ -1386,7 +1386,7 @@
13861386
" meter.amplitude, # second measurement, at c2=1 -> amplitude_4 bcs it's action 4\n",
13871387
" qc.Task(c2.set, 0)\n",
13881388
" )\n",
1389-
"data = loop.get_data_set(data_manager=False)"
1389+
"data = loop.get_data_set()"
13901390
]
13911391
},
13921392
{
@@ -2199,7 +2199,7 @@
21992199
"source": [
22002200
"plot = qc.MatPlot(data.meter_amplitude_0, cmap=plt.cm.hot, figsize=(12, 4.5), subplots=(1, 2))\n",
22012201
"plot.add(data.meter_amplitude_3, cmap=plt.cm.hot, subplot=2)\n",
2202-
"data2 = loop.with_bg_task(plot.update, 0.0005).run(name='2D_test',background=False)"
2202+
"data2 = loop.with_bg_task(plot.update, 0.0005).run(name='2D_test')"
22032203
]
22042204
},
22052205
{
@@ -2240,12 +2240,12 @@
22402240
" meter.amplitude, # second measurement, at c2=1 -> amplitude_4 bcs it's action 4\n",
22412241
" qc.Task(c2.set, 0)\n",
22422242
" )\n",
2243-
"data = loop.get_data_set(data_manager=False)\n",
2243+
"data = loop.get_data_set()\n",
22442244
"\n",
22452245
"plotQ = qc.QtPlot()\n",
22462246
"plotQ.add(data.meter_amplitude_0, figsize=(1200, 500))\n",
22472247
"plotQ.add(data.meter_amplitude_3, subplot=2)\n",
2248-
"data2 = loop.with_bg_task(plotQ.update, 0.0005).run(name='2D_test',background=False)"
2248+
"data2 = loop.with_bg_task(plotQ.update, 0.0005).run(name='2D_test')"
22492249
]
22502250
},
22512251
{
@@ -2275,7 +2275,7 @@
22752275
" qc.Loop(c2[-10:10:0.2], 0.001).each(meter.amplitude),\n",
22762276
" AverageGetter(meter.amplitude, c2[-10:10:0.2], 0.001)\n",
22772277
")\n",
2278-
"data = loop3.get_data_set(data_manager=False) \n"
2278+
"data = loop3.get_data_set() "
22792279
]
22802280
},
22812281
{
@@ -2324,7 +2324,7 @@
23242324
"plotQ.add(data.meter_amplitude_3_0)\n",
23252325
"plotQ.add(data.meter_amplitude_5_0, cmap='viridis', subplot=2)\n",
23262326
"plotQ.add(data.meter_avg_amplitude, subplot=3)\n",
2327-
"data = loop3.with_bg_task(plotQ.update, 0.0005).run(name='TwoD_different_inner_test', background=False)"
2327+
"data = loop3.with_bg_task(plotQ.update, 0.0005).run(name='TwoD_different_inner_test')"
23282328
]
23292329
},
23302330
{
@@ -2365,11 +2365,11 @@
23652365
"loop4 = qc.Loop(c1[-15:15:1], 0.01).each(\n",
23662366
" AverageAndRaw(meter.amplitude, c2[-10:10:0.2], 0.001)\n",
23672367
")\n",
2368-
"data4 = loop4.get_data_set(data_manager=False)\n",
2368+
"data4 = loop4.get_data_set()\n",
23692369
"plotQ = qc.QtPlot()\n",
23702370
"plotQ.add(data4.meter_amplitude, figsize=(1200, 500), cmap='viridis')\n",
23712371
"plotQ.add(data4.meter_avg_amplitude, subplot=2)\n",
2372-
"data4 = loop4.with_bg_task(plotQ.update, 0.005).run(name='TwoD_average_test', background=False)"
2372+
"data4 = loop4.with_bg_task(plotQ.update, 0.005).run(name='TwoD_average_test')"
23732373
]
23742374
}
23752375
],
@@ -2391,10 +2391,6 @@
23912391
"nbconvert_exporter": "python",
23922392
"pygments_lexer": "ipython3",
23932393
"version": "3.5.2"
2394-
},
2395-
"widgets": {
2396-
"state": {},
2397-
"version": "1.1.1"
23982394
}
23992395
},
24002396
"nbformat": 4,

qcodes/data/data_set.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ class DataMode(Enum):
2727

2828

2929
def new_data(location=None, loc_record=None, name=None, overwrite=False,
30-
io=None, data_manager=None, mode=DataMode.LOCAL, **kwargs):
30+
io=None, data_manager=False, mode=DataMode.LOCAL, **kwargs):
31+
# NOTE(giulioungaretti): leave this docstrings as it is, because
32+
# documenting the types is silly in this case.
3133
"""
3234
Create a new DataSet.
3335
@@ -57,11 +59,11 @@ def new_data(location=None, loc_record=None, name=None, overwrite=False,
5759
says the root data directory is the current working directory, ie
5860
where you started the python session.
5961
60-
data_manager (DataManager or False, optional): manager for the
61-
``DataServer`` that offloads storage and syncing of this
62-
``DataSet``. Usually omitted (default None) to use the default
63-
from ``get_data_manager()``. If ``False``, this ``DataSet`` will
64-
store itself.
62+
data_manager (Optional[bool]): use a manager for the
63+
``DataServer`` that offloads storage and syncing of this Defaults
64+
to ``False`` i.e. this ``DataSet`` will store itself without extra
65+
processes. Set to ``True`` to use the default from
66+
``get_data_manager()``.
6567
6668
mode (DataMode, optional): connection type to the ``DataServer``.
6769
``DataMode.LOCAL``: this DataSet doesn't communicate across
@@ -105,11 +107,11 @@ def new_data(location=None, loc_record=None, name=None, overwrite=False,
105107
if location and (not overwrite) and io.list(location):
106108
raise FileExistsError('"' + location + '" already has data')
107109

108-
if data_manager is False:
110+
if data_manager is True:
111+
data_manager = get_data_manager()
112+
else:
109113
if mode != DataMode.LOCAL:
110114
raise ValueError('DataSets without a data_manager must be local')
111-
elif data_manager is None:
112-
data_manager = get_data_manager()
113115

114116
return DataSet(location=location, io=io, data_manager=data_manager,
115117
mode=mode, **kwargs)
@@ -206,11 +208,11 @@ class DataSet(DelegateAttributes):
206208
says the root data directory is the current working directory, ie
207209
where you started the python session.
208210
209-
data_manager (DataManager or False, optional): manager for the
210-
``DataServer`` that offloads storage and syncing of this
211-
``DataSet``. Usually omitted (default None) to use the default
212-
from ``get_data_manager()``. If ``False``, this ``DataSet`` will
213-
store itself.
211+
data_manager (Optional[bool]): use a manager for the
212+
``DataServer`` that offloads storage and syncing of this Defaults
213+
to ``False`` i.e. this ``DataSet`` will store itself without extra
214+
processes. Set to ``True`` to use the default from
215+
``get_data_manager()``.
214216
215217
mode (DataMode, optional): connection type to the ``DataServer``.
216218
``DataMode.LOCAL``: this DataSet doesn't communicate across
@@ -258,7 +260,7 @@ class DataSet(DelegateAttributes):
258260
background_functions = OrderedDict()
259261

260262
def __init__(self, location=None, mode=DataMode.LOCAL, arrays=None,
261-
data_manager=None, formatter=None, io=None, write_period=5):
263+
data_manager=False, formatter=None, io=None, write_period=5):
262264
if location is False or isinstance(location, str):
263265
self.location = location
264266
else:
@@ -281,7 +283,7 @@ def __init__(self, location=None, mode=DataMode.LOCAL, arrays=None,
281283
for array in arrays:
282284
self.add_array(array)
283285

284-
if data_manager is None and mode in SERVER_MODES:
286+
if data_manager is True and mode in SERVER_MODES:
285287
data_manager = get_data_manager()
286288

287289
if mode == DataMode.LOCAL:

qcodes/instrument/base.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
"""Instrument base class."""
2-
import weakref
3-
import time
42
import logging
3+
import time
4+
import warnings
5+
import weakref
56

67
from qcodes.utils.metadata import Metadatable
78
from qcodes.utils.helpers import DelegateAttributes, strip_attrs, full_class
@@ -75,11 +76,12 @@ class Instrument(Metadatable, DelegateAttributes, NestedAttrAccess):
7576

7677
_all_instruments = {}
7778

78-
def __new__(cls, *args, server_name='', **kwargs):
79+
def __new__(cls, *args, server_name=None, **kwargs):
7980
"""Figure out whether to create a base instrument or proxy."""
8081
if server_name is None:
8182
return super().__new__(cls)
8283
else:
84+
warnings.warn("Multiprocessing is in beta, use at own risk", UserWarning)
8385
return RemoteInstrument(*args, instrument_class=cls,
8486
server_name=server_name, **kwargs)
8587

qcodes/instrument/remote.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ class RemoteInstrument(DelegateAttributes):
4343

4444
def __init__(self, *args, instrument_class=None, server_name='',
4545
**kwargs):
46-
4746
if server_name == '':
4847
server_name = instrument_class.default_server_name(**kwargs)
4948

qcodes/loops.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import multiprocessing as mp
5151
import time
5252
import numpy as np
53+
import warnings
5354

5455
from qcodes.station import Station
5556
from qcodes.data.data_set import new_data, DataMode
@@ -62,7 +63,10 @@
6263
from .actions import (_actions_snapshot, Task, Wait, _Measure, _Nest,
6364
BreakIf, _QcodesBreak)
6465

66+
# Switches off multiprocessing by default, cant' be altered after module import.
67+
# TODO(giulioungaretti) use config.
6568

69+
USE_MP = False
6670
MP_NAME = 'Measurement'
6771

6872

@@ -640,7 +644,7 @@ def _check_signal(self):
640644
else:
641645
raise ValueError('unknown signal', signal_)
642646

643-
def get_data_set(self, data_manager=None, *args, **kwargs):
647+
def get_data_set(self, data_manager=False, *args, **kwargs):
644648
"""
645649
Return the data set for this loop.
646650
If no data set has been created yet, a new one will be created and returned.
@@ -670,6 +674,7 @@ def get_data_set(self, data_manager=None, *args, **kwargs):
670674
if data_manager is False:
671675
data_mode = DataMode.LOCAL
672676
else:
677+
warnings.warn("Multiprocessing is in beta, use at own risk", UserWarning)
673678
data_mode = DataMode.PUSH_TO_SERVER
674679

675680
data_set = new_data(arrays=self.containers(), mode=data_mode,
@@ -688,20 +693,19 @@ def run_temp(self, **kwargs):
688693
return self.run(background=False, quiet=True,
689694
data_manager=False, location=False, **kwargs)
690695

691-
def run(self, background=True, use_threads=True, quiet=False,
692-
data_manager=None, station=None, progress_interval=False,
696+
def run(self, background=USE_MP, use_threads=False, quiet=False,
697+
data_manager=USE_MP, station=None, progress_interval=False,
693698
*args, **kwargs):
694699
"""
695700
Execute this loop.
696701
697-
background: (default True) run this sweep in a separate process
702+
background: (default False) run this sweep in a separate process
698703
so we can have live plotting and other analysis in the main process
699704
use_threads: (default True): whenever there are multiple `get` calls
700705
back-to-back, execute them in separate threads so they run in
701706
parallel (as long as they don't block each other)
702707
quiet: (default False): set True to not print anything except errors
703-
data_manager: a DataManager instance (omit to use default,
704-
False to store locally)
708+
data_manager: set to True to use a DataManager. Default to False.
705709
station: a Station instance for snapshots (omit to use a previously
706710
provided Station, or the default Station)
707711
progress_interval (default None): show progress of the loop every x
@@ -737,6 +741,7 @@ def run(self, background=True, use_threads=True, quiet=False,
737741
prev_loop.join()
738742

739743
data_set = self.get_data_set(data_manager, *args, **kwargs)
744+
740745
self.set_common_attrs(data_set=data_set, use_threads=use_threads,
741746
signal_queue=self.signal_queue)
742747

@@ -762,6 +767,7 @@ def run(self, background=True, use_threads=True, quiet=False,
762767
flush=True)
763768

764769
if background:
770+
warnings.warn("Multiprocessing is in beta, use at own risk", UserWarning)
765771
p = QcodesProcess(target=self._run_wrapper, name=MP_NAME)
766772
p.is_sweep = True
767773
p.signal_queue = self.signal_queue

qcodes/process/helpers.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import multiprocessing as mp
44
import time
5+
import warnings
56

67
MP_ERR = 'context has already been set'
78

@@ -23,6 +24,7 @@ def set_mp_method(method, force=False):
2324
with the *same* method raises an error, but here we only
2425
raise the error if you *don't* force *and* the context changes
2526
"""
27+
warnings.warn("Multiprocessing is in beta, use at own risk", UserWarning)
2628
try:
2729
mp.set_start_method(method, force=force)
2830
except RuntimeError as err:

qcodes/process/stream_queue.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
import multiprocessing as mp
44
import sys
5-
from datetime import datetime
65
import time
76

7+
from datetime import datetime
8+
89
from .helpers import kill_queue
910

1011

qcodes/tests/test_data.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -449,14 +449,14 @@ def test_from_server(self, gdm_mock):
449449
mock_dm.live_data = MockLive()
450450

451451
# wrong location or False location - converts to local
452-
data = DataSet(location='Jupiter', mode=DataMode.PULL_FROM_SERVER)
452+
data = DataSet(location='Jupiter', data_manager=True, mode=DataMode.PULL_FROM_SERVER)
453453
self.assertEqual(data.mode, DataMode.LOCAL)
454454

455-
data = DataSet(location=False, mode=DataMode.PULL_FROM_SERVER)
455+
data = DataSet(location=False, data_manager=True, mode=DataMode.PULL_FROM_SERVER)
456456
self.assertEqual(data.mode, DataMode.LOCAL)
457457

458458
# location matching server - stays in server mode
459-
data = DataSet(location='Mars', mode=DataMode.PULL_FROM_SERVER,
459+
data = DataSet(location='Mars', data_manager=True, mode=DataMode.PULL_FROM_SERVER,
460460
formatter=MockFormatter())
461461
self.assertEqual(data.mode, DataMode.PULL_FROM_SERVER)
462462
self.assertEqual(data.arrays, MockLive.arrays)
@@ -495,7 +495,7 @@ def test_to_server(self, gdm_mock):
495495
mock_dm.needs_restart = True
496496
gdm_mock.return_value = mock_dm
497497

498-
data = DataSet(location='Venus', mode=DataMode.PUSH_TO_SERVER)
498+
data = DataSet(location='Venus', data_manager=True, mode=DataMode.PUSH_TO_SERVER)
499499
self.assertEqual(mock_dm.needs_restart, False, data)
500500
self.assertEqual(mock_dm.data_set, data)
501501
self.assertEqual(data.data_manager, mock_dm)

qcodes/tests/test_driver_testcase.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class TestDriverTestCase(DriverTestCase):
3434
@classmethod
3535
def setUpClass(cls):
3636
cls.an_empty_model = EmptyModel()
37-
cls.an_instrument = MockMock('a', model=cls.an_empty_model)
37+
cls.an_instrument = MockMock('a', model=cls.an_empty_model, server_name='')
3838
super().setUpClass()
3939

4040
@classmethod

0 commit comments

Comments
 (0)