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.
Semantic Versioning
All of the OmniGraph extensions adhere to Semantic Versioning. See the changelogs from each extension for details on what is included in each of the versions.
Given a version number MAJOR.MINOR.PATCH, expect an increment to the:
**MAJOR** version for incompatible API changes,
**MINOR** version for functionality added or modified in a backwards compatible manner
**PATCH** version for mostly invisible 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 behaviors. (You may need to refactor if your code relied on incorrect behavior.)
The Public Python API
We are using the PEP8 Standard for defining the actual public API we are supporting. Note especially how the presence of a leading underscore in any named module, class, function, or constant, indicates that it is internal and has no guarantee of backward compatibility.
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()
# The code generator framework - for utilities, key/value constants, and typing
import omni.graph.tools.ogn 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 as part of the omni.graph.core
module, imported from the
internal Python bindings module _omni_graph_core
.
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.
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 omni::graph::core::INodeType::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!
Deprecation
Deprecation Policy
As an evolving framework, OmniGraph tries to balance stability with continuous improvement. As such, we have adopted a “no deprecation” policy where, until it becomes absolutely untenable, we continue to support anything that we have previously made publicly available. This includes our C++ ABIs and published Python APIs. We will also attempt to be forward compatible to the extent that it is possible given the nature of the Kit extension system. When we find it necessary to deprecate a feature for any reason we will follow the procedures outlined below.
Deprecation Communication
The first thing we will do when some functionality is to be deprecated is to communicate our intent through any channel that we have available to us at the time, which may include Discord, user forums, and release notes. 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 announcement will be posted 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 announcement will be posted 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 announcement will be posted 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