Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

after I got such a great response for my first question on this site, I'm very encouraged to asked my second one!

So here it is, very generally: To speed up a "row-wise" (i.e. 1D) operation on a matrix, I tried to use the ParallelTable instead of the Table function. I don't know why, but due to some reason this fails. It seems that the expression inside the ParallelTable gets not evaluated correctly. Maybe somebody knows why?

I start with my functions: The "FftShift1D" is simply to reorder the result of the Fourier function. The "eqn" function is just an arbitrary function to test the parallelization later on.

ClearAll["Global`*"]

FftShift1D[x_?VectorQ] := 
 Module[{n = Ceiling[Length[x]/2]}, RotateRight[x, n]]

eqn[kx_?MachineNumberQ, y_?MachineNumberQ] := 
 2/3 Exp[-I kx] (1 + I kx) + Sin[y]/y

Now, I create a matrix with the help of the "Table" function. The following definitions are used to change the size of the matrix easily.

kxmin = -100; kxmax = 100; kxdiv = 2000; kxinc = (kxmax - 
    kxmin)/(kxdiv - 1);
zmin = -5; zmax = 5; zdiv = 200; zinc = (zmax - zmin)/(zdiv - 1);

kspace = Table[
   eqn[kx, z], {kx, kxmin, kxmax, kxinc}, {z, zmin, zmax, zinc}];

So I want to apply a FFT only on the "kx" direction, i.e. there are "zdiv" times a 1D FFT. This is how I've done this "serially":

res = Table[
   FftShift1D[Fourier[N[
   kspace[[;; kxdiv, i]]
]]], {i, 1, zdiv}];

This works properly, and it results in "res" being a matrix (or Table, however you like to call it) with the same size as "kspace". Changing now to

SetSharedVariable[kxmin, kxmax, kxdiv, kxinc, zmin, zmax, zdiv, zinc, 
  kspace, res];

res = ParallelTable[
   FftShift1D[Fourier[N[
   kspace[[;; kxdiv, i]]
]]], {i, 1, zdiv}];

fails with the following messages:

Fourier::fftl: Argument {eqn[-100.,-5.],eqn[-99.8999,-5.],
eqn[-99.7999,-5.],<<6>>,eqn[-99.0995,-5.],<<1990>>}
is not a nonempty list or rectangular array of numeric quantities.

You see, that although I call "N", the "eqn" gets not evaluated properly... Does someone knows why? Kind regards Clemens

PS: I've found something not completely unlike my problem here, but not as in ParallelTable and Table do not give same result my problem does not change when using Parellelize[Table[...]] instead of ParellelTable[...]

share|improve this question
    
you probably need to distribute definitions. –  acl Mar 17 '13 at 11:36
    
@acl I don't do much in parallel; with DistributeDefinitions as used in my answer the code apparently never finishes. Does it work on your machine? –  Mr.Wizard Mar 17 '13 at 11:42
    
@Mr.Wizard if I do ParallelTable[FftShift1D[Fourier[N[kspace[[;; 10, i]]]]], {i, 1, 2}] (ie, decrease the limits) it does work properly (ie gives same as Table). This on 9.0.1. If Clemens still has not worked out what is going on, I'll give it a shot later today (I need to do something first). Would be nice to have a minimal example by the way. –  acl Mar 17 '13 at 15:55
    
There is probably very limited benefit in using the Parallel` package for this since Fourier is already multithreaded via the MKL. Please see also this question, which perhaps is not the most clearly titled. –  Oleksandr R. Mar 17 '13 at 22:16
add comment

1 Answer

up vote 5 down vote accepted

In version 7 you will need to use use DistributeDefinitions for FftShift1D and eqn. Furthermore, as Szabolcs kindly explains in the comments you should be using DistributeDefinitions for the other symbols as well, instead of SetSharedVariable:

DistributeDefinitions[FftShift1D, eqn, kxmin, kxmax,
  kxdiv, kxinc, zmin, zmax, zdiv, zinc, kspace];

With this your ParallelTable runs, and slightly faster than the non-parallel version, but not by a lot. A modified suggestion of Szabolcs's proves considerably faster:

res2 = ParallelMap[FftShift1D @ Fourier @ N @ # &, kspace\[Transpose]];
share|improve this answer
    
Yes, it works, but it's really very slow... –  Clemens Mar 17 '13 at 13:06
    
@Clemens yes, very slow. I'm hoping that someone who actually uses the Parallel tools will stop by with an answer. I typically just leave slow computations running in the background and therefore I don't want them using all the cores, so I've never really learned to use the Parallel tools. Sorry I can't be of more help at the moment. :-/ –  Mr.Wizard Mar 17 '13 at 13:12
1  
@Clemens Using SetSharedVariable will force all those variables to be accessed through the main kernel. By making all these variables shared, you nullify all advantages of parallelization. You should use DistributeDefinitions for these, not SetSharedVariable, then precompute the quantity N[ kspace[[;; kxdiv, i]]] on the main kernel, then finally ParallelMap your function. Unfortunately I don't have access to a multicore machine at this moment, so I coulnd't actually test this. –  Szabolcs Mar 17 '13 at 16:15
    
@Szabolcs That makes a lot of sense; thanks. –  Mr.Wizard Mar 17 '13 at 18:17
1  
@Szabolcs actually, the way his code is written all the time is spent on the N operation as that triggers the evaluation of eqn. I did however realize he was doing a complicated transpose and replaced it with Transpose. –  Mr.Wizard Mar 17 '13 at 18:43
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.