2
$\begingroup$

I have a rather complicated code for an ImageTransformation, which would benefit from some acceleration. Since every pixel is independend of every other, I tried Parallelize, which, in a simplified form, would look like

pic = Import["http://666kb.com/i/dsfr4u76175v8q277.png"]
Parallelize[ImageTransformation[pic, Sin]]

but it only gives me the error message

ImageTransformation[...] cannot be parallelized; proceeding with sequential evaluation

However, when I split the PlotRange manually, for example, into four quadrants, which I render simultaneously on four kernels, the whole job only takes 1/4 of the time, because each kernel has only 1/4 of the pixels to render, and the CPU is at 100% as it should be.

I'd expect Parallelize to do the same thing, but it doesn't; on my four kernel machine only one kernel is used. The CPU is therefore only at 25% — so the whole job takes four times longer than nescessary.

Is there a way to get the same effect automatically, so that I don't have to split the PlotRange manually, and submit the calculation to four different .nb-Files (or, as many as there are available kernels on my machine) every time, and then join the four parts of the resulting image with ImageAssemble?

With four kernels, it's not that bad, but if I were to work on a 16 kernel machine, it would be a nuissance to do the breakdown every time to get the speed up. Perhaps Parallelize it the wrong way to do it. Is there is a better way to achieve the parallelization?

$\endgroup$
  • $\begingroup$ The documentation says that "Parallelize distributes different parts of expr..." In your case, there is only one part, so there is nothing to distribute. You have a more general notion of what you think Parallelize should do, but it isn't what it does. I think splitting the image into parts like you did is a good way to do it, you could write a function to do that automatically. $\endgroup$ – C. E. Apr 21 '18 at 6:35
  • $\begingroup$ But since every pixel needs a different integration time, it would be better to have Mathematica distributing the next pixel to the next available Kernel as soon as the previous pixel is finished, is there really no built in command for that? If I split them manually there are always some parts that take longer than the others, while functions like Parallelize, if they would work here, could do a fine or coarse graining, depending on the problem. $\endgroup$ – Yukterez Apr 21 '18 at 6:54
  • $\begingroup$ I'm now confused about why it works to split the image into four. In general that shouldn't produce the same result when using ImageTransformation on each quadrant, is there something special about your transformation function that ensures that this works? $\endgroup$ – C. E. Apr 21 '18 at 10:36
  • $\begingroup$ Light rays don't gravitationally attract each other in this scenario, so every ray can be traced independend of each other. $\endgroup$ – Yukterez Apr 21 '18 at 15:30
  • $\begingroup$ You can always use ImagePartition to split the image up and then use a ParallelTable or ParallelMap to parallelize the transformation over the parts. $\endgroup$ – Sjoerd Smit Apr 22 '18 at 12:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.