Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p><code>multiprocessing</code> makes some bad choices about pickling. Don't get me wrong, it makes some good choices that enable it to pickle certain types so they can be used in a pool's map function. However, since we have <code>dill</code> that can do the pickling, multiprocessing's own pickling becomes a bit limiting. Actually, if <code>multiprocessing</code> were to use <code>pickle</code> instead of <code>cPickle</code>... and also drop some of it's own pickling overrides, then <code>dill</code> could take over and give a much more full serialization for <code>multiprocessing</code>.</p> <p>Until that happens, there's a fork of <code>multiprocessing</code> called <a href="https://github.com/uqfoundation/pathos" rel="noreferrer">pathos</a> (the release version is a bit stale, unfortunately) that removes the above limitations. Pathos also adds some nice features that multiprocessing doesn't have, like multi-args in the map function. Pathos is due for a release, after some mild updating -- mostly conversion to python 3.x.</p> <pre><code>Python 2.7.5 (default, Sep 30 2013, 20:15:49) [GCC 4.2.1 (Apple Inc. build 5566)] on darwin Type "help", "copyright", "credits" or "license" for more information. &gt;&gt;&gt; import dill &gt;&gt;&gt; from pathos.multiprocessing import ProcessingPool &gt;&gt;&gt; pool = ProcessingPool(nodes=4) &gt;&gt;&gt; result = pool.map(lambda x: x**2, range(10)) &gt;&gt;&gt; result [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] </code></pre> <p>and just to show off a little of what <code>pathos.multiprocessing</code> can do...</p> <pre><code>&gt;&gt;&gt; def busy_add(x,y, delay=0.01): ... for n in range(x): ... x += n ... for n in range(y): ... y -= n ... import time ... time.sleep(delay) ... return x + y ... &gt;&gt;&gt; def busy_squared(x): ... import time, random ... time.sleep(2*random.random()) ... return x*x ... &gt;&gt;&gt; def squared(x): ... return x*x ... &gt;&gt;&gt; def quad_factory(a=1, b=1, c=0): ... def quad(x): ... return a*x**2 + b*x + c ... return quad ... &gt;&gt;&gt; square_plus_one = quad_factory(2,0,1) &gt;&gt;&gt; &gt;&gt;&gt; def test1(pool): ... print pool ... print "x: %s\n" % str(x) ... print pool.map.__name__ ... start = time.time() ... res = pool.map(squared, x) ... print "time to results:", time.time() - start ... print "y: %s\n" % str(res) ... print pool.imap.__name__ ... start = time.time() ... res = pool.imap(squared, x) ... print "time to queue:", time.time() - start ... start = time.time() ... res = list(res) ... print "time to results:", time.time() - start ... print "y: %s\n" % str(res) ... print pool.amap.__name__ ... start = time.time() ... res = pool.amap(squared, x) ... print "time to queue:", time.time() - start ... start = time.time() ... res = res.get() ... print "time to results:", time.time() - start ... print "y: %s\n" % str(res) ... &gt;&gt;&gt; def test2(pool, items=4, delay=0): ... _x = range(-items/2,items/2,2) ... _y = range(len(_x)) ... _d = [delay]*len(_x) ... print map ... res1 = map(busy_squared, _x) ... res2 = map(busy_add, _x, _y, _d) ... print pool.map ... _res1 = pool.map(busy_squared, _x) ... _res2 = pool.map(busy_add, _x, _y, _d) ... assert _res1 == res1 ... assert _res2 == res2 ... print pool.imap ... _res1 = pool.imap(busy_squared, _x) ... _res2 = pool.imap(busy_add, _x, _y, _d) ... assert list(_res1) == res1 ... assert list(_res2) == res2 ... print pool.amap ... _res1 = pool.amap(busy_squared, _x) ... _res2 = pool.amap(busy_add, _x, _y, _d) ... assert _res1.get() == res1 ... assert _res2.get() == res2 ... print "" ... &gt;&gt;&gt; def test3(pool): # test against a function that should fail in pickle ... print pool ... print "x: %s\n" % str(x) ... print pool.map.__name__ ... start = time.time() ... res = pool.map(square_plus_one, x) ... print "time to results:", time.time() - start ... print "y: %s\n" % str(res) ... &gt;&gt;&gt; def test4(pool, maxtries, delay): ... print pool ... m = pool.amap(busy_add, x, x) ... tries = 0 ... while not m.ready(): ... time.sleep(delay) ... tries += 1 ... print "TRY: %s" % tries ... if tries &gt;= maxtries: ... print "TIMEOUT" ... break ... print m.get() ... &gt;&gt;&gt; import time &gt;&gt;&gt; x = range(18) &gt;&gt;&gt; delay = 0.01 &gt;&gt;&gt; items = 20 &gt;&gt;&gt; maxtries = 20 &gt;&gt;&gt; from pathos.multiprocessing import ProcessingPool as Pool &gt;&gt;&gt; pool = Pool(nodes=4) &gt;&gt;&gt; test1(pool) &lt;pool ProcessingPool(ncpus=4)&gt; x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17] map time to results: 0.0553691387177 y: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289] imap time to queue: 7.91549682617e-05 time to results: 0.102381229401 y: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289] amap time to queue: 7.08103179932e-05 time to results: 0.0489699840546 y: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289] &gt;&gt;&gt; test2(pool, items, delay) &lt;built-in function map&gt; &lt;bound method ProcessingPool.map of &lt;pool ProcessingPool(ncpus=4)&gt;&gt; &lt;bound method ProcessingPool.imap of &lt;pool ProcessingPool(ncpus=4)&gt;&gt; &lt;bound method ProcessingPool.amap of &lt;pool ProcessingPool(ncpus=4)&gt;&gt; &gt;&gt;&gt; test3(pool) &lt;pool ProcessingPool(ncpus=4)&gt; x: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17] map time to results: 0.0523059368134 y: [1, 3, 9, 19, 33, 51, 73, 99, 129, 163, 201, 243, 289, 339, 393, 451, 513, 579] &gt;&gt;&gt; test4(pool, maxtries, delay) &lt;pool ProcessingPool(ncpus=4)&gt; TRY: 1 TRY: 2 TRY: 3 TRY: 4 TRY: 5 TRY: 6 TRY: 7 [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34] </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload