Jump to content

Descriptor-Tensor External Topics

From RidgeRun Developer Wiki

🚧 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.

Contents Pin





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.


Continue the flow


Structured metadata does not own the Tensor bytes
Keep the received bundle and its owning Tensor values alive through the last read, copy, export, or asynchronous device operation. A descriptor can identify a field without keeping its storage available.


Related examples and concepts

Examples

Concepts

Further reading

Source


Cookies help us deliver our services. By using our services, you agree to our use of cookies.