Skip to content

Replication and Replication Guide Part 3

aparajit-pratap edited this page Jan 13, 2022 · 6 revisions

Replication and Replication Guid

  1. Replication and Replication Guide 1: Replication
  2. Replication and Replication Guide 2: Design for Replication
  3. Replication and Replication Guide 3: Replication Guide

1. Replication Guide

In Part 2 we listed some problems that Replication is not able to solve. We need a way to:

  • enforce iteration even when no replication will happen.
  • have a better control of Zip Replication.

Replication Guide is introduced for this purpose. Each argument could be appended with one or more Replication Guides in the syntax of <n> or <nL> where n is an integer value and an optional suffix L is for Longest Lacing. We will talk about different lacing strategies later. Following is an example of using replication guides, where argument xs has two replication guides <1L> and <2>; ys has two replication guides <1L> and <3> and zs has three replication guides <1L>, <2> and <2>:

foo(xs<1L><2>, ys<1L><3>, zs<1L><2><2>)

Each replication guide is on different replication level, from left to right. In previous example, these replication guides are in three replication levels:

    level 1  | level 2 | level 3
    ---------+---------+--------
xs    <1L>   |   <2>   |
ys    <1L>   |   <3>   |
zs    <1L>   |   <2>   |   <2>

Replication guides are processed level by level, starting from level 1. Each level enforce one or more iterations, so if the argument is not a list, replication guide will promote it to a list so that the argument could be iterated.

It is really important to remember that Replication Guides are processed before Replication. That is, Replication Guide is a way to enforce iteration, and after replication guides are processed, ranks of arguments may not match with ranks of parameters, and Replication may still happen.

2. Unroll to loops

As we said, replication guides are processed level by level. For each level, we process the corresponding replication guides on that level for all arguments and decide to do Zip Replication or Cartesian Replication. The following pseudo-code shows this process:

Process replication guides level by level, start from level 1

For each level
    Step 1. Sort replication guides on that level by ascending order
    Step 2. For each replication guide value
        Step 3.
        If it appears at multiple arguments
            Apply Zip Replication for the corresponding arguments
        otherwise
            Apply Cartesian Replication for the corresponding argument

The numeric values for replication guides do not necessarily start from 1, negative values could even be used. "Replication guide values" in step 2 means those unique replication guide values after sorting. For example, for function call

foo(xs<1L><2>, ys<1L><3>, zs<1L><2><2>)

on level 2 there are replication guides <2> for argument xs, <3> for argument ys, <2> for argument zs. After sorting <2>, <3>, <2> we get unique values <2> and <3>. For <2>, as it appears on xs and zs, Zip Replication will be applied to xs and zs; for <3>, as it only appears on ys, Cartesian Replication will be applied to ys.

By default, if no suffix L is appended to all replication guides, shortest lacing will be applied to Zip Replication, that is, the length of output list depends on the shortest length of inputs; otherwise longest lacing will be applied, that is, if the lengths of multiple inputs are different, the last items of those shorter inputs will be repeated in doing Zip Replication. If all replication guide values are different on that level, we call this case cross product. Both Zip Replication and Cartesian Replication enforce an iteration, therefore there could be multiple iterations on same levels.

For the function call shown before, it will be unrolled to the following for-loop:

# Zip Replication on Level 1 for <1L> of xs, <1L> of ys, <1L> of zs
for each x, y, z in xs, ys, zs  
    # Zip Replication on level 2 for <2> of xs, <2> of zs
    for each ix, iz in x, z
        # Cartesian Replication on level 2 for <3> of ys
        for each iy in y
            # Cartesian Replication on level 3 for <2> of zs
            for each iiz in iz
                foo(ix, iy, iiz)

For the innermost function call foo(ix, iy, iiz), if ranks of arguments ix, iy and iiz don't match with ranks of parameters of foo(), Replicaiton may still happen, see Part 2.

Do we remember the broken case shown in last article?

As we try to get first item of each sub-list, we need to enforce iteration on the input argument: iterate all elements in the input, and for each element return its first item. We could fix it through appending a replication guide <1>:

3. How to do that in Dynamo?

Dynamo UI only provides limit support for adding replication guides through Lacing option:

Following pictures show different lacings and the corresponding code:

  • Shortest Lacing (Note: unfortunately, shortest lacing is broken: it should append Replication Guide to arguments. This issue will be fixed soon.)
  • Longest Lacing
  • Cross-product

I think lacing will cover probably 80% cases of using replication guide. But if we really need to do more control, we have to that in code block node.

4. Issue

When users are using replication guide, as replication guide will create multiple levels of iteration and each iteration wraps the inner result in a list, finally the output could be multiple dimensional list, so Flatten node is frequently used to connect to the output, so that the result could be used as an input for other nodes. Is it possible to "extract" values that we are interested from input instead of flattening it? At-level! :-)

Releases

Roadmap

How To

Dynamo Internals

Contributing

Python3 Upgrade Work

Libraries

FAQs

API and Dynamo Nodes

Clone this wiki locally