5

I can't seem to figure out how to dynamically output a variable that is being used in a parallel evaluation. Below is an example function that demonstrates my problem.

TestCount[n_Integer] := Module[{bar, i},
   bar = PrintTemporary[Dynamic[i], " ", ProgressIndicator[Dynamic[i/n]], " ", n];
   Do[(*Nothing Really*), {i, n}];
];

Running TestCount[123456789] works as expected and prints a nice temporary progress bar, but running it in parallel with ParallelMap[TestCount, {123456789, 98765432}] doesn't properly print the value of i, but instead prints i$208 or with some number other than 208.

Mike Pierce
  • 593
  • 5
  • 14

1 Answers1

2

Three changes are needed to make this code work:

  1. Move PrintTemporary inside the Do loop, so that it can access i.
  2. Remove i from the list of Module temporary variables. You may as well eliminate the symbol bar as well, because there is no need for it.
  3. Replace Dynamic[i] with With[{i = i}, Dynamic[i]], as aptly explained in "A Good Trick to Know" of Introduction to Dynamic.

With these changes, the code becomes

TestCount[n_Integer] := Module[{}, Do[PrintTemporary[With[{i = i}, Dynamic[i]], " ",
    With[{i = i}, ProgressIndicator[Dynamic[i/n]]], " ", n]; Pause[1], {i, n}]];

and

TestCount[10]

produces a list of ten ProgressIndicator bars, numbered 1 - 10, and then erases them at the end of the loop, as expected

Perhaps more useful would be to move ProgressIndicator outside the Module

ProgressIndicator[Dynamic[x]]

TestCount[n_Integer] := Module[{}, Do[Pause[1]; 
    PrintTemporary[i, " ", With[{i = i}, Dynamic[x = N[i/n]]]], {i, n}]]

which produces a single ProgressIndicator bar that follows the progress of the loop, as well as temporarily printing i and x.

bbgodfrey
  • 61,439
  • 17
  • 89
  • 156