parfor loop with continue gives incorrect results

8 vues (au cours des 30 derniers jours)
Steve Chang
Steve Chang le 8 Oct 2018
Commenté : Steve Chang le 11 Oct 2018
Consider the following code:
N = 1000;
failed = false( 1, N );
values = cell( 1, N );
n_failed = 0;
parfor idx = 1:N
try
if ( rand() > 0.7 )
n_failed = n_failed + 1;
error( '' );
end
catch err
failed(idx) = true;
continue;
end
values{idx} = rand( 1e3, 1 );
end
fprintf( 'N failed 1: %d\n\n', sum(failed) );
fprintf( 'N failed 2: %d\n', n_failed );
If I run this on my machine (macOS 10.12, r2017a), `sum(failed)` is 0, while `n_failed` is, as expected, ~300. What am I missing here? I don't see anything in the documentation about `continue` not being supported in a parfor loop?
  4 commentaires
Steve Chang
Steve Chang le 9 Oct 2018
Using nnz instead of sum gives the same result. Also, regarding the randomization -- removing the if statement gives the same behavior (i.e., sum(failed) is 0, while n_failed is 1000).
I guess there's a bug in how continue is handled in a try / catch context, or else it is not meant to be used in this way in a parfor loop.
Matt J
Matt J le 9 Oct 2018
Modifié(e) : Matt J le 9 Oct 2018
The problem doesn't seem to have anything to do with 'continue'. Even when the continue is commented out, I still obtain sum(failed)=0. It might have more to do with try...catch.

Connectez-vous pour commenter.

Réponses (1)

Matt J
Matt J le 9 Oct 2018
Modifié(e) : Matt J le 9 Oct 2018
Don't pass an empty string '' to error() if you want the catch block to be triggered. An empty string apparently does not result in an error being thrown.
In other words, this works fine:
N = 1000;
failed = false( 1, N );
n_failed = 0;
parfor i = 1:N
try
if ( rand() > 0.7 )
n_failed = n_failed + 1;
error('an error');
end
catch
failed(i) = true;
continue
end
end
fprintf( 'N failed 1: %d\n\n', sum(failed) );
fprintf( 'N failed 2: %d\n', n_failed );
  9 commentaires
Edric Ellis
Edric Ellis le 11 Oct 2018
There's an existing problem in the parfor machinery that causes the values assignment to fail. The problem relates to the combination of try / catch and the assignment to values. You can trick the parfor machinery into operating correctly by changing how it analyses values. The following should work:
N = 1000;
failed = false( 1, N );
values = cell( 1, N );
n_failed = 0;
parfor idx = 1:N
% Dummy reference to "values(idx)":
if false
values(idx);
end
try
if ( rand() > 0.7 )
n_failed = n_failed + 1;
assert(false);
end
catch err
failed(idx) = true;
continue;
end
values{idx} = rand( 1e3, 1 );
end
fprintf( 'N failed 1: %d\n\n', sum(failed) );
fprintf( 'N failed 2: %d\n', n_failed );
Steve Chang
Steve Chang le 11 Oct 2018
Good to know -- thanks for the response!

Connectez-vous pour commenter.

Catégories

En savoir plus sur Data Type Identification dans Help Center et File Exchange

Produits


Version

R2017a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by