Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matlab 使用SPMD在更新公共变量时运行一系列作业_Matlab_Parallel Processing - Fatal编程技术网

Matlab 使用SPMD在更新公共变量时运行一系列作业

Matlab 使用SPMD在更新公共变量时运行一系列作业,matlab,parallel-processing,Matlab,Parallel Processing,我目前正在尝试使用Matlab2013b并行运行非常耗时的实验 加速的一个策略是使用一个实验的结果来“热启动”下一个实验。在我的例子中,这有点复杂,因为每个实验都有一个n_类型类型,我只能使用k类型的实验来加速另一个k类型的实验 不幸的是,我无法使用parfor函数实现此策略,因为它需要每个作业更新一个公共变量(存储热启动信息)。也就是说,我听说可以使用spmd框架来实现这一点 我想知道是否有人能帮我将下面的一段通用(非工作)parfor代码“翻译”成能在spmd代码中工作的代码 n_cores

我目前正在尝试使用Matlab2013b并行运行非常耗时的实验

加速的一个策略是使用一个实验的结果来“热启动”下一个实验。在我的例子中,这有点复杂,因为每个实验都有一个
n_类型
类型,我只能使用
k
类型的实验来加速另一个
k
类型的实验

不幸的是,我无法使用
parfor
函数实现此策略,因为它需要每个作业更新一个公共变量(存储热启动信息)。也就是说,我听说可以使用
spmd
框架来实现这一点

我想知道是否有人能帮我将下面的一段通用(非工作)
parfor
代码“翻译”成能在
spmd
代码中工作的代码

n_cores = %provided by user (# of workers that are available)
inputs  = %provided by user (n_jobs x 1 cell array of structs)
types   = %provided by user (n_types x 1 array of integer values)
n_jobs  = length(inputs)
n_types = length(unique(types))

outputs     = cell(n_jobs,1) %cell array to store job output
warm_starts = cell(0,n_types) %empty 0 x n_type cell array to store warm start data

matlabpool('open',n_cores)

parfor i = 1:length(jobs)

   %run myfun in parallel
   outputs{i} = myfun(inputs{i},warm_starts(types(i)));

   %update warm start data for experiments of this type with data from current experiment
   warm_starts{end+1,types(i)) = get_warm_start(job_outputs{i});

end

我不太清楚每个
类型
可能需要存储多少不同的
热启动。我假设您只想存储1个。以下是您可以如何做到这一点:

jobs  = rand(1,97); % note prime number of jobs
types = randi([1, 5], size(jobs));
n_jobs = numel(jobs);
n_types = numel(unique(types));
warm_starts = cell(1, n_types);

spmd
    jobs_per_lab = ceil(n_jobs / numlabs);
    outputs = cell(jobs_per_lab, 1);
    for idx = 1:jobs_per_lab
        job_idx = idx + ((labindex-1)*jobs_per_lab);
        if job_idx > n_jobs
            % Off the end of 'jobs', no work to do
            this_warm_start = NaN;
            this_type       = NaN;
        else
            this_type = types(job_idx);
            if ~isempty(warm_starts{this_type})
                this_warm_start = warm_starts{this_type};
            else
                this_warm_start = 0;
            end
            outputs{idx} = this_warm_start + types(job_idx) * jobs(job_idx); % some function goes here
            this_warm_start = rand();
        end
        % All-to-all communication to exchange 'this_warm_start' values.
        % After this, each worker has a 2 x numlabs cell array of warm starts and types
        all_warm_starts_this_round = gcat({this_type; this_warm_start}, 2);
        for w = 1:numlabs
            warm_start_type = all_warm_starts_this_round{1, w};
            warm_start_value = all_warm_starts_this_round{2, w};
            if ~isnan(warm_start_type)
                warm_starts{warm_start_type} = warm_start_value;
            end
        end
    end
    % Finally, collect all results on lab 1
    outputs = gcat(outputs, 1, 1);
end
% Dereference the Composite
outputs = outputs{1};

我在那里做的主要工作是手动分割工作,以便每个工人操作一大块“作业”,然后在每轮之后使用广播热启动信息。

谢谢!可以肯定的是:除非n_jobs是numlab的倍数,否则这段代码不会出错吗?在这种情况下,我觉得您可能会引用不存在的类型/作业。Gah。如果作业的数量不是numlab的倍数,那么肯定存在一个非常重要的错误。在这种情况下,一些工作人员提前完成,对其余mod(n_作业,numlabs)工作人员的“gcat”调用返回以下错误:“使用labReceive时出错。遇到通信不匹配错误:另一个实验室在labReceive期间变为空闲状态。”是的,对gcat的调用是集体的,因此必须确保它们一起调用。我更新了示例代码,以展示如何处理n_作业不是numlab的倍数的情况。谢谢!理解GCAT如何工作的最后一个问题:假设worker 1仍在运行实验函数,但worker 2已完成并到达GCAT调用。。工人2会执行这个呼叫吗?或者它也必须等到工作人员1到达GCAT吗?GCAT是集体所有对所有通信-因此,工作人员2在工作人员1至少进入GCAT之前不能离开GCAT。如果你的实验需要不同的时间,那可能会导致你的工人无所事事地等待其他人。