我收到以下错误:“parfor中的变量X_bs不能 在尝试运行以下parfor循环时分类:
y = zeros(1000,1)
parfor bb = 1:1000
rng(bb)
% deleted line: X_bs{8} = [];
for ii = 1:8
ind = ceil(N(ii)*rand(N(ii),1));
X_bs{ii} = X{ii}(ind,:);
end
y(bb) = another_function(X_bs)
end
X
是1x8单元格数组,每个单元格包含N(ii)x4
矩阵(N(ii)
更改)。代码重新对X
行进行采样,并创建一个名为X_bs
的单元阵列。我通过一个函数传递X_bs
,该函数输出我感兴趣的变量y(bb)
。
为什么我收到此错误?我该如何解决这个问题?
以下是一个例子:
X{1} = [1 ; 2 ; 3]
X{2} = [4 ; 5 ; 6; 7]
N(1) = 3 % size of X{1}
N(2) = 4 % size of X{2}
parfor bb=1:10
rng(bb)
for ii = 1:2
X_bs{ii} = zeros(N(ii),1);
ind = ceil(N(ii)*rand(N(ii),1));
X_bs{ii} = X{ii}(ind,:);
end
% Output is a function of X_bs. For illustration, say it is the sum
y(bb) = sum(X_bs{1}) + sum(X_bs{2});
end
上面的代码与前面的代码有相同的错误:“parfor中的变量X_bs无法分类”。这是一个更简单的版本,它可以工作,不使用单元格结构:
X = [1 ; 2 ; 3]
N = 3; %size of X
parfor bb=1:10
rng(bb)
X_bs = zeros(N,1);
ind = ceil(N*rand(N,1));
X_bs= X(ind,:);
y(bb) = sum(X_bs)
end
问题(我认为)在于覆盖细胞结构。也许parfor将细胞结构视为切片变量而不是临时变量。有什么想法吗?
更新:Adriaan建议随机向量ind
和单元结构X_bs{ii}
存在问题。这是一个更简单的示例,它不会调用随机向量ind并且仍然具有相同的错误:
X{1} = [1 ; 2 ; 3]
X{2} = [4 ; 5 ; 6; 7]
N(1) = 3 % size of X{1}
N(2) = 4 % size of X{2}
parfor bb=1:10
for ii = 1:2
X_bs{ii} = X{ii};
end
% Output is a function of X_bs. For illustration, say it is the sum
y(bb) = sum(X_bs{1}) + sum(X_bs{2});
end
因此,我相当确定MatLab不会将单元格结构X_bs{ii}
视为临时变量。
答案 0 :(得分:1)
问题是在该行上创建的:
ind = ceil(N(ii)*rand(N(ii),1));
和表面在这里:
X_bs{ii} = X{ii}(ind,:);
ind
的大小是"未知"在执行parfor
之前到MATLAB,因此无法运行。 parfor
不会以连续的顺序运行,因此最重要的是事先指定所有必需的大小。可能你可以在调用clear X_bs
之前使用y(bb)
绕过它,这会将它们从内存中删除,并确保包含的矩阵的大小不同于上一次迭代所分配的矩阵。
如果另一方面这不能解决问题,则无法将其与此并行化,因为每次都使用随机大小的矩阵。为了扩展这一点:rand(N(ii))
可以生成相当多的数字。无论范围如何,重要的事实是范围 indeterminable ,这意味着在执行它之前你无法知道它是什么。即使这通常没有问题,因为单元格将存储任何旧的矩阵大小,parfor
环境需要才能知道所有大小,以便在分配之前优化内存和CPU使用率工作岗位。
如果可能:获取最大值ind
可以获得并将临时变量中所需的矩阵初始化为最大允许大小,并仅访问使用的条目。
答案 1 :(得分:0)
解决方案(感谢Andriaan的评论)是将生成X_bs
的forloop放入嵌套函数randomize_X
中。请参阅下面的工作示例解决方案:
X{1} = [1 ; 2 ; 3]
X{2} = [4 ; 5 ; 6; 7]
N(1) = 3 % size of X{1}
N(2) = 4 % size of X{2}
parfor bb=1:10
[X_bs] = randomize_X(X,N)
% Output is a function of X_bs. For illustration, say it is the sum
y(bb) = sum(X_bs{1}) + sum(X_bs{2});
end
,其中
function [X_bs] = randomize_X(X,N)
for ii = 1:2
X_bs{ii} = zeros(N(ii),1);
ind = ceil(N(ii)*rand(N(ii),1));
X_bs{ii} = X{ii}(ind,:);
end
end
我非常确定parfor
循环将单元格结构视为切片变量,因此需要事先指定并且不能在parfor
循环中覆盖。为了解决这个问题,一个简单的技巧是将单元结构的计算发送到另一个函数。 parfoor
循环与优化工具箱CVX有类似的问题。可以采用相同的技巧 - 在parfor
内的子程序中调用CVX。