omni::graph::exec::unstable::IExecutionContext

Defined in omni/graph/exec/unstable/IExecutionContext.h

class IExecutionContext : public omni::core::Generated<omni::graph::exec::unstable::IExecutionContext_abi>

Stores and provides access to the execution state of the graph.

The execution graph is only a description of what needs to be executed. The actual graph state is stored separately in an instance of this object.

The execution context allows computing the same graph description within multiple contexts. It also enables the ability to perform this computation concurrently. Some example use cases of this class:

  • Computing the state of a graph at a time different than the current time (e.g. asynchronous caching, fake dynamics)

  • Computing the state of a graph with a inputs different than the current input state (e.g. double solve)

All execution begins with a call to one of the execute methods on this interface. omni::graph::exec::unstable::IExecutionContext::execute() is used to execute the entire execution graph while omni::graph::exec::unstable::IExecutionContext::executeNode() can be used to execute only a part of the graph.

Part of this interface defines a key/value store. The key in this store is an omni::graph::exec::unstable::ExecutionPath. The value is an implementation of omni::graph::exec::unstable::IExecutionStateInfo, which in addition to storing computation state, can also store user defined data. The computation state and user data can be accessed with the getStateInfo / getNodeData methods (though the latter is slightly faster) and set with the setNodeData.

Another feature of omni::graph::exec::unstable::IExecutionContext is the ability to quickly search for nodes using a particular definition and apply a function on them. Definitions can be searched by name or by pointer (see omni::graph::exec::unstable::IExecutionContext::applyOnEach()). These methods are used extensively during Graph Construction .

See Execution Concepts for an in-depth guide on how this object is used during execution.

Thread Safety

Since multiple threads can concurrently traverse a graph, implementors of methods within this class should expect that multiple threads will be accessing this object in parallel.

Subclassed by omni::graph::exec::unstable::ImplementsCastWithoutAcquire< IExecutionContext, Rest… >

Public Functions

inline Status execute(const ExecutionPath &path, omni::core::ObjectParam<INode> node) noexcept

On-demand execution method. Executes the given node.

The given path must not be nullptr.

The given node must not be nullptr.

See Error Handling to understand the error handling/reporting responsibilities of implementors of this method.

Thread Safety

See thread safety information in interface description.

inline IExecutionStateInfo *getStateInfo(const ExecutionTask &task) noexcept

Retrieves the state info for the node in the given task.

The task’s upstream path and node are hashed for the lookup.

The returned omni::graph::exec::unstable::IExecutionStateInfo will not have omni::core::IObject::acquire() called on it.

This method always returns a valid pointer.

See omni::graph::exec::unstable::IExecutionContext::getStateInfo_abi() for further details.

Thread Safety

See thread safety information in interface description.

inline IExecutionStateInfo *getStateInfo(const ExecutionPath &path) noexcept

Retrieves the state info at the given execution path.

The returned omni::graph::exec::unstable::IExecutionStateInfo will not have omni::core::IObject::acquire() called on it.

This method always returns a valid pointer.

See omni::graph::exec::unstable::IExecutionContext::getStateInfo_abi() for further details.

Thread Safety

See thread safety information in interface description.

template<typename T>
inline T *getStateInfoAs(const ExecutionTask &info) noexcept

Access state for the node in a given task. The returned object will be the given template type.

nullptr may be returned if the retrieved omni::graph::exec::unstable::IExecutionStateInfo could not be casted to T.

See omni::graph::exec::unstable::IExecutionContext::getStateInfo_abi() for further details.

Thread Safety

See thread safety information in interface description.

template<typename T>
inline T *getStateInfoAs(const ExecutionPath &path) noexcept

Access state for a given execution path. The returned object will be the given template type.

nullptr may be returned if the retrieved omni::graph::exec::unstable::IExecutionStateInfo could not be casted to T.

See omni::graph::exec::unstable::IExecutionContext::getStateInfo_abi() for further details.

Thread Safety

See thread safety information in interface description.

template<typename T>
inline T *getStateInfoAs(const ExecutionPath &path, omni::core::ObjectParam<INode> node) noexcept

