## Sliced Variables

A *sliced variable* is one whose value can be broken up into
segments, or *slices*, which are then operated on separately by
different workers. Each iteration of the loop works on a different slice of the array.
Using sliced variables can reduce communication between the client and workers.

In this example, the workers apply `f`

to the elements of
`A`

separately.

parfor i = 1:length(A) B(i) = f(A(i)); end

### Characteristics of a Sliced Variable

If a variable in a `parfor`

-loop has all the following
characteristics, then the variable is sliced:

Type of First-Level Indexing — The first level of indexing is either parentheses,

`()`

, or braces,`{}`

.Fixed Index Listing — Within the first-level parentheses or braces, the list of indices is the same for all occurrences of a given variable.

Form of Indexing — Within the list of indices for the variable, exactly one index involves the loop variable.

Shape of Array — The array maintains a constant shape. In assigning to a sliced variable, the right side of the assignment cannot be

`[]`

or`''`

, because these operators attempt to delete elements.

*Type of First-Level Indexing*. For a sliced variable, the
first level of indexing is enclosed in either parentheses, `()`

, or
braces, `{}`

.

Here are the forms for the first level of indexing for arrays that are sliced and not sliced.

Not Sliced | Sliced |
---|---|

`A.x` | `A(...)` |

`A.(...)` | `A{...}` |

After the first level, you can use any type of valid MATLAB^{®} indexing in the second and subsequent levels.

The variable `A`

shown here on the left is not sliced; that shown
on the right is sliced.

A.q{i,12} A{i,12}.q

*Fixed Index Listing*. Within the first-level indexing of a
sliced variable, the list of indices is the same for all occurrences of a given
variable.

The variable `A`

on the left is not sliced because
`A`

is indexed by `i`

and
`i+1`

in different places. In the code on the right, variable
`A`

is sliced correctly.

Not sliced | Sliced |
---|---|

parfor i = 1:k B(:) = h(A(i), A(i+1)); end |
parfor i = 1:k B(i) = f(A(i)); C(i) = g(A{i}); end |

The example on the right shows occurrences of first-level indexing using both parentheses and braces in the same loop, which is acceptable.

The following example on the left does not slice `A`

because the
indexing of `A`

is not the same in all places. The example on the
right slices both `A`

and `B`

. The indexing of
`A`

is not the same as the indexing of `B`

.
However, the indexing of both `A`

and `B`

are
individually consistent.

Not sliced | Sliced |
---|---|

parfor i=1:10 b = A(1,i) + A(2,i) end |
A = [ 1 2 3 4 5 6 7 8 9 10; 10 20 30 40 50 60 70 80 90 100]; B = zeros(1,10); parfor i=1:10 for n=1:2 B(i) = B(i)+A(n,i) end end |

*Form of Indexing*. Within the first-level of indexing for a
sliced variable, exactly one indexing expression is of the form
`i`

, `i+k`

, `i-k`

, or
`k+i`

. The index `i`

is the loop variable and
`k`

is a scalar integer constant or a simple (non-indexed)
broadcast variable. Every other indexing expression is a positive integer constant,
a simple (non-indexed) broadcast variable, a nested `for`

-loop
index variable, colon, or `end`

.

With `i`

as the loop variable, the `A`

variables
shown on the left are not sliced, while the `A`

variables on the
right are sliced.

Not sliced | Sliced |
---|---|

A(i+f(k),j,:,3) % f(k) invalid for slicing A(i,20:30,end) % 20:30 not scalar A(i,:,s.field1) % s.field1 not simple broadcast var |
A(i+k,j,:,3) A(i,:,end) A(i,:,k) |

When you use other variables along with the loop variable to index an array, you
cannot set these variables inside the loop. In effect, such variables are constant
over the execution of the entire `parfor`

statement. You cannot
combine the loop variable with itself to form an index expression.

