Descriptor-Tensor External Topics
🚧 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
-
Descriptor-Tensor External Topics
An image, IMU sample, or application message often contains metadata together with one or more Tensor fields. A descriptor-backed topic keeps those pieces under one message identity. The metadata travels as a schema value, while each Tensor field follows its own storage, readiness, and retention contract.
Start with External Endpoints and Endpoint Catalogs to choose the direction, name, capacity, and catalog. Then use this page when the endpoint carries more than one Tensor or uses a generated schema with Tensor fields.
The Sensor Payloads and Schemas page introduces ImageT, ImuT, field interpretation, and capture metadata. The Tensor Contracts and Memory Types page explains the representation and storage decisions applied to each field.
Choose a structured payload
Use a descriptor-backed topic when the receiver needs the relationship between metadata and several arrays:
| Payload | Example fields | Why use a descriptor-backed topic |
|---|---|---|
| Image with calibration | Pixel Tensor, calibration Tensor, frame metadata | The receiver gets the image description and its related arrays as one typed value. |
| IMU sample batch | Acceleration Tensor, angular-rate Tensor, sample times | The receiver can associate measurements with their units and acquisition information. |
| Application record | Features Tensor, confidence Tensor, labels and identifiers | The receiver can validate the field inventory before using the arrays. |
The generated schema defines field identity and order. The Tensor contracts define the admitted representation and storage for each field. A descriptor is metadata, so it does not make the Tensor bytes inline or prove that a device operation has completed.
Declare one boundary contract per Tensor field
DescriptorTensorTopicContract<SchemaT> connects a generated schema to its Tensor boundary contracts. Add exactly one finite TensorBoundaryContract for every Tensor field. Keep the contracts in a shared helper so the graph and client use the same field inventory.
The following helper describes two small host fields. The application can replace the representations and bounds with the image or IMU shapes it needs:
holoscan::DescriptorTensorTopicContract<Frame> contract;
contract
.field(Fields::pixels,
holoscan::TensorBoundaryContract{
.representation = pixels_representation,
.bounds = holoscan::tensor_bounds(2U * 4U),
})
.field(Fields::calibration,
holoscan::TensorBoundaryContract{
.representation = calibration_representation,
.bounds = holoscan::tensor_bounds(3U * sizeof(float)),
});
Here Frame, Fields, and the representations are generated schema or application aliases. The important rule is that every Tensor field has one named contract and one finite bound. A missing or duplicated field is a contract error before the application can safely attach a client.
The transfer policy belongs to each field. InterfaceTensorEmitPolicy can require exportable storage or admit a bounded copy path. Read Copy Paths and Memory Conversion before selecting a policy for a device or external-memory field.
Use the same field inventory on both sides
Apply the helper to the graph's import or export options before calling Graph::import_topic() or Graph::export_topic(). Give the import and export stable names, and set the publisher or subscriber capacity for the direction that each endpoint uses.
After compilation, the standalone client loads the accepted catalog and uses create_tensor_schema_publisher<Payload>() for an import or create_tensor_schema_subscriber<Payload>() for an export. The schema root and every field contract must match the catalog.
The SDK's shared field definitions and graph declarations show how one inventory is reused across the two programs.
Receive the complete schema value
For a multi-field message, receive_tensors() returns a checked bundle containing the generated metadata and the Tensor values in field order. Keep the bundle alive while reading its root object or any field view.
auto received = subscriber->receive_tensors();
if (!received) {
return holoscan::make_unexpected(std::move(received).error());
}
const auto& bundle = *received;
const auto* frame = bundle.root();
use_pixels(frame->pixels(), bundle.tensor(Fields::pixels));
use_calibration(frame->calibration(), bundle.tensor(Fields::calibration));
ChannelResolvedTensorBundle<Payload> owns the checked metadata and Tensor association. A root pointer borrows the bundle's metadata, so do not keep that pointer after the bundle is released. The owning Tensor values still carry the storage and asynchronous-work obligations described in Standalone ChannelRuntime Clients and Zero-Copy Data Flow and CUDA Stream Ordering.
When the application waits for a sample, wait_for_sample(deadline, token) is a readiness notification. Follow it with a checked receive using the same deadline. A wake does not guarantee that a complete bundle is still queued.
Publish and close the structured stream
Build the schema metadata and the complete Tensor inventory before calling emit(metadata, tensors). The field order and representation must match the catalog contract. A successful result reports the recipients reached by publication; it does not mean that those recipients finished processing the data.
For a finite producer, check close() and treat ordered end-of-stream separately from process exit or object destruction. Stop and join receive waiters before closing their endpoint. Release received bundles, Tensor views, destinations, and streams after their work completes.