Access state for a given node under the given execution path. The returned object will be the given template type.

nullptr may be returned if the retrieved omni::graph::exec::unstable::IExecutionStateInfo could not be casted to T.

The given node may be nullptr.

See omni::graph::exec::unstable::IExecutionContext::getStateInfo_abi() for further details.

Thread Safety

See thread safety information in interface description.

template<typename T>
inline omni::expected<Span<T>, omni::core::Result> getNodeDataAs(omni::core::TypeId desiredType, const ExecutionPath &path, omni::core::ObjectParam<INode> node, NodeDataKey key) noexcept

Returns a pointer to a value stored in a node’s key/value datastore.

The node whose key/value datastore should be used is identified by combining the given path and node. node may be nullptr.

The type T must match the type specified in desiredType. Prefer using OMNI_GRAPH_EXEC_GET_NODE_DATA_AS() instead of this method, which will ensure desiredType and T match.

If desiredType does not match the type of the stored data, omni::core::kResultInvalidDataType is returned.

If no data exists at the given key (i.e omni::graph::exec::unstable::IExecutionContext::setNodeData() has not previously been called at the given key), omni::core::kResultNotFound is returned.

The returned span may point to nullptr if omni::graph::exec::unstable::IExecutionContext::setNodeData() was previously called with a nullptr data pointer.

Thread Safety

See thread safety information in interface description.

template<typename T>
inline omni::expected<Span<T>, omni::core::Result> getNodeDataAs(omni::core::TypeId desiredType, const ExecutionTask &path, NodeDataKey key) noexcept

Returns a pointer to a value stored in a node’s key/value datastore.

The node whose key/value datastore should be used is identified by combining the given path and node in the given task.

The type T must match the type specified in desiredType. Prefer using OMNI_GRAPH_EXEC_GET_NODE_DATA_AS() instead of this method, which will populate the desiredType for you.

If desiredType does not match the type of the stored data, omni::core::kResultInvalidDataType is returned.

If no data exists at the given key (i.e omni::graph::exec::unstable::IExecutionContext::setNodeData() has not previously been called at the given key), omni::core::kResultNotFound is returned.

The returned span may point to nullptr if omni::graph::exec::unstable::IExecutionContext::setNodeData() was previously called with a nullptr data pointer.

Thread Safety

See thread safety information in interface description.

template<typename SpecifiedT, typename DataT>
inline DataT *setNodeData(omni::core::TypeId itemType, const ExecutionPath &path, omni::core::ObjectParam<INode> node, NodeDataKey key, std::unique_ptr<DataT> data) noexcept

Stores a value in a node’s key/value datastore.

The node whose key/value datastore should be used is identified by combining the given path and node. node may be nullptr.

If a value is already stored at the given key it will be replaced.

SpecifiedT, itemType, and DataT describe the type of the supplied data and must all be the same type. Prefer using OMNI_GRAPH_EXEC_SET_NODE_DATA() instead of this method, which will populate the itemType for you.

data may be nullptr.

Returns a pointer to data.

Thread Safety

See thread safety information in interface description.

template<typename SpecifiedT, typename DataT>
inline DataT *setNodeData(omni::core::TypeId itemType, const ExecutionTask &path, NodeDataKey key, std::unique_ptr<DataT> data) noexcept

Stores a value in a node’s key/value datastore.

The node whose key/value datastore should be used is identified by combining the given path and node in the given task.

If a value is already stored at the given key it will be replaced. SpecifiedT, itemType, and DataT describe the type of the supplied data and must all be the same type. Prefer using OMNI_GRAPH_EXEC_SET_NODE_DATA() instead of this method, which will populate the itemType for you.

data may be nullptr.

Returns a pointer to data.

Thread Safety

See thread safety information in interface description.

template<typename Fn>
inline void applyOnEach(omni::core::ObjectParam<omni::graph::exec::unstable::IDef> def, Fn &&callback) noexcept

Discover all execution paths leading to given definition and invoke given function with each of them.

This inline implementation wraps lambda into IApplyOnEachFunction

The supplied function should have the signature of void(const ExecutionPath&).

