Skip to navigation

Holoscan by Example

View as Markdown

Holoscan SDK 5.0 ships a compact set of runnable C++ examples, each one built to exercise a specific slice of the runtime: from a one-line install check to a full multi-rate sensor-fusion application with external client processes. This page is the gallery. It tells you what each example demonstrates, which guide chapters it pairs with, and how to build and run everything.

Every example lives under public/examples/ in the SDK source tree. Its source is installed alongside the SDK when the corresponding component is enabled, so you can read it next to the guide pages that explain it.

You will learn
  • What each shipped example demonstrates, at a glance
  • Which guide chapters each example pairs with
  • The role of the hero application (camera_imu_control) and its companion processes
  • How to build the examples in-tree or standalone against an installed SDK
  • How to run examples and their bundled tests

The examples are actively being improved for the 5.0 release. Names and observable behavior described here are stable, but internal details of the sources may shift between releases. When an excerpt in the guide differs from the tree you have, trust the tree.

Each entry links to the exact source directory. Core and Essential identify the implementation layer of the capability the example teaches; Experimental identifies its experimental status. Parenthetical maturity qualifiers such as Beta mirror the linked page or stability callout where shown; their absence is not a declaration that a capability is Stable. Use API stability as the area-level authority. The examples/experimental/ directory is a baseline example-catalog location, not the stability authority — an example may live there while the capability it demonstrates is Beta.

Installation smoke tests

ExampleClassificationWhat it exercisesGuide
hello_worldCoreOne call to holoscan::hello() verifies the install, compiler, and link line.Hello World
hello_coreCoreexpected<T, Error> and stable error-code names.Hello Tour
hello_tensorCoreHost Tensor construction and metadata.Hello Tour
hello_schemaCoreGenerated schema helpers and image metadata.Hello Tour
hello_loggerCoreLog-level policy and HOLOSCAN_LOG_* macros.Hello Tour
hello_ccclCoreCCCL interoperability beside Holoscan headers.Hello Tour
hello_matxCoreMatX interoperability beside Holoscan headers.Hello Tour

Beginner learning chain

StepExampleClassificationWhat it exercisesGuide
E01first_pipelineCoreCompose, compile, run, observe, and stop a complete typed graph.Your First Pipeline
E02first_operatorCoreContract-less and explicitly contracted operators.Your First Operator
E03tensors_101CoreThe minimal bounded host-Tensor loan lifecycle.Tensors 101

Temporal contracts

StepExampleClassificationWhat it exercisesGuide
E04on_any_inputCoreDefault arrival-driven activation.Temporal Contracts
E05on_eachCoreAnchor-driven sampling with bounded reuse.Temporal Contracts
E06on_clockCoreFixed-rate activation and causal selection.Temporal Contracts
E07on_alignedCoreDeterministic multi-input alignment.Temporal Contracts
E08on_windowCoreBracketed windows around an anchor.Temporal Contracts
E09selectorsCoreExact, LatestWithin, and DrainAll.Temporal Contracts
E10missing_dataCoreSkip, SafeDefault, and ReuseLast.Temporal Contracts
E11max_start_delayCoreMaximum start delays and violation policies.Temporal Contracts
E12on_predicateCore (guide preview)Data-dependent activation and predicate inputs.Advanced Temporal Patterns

Core depth

StepExampleClassificationWhat it exercisesGuide
E13typed_parametersCoreTyped parameter aggregates, overrides, and validation.Typed Parameters
E14errors_as_valuesCoreExpected-return propagation and runtime failure channels.Errors as Values
E15time_and_clocksCoreClock domains, capture time, and deterministic test clocks.Time and Clocks
E16compile_and_checkCoreAdmission diagnostics, canonical plans, and digest gates.Compile and Check
E17running_and_stoppingCoreRunSession, requested completion, cooperative stop, and termination evidence.Running and Stopping
E18operator_anatomyCorePorts, parameters, contracts, lifecycle, and compute().Operator Anatomy
E19parameter_schemasCoreSchema field policies and validation.Parameter Schemas
E20lifecycle_callbacksCore (Beta)Sparse lifecycle callbacks and dependency ordering.Lifecycle Callbacks
E21graph_compositionCoreEdge configurators, external topics, and graph validation.Graph Composition
E22reusable_graphsCoreEmbedded graphs, public ports, and restart scopes.Reusable Graphs
E24schema_payloadsCoreSDK-generated owning schema values.Schema Payloads
E25tensors_in_depthCore (Beta)Device pools, stream ordering, and bounded exhaustion.Tensors in Depth
E32custom_schemaCoreApplication-owned FlatBuffer types on generated Operator ports.Custom FlatBuffer Schemas
E33descriptor_tensor_schemaCoreApplication-owned FlatBuffer metadata with descriptor-backed Tensor storage.Custom FlatBuffer Schemas
E34descriptor_tensor_external_topicCoreApplication-owned multi-Tensor schema exchange between a Graph and standalone catalog client.External Topics
E35derived_tensor_pool_capacityCoreCompose Parameter- and input-derived bytes per slot with fixed, expected, followed, and lifecycle-selected rates; compare automatic sizing with an exact explicit depth.Tensors in Depth
E36cuda_graph_regionCoreCompare ordinary dispatch with an explicitly fused, fixed-shape CUDA Graph region.CUDA Graph Regions

