OmniGraph Versioning

There are many facets to OmniGraph that can and will change over time as OmniGraph is still very much a work in progress. In order to minimize disruption to our users all of these types of changes have been enumerated and incremental deprecation plans have been created.

Deprecation Communication

The first thing we will do when some functionality is to be deprecated is to communicate our intent in the #omni-graph Slack channel, and in the Slack channel of any groups we believe will be affected by the change. The intent of this initial communication is to coordinate with stakeholders to come to an agreement on a timeline for the deprecation.

Once a date has been determined we will proceed with up to three phases of deprecation. The combination of phases will depend on the exact nature of the change and the timeline that has been decided.

Soft Deprecation

The soft deprecation phase is where a setting will be introduced to toggle between the old and new behaviors. The difference between the two could be as trivial as the availability of a deprecated function or as complex as a complete replacement of a commonly used data structure or algorithm. The setting will be a Carbonite setting under the tree /persistent/omnigraph/deprecation/….

At this phase the default value of the setting will be to take the original code paths, which will remain untouched.

Communication of the change will take place in two ways:

  • An @channel announcement will be posted in the Slack channel(s) indicating the new behavior is available

  • A deprecation message is added to the original code paths as a one-time warning

Default Deprecation

Once you have had a chance to migrate to the new behavior the default behavior will switch:

  • An @channel announcement will be posted in the Slack channel(s) indicating the new behavior is to be the default

  • The setting default will change to take the new code path

  • The settings manager will emit a deprecation warning whenever the setting is changed to specify the old code path

Hard Deprecation

In the rare case when old behavior must be completely removed, after the agreed on time has passed the old code path will be removed:

  • An @channel announcement will be posted in the Slack channel(s) indicating the old behavior is being removed

  • The setting and all of the old code paths will be physically deleted

  • The settings manager will emit an error whenever the now-deleted setting is attempted to be accessed

Semantic Versioning

CHANGELOG.md:and this project adheres to Semantic Versioning, mostly applied to changes made via the extension versions.

Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version when you make incompatible API changes,

MINOR version when you add functionality in a backwards compatible manner

PATCH version when you make backwards compatible bug fixes.

What this means to the C++ programmer is:

MAJOR change: You must recompile and potentially refactor your code for compatibility

MINOR change: You can use your code as-is in binary form, and optionally recompile for compatibility

PATCH change: Your code works as-is in binary form, no need for recompiling

What this means to the Python programmer is:

MAJOR change: Your code may not work. You should refactor to restore correct execution.

MINOR change: Your code will continue to work, however you may receive deprecation warnings and should refactor your code to use the latest interfaces.

PATCH change: Your code will be mostly unaware of the change, other than corrections to previously incorrect behaviours. (You may need to refactor if your code relied on incorrect behaviour.)

The Public Python API

We are using the PEP8 Standard for defining the actual public API we are supporting.

Warning

Although the nature of Python allows you to inspect and access pretty much anything if it doesn’t appear as part of our “published” API then it is subject to change at any time without warning. If there is something that is not part of the interface you might find particular useful then request that it be surfaced.

The model of import we use is similar to what is used by popular packages like numpy, pandas, and scikit-learn. You import the top level module as a simple prefix and use the API directly from there.

# The core OmniGraph functionality
import omni.graph.core as og
og.get_all_graphs()

There are two more modules we provide for interacting with OmniGraph:

# A subset of the OmniGraph functionality that facilitates integration testing
import omni.graph.core.tests as ogt
# NOT YET AVAILABLE: A subset of the OmniGraph functionality that implements the AutoNode functionality
import omni.graph.core.autonode as oga
# NOT YET AVAILABLE: The code generator framework - for utilities, key/value constants, and typing
import omni.graph.tools as ogn

Hint

The Python bindings to our ABI are considered part of the published API and are available in the same way as all of the other Python functions. They are available in the omni.graph.core module.

Getting Old Versions

By default you will always get the latest version of the module, however some level of backward compatibility will be provided through importing a version-specific module. This module will be frozen at the state of the API contents as of the specified version so that you can continue to access old functionality without warnings until such time as it is hard deprecated.

import omni.graph.core._1 as og
og.the_deprecated_function()

Other Types Of Versions

OmniGraph Extension Versions

As with other parts of Kit the OmniGraph extensions have their own version number, and the interface definitions each have their own version number. These version numbers follow the general guidelines used by Kit,

OmniGraph Carbonite Interface Versions

A good portion of the OmniGraph interfaces are Carbonite style for historic reasons, so they will follow the Carbonite upgrade procedures. The primary rules are:

  • Existing functions in an interface always work as described

  • Functions are never removed from an interface

  • Add all new functions to the end of the interface

  • Increment the minor version of the interface whenever a new function is added

Hint

Most Carbonite version changes will result in a corresponding minor version bump of the extension in which they live as it involves new functionality being added.

OmniGraph ONI Versions

Some of the OmniGraph interfaces, and those developed in the future, will be ONI style, so they will follow the ONI upgrade procedures. The primary rules are:

  • Once an interface is published it can never be changed

  • New functionality in an interface is created by adding a new version that is a derived class (e.g. IBundle2 and IBundle3)

Hint

Most ONI version changes will result in a corresponding minor version bump of the extension in which they live as it involves new functionality being added.

OmniGraph File Format Versions

The OmniGraph nodes also have a USD backing which itself contains a file format version number. For the most part this version number is strictly used to automatically migrate a USD scene to the latest version as it would be problematic to maintain multiple versions within the same code base. It appears as an attribute on the OmniGraph prim type.

OmniGraph prim using version 1.4
def OmniGraph "TestGraph"
{
    token evaluator:type = "push"
    int2 fileFormatVersion = (1, 4)
    token flatCacheBacking = "Shared"
    token pipelineStage = "pipelineStageSimulation"
    token evaluationMode = "Automatic"
}

OGN Code Generator Versions

There is also a version number for the .ogn node generator. It is equal to the version number of the extension containing it (omni.graph.tools) and is embedded into the generated code for version management. You should not need to worry about this version number unless you want to file a bug report, where it would be valuable information.

Node Type Versions

Every node type definition has a version number with it. The number should be incremented every time there is a change in behavior of the node, such as adding or removing attributes or changing the computation algorithm. This applies to nodes you write as well as nodes you consume.

A mismatch in version number between a node being created and the current node implementation will trigger a callback to the updateNodeVersion function, which your node can override if there is some cleanup you can do that will help maintain expected operation of the node.

Protecting Yourself With Tests

OmniGraph uses something called the Extension Testing Matrix to validate any dangerous changes. The more tests you have written that typify your pattern of OmniGraph use the safer it will be for you when changes are made. We can’t run tests we don’t have so please help us help you; write more tests!