Main Content

本页采用了机器翻译。点击此处可查看最新英文版本。

使用复合材料访问工作进程变量

复合材料简介

MATLAB® 客户端会话中的复合对象让您直接访问工作进程上的数据值。您通常在 spmd 语句中分配这些变量。在显示和使用方面,复合材料类似于元胞数组。有两种方法可以创建复合材料:

  • 在客户端上使用 Composite 函数。分配给复合元素的值存储在工作进程上。

  • spmd 语句内定义工作进程的变量。在 spmd 语句之后,存储的值可以在客户端以复合值的形式访问。

spmd 语句中创建复合语句

当您在 spmd 语句内定义或分配变量值时,数据值将存储在工作进程上。

spmd 语句之后,这些数据值可以作为复合数据在客户端进行访问。复合对象类似于元胞数组,并且行为也类似。在客户端,每个 Composite 中每个工作进程对应一个元素。例如,假设您创建一个由三个本地工作进程组成的并行池,并在该池上运行 spmd 语句:

parpool("Processes",3)

spmd  % Uses all 3 workers
    MM = magic(spmdIndex+2); % MM is a variable on each worker
end
MM{1} % In the client, MM is a Composite with one element per worker
ans =     
     8     1     6
     3     5     7
     4     9     2
MM{2}
ans =
    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

并非所有工作进程都定义一个变量。对于未定义变量的工作进程,相应的复合元素没有值。尝试读取该元素会引发错误。

spmd
    if spmdIndex > 1
         HH = rand(4);
    end
end
HH
HH =
     Worker 1: No data
     Worker 2: class = double, size = [4  4]
     Worker 3: class = double, size = [4  4] 

您还可以从客户端设置复合元素的值。这会导致数据传输,将值存储在适当的工作进程上,即使它不是在 spmd 语句中执行的:

MM{3} = eye(4);

在这种情况下,MM 必须已经作为复合体存在,否则 MATLAB 会将其解释为单元数组。

现在,当您输入 spmd 语句时,工作进程 3 上的变量 MM 的值如下设置:

spmd
    if spmdIndex == 3, MM, end
end
Worker 3: 
    MM =
         1     0     0     0
         0     1     0     0
         0     0     1     0
         0     0     0     1

当您使用复合元素在客户端工作区中明确分配变量时,数据会从工作进程传输到客户端:

M = MM{1} % Transfer data from worker 1 to variable M on the client
M =
     8     1     6
     3     5     7
     4     9     2

将整个 Composite 分配给另一个 Composite 不会导致数据传输。相反,客户端仅仅复制 Composite 作为对存储在工作进程上的相应数据的引用:

NN = MM % Set entire Composite equal to another, without transfer

但是,访问 Composite 的元素来为其他 Composites 赋值确实会导致数据从工作进程传输到客户端,即使该赋值随后转到了同一个工作进程。在这种情况下,NN 必须已经作为复合体存在:

NN{1} = MM{1} % Transfer data to the client and then to worker

完成后,您可以删除该池:

delete(gcp)

spmd 的变量持久性和序列

存储在工作进程上的值保留在 spmd 语句之间。这使得您可以按顺序使用多个 spmd 语句,并继续使用前面 spmd 代码块中定义的相同变量。

这些值将保留在工作进程上,直到客户端上相应的合成器被清除,或者直到并行池被删除。以下示例使用由四个工作进程组成的池来说明 spmd 代码块的数据值寿命:

parpool('Processes',4)

spmd
    AA = spmdIndex; % Initial setting
end
AA(:)  % Composite
ans =

  4×1 cell array

    {[1]}
    {[2]}
    {[3]}
    {[4]}
spmd
    AA = AA * 2; % Multiply existing value
end
AA(:)  % Composite
ans =

  4×1 cell array

    {[2]}
    {[4]}
    {[6]}
    {[8]}
clear AA % Clearing in client also clears on workers

spmd
    AA = AA * 2; 
end   % Generates error

delete(gcp)
Analyzing and transferring files to the workers ...done.
Error detected on workers 2 3 4.

Caused by:
    An UndefinedFunction error was thrown on the workers for 'AA'.  
    This may be because the file containing 'AA' is not accessible on the workers. 
    Specify the required files for this parallel pool 
    using the command: addAttachedFiles(pool, ...).  
    See the documentation for parpool for more details.
        Unrecognized function or variable 'AA'.

spmd 语句之外创建复合语句

Composite 函数无需使用 spmd 语句即可创建 Composite 对象。在 spmd 语句开始在这些工作进程上执行之前,预先填充工作进程身上变量的值可能会很有用。假设并行池已在运行:

PP = Composite()

默认情况下,这将为并行池中的每个工作进程创建一个包含一个元素的复合体。您还可以仅在池中的一部分工作进程上创建复合体。请参阅 Composite 参考页以获取更多详细信息。现在可以在客户端上照常设置 Composite 的元素,或者将其作为 spmd 语句内的变量。当您设置 Composite 的一个元素时,数据会立即传输到相应的工作进程:

for ii = 1:numel(PP)
    PP{ii} = ii; 
end

另请参阅

|

相关主题