The given callback is free to invoke this method.

Thread Safety

The given function will be called serially by this method. However, other threads may also invoke this method, meaning the callback must coordinate access to shared data.

template<typename Fn>
inline void applyOnEach(const ConstName &name, Fn &&callback) noexcept

Discover all execution paths leading to definition with the given name and invoke the given function with each of them.

This inline implementation wraps lambda into IApplyOnEachFunction

The supplied function should have the signature of void(const ExecutionPath&).

The given callback is free to invoke this method.

Thread Safety

The given function will be called serially by this method. However, other threads may also invoke this method, meaning the callback must coordinate access to shared data.

inline omni::graph::exec::unstable::Stamp getExecutionStamp() noexcept

Current execution version. Incremented with each execution of the context.

Thread Safety

See thread safety information in interface description.

inline bool inExecute() noexcept

Returns true if context is currently executing.

Thread Safety

See thread safety information in interface description.

inline bool isExecutingThread() noexcept

Returns true if the current thread is one, of potentially many, which started this context’s execution. In other words, invoking this method in any thread that kickstarted this context’s execution will return true.

When a given context’s execution from within a thread completes, that thread will no longer be associated with that context as a “kickstarting” thread, so any subsequent calls to this method from within that same thread will return false until execution is invoked on the context once again.

Note, do not assume that the “main” thread acts as an evaluation kickstarter to any given context.

Thread Safety

See thread safety information in interface description.

inline omni::graph::exec::unstable::Status execute() noexcept

Main execution method. Executes the entire execution graph.

See Error Handling to understand the error handling/reporting responsibilities of implementors of this method.

Thread Safety

See thread safety information in interface description.

inline omni::graph::exec::unstable::Status executeNode(const omni::graph::exec::unstable::ExecutionPath &upstreamPath, omni::core::ObjectParam<omni::graph::exec::unstable::INode> node) noexcept

On-demand execution method. Executes the given node.

The given path must not be nullptr.

The given node must not be nullptr.

See Error Handling to understand the error handling/reporting responsibilities of implementors of this method.

Thread Safety

See thread safety information in interface description.

inline void initialize() noexcept

Context initialization. Responsible to propagate initialization to graphs.

Thread Safety

See thread safety information in interface description.

inline omni::graph::exec::unstable::IExecutionStateInfo *getStateInfo(const omni::graph::exec::unstable::ExecutionPath &path, omni::core::ObjectParam<omni::graph::exec::unstable::INode> node) noexcept

Access state for a given execution path.

If the given node is not nullptr, a copy of the given path with the node appended will be used as the lookup key.

This method always returns a valid pointer.

Thread Safety

See thread safety information in interface description.

Warning

This method should be used for read only access by downstream nodes, example accessing graph state when executing downstream nodes. Extra care needs to be taken if this state has to be mutated concurrently.

inline void *castWithoutAcquire(omni::core::TypeId id) noexcept

Casts this object to the type described the the given id.

Returns nullptr if the cast was not successful.

Unlike omni::core::IObject::cast(), this casting method does not call omni::core::IObject::acquire().

Thread Safety

This method is thread safe.

inline uint32_t getUseCount() noexcept

Returns the number of different instances (this included) referencing the current object.

Thread Safety

This method is thread safe.

inline void *cast(omni::core::TypeId id) noexcept

Returns a pointer to the interface defined by the given type id if this object implements the type id’s interface.

Objects can support multiple interfaces, even interfaces that are in different inheritance chains.

The returned object will have omni::core::IObject::acquire() called on it before it is returned, meaning it is up to the caller to call omni::core::IObject::release() on the returned pointer.

The returned pointer can be safely reinterpret_cast<> to the type id’s C++ class. For example, “omni.windowing.IWindow” can be cast to omni::windowing::IWindow.

Do not directly use this method, rather use a wrapper function like omni::core::cast() or omni::core::ObjectPtr::as().

Thread Safety

This method is thread safe.

inline void acquire() noexcept

Increments the object’s reference count.

Objects may have multiple reference counts (e.g. one per interface implemented). As such, it is important that you call omni::core::IObject::release() on the same pointer from which you called omni::core::IObject::acquire().

