Access Worker Variables with Composites
Introduction to Composites
Composite objects in the MATLAB® client session let you directly access data values on the workers.
Most often you assigned these variables within spmd
statements.
In their display and usage, Composites resemble cell arrays. There are two ways to
create Composites:
Create Composites in spmd
Statements
When you define or assign values to variables inside an spmd
statement, the data values are stored on the workers.
After the spmd
statement, those data values are accessible on
the client as Composites. Composite objects resemble cell arrays, and behave
similarly. On the client, a Composite has one element per worker. For example,
suppose you create a parallel pool of three local workers and run an
spmd
statement on that pool:
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
A variable might not be defined on every worker. For the workers on which a variable is not defined, the corresponding Composite element has no value. Trying to read that element throws an error.
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]
You can also set values of Composite elements from the client. This causes a
transfer of data, storing the value on the appropriate worker even though it is not
executed within an spmd
statement:
MM{3} = eye(4);
In this case, MM
must already exist as a Composite, otherwise
MATLAB interprets it as a cell array.
Now when you do enter an spmd
statement, the value of the
variable MM
on worker 3 is as set:
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
Data transfers from worker to client when you explicitly assign a variable in the client workspace using a Composite element:
M = MM{1} % Transfer data from worker 1 to variable M on the client
M = 8 1 6 3 5 7 4 9 2
Assigning an entire Composite to another Composite does not cause a data transfer. Instead, the client merely duplicates the Composite as a reference to the appropriate data stored on the workers:
NN = MM % Set entire Composite equal to another, without transfer
However, accessing a Composite's elements to assign values to other Composites
does result in a transfer of data from the workers to the
client, even if the assignment then goes to the same worker. In this case,
NN
must already exist as a Composite:
NN{1} = MM{1} % Transfer data to the client and then to worker
When finished, you can delete the pool:
delete(gcp)
Variable Persistence and Sequences of spmd
The values stored on the workers are retained between spmd
statements. This allows you to use multiple spmd
statements in
sequence, and continue to use the same variables defined in previous
spmd
blocks.
The values are retained on the workers until the corresponding Composites are
cleared on the client, or until the parallel pool is deleted. The following example
illustrates data value lifespan with spmd
blocks, using a pool of
four workers:
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'.
Create Composites Outside spmd
Statements
The Composite
function creates Composite objects without
using an spmd
statement. This might be useful to prepopulate
values of variables on workers before an spmd
statement begins
executing on those workers. Assume a parallel pool is already running:
PP = Composite()
By default, this creates a Composite with an element for each worker in the
parallel pool. You can also create Composites on only a subset of the workers in the
pool. See the Composite reference page for more details. The elements of the
Composite can now be set as usual on the client, or as variables inside an
spmd
statement. When you set an element of a Composite, the
data is immediately transferred to the appropriate worker:
for ii = 1:numel(PP) PP{ii} = ii; end