在外部 for 中使用 parfor 的两个循环错误
Two-loops error using parfor in the external for
我需要并行化代码以节省时间。我有一个内部循环到另一个循环,我想并行化外部循环(因为我认为这样代码更快)。我的代码如下所示:
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(1000,1000);
parfor i = 1:size(A,1)
for j= 1:1:size(B,1)
if B(i,1) > A(j,1)
Biggers(i,j) = A(j,1);
end
end
end
但是如果我运行这样我得到错误:
Error: The variable Biggers in a parfor cannot be classified.
See Parallel for Loops in MATLAB, "Overview".
如果我改为并行化内部循环,即如果将代码设计为:
,则不会出现这种情况
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(1000,1000);
for i = 1:size(A,1)
parfor j= 1:1:size(B,1)
if B(i,1) > A(j,1)
Biggers(i,j) = A(j,1);
end
end
end
我不明白为什么在第一种情况下 Biggers
不被视为切片变量,因为每个工作人员都应该只关注我的变量的一行。
我该如何解决这个问题?
至于为什么它不能与外循环一起工作,我不确定。 MATLAB 对什么可以和什么不能进入 parfor
循环有非常严格的规定,这些规定并不总是 crystal 清楚。
"simple" 解决方案是将 中的所有东西都包装在 中 parfor
循环到一个函数中,然后 parfor
突然吃掉所有东西.即
function Biggers = parforfunc(A,B,ii)
for jj= 1:size(B,1)
if B(ii,1) > A(jj,1)
Biggers(ii,jj) = A(jj,1);
end
end
end
将其另存为 parforfunc.m
和 运行 您的脚本
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(size(B,1),size(A,1));
parfor ii = 1:size(A,1)
Biggers = parforfunc(A,B,ii);
end
@Adriaan 的回答巧妙地解决了这个问题——但如果您好奇的话,这里的问题是 "non-constant" 内部 for
循环的边界。你我都可以清楚地看到内部 for
循环的边界在实践中是不变的,但是 MATLAB 的 parfor
规则要求任何内部 for
循环的边界是 "broadcast" 变量。因此,修复是微不足道的 - 将内部循环边界计算提升到 parfor
循环之外,如下所示:
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(1000,1000);
n = size(B,1);
parfor i = 1:size(A,1)
for j= 1:n
if B(i,1) > A(j,1)
Biggers(i,j) = A(j,1);
end
end
end
本例描述为in the doc。
我需要并行化代码以节省时间。我有一个内部循环到另一个循环,我想并行化外部循环(因为我认为这样代码更快)。我的代码如下所示:
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(1000,1000);
parfor i = 1:size(A,1)
for j= 1:1:size(B,1)
if B(i,1) > A(j,1)
Biggers(i,j) = A(j,1);
end
end
end
但是如果我运行这样我得到错误:
Error: The variable Biggers in a parfor cannot be classified.
See Parallel for Loops in MATLAB, "Overview".
如果我改为并行化内部循环,即如果将代码设计为:
,则不会出现这种情况A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(1000,1000);
for i = 1:size(A,1)
parfor j= 1:1:size(B,1)
if B(i,1) > A(j,1)
Biggers(i,j) = A(j,1);
end
end
end
我不明白为什么在第一种情况下 Biggers
不被视为切片变量,因为每个工作人员都应该只关注我的变量的一行。
我该如何解决这个问题?
至于为什么它不能与外循环一起工作,我不确定。 MATLAB 对什么可以和什么不能进入 parfor
循环有非常严格的规定,这些规定并不总是 crystal 清楚。
"simple" 解决方案是将 中的所有东西都包装在 中 parfor
循环到一个函数中,然后 parfor
突然吃掉所有东西.即
function Biggers = parforfunc(A,B,ii)
for jj= 1:size(B,1)
if B(ii,1) > A(jj,1)
Biggers(ii,jj) = A(jj,1);
end
end
end
将其另存为 parforfunc.m
和 运行 您的脚本
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(size(B,1),size(A,1));
parfor ii = 1:size(A,1)
Biggers = parforfunc(A,B,ii);
end
@Adriaan 的回答巧妙地解决了这个问题——但如果您好奇的话,这里的问题是 "non-constant" 内部 for
循环的边界。你我都可以清楚地看到内部 for
循环的边界在实践中是不变的,但是 MATLAB 的 parfor
规则要求任何内部 for
循环的边界是 "broadcast" 变量。因此,修复是微不足道的 - 将内部循环边界计算提升到 parfor
循环之外,如下所示:
A = rand(1000,1);
B = rand(1000,1);
Biggers = zeros(1000,1000);
n = size(B,1);
parfor i = 1:size(A,1)
for j= 1:n
if B(i,1) > A(j,1)
Biggers(i,j) = A(j,1);
end
end
end
本例描述为in the doc。