Avoid race conditions when using parfor in MATLAB

I loop in parallel and change the variable if the condition is met. Super idiomatic code that I'm sure everyone has written a hundred times:

``````trials = 100;
greatest_so_far = 0;
best_result = 0;

for trial_i = 1:trials
[amount, result] = do_work();

if amount > greatest_so_far
greatest_so_far = amount;
best_result = result;
end
end
```

```

If I wanted to replace `for`

with `parfor`

, how can I ensure that race conditions are not checked, should we replace `greatest_so_far`

? Is there a way to block this variable outside of validation? Perhaps for example:

``````trials = 100;
greatest_so_far = 0;
best_result = 0;

parfor trial_i = 1:trials
[amount, result] = do_work();

somehow_lock(greatest_so_far);
if amount > greatest_so_far
greatest_so_far = amount;
best_result = result;
end
somehow_unlock(greatest_so_far);
end
```

```
+3

source to share

If you can let memory store the outputs of yours `do_work()`

in some vectors, then you can just run yours in `parfor`

that function alone, store the result, and then hammer the result at the end (outside of the loop):

``````amount = zeros( trials , 1 ) ;
result = zeros( trials , 1 ) ;

parfor trial_i = 1:trials
[amount(i), result(i)] = do_work();
end

[ greatest_of_all , greatest_index ] = max(amount) ;
best_result = result(greatest_index) ;
```

```

Edit / Comment : (I would like to put this in a comment on your question, but it was too long, sorry).
I am familiar with `.net`

and fully understand your lock / unlock request. I myself have tried many attempts to implement some sort of progress bar for a very long loop `parfor`

... to no avail.

If I understand Matlab's classification of the variable correctly , the fact that you assign `greatest_so_far`

(to `greatest_so_far=amount`

) makes Matlab treat this temporary variable, which will be cleared and reinitialized at the beginning of each iteration of the loop (therefore unsuitable for your purpose).

Thus, a simple locked variable may not be a concept that we can simply implement for now. Some confusing class event or file writing / checking might do the trick, but I'm afraid the time will suffer a lot. If each iteration takes a long time, the overhead may be worth it, but if you are using a `parfoor`

lot of short execution iterations to speed up, then confusing solutions will slow you down more than they help ...

You can take a look at this stack exchange question, you might find something interesting for your case: Semaphores and Locks in MATLAB

+2

source

Solution from Hoki is the correct way to solve the problem as stated. However, when you asked about race conditions and prevented them when loop iterations depend on each other, you may need to look into the `spmd`

various functions as well`lab*`

.

+2

source

To do this you need to use SPMD - SPMD allows communication between workers. Something like that:

``````bestResult = -Inf;
bestIndex  = NaN;
N = 97;
spmd
% we need to round up the loop range to ensure that each
% worker executes the same number of iterations
loopRange = numlabs * ceil(N / numlabs);
for idx = 1:numlabs:loopRange
if idx <= N
local_result = rand(); % obviously replace this with your actual function
else
local_result = -Inf;
end
% Work out which index has the best result - use a really simple approach
% by concatenating all the results this time from each worker
% allResultsThisTime will be 2-by-numlabs where the first row is all the
% the results this time, and the second row is all the values of idx from this time
allResultsThisTime = gcat([local_result; idx]);
% The best result this time - consider the first row
[bestResultThisTime, labOfBestResult] = max(allResultsThisTime(1, :));
if bestResultThisTime > bestResult
bestResult = bestResultThisTime;
bestIndex  = allResultsThisTime(2, labOfBestResult);
end
end
end
disp(bestResult{1})
disp(bestIndex{1})
```

```
+1

source

All Articles