Conditions and Temporal Contracts
🚧 Documentation is under development
The Holoscan SDK guide is currently under active development. Some sections may be incomplete or change without notice.
Questions? Contact RidgeRun or email to support@ridgerun.com.
-
Overview
-
Build, Run, and Validate
-
Core Concepts
-
Operators and Graphs
-
Tensor Data and Memory
-
Interprocess Communication
-
-
Application and Operator Development
- Building an HSDK Application
- Writing a Minimal Operator
- Typed Parameters and Configuration
- Reading, Writing, and Forwarding Data
- Writing Tensor Operators
- Complete Operator Patterns
- Authoring Runtime Behavior
- Runtime Parameter Updates
- Lifecycle Callbacks and Restart Control
- Performance and Debugging
- SDK Source Map
-
Operator Reference
-
Core Operators
-
Holoscan Camera
-
Holoscan RidgeRun
- Overview
- Build and Installation
- ArgusCameraOp
- V4L2SourceOp
- V4L2UserPtrSourceOp
- BgraToPlanarTensorOp
- RawBayerToBgraOp
- RawBayerToYoloTensorOp
- YuyvToBgraOp
- TensorRtInferenceOp
- DrmDisplayOp
- DrmBgraDisplayOp
- X11DisplayOp
- CudaCompositorOp
- DepthColorizerOp
- FakesinkOp
- FrameSkipperOp
- InterprocessSrcOp
- TestPatternOp
-
-
Migration from Holoscan 4.x
-
Examples
-
Core
-
Holoscan Camera
-
Holoscan RidgeRun
-
-
Benchmark and Use Cases
-
Holoscan vs GStreamer
- Overview
-
Capture and Display
-
Capture and Inference
- Compare the workloads
- Implemented Applications
- Framework Selection
- Interprocess
-
Conditions and Temporal Contracts
After the graph structure is in place, preserve the moment when each operator runs and the values it should see. A temporal contract gives the runtime that information: a trigger says when work becomes eligible, a selector says which values to prepare, and a missing-data policy says what to do when the ideal value is unavailable.
Start from the old condition and queue behavior. Then choose the current trigger and input selection together. The goal is to preserve the application's timing and data decisions, not to find a one-to-one replacement for every old class.
Choose when the operator runs
| Older intent | Current starting point |
|---|---|
| A periodic source or timer-driven check | OnClock with a positive period and a graph clock.
|
| One activation for each new input value | OnEach{input}. The selected input drives the activation.
|
| Any connected input may start work | OnAnyInput when the application accepts activation from whichever input produces a value.
|
| Several inputs must arrive with comparable capture times | OnAligned for aligned values or OnWindow for a bounded time window.
|
| A predicate decides whether an evaluation can fire | OnPredicate with an explicit evaluation source and firing rule.
|
A source with no input must declare its trigger. An input operator with no explicit trigger uses the documented input-driven default, not an implicit periodic rate.
Choose which values the operator receives
The trigger and the selector answer different questions. The trigger tells the runtime when compute() may become eligible. The selector tells it which values to prepare for that activation. The operator can then process the prepared data without polling queues or coordinating another input.
| Migration question | Selector to evaluate | Use it when |
|---|---|---|
| Do the inputs represent one event? | Exact
|
The selected values must share the activation's event-time reference. |
| Can a recent value stand in for a slower input? | LatestWithin
|
A bounded age is acceptable and the value remains causally valid. |
| Should the operator consume a bounded batch? | DrainAll
|
The application can process all causally available values in one activation. |
| Is the result defined by a time interval? | BracketedWindow
|
The application needs a bounded interval with valid outer samples. |
Selectors do not create comparable timestamps. Use the capture coordinates and clock mapping produced by the application, and provide enough queue or history capacity for the selected policy. Temporal Contracts and Input Selection provides the complete selection model.
Handle missing values explicitly
Choose the policy that matches the application's output behavior:
Skipkeeps the incomplete selection out of the normal callback path.SafeDefaultcalls the operator's explicit degraded branch. It does not create a sample or fill an input with an invented value.ReuseLastallows a bounded prior value when the retention age and producer or clock conditions are valid.
When a safe branch is admitted, inspect the realized input state before accessing the value. A successful activation does not guarantee that every input contains a fresh sample. The Missing Data example shows selected, reused, and safe-default paths separately.
A small timing translation
The following fragment uses holoscan::Contract with a trigger, selector, and missing-data policy. It describes an input-driven operator that can run a safe branch when its input is unavailable:
holoscan::Contract contract() const override {
holoscan::Contract result;
result.trigger(holoscan::OnEach{input})
.input(input, holoscan::Exact{})
.on_missing(input, holoscan::SafeDefault{});
return result;
}
The runtime evaluates the trigger and selector before calling compute(). The callback checks the realized input state and either processes the selected value or produces the operator's documented safe result. It does not wait for another input or search a queue for a better match.
For a finite inputless producer, complete_after(ComputeCalls) limits successful source calls after an explicit source trigger. It describes completion; it does not decide when a call becomes eligible. Whole-application stop and completion remain separate decisions documented in Running and Stopping.
Check the migrated behavior
Test the cases that made the old condition configuration important:
- one normal input value
- a late or missing input
- a reused value that reaches its age limit
- a bounded window with insufficient history
- natural source completion and requested application stop
Then continue with Code-Level API Evolution to translate the operator declarations and callbacks.