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