Do not directly use this method, rather use omni::core::ObjectPtr, which will manage calling omni::core::IObject::acquire() and omni::core::IObject::release() for you.

Thread Safety

This method is thread safe.

inline void release() noexcept

Decrements the objects reference count.

Most implementations will destroy the object if the reference count reaches 0 (though this is not a requirement).

Objects may have multiple reference counts (e.g. one per interface implemented). As such, it is important that you call omni::core::IObject::release() on the same pointer from which you called omni::core::IObject::acquire().

Do not directly use this method, rather use omni::core::ObjectPtr, which will manage calling omni::core::IObject::acquire() and omni::core::IObject::release() for you.

Thread Safety

This method is thread safe.

Protected Functions

virtual Stamp getExecutionStamp_abi() noexcept = 0

Current execution version. Incremented with each execution of the context.

Thread Safety

See thread safety information in interface description.

virtual bool inExecute_abi() noexcept = 0

Returns true if context is currently executing.

Thread Safety

See thread safety information in interface description.

virtual bool isExecutingThread_abi() noexcept = 0

Returns true if the current thread is one, of potentially many, which started this context’s execution. In other words, invoking this method in any thread that kickstarted this context’s execution will return true.

When a given context’s execution from within a thread completes, that thread will no longer be associated with that context as a “kickstarting” thread, so any subsequent calls to this method from within that same thread will return false until execution is invoked on the context once again.

Note, do not assume that the “main” thread acts as an evaluation kickstarter to any given context.

Thread Safety

See thread safety information in interface description.

virtual Status execute_abi() noexcept = 0

Main execution method. Executes the entire execution graph.

See Error Handling to understand the error handling/reporting responsibilities of implementors of this method.

Thread Safety

See thread safety information in interface description.

virtual Status executeNode_abi(const ExecutionPath *upstreamPath, INode *node) noexcept = 0

On-demand execution method. Executes the given node.

The given path must not be nullptr.

The given node must not be nullptr.

See Error Handling to understand the error handling/reporting responsibilities of implementors of this method.

Thread Safety

See thread safety information in interface description.

virtual void initialize_abi() noexcept = 0

Context initialization. Responsible to propagate initialization to graphs.

Thread Safety

See thread safety information in interface description.

virtual IExecutionStateInfo *getStateInfo_abi(const ExecutionPath *path, INode *node) noexcept = 0

Access state for a given execution path.

If the given node is not nullptr, a copy of the given path with the node appended will be used as the lookup key.

This method always returns a valid pointer.

Thread Safety

See thread safety information in interface description.

Warning

This method should be used for read only access by downstream nodes, example accessing graph state when executing downstream nodes. Extra care needs to be taken if this state has to be mutated concurrently.

virtual omni::core::Result getNodeData_abi(const ExecutionPath *path, INode *node, NodeDataKey key, omni::core::TypeId *outTypeId, void **outPtr, uint64_t *outItemSize, uint64_t *outItemCount) noexcept = 0

Returns a value from a node’s key/value datastore.

The node from which to grab data is identified by the given path and node. The node may be nullptr.

The key is used as a look-up in the node’s key/value datastore.

The type of each data item is returned in outTypeId.

outPtr will be updated with a pointer to the actual data. outPtr must not be nullptr.

outItemSize store the size of each item in the returned array. outItemSize must not be nullptr

outItemCount contains the number of items returned (i.e. the number of items outPtr points to). For an array, this will be greater than 1. outItemCount must not be nullptr.

If the key is not found, omni::core::kResultNotFound is returned.

The returned data may point to nullptr if omni::graph::exec::unstable::IExecutionContext::setNodeData() was previously called with a nullptr data pointer.

path must not be nullptr.

See Error Handling to understand the error handling/reporting responsibilities of implementors of this method.

Thread Safety

See thread safety information in interface description.

virtual void setNodeData_abi(const ExecutionPath *path, INode *node, NodeDataKey key, omni::core::TypeId typeId, void *data, uint64_t itemSize, uint64_t itemCount, NodeDataDeleterFn *deleter) noexcept = 0

