1

I m trying to use multiprocess in order to decrease the time of calculation of functions whose depend of 2D arrays whose shape is 2000x2000. I have 2 inputs arrays for the function but with p.map it doesnt work...(with one it s ok). How can i do to enable that?

from multiprocessing import Pool
from numpy import *
import time
tic=time.clock()

Y=(arange(2000.))
X=(arange(2000.))
(xx,yy)=meshgrid(X,Y)


r = sqrt((xx)**2 + (yy)**2)

theta = (arctan2((yy),(xx)))

def f(theta,r):
  return 1.*r**(-3/2.)*cos(-3/2.*theta)

p = Pool(4)
print p.map(f, theta,r)
toc=time.clock()

print 'Temps=', toc-tic

and i get an error : "The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()"

user3601754
  • 3,792
  • 11
  • 43
  • 77
  • 1
    what version of python are you using? the answer can depend on it. – Julien Spronck Apr 28 '15 at 15:23
  • I m using ipython with python 2.7.8 – user3601754 Apr 28 '15 at 15:27
  • 1
    possible duplicate http://stackoverflow.com/questions/5442910/python-multiprocessing-pool-map-for-multiple-arguments – Julien Spronck Apr 28 '15 at 15:29
  • What platform are you on? – dano Apr 28 '15 at 15:50
  • @JulienSpronck: partial won't work in there without changing the function itself, since the first array that you pass to the function will be taken as a whole and not element by element. – paulo.filip3 Apr 28 '15 at 15:59
  • @user3601754 I mean what Operating System? – dano Apr 28 '15 at 16:00
  • 1
    Also, `map` is going to iterate over every item in the iterable you pass to it, and call `f` on each individual element. Is that actually what you want here? It looks like you want to pass both arrays in their entirety to the child process, and have `f` work on the whole array. If that's the case, `multiprocessing.Pool.map` won't help improve performance at all. – dano Apr 28 '15 at 16:02
  • 2
    I actually don't think that multiprocessing will help at all for what you need to do with the arrays. numpy already does a good job with that. – Julien Spronck Apr 28 '15 at 16:03
  • For my real case, my function needs 2 seconds to be created...too long for me but the answer of Paulo.filip3 seems to work – user3601754 Apr 28 '15 at 16:07
  • The answer of Paulo works but i dont win time with...how can i get more time? – user3601754 Apr 28 '15 at 16:46
  • Dano sorry i m on ubuntu 14.10 Yep no better performance :( – user3601754 Apr 28 '15 at 18:54

1 Answers1

2

A way to do solve that is to zip the input arrays

def f(values):
    return 1.*values[1]**(-3/2.)*cos(-3/2.*values[0])

p = Pool(4)
print p.map(f, zip(theta, r))
paulo.filip3
  • 3,167
  • 1
  • 23
  • 28
  • Thanks it works, just one little problem i get a list of array... : "array([ -2.23942628e-05, -2.23605957e-05, -2.23268448e-05, ..., 7.27439741e-06, 7.27185262e-06, 7.26930745e-06]), array..." How can i get an array with same shape as r or theta? – user3601754 Apr 28 '15 at 17:32
  • Oh, I see. You want the function to take the whole array instead of element by element. Then multiprocessing probably won't speed up much at all. In that case do `print p.map(f, [[theta, r]])` – paulo.filip3 Apr 28 '15 at 18:04
  • 1
    In that case you could also have done. `from functools import partial; partial_f = partial(f, theta); res = p.map(partial_f, [r])` – paulo.filip3 Apr 28 '15 at 18:11
  • thanks for your help! :) i will try that and i tell you if i won time! ;) – user3601754 Apr 28 '15 at 18:35