*Shape of Array*. A sliced variable must maintain a constant
shape. The variable `A`

shown here is not sliced:

A(i,:) = [];

`A`

is not sliced because changing the shape of a sliced array
would violate assumptions governing communication between the client and
workers.

### Sliced Input and Output Variables

A sliced variable can be an input variable, an output variable, or both. MATLAB transmits sliced input variables from the client to the workers, and sliced output variables from workers back to the client. If a variable is both input and output, it is transmitted in both directions.

In this `parfor`

-loop, `A`

is a sliced input
variable and `B`

is a sliced output variable.

A = rand(1,10); parfor ii = 1:10 B(ii) = A(ii); end

However, if MATLAB determines that, in each iteration, the sliced variable elements are
set before any use, then MATLAB does not transmit the variable to the workers. In this example, all
elements of `A`

are set before any use.

parfor ii = 1:n if someCondition A(ii) = 32; else A(ii) = 17; end % loop code that uses A(ii) end

Sliced-output variables can grow dynamically through indexed assignments with
default values inserted at intermediate indices. In this example, you can see that
the default value of 0 has been inserted at several places in
`A`

.

A = []; parfor idx = 1:10 if rand < 0.5 A(idx) = idx; end end disp(A);

0 2 0 4 5 0 0 8 9 10

Even if a sliced variable is not explicitly referenced as an input, implicit usage
can make it so. In the following example, not all elements of `A`

are necessarily set inside the `parfor`

-loop. Therefore the
original values of the array are received, held, and then returned from the
loop.

A = 1:10; parfor ii = 1:10 if rand < 0.5 A(ii) = 0; end end

Under some circumstances, `parfor`

-loops must assume that a
worker may need all segments of a sliced variable. In this example, it is not
possible to determine which elements of the sliced variable will be read before
execution, so `parfor`

sends all possible
segments.

A = 1:10; parfor ii=1:11 if ii <= randi([10 11]) A(ii) = A(ii) + 1; end end

### Nested `for`

-Loops with Sliced Variables

When you index a sliced variable with a nested `for`

-loop
variable, keep these requirements in mind:

The sliced variable must be enclosed within the corresponding

`for`

-loop.In this example, the code on the left does not work because it indexes the sliced variable

`A`

outside the nested`for`

-loop that defines`j`

.Not Sliced Sliced A = zeros(10); parfor i=1:10 for j=1:10 end A(i,j)=1; end

A = zeros(10); parfor i=1:10 for j=1:10 A(i,j) = 1; end end

The range of the

`for`

-loop variable must be a row vector of positive constant numbers or variables.In this example, the code on the left does not work because it defines the upper limit of the nested

`for`

-loop with a function call. The code on the right provides a workaround by defining the upper limit in a constant variable outside the`parfor`

-loop.Not Sliced Sliced A = zeros(10); parfor i=1:10 for j=1:size(A,2) A(i,j)=1; end end

A = zeros(10); L = size(A,2); parfor i=1:10 for j=1:L A(i,j)=1; end end

The

`for`

-loop variable must not be assigned other than by its`for`

statement.In this example, the code on the left does not work because it reassigns the

`for`

-loop variable inside the`for`

-loop. The code on the right provides a workaround by assigning`i`

to the temporary variable`t`

.Not Sliced Sliced A = zeros(10); parfor i=1:10 for j=1:10 if i == j j = i; A(i,j) = j; end end end

A = zeros(10); parfor i=1:10 for j=1:10 if i == j t = i; A(i,j) = t; end end end

### Data Type Limitations

Some MATLAB data types do not support being used as sliced input or output variables for a

`parfor`

loop. To use a variable as a sliced variable, the`parfor`

implementation must be able to extend the variable using indexing.The following data types are not supported as sliced variables:

`dictionary`

`table`

When you use sliced arrays of

`handle`

objects, MATLAB constructs default elements. For more information, see Initialize Arrays of Handle Objects.