parfor loop with continue gives incorrect results

5 ビュー (過去 30 日間)
Steve Chang
Steve Chang 2018 年 10 月 8 日
コメント済み: Steve Chang 2018 年 10 月 11 日
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 件のコメント
Steve Chang
Steve Chang 2018 年 10 月 9 日
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 2018 年 10 月 9 日
編集済み: Matt J 2018 年 10 月 9 日
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.

サインインしてコメントする。

回答 (1 件)

Matt J
Matt J 2018 年 10 月 9 日
編集済み: Matt J 2018 年 10 月 9 日
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 件のコメント
Edric Ellis
Edric Ellis 2018 年 10 月 11 日
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 2018 年 10 月 11 日
Good to know -- thanks for the response!

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeData Type Identification についてさらに検索

製品


リリース

R2017a

Community Treasure Hunt

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

Start Hunting!

Translated by