Sets a value in a node’s key/value datastore.

The node in which to set the data is identified by the given path and node. path must not be nullptr. The node may be nullptr.

The key is used as a look-up in the node’s key/value datastore.

The type of each data item is set with typeId.

If data already exists at the given key, it will be replaced.

data points to an array of data items. data may be nullptr.

itemSize is the size of each item in the given array.

itemCount contains the number of items pointed to by data. For an array, this will be greater than 1.

deleter is a function used to delete data when either a new value is set at the key or the context is invalidated. If deleter is nullptr, it is up to the calling code to manage the lifetime of the data.

Thread Safety

See thread safety information in interface description.

virtual void applyOnEachDef_abi(IDef *def, IApplyOnEachFunction *callback) noexcept = 0

Discover all execution paths leading to the given definition and invoke the given function with each of them.

Implementations of this interface may cache results to remove the traversal cost for subsequent call. Any change in the execution graph topology will invalidate this cache.

This method must not be called during graph construction.

def is the definition for which to look. This pointer may be nullptr.

callback is the callback to execute with each path to given definition. This pointer must not be nullptr.

The given callback is free to invoke this method.

Thread Safety

The given callback will be called serially by this method. However, other threads may also invoke this method, meaning the callback must coordinate access to shared data.

virtual void applyOnEachDefWithName_abi(const ConstName *name, IApplyOnEachFunction *callback) noexcept = 0

Discover all execution paths leading to definitions with the given name and invoke the given function with each of them.

Implementation of this interface may cache results to remove the traversal cost for subsequent calls. Any change in the execution graph topology will invalidate this cache.

This method must not be called during graph construction.

name is the name of definition for which to look. This pointer must not be nullptr.

callback is the callback to execute with each path to given definition. This pointer must not be nullptr.

The given callback is free to invoke this method.

Thread Safety

The given callback will be called serially by this method. However, other threads may also invoke this method, meaning the callback must coordinate access to shared data.

virtual void *castWithoutAcquire_abi(omni::core::TypeId id) noexcept = 0

Casts this object to the type described the the given id.

Returns nullptr if the cast was not successful.

Unlike omni::core::IObject::cast(), this casting method does not call omni::core::IObject::acquire().

Thread Safety

This method is thread safe.

virtual uint32_t getUseCount_abi() noexcept = 0

Returns the number of different instances (this included) referencing the current object.

Thread Safety

This method is thread safe.

virtual void *cast_abi(TypeId id) noexcept = 0

Returns a pointer to the interface defined by the given type id if this object implements the type id’s interface.

Objects can support multiple interfaces, even interfaces that are in different inheritance chains.

The returned object will have omni::core::IObject::acquire() called on it before it is returned, meaning it is up to the caller to call omni::core::IObject::release() on the returned pointer.

The returned pointer can be safely reinterpret_cast<> to the type id’s C++ class. For example, “omni.windowing.IWindow” can be cast to omni::windowing::IWindow.

Do not directly use this method, rather use a wrapper function like omni::core::cast() or omni::core::ObjectPtr::as().

Thread Safety

This method is thread safe.

virtual void acquire_abi() noexcept = 0

Increments the object’s reference count.

Objects may have multiple reference counts (e.g. one per interface implemented). As such, it is important that you call omni::core::IObject::release() on the same pointer from which you called omni::core::IObject::acquire().

Do not directly use this method, rather use omni::core::ObjectPtr, which will manage calling omni::core::IObject::acquire() and omni::core::IObject::release() for you.

Thread Safety

This method is thread safe.

virtual void release_abi() noexcept = 0

Decrements the objects reference count.

Most implementations will destroy the object if the reference count reaches 0 (though this is not a requirement).

Objects may have multiple reference counts (e.g. one per interface implemented). As such, it is important that you call omni::core::IObject::release() on the same pointer from which you called omni::core::IObject::acquire().

Do not directly use this method, rather use omni::core::ObjectPtr, which will manage calling omni::core::IObject::acquire() and omni::core::IObject::release() for you.

Thread Safety

This method is thread safe.