Essential, advanced, and experimental

StepExampleClassificationWhat it exercisesGuide
E23pod_payloadsExperimentalExpert-only fixed-layout raw POD payloads.Experimental Raw POD Payloads
E26config_fileEssentialJSON/YAML configuration bound to typed parameters.Configuring Applications
E27plan_artifactsExperimentalPlan inspection, serialization, and artifact publication.Plan Tooling
E28restart_controlCore (Beta)Deny-by-default restart authority and receipts.Restart Control
E29runtime_paramsCore (Beta)Programmatic parameter generations and snapshots.Runtime Parameter Updates
E30web_tunerExperimentalThe loopback-only parameter tuner facade.Runtime Parameter Updates
E31determinism_replayCore (Beta)Replay-stable tags and manual-clock substitution.Determinism and Replay

Complete reference applications

ExampleClassificationWhat it exercisesGuide
camera_imu_controlCoreThe hero application: fusion, contracts, bounded tensors, and external endpoints.Camera + IMU Control
slow_fast_fusionCoreMulti-rate selection with OnEach, LatestWithin, and Skip.Slow/Fast Fusion
external_clientsCoreStandalone non-operator processes attaching through ChannelRuntime.External Clients

Start here: hello_world

hello_world is the smallest possible Holoscan program — a single call to holoscan::hello() that prints Hello Holoscan!. Its only job is to prove that find_package(holoscan) resolves, the headers are on your include path, and holoscan::core links. If this builds and runs, your installation is sound. Walk through it on the Hello World page.

#include <holoscan/holoscan.hpp>
int main() {
holoscan::hello();
return 0;
}

The hello tour: one concern per example

The remaining hello_* examples are deliberate one-liners. Each is a smoke test for exactly one public API surface and the header-only dependencies it pulls in, so a failure points directly at the missing piece:

  • hello_core — returns and branches on holoscan::expected<int, holoscan::Error>, the SDK’s errors-as-values currency, and prints an ErrorCode name.
  • hello_tensor — constructs a host holoscan::Tensor from a DLPack managed-tensor context and queries shape and dtype metadata. Host-only; it needs no CUDA device.
  • hello_schema — encodes a tensor’s image metadata with the schema helpers and parses it back. The helpers live in holoscan::sensor_io, which brings the FlatBuffers-backed holoscan::schema library with it.
  • hello_logger — sets a runtime log level and emits fmt-formatted messages through HOLOSCAN_LOG_INFO and friends, verifying that the SDK never overrides your compile-time log threshold.
  • hello_cccl — a small CUDA reduction using CUB and Thrust, confirming that CCCL coexists with Holoscan in one translation unit. Exits with a skip code when no CUDA device is present.
  • hello_matx — the same idea for MatX numerical primitives.

Each takes a few minutes to read end to end. The guided walkthrough is the Hello Tour.

The hero application: camera_imu_control

camera_imu_control is the running example used throughout this guide: a camera producer, a high-rate IMU input, a fusion stage, and a control output. It is the single best example to study once you have finished Getting Started, because it exercises the whole compose → compile → run arc in one executable:

  • an embedded fusion graph with typed operators and temporal contracts,
  • a bounded host Tensor producer drawing from a preallocated pool,
  • an IMU external import and a control-result external export with stable, explicit endpoint names (baseline.camera_imu.imu, baseline.camera_imu.control),
  • a real RunSession plus an in-process ChannelRuntime client that publishes IMU samples and consumes one control result through the same catalog contract the standalone companions use,
  • deterministic bounded shutdown — the executable stops and joins on its own.

It also demonstrates cold artifact publication: passing --emit-artifacts emits the four-file deployment bundle (including endpoint-catalog.json) without starting lifecycle, CUDA, or channel services, so build tooling can generate deployment artifacts as a pure build step. The full walkthrough is Camera + IMU Control; the artifact story continues in Plan Tooling.

Multi-rate selection: slow_fast_fusion

slow_fast_fusion is the ordinary application root distilled: one holoscan::Graph, the free compile() and run_async() functions, typed operators, and two periodic rates. The fast input drives fusion via OnEach; the most recent causal slow sample is admitted with LatestWithin only while it is within its declared age, and the activation is skipped (Skip) otherwise. After the sixth fused sample, the sink requests immediate whole-run success and the main routine verifies kRequestedCompleted; this request does not imply downstream drain. The program also reports the compiled plan’s trigger and selection counts.

