在现有matlabpool中并行运行内部matlab函数-“单线程”;

在现有matlabpool中并行运行内部matlab函数-“单线程”;,matlab,parallel-processing,Matlab,Parallel Processing,我正在为非常大的系统(已知的稀疏结构)实现一个自适应(近似)矩阵向量乘法-请参阅,以获得更冗长的描述。我首先确定我需要为每个块计算的条目,但即使条目只是一个小子集,直接(使用正交)计算它们的成本也不可能高。然而,它们的特点是有一个底层结构(它们各自调制的差异),这意味着我只需要为每个“等价类”计算一次求积,我通过调用一个大的2xN差异矩阵(然后映射回原始条目)上的unique 不幸的是,这个2xN矩阵在实践中变得如此之大,以至于它在我的代码中成为了一个瓶颈——它仍然比冗余计算正交快几个数量级,但

我正在为非常大的系统(已知的稀疏结构)实现一个自适应(近似)矩阵向量乘法-请参阅,以获得更冗长的描述。我首先确定我需要为每个块计算的条目,但即使条目只是一个小子集,直接(使用正交)计算它们的成本也不可能高。然而,它们的特点是有一个底层结构(它们各自调制的差异),这意味着我只需要为每个“等价类”计算一次求积,我通过调用一个大的2xN差异矩阵(然后映射回原始条目)上的
unique

不幸的是,这个2xN矩阵在实践中变得如此之大,以至于它在我的代码中成为了一个瓶颈——它仍然比冗余计算正交快几个数量级,但令人恼火,因为它在原则上可以运行得更快

问题是,我计算的集群需要
-singleCompThread
选项,这样Matlab就不会扩散到不应该扩散的地方。这意味着
unique
只能使用一个核心,即使我可以将它安排在串行调用的代码中(因为必须为所有相关块完成此过程)

我对解决方案的搜索使我找到了函数
maxNumCompThreads
,但它已被弃用,并将在将来的版本中删除(除了每次调用时都会发出警告),因此我没有进一步研究它

还可以将函数传递给批处理作业并指定集群和它应该运行的池大小(例如
j=batch(集群,@my_unique,3,{D,'cols},'matlabpool',127)
;这是2013a;在2013b中,
'matlabpool'
的键更改为
'Pool'
),但问题是批处理打开了一个新的池。在我当前的设置中,我可以在集群上有一个永久打开的池,并且总是为
批处理
打开和关闭池会花费很多不必要的时间(除了我可以打开的池的最大大小会减少这一事实)

我想调用
unique
,这样它就可以利用当前打开的matlabpool,而无需请求新的作业池或向集群提交作业

有什么想法吗?或者这是不可能的

致以最良好的祝愿, 阿克塞尔

另外,我完全无法理解为什么Matlab中的标准集函数有一个
'rows'
-选项,而没有一个
'cols'
-选项,特别是因为这将在每个函数中“花费”大约5行代码。这就是我的唯一性的原因:

function varargout=my_unique(a,elem_type,varargin)
% Adapt unique to be able to deal with columns as well

% Inputs:
%   a:
%       Set of which the unique values are sought
%   elem_type (optional, default='scalar'):
%       Parameter determining which kind of unique elements are sought.
%       Possible arguments are 'scalar', 'rows' and 'cols'.
%   varargin (optional):
%       Any valid combination of optional arguments that can be passed to
%       unique (with the exception of 'rows' if elem_type is either 'rows'
%       or 'cols')
%
% Outputs:
%   varargout:
%       Same outputs as unique

if nargin < 2; elem_type='scalar'; end
if ~any(strcmp(elem_type,{'scalar','rows','cols'}))
    error('Unknown Flag')
end

varargout=cell(1,max(nargout,1));

switch (elem_type)
    case 'scalar'
        [varargout{:}]=unique(a,varargin{:});
    case 'rows'
        [varargout{:}]=unique(a,'rows',varargin{:});
    case 'cols'
        [varargout{:}]=unique(transpose(a),'rows',varargin{:});
        varargout=cellfun(@transpose,varargout,'UniformOutput',false);
end

end
function varargout=my_unique(a,elem_类型,varargin)
%适应独特的,以便能够处理列以及
%投入:
%a:
%寻找唯一值的集合
%元素类型(可选,默认为标量):
%确定寻找哪种唯一元素的参数。
%可能的参数为“标量”、“行”和“列”。
%varargin(可选):
%可以传递给的可选参数的任何有效组合
%唯一(如果元素类型为“行”,则“行”除外)
%或“科尔斯”)
%
%产出:
%瓦拉戈特:
%输出与唯一输出相同
如果nargin<2;elem_type='scalar';结束
if~any(strcmp(elem_类型,{'scalar','rows','cols}))
错误('未知标志')
结束
varargout=单元(1,最大值(nargout,1));
开关(elem_型)
大小写“标量”
[varargout{:}]=unique(a,varargin{:});
案例“行”
[varargout{:}]=unique(a,'rows',varargin{:});
“科尔斯”案
[varargout{:}]=unique(转置(a),'rows',varargin{:});
varargout=cellfun(@transpose,varargout,'UniformOutput',false);
结束
结束

无需尝试上述示例,您可以尝试执行块处理。但是,它属于图像处理工具箱。

暂时撇开
'rows'
问题不谈,如果我理解正确的话,您想要的是一种使用开放的并行池对
'unique'
进行大规模调用的方法。一种选择可能是使用。例如,您可以执行以下操作:

spmd
    A = randi([1 100], 1e6, 2); % already transposed to Nx2
    r = unique(A, 'rows'); % operates in parallel
end

这是因为
sortrows
是为
coddistributed
数组实现的。您会发现,如果您可以安排数据始终驻留在集群上,并且当数据太大以至于无法在一台机器上处理时,您只能从(共)分布式阵列中获得加速。

感谢您的提示,也许这是一个可行的解决方案-我会尽快检查它。我知道spmd,但没有研究它,因为a),我错误地记住它的意思是“单处理器,多数据”,而不是“单程序,多数据”,b),因为我觉得“多数据”部分与我正在寻找的相反-即在单个数据(大尺寸)上设置多个工人。我在开放MatlabPool(本地池和集群)中使用不同数量的工作线程(3,6,12,64128)尝试了您的代码(使用
5e7
而不是
1e6
),但不幸的是,没有观察到任何缩放。