Op Hashing & CachingΒΆ

NUKE attempts to cache data and minimise generation of duplicate data. The main way in which it does this is its hashing system. Every Op, after it has been constructed for a particular OutputContext (frame/view/proxy setting) has a hash. This hash is used as a key for the data, and other Ops with the same Hash will be treated as having the same data.

The default hash of an Op is derived from the following sources:

  • the hashes of all its inputs, generated for the same frame/view/proxy setting as that Op
  • the hashes of all the knob values at that frame/view

This means that a generator op, with no input, and no animations on its knobs, will produce the same hash for frame 1 and 2. Similarly, it will produce the same hash for the left and right view. In fact, the Ops at frame 1 and frame 2 will be unified into the same Op. This default behaviour can be changed in various ways.

Overriding Op::append(Hash& hash) can be used to introduce extra data into the hash. In particular, a generator which wishes to produce different outputs at different times, even without the knobs being animated, could implement Op::append like so

void Op::append(Hash& hash)
{
  hash.append(outputContext().frame());
}

This will result in the frame number being taken into account in the hash, and therefore frame 1 being different from frame 2. It is also possible to exclude particular knobs from being taken into account when calculating a hash. Suppose there is a knob that does nothing in itself, but is just there to provide an input for a button. When the button is pressed, that does some calculations that changes other knobs, that does result in a change in the image. The hash should then change, but it shouldn’t have changed merely because some knob whose value was not used was altered.

In order to do this, the NO_RERENDER flag should be set on the flag - it will not contribute towards the hash, and therefore not cause a rerender when it is changed.

Apart from deciding whether or not to recalculate at all, by checking whether the hash remains the same, and unifying duplicate Ops on the same Node, the hashes are used as indexes for caching. The Viewer and the DiskCache node, store all data passing through them to the file system and use the Op hash as a key directly. There is another in-memory cache, that is used when NUKE identifies that data would otherwise have to be generated twice or more.

This is invoked in the case where a node is used as the input at more than one point in the “tree”.

Other cases exist. Passing a count of 2 or more, or simply making two different requests to the same Iop covering overlapping regions from the same Iop will result in an in-memory Cache being created, as will creating a Tile or Interest in engine()

The cache will exist until NUKE runs out of memory and decides to free it.

Previous topic

Architecture

Next topic

Sample Source code