Read it when you reach Temporal Contracts — it is the smallest complete demonstration of trigger, input selection, and missing-data policy working together. The walkthrough is Slow/Fast Fusion.

Standalone processes: external_clients

external_clients contains two ordinary, non-operator programs that talk to the hero application from separate processes:

  • sensor_daemon publishes uint32_t IMU samples with caller-owned capture coordinates.
  • recorder consumes exported control results with receive_sample() and prints the public SampleMetadata. It drains finite streams through remote EOS by default and accepts a positive sample limit for an unbounded graph such as the hero application.

Each receives the exact endpoint-catalog.json path emitted by the graph-definition executable and attaches by explicit endpoint name — there is no global “latest catalog” discovery. Neither program includes any transport headers; the public ChannelRuntime client API is the entire surface. See External Clients and Standalone Channel Clients.

One graph, one vocabulary. Inside a graph, operators communicate through typed ports (Input<T>/Output<T>) wired with add_flow() — the runtime materializes the channels for you. The ChannelRuntime client API exists only for standalone processes outside any graph. Never mix the two: using ChannelRuntime inside an operator bypasses the compiled plan and its guarantees.

Building and running the examples

Every example ships with two CMake entry points:

  • CMakeLists.txt — used when the examples build as part of the SDK tree, or all together via the top-level examples/CMakeLists.txt.
  • CMakeLists.min.txt — a minimal, self-contained project that builds one example standalone against an installed SDK. Core examples use find_package(holoscan REQUIRED); optional-tooling examples request the exact COMPONENTS they consume. This is the file to copy when starting your own project.

Each example’s CMakeLists.txt follows one layout so it can be configured in-tree or by itself: it declares cmake_minimum_required and its own project() unconditionally (project name holoscan_<example>, languages identical to CMakeLists.min.txt), then defers to CMakeLists.min.txt when it is the top-level project. Executable targets, install destinations, and CTest names use the plain example name.

cmake_minimum_required(VERSION 4.0)
project(holoscan_hello_world LANGUAGES CXX)
if(PROJECT_IS_TOP_LEVEL)
include("${CMAKE_CURRENT_LIST_DIR}/CMakeLists.min.txt")
return()
endif()
add_executable(hello_world hello_world.cpp)
target_link_libraries(hello_world PRIVATE holoscan::core)

Installed tooling. params and params_io ship with holoscan-core; a COMPONENTS params_io request remains accepted for compatibility but is unnecessary. The lightweight config and config_io components are prerequisites of every Core install. A plain find_package(holoscan REQUIRED) therefore imports core, config, config_io, params, and params_io, and fails only when the install is incomplete. An unqualified aggregate find also exposes every optional module present in the installed variant; component-qualified discovery is the precise, portable spelling for applications that depend on optional tooling such as the experimental web tuner. See Configuring applications and the example’s CMakeLists.min.txt for the exact request.

The installed SDK places holoscan-config.cmake under cmake/holoscan in its library directory: /usr/lib/<triplet>/cmake/holoscan for the Debian packages, or <prefix>/lib/cmake/holoscan for an SDK installed to a custom prefix. To build all examples against that SDK:

cd examples
cmake -B build -S .
cmake --build build

Then run any example directly from its build directory:

./build/hello_world/cpp/hello_world
./build/slow_fast_fusion/cpp/slow_fast_fusion

Each example registers a CTest entry with a pass expression, so the whole gallery doubles as an install-acceptance suite:

ctest --test-dir build --output-on-failure

The CUDA examples (hello_cccl, hello_matx) exit with a skip code when no CUDA-capable device is present, so the test suite passes on CPU-only machines instead of failing.

The hero application additionally exposes a dedicated build target that emits its deployment bundle without running anything:

cmake --build build --target camera_imu_control_graph_artifacts

Building hello_cccl and hello_matx requires the CUDA Toolkit and CCCL to be discoverable; the top-level examples/CMakeLists.txt shows the find_package incantations. hello_matx uses an installed MatX when CMake finds one (for example through CMAKE_PREFIX_PATH) and otherwise downloads it at configure time, which needs network access. If you only want the CPU-side examples, build them individually from each example’s cpp/ directory, whose CMakeLists.min.txt builds the example as a standalone project.

Recap

  • hello_world is the install check: one call, one link line, one printed greeting.
  • The hello_* tour isolates one public surface per example — errors, tensors, schemas, logging, CCCL, MatX.
  • camera_imu_control is the hero application: contracts, bounded tensors, external endpoints, and cold artifact emission in one executable.
  • slow_fast_fusion is the minimal demonstration of multi-rate selection with OnEach, LatestWithin, and Skip.
  • external_clients shows standalone processes attaching through the public ChannelRuntime API and an explicit endpoint catalog.
  • Build in-tree with CMakeLists.txt or standalone with CMakeLists.min.txt; run the gallery as a test suite with ctest.

Next: Hello World.