omni::graph::exec::unstable::ExecutionContext

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

Classes

  • ScopedInExecute: Helper RAII object controlling in execution flag. Note that this object will handle the execution flag differently depending on whether or not recursive execution (i.e., invoking execution from a specific context within another task) is allowed. This recursive execution pattern is only allowed for on-demand definition evaluation (i.e., calls to executeNode_abi).

template<typename StorageType, typename ParentInterface = IExecutionContext>
class ExecutionContext : public omni::graph::exec::unstable::Implements<IExecutionContext>

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.

Public Functions

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.

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

See omni::core::IObject::cast.

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

See omni::graph::exec::unstable::IBase_abi::castWithoutAcquire_abi.

Protected Functions

inline Stamp getExecutionStamp_abi() noexcept override

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

Thread Safety

See thread safety information in interface description.

inline bool inExecute_abi() noexcept override

Returns true if context is currently executing.

Thread Safety

See thread safety information in interface description.

inline bool isExecutingThread_abi() noexcept override

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 Status execute_abi() noexcept override

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 Status executeNode_abi(const ExecutionPath *path, INode *node) noexcept override

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_abi() noexcept override

Context initialization. Responsible to propagate initialization to graphs.

Thread Safety

See thread safety information in interface description.

inline virtual IExecutionStateInfo *getStateInfo_abi(const ExecutionPath *path, INode *node) noexcept override

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 virtual omni::core::Result getNodeData_abi(const ExecutionPath *path, INode *node, NodeDataKey key, omni::core::TypeId *outTypeId, void **outPtr, uint64_t *outItemSize, uint64_t *outBufferSize) noexcept override

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.

inline virtual void setNodeData_abi(const ExecutionPath *path, INode *node, NodeDataKey key, omni::core::TypeId typeId, void *data, uint64_t dataByteCount, uint64_t dataItemCount, NodeDataDeleterFn *deleter) noexcept override

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.

inline void applyOnEachDef_abi(IDef *def, IApplyOnEachFunction *callback) noexcept override

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.

inline void applyOnEachDefWithName_abi(const ConstName *name, IApplyOnEachFunction *callback) noexcept override

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.

inline ExecutionContext(IGraph *graph) noexcept

Constructor.

inline void acquire_abi() noexcept override

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_abi() noexcept override

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.

inline uint32_t getUseCount_abi() noexcept override

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

inline void *cast_abi(omni::core::TypeId id) noexcept override

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 *castWithoutAcquire_abi(omni::core::TypeId id) noexcept override

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.

Protected Attributes

StorageType m_storage

Data store.

std::atomic<uint32_t> m_refCount = {1}

Reference count.

class ScopedInExecute

Helper RAII object controlling in execution flag. Note that this object will handle the execution flag differently depending on whether or not recursive execution (i.e., invoking execution from a specific context within another task) is allowed. This recursive execution pattern is only allowed for on-demand definition evaluation (i.e., calls to executeNode_abi).

Public Functions

inline ScopedInExecute(ExecutionContext &context, const bool recursive) noexcept

Constructor.

inline ~ScopedInExecute() noexcept

Destructor.