holoscan::Application

Beta
View as Markdown

Application class.

An application acquires and processes streaming data. An application is a collection of fragments where each fragment can be allocated to execute on a physical node of a Holoscan cluster.

#include <holoscan/application.hpp>

Inherits from: holoscan::Fragment (public)


Constructors

Application

holoscan::Application::Application(
const std::vector<std::string> &argv = {}
)

Construct a new Application object.

This constructor parses the command line for flags that are recognized by App Driver/Worker, and removes all recognized flags so users can use the remaining flags for their own purposes.

The command line arguments are retrieved from /proc/self/cmdline so that the single-fragment application works as expected without any command line arguments.

The arguments after processing arguments are stored in the argv_ member variable and the reference to the vector of arguments can be accessed through the argv() method.

Example:

Parameters

argv
const std::vector<std::string> &Defaults to {}

The command line arguments.

Example

#include <holoscan/holoscan.hpp>
class MyPingApp : public holoscan::Application {
// ...
};
int main(int argc, char** argv) {
auto my_argv =
holoscan::Application({"myapp", "--driver", "my_arg1", "--address=10.0.0.1"}).argv();
HOLOSCAN_LOG_INFO(" my_argv: {}", fmt::join(my_argv, " "));
HOLOSCAN_LOG_INFO(
" argv: {} (argc: {}) ",
fmt::join(std::vector<std::string>(argv, argv + argc), " "),
argc);
auto app_argv = holoscan::Application().argv(); // do not use reference ('auto&') here
HOLOSCAN_LOG_INFO("app_argv: {} (size: {})", fmt::join(app_argv, " "), app_argv.size());
auto app = holoscan::make_application<MyPingApp>();
HOLOSCAN_LOG_INFO("app->argv() == app_argv: {}", app->argv() == app_argv);
app->run();
return 0;
}
// $ ./myapp --driver --input image.dat --address 10.0.0.20
// my_argv: myapp my_arg1
// argv: ./myapp --driver --input image.dat --address 10.0.0.20 (argc: 6)
// app_argv: ./myapp --input image.dat (size: 3)
// app->argv() == app_argv: true

Destructor

~Application

holoscan::Application::~Application() override = default

Methods

make_fragment

template <typename FragmentT = Fragment,
typename StringT,
typename... ArgsT,
typename = std::enable_if_t<std::is_constructible_v<std::string, StringT>>>
std::shared_ptr<Fragment> holoscan::Application::make_fragment(
StringT name,
ArgsT &&... args
)

Create a new fragment.

Returns: The shared pointer to the created fragment.

Template parameters

FragmentT
typename

The type of the fragment to create.

Parameters

name
StringT

The name of the fragment.

args
ArgsT &&...

The arguments to pass to the fragment constructor.

description

std::string & holoscan::Application::description()

Get the application description.

Returns: The application description.

version

std::string & holoscan::Application::version()

Get the application version.

Returns: The application version.

argv

std::vector<std::string> & holoscan::Application::argv()

Get the reference to the command line arguments after processing flags.

The returned vector includes the executable name as the first element.

Returns: The reference to the command line arguments after processing flags.

options

CLIOptions & holoscan::Application::options()

Get the reference to the CLI options.

Returns: The reference to the CLI options.

fragment_graph

FragmentFlowGraph & holoscan::Application::fragment_graph()

Get the fragment connection graph.

When two operators are connected through add_flow(Fragment, Fragment), the fragment connection graph is automatically updated. The fragment connection graph is used to assign transmitters and receivers to the corresponding Operator instances in the fragment so that the application can be executed in a distributed manner.

Returns: The reference to the fragment connection graph (FragmentFlowGraph object.)

add_fragment

virtual void holoscan::Application::add_fragment(
const std::shared_ptr<Fragment> &frag
)

Add a fragment to the graph.

The information of the fragment is stored in the FragmentFlowGraph object. If the fragment is already added, this method does nothing.

Parameters

frag
const std::shared_ptr<Fragment> &

The fragment to be added.

add_flow

virtual void holoscan::Application::add_flow(
const std::shared_ptr<Fragment> &upstream_frag,
const std::shared_ptr<Fragment> &downstream_frag,
const std::set<std::pair<std::string, std::string>> &port_pairs
)

Add a flow between two fragments.

It takes two fragments and a vector of string pairs as arguments. The vector of string pairs is used to connect the output ports of the first fragment to the input ports of the second fragment. The input and output ports of the operators are specified as a string in the format of <operator name>.<port name>. If the operator has only one input or output port, the port name can be omitted.

In the above example, the output port of the blur_image operator in fragment1 is connected to the input port of the sharpen_image operator in fragment2. Since blur_image and sharpen_image operators have only one output/input port, the port names are omitted.

The information about the flow (edge) is stored in the FragmentFlowGraph object and can be accessed through the fragment_graph() method.

If the upstream fragment or the downstream fragment is not in the graph, it will be added to the graph.

Parameters

upstream_frag
const std::shared_ptr<Fragment> &

The upstream fragment.

downstream_frag
const std::shared_ptr<Fragment> &

The downstream fragment.

port_pairs
const std::set<std::pair<std::string, std::string>> &

The port pairs. The first element of the pair is the output port of the operator in the upstream fragment and the second element is the input port of the operator in the downstream fragment.

Example

class App : public holoscan::Application {
public:
void compose() override {
using namespace holoscan;
auto fragment1 = make_fragment<Fragment1>("fragment1");
auto fragment2 = make_fragment<Fragment2>("fragment2");
add_flow(fragment1, fragment2, {{"blur_image", "sharpen_image"}});
}
};

compose_graph

void holoscan::Application::compose_graph() override

Calls compose() if the fragment graph is not composed yet.

run

void holoscan::Application::run() override

Initialize the graph and run the graph.

This method calls compose() to compose the graph, and runs the graph.

run_async

std::future<void> holoscan::Application::run_async() override

Initialize the graph and run the graph asynchronously.

This method calls compose() to compose the graph, and runs the graph asynchronously.

Returns: The future object.

track_distributed

std::unordered_map<std::string, DataFlowTracker *> holoscan::Application::track_distributed(
uint64_t num_start_messages_to_skip = kDefaultNumStartMessagesToSkip,
uint64_t num_last_messages_to_discard = kDefaultNumLastMessagesToDiscard,
int latency_threshold = kDefaultLatencyThreshold,
bool is_limited_tracking = false
)

Returns a map of fragment names to DataFlowTracker* corresponding to respective fragments.

The trackers will store cumulatively progressive timestamps, meaning a fragment tracker will store the timestamps of operators in the previous fragments as well.

Returns: std::unordered_map<std::string, DataFlowTracker*> Fragment name to DataFlowTracker* mapping.

Parameters

num_start_messages_to_skip
uint64_tDefaults to kDefaultNumStartMessagesToSkip

The number of start messages to skip.

num_last_messages_to_discard
uint64_tDefaults to kDefaultNumLastMessagesToDiscard

The number of last messages to discard.

latency_threshold
intDefaults to kDefaultLatencyThreshold

The latency threshold.

is_limited_tracking
boolDefaults to false

Whether to enable limited tracking for performance.

is_metadata_enabled

void holoscan::Application::is_metadata_enabled(
bool enable
) override

Deprecated method to enable or disable metadata for the application.

Please use enable_metadata instead.

Parameters

enable
bool

Boolean indicating whether metadata should be enabled.

enable_metadata

void holoscan::Application::enable_metadata(
bool enable
) override

Enable or disable metadata for the application.

Controls whether metadata is enabled or disabled by default for fragments in this application. Individual fragments of a distributed application can override this setting using the Fragment::enable_metadata() method. Similarly, individual operators can override the default for their fragment by using the Operator::enable_metadata() method.

Parameters

enable
bool

Boolean indicating whether metadata should be enabled.

metadata_policy

void holoscan::Application::metadata_policy(
MetadataPolicy policy
) override

Set the default metadata update policy to be used for fragments within this application.

The metadata policy determines how metadata is merged across multiple receive calls:

  • MetadataPolicy::kUpdate: Update the existing value when a key already exists.
  • MetadataPolicy::kInplaceUpdate: Update the existing MetadataObject’s value in-place when a key already exists.
  • MetadataPolicy::kReject: Do not modify the existing value if a key already exists.
  • MetadataPolicy::kRaise: Raise an exception if a key already exists (default).

For distributed applications, individual fragments can override the application-level default via Fragment::metadata_policy.

Parameters

policy
MetadataPolicy

The metadata update policy to be used by this operator.

app_driver_client

std::shared_ptr<distributed::AppDriverClient> holoscan::Application::app_driver_client() const

Get the AppDriverClient for the application.

Returns: The shared pointer to the AppDriverClient.

initiate_distributed_app_shutdown

void holoscan::Application::initiate_distributed_app_shutdown(
const std::string &fragment_name
)

Initiate shutdown of the distributed application.

This method initiates a shutdown of the distributed application by calling the initiate_shutdown method on the AppDriverClient.

Parameters

fragment_name
const std::string &

The name of the fragment initiating the shutdown.

add_data_logger

void holoscan::Application::add_data_logger(
const std::shared_ptr<DataLogger> &logger
)

Add a data logger to the application.

This method adds a data logger to the application. For distributed applications, the data logger is added to each fragment in the fragment graph.

Parameters

logger
const std::shared_ptr<DataLogger> &

The data logger to add.

name

Fragment & holoscan::Application::name(
const std::string &name
) &

Set the name of the operator.

Returns: The reference to this fragment (for chaining).

Parameters

name
const std::string &

The name of the operator.

application

Fragment & holoscan::Application::application(
Application *app
)

Set the application of the fragment.

Returns: The reference to this fragment (for chaining).

Parameters

app
Application *

The pointer to the application of the fragment.

config

void holoscan::Application::config(
const std::string &config_file,
const std::string &prefix = ""
)

Set the configuration of the fragment.

The configuration file is a YAML file that has the information of GXF extension paths and some parameter values for operators.

The extensions field in the YAML configuration file is a list of GXF extension paths. The paths can be absolute or relative to the current working directory, considering paths in LD_LIBRARY_PATH environment variable.

The paths can consist of the following parts:

  • GXF core extensions built-in extensions such as libgxf_std.so and libgxf_cuda.so. libgxf_std.so, libgxf_cuda.so, libgxf_multimedia.so, libgxf_serialization.so are always loaded by default. GXF core extensions are copied to the lib directory of the build/installation directory.
    • built-in extensions such as libgxf_std.so and libgxf_cuda.so.
    • libgxf_std.so, libgxf_cuda.so, libgxf_multimedia.so, libgxf_serialization.so are always loaded by default.
    • GXF core extensions are copied to the lib directory of the build/installation directory.
  • Other GXF extensions GXF extensions that are required for operators that this fragment uses. some core GXF extensions such as libgxf_stream_playback.so are always loaded by default. these paths are usually relative to the build/installation directory.
    • GXF extensions that are required for operators that this fragment uses.
    • some core GXF extensions such as libgxf_stream_playback.so are always loaded by default.
    • these paths are usually relative to the build/installation directory.

The extension paths are used to load dependent GXF extensions at runtime when ::run() method is called.

For other fields in the YAML file, you can freely define the parameter values for operators/fragments.

For example:

You can get the value of this configuration file by calling ::from_config() method.

If the application is executed with --config option or HOLOSCAN_CONFIG_PATH environment, the configuration file is overridden by the configuration file specified by the option or environment variable.

Throws: RuntimeError if the config_file is non-empty and the file doesn’t exist.

Parameters

config_file
const std::string &

The path to the configuration file.

prefix
const std::string &Defaults to ""

The prefix string that is prepended to the key of the configuration. (not implemented yet)

Example

extensions:
- libmy_recorder.so
replayer:
directory: "../data/racerx"
basename: "racerx"
frame_rate: 0 # as specified in timestamps
repeat: false # default: false
realtime: true # default: true
count: 0 # default: 0 (no frame count restriction)
recorder:
out_directory: "/tmp"
basename: "tensor_out"

config_shared

std::shared_ptr<Config> holoscan::Application::config_shared()

Get the shared pointer to the configuration of the fragment.

Returns: The shared pointer to the configuration of the fragment.

graph

OperatorFlowGraph & holoscan::Application::graph()

Get the graph of the fragment.

Returns: The reference to the graph of the fragment (OperatorFlowGraph object.)

graph_shared

std::shared_ptr<OperatorFlowGraph> holoscan::Application::graph_shared()

Get the shared pointer to the graph of the fragment.

Returns: The shared pointer to the graph of the fragment.

executor

void holoscan::Application::executor(
const std::shared_ptr<Executor> &executor
)

Set the executor of the fragment.

Parameters

executor
const std::shared_ptr<Executor> &

The executor to be added.

executor_shared

std::shared_ptr<Executor> holoscan::Application::executor_shared()

Get the shared pointer to the executor of the fragment.

Returns: The shared pointer to the executor of the fragment.

scheduler

std::shared_ptr<Scheduler> holoscan::Application::scheduler()

Get the scheduler used by the executor.

Returns: The reference to the scheduler of the fragment’s executor (Scheduler object.)

network_context

std::shared_ptr<NetworkContext> holoscan::Application::network_context()

Get the network context used by the executor.

Returns: The reference to the network context of the fragment’s executor (NetworkContext object.)

create_pubsub_network_context

virtual std::shared_ptr<NetworkContext> holoscan::Application::create_pubsub_network_context()

Create the NetworkContext for PubSub connectors.

Called by the executor when PubSub connectors are detected and no NetworkContext has been explicitly set via network_context().

Override in your Application subclass to return a custom PubSubContext subclass with a concrete backend:

Returns: A new NetworkContext to use for PubSub connectors.

Example

std::shared_ptr<NetworkContext> create_pubsub_network_context() override {
return make_network_context<MyCustomPubSubContext>("pubsub_context");
}

from_config

ArgList holoscan::Application::from_config(
const std::string &key
)

Get the Argument(s) from the configuration file.

For the given key, this method returns the value of the configuration file.

For example:

from_config("capture_card") returns an ArgList (vector-like) object that contains the following items:

  • Arg("width") = 1920
  • Arg("height") = 1080
  • Arg("rdma") = true

You can use ’.’ (dot) to access nested fields.

from_config("capture_card.rdma") returns an ArgList object that contains only one item and it can be converted to bool through ArgList::as() method:

Returns: The argument list of the configuration for the key.

Parameters

key
const std::string &

The key of the configuration.

Example

source: "replayer"
do_record: false # or 'true' if you want to record input video stream.
capture_card:
width: 1920
height: 1080
rdma: true

Example

auto is_rdma = from_config("capture_card.rdma").as<bool>();

config_keys

std::unordered_set<std::string> holoscan::Application::config_keys()

Determine the set of keys present in a Fragment’s config.

Returns: The set of valid keys.

make_operator

template <typename OperatorT,
typename StringT,
typename... ArgsT,
typename = std::enable_if_t<std::is_constructible_v<std::string, StringT>>>
std::shared_ptr<OperatorT> holoscan::Application::make_operator(
StringT name,
ArgsT &&... args
)

Create a new operator.

Returns: The shared pointer to the operator.

Template parameters

OperatorT
typename

The type of the operator.

Parameters

name
StringT

The name of the operator.

args
ArgsT &&...

The arguments for the operator.

make_resource

template <typename ResourceT,
typename StringT,
typename... ArgsT,
typename = std::enable_if_t<std::is_constructible_v<std::string, StringT>>>
std::shared_ptr<ResourceT> holoscan::Application::make_resource(
StringT name,
ArgsT &&... args
)

Create a new (operator) resource.

Returns: The shared pointer to the resource.

Template parameters

ResourceT
typename

The type of the resource.

Parameters

name
StringT

The name of the resource.

args
ArgsT &&...

The arguments for the resource.

make_condition

template <typename ConditionT,
typename StringT,
typename... ArgsT,
typename = std::enable_if_t<std::is_constructible_v<std::string, StringT>>>
std::shared_ptr<ConditionT> holoscan::Application::make_condition(
StringT name,
ArgsT &&... args
)

Create a new condition.

Returns: The shared pointer to the condition.

Template parameters

ConditionT
typename

The type of the condition.

Parameters

name
StringT

The name of the condition.

args
ArgsT &&...

The arguments for the condition.

make_scheduler

template <typename SchedulerT,
typename StringT,
typename... ArgsT,
typename = std::enable_if_t<std::is_constructible_v<std::string, StringT>>>
std::shared_ptr<SchedulerT> holoscan::Application::make_scheduler(
StringT name,
ArgsT &&... args
)

Create a new scheduler.

Returns: The shared pointer to the scheduler.

Template parameters

SchedulerT
typename

The type of the scheduler.

Parameters

name
StringT

The name of the scheduler.

args
ArgsT &&...

The arguments for the scheduler.

make_network_context

template <typename NetworkContextT,
typename StringT,
typename... ArgsT,
typename = std::enable_if_t<std::is_constructible_v<std::string, StringT>>>
std::shared_ptr<NetworkContextT> holoscan::Application::make_network_context(
StringT name,
ArgsT &&... args
)

Create a new network context.

Returns: The shared pointer to the network context.

Template parameters

NetworkContextT
typename

The type of the network context.

Parameters

name
StringT

The name of the network context.

args
ArgsT &&...

The arguments for the network context.

make_thread_pool

std::shared_ptr<ThreadPool> holoscan::Application::make_thread_pool(
const std::string &name,
int64_t initial_size = 1
)

Create a new thread pool resource.

Returns: The shared pointer to the thread pool resource.

Parameters

name
const std::string &

The name of the thread pool.

initial_size
int64_tDefaults to 1

The initial number of threads in the thread pool.

add_default_green_context_pool

std::shared_ptr<CudaGreenContextPool> holoscan::Application::add_default_green_context_pool(
int32_t dev_id,
std::vector<uint32_t> sms_per_partition = {},
int32_t default_context_index = -1,
uint32_t min_sm_size = 2
)

Add default green context pool.

Returns: The shared pointer to the green context pool resource.

Parameters

dev_id
int32_t

The device id.

sms_per_partition
std::vector<uint32_t>Defaults to {}

The number of SMs per partition.

default_context_index
int32_tDefaults to -1

The index of the default green context.

min_sm_size
uint32_tDefaults to 2

The minimum number of SMs per partition.

get_default_green_context_pool

std::shared_ptr<CudaGreenContextPool> holoscan::Application::get_default_green_context_pool()

Get the default green context pool.

Returns: The shared pointer to the default green context pool.

get_service_erased

std::shared_ptr<FragmentService> holoscan::Application::get_service_erased(
const std::type_info &service_type,
std::string_view id
) const override

Get a fragment service by type information and identifier.

Implementation of the FragmentServiceProvider interface method for retrieving registered fragment services using runtime type information. This method provides type-erased access to services and is thread-safe.

Returns: The shared pointer to the fragment service, or nullptr if not found.

Parameters

service_type
const std::type_info &

The type information of the service to retrieve.

id
std::string_view

The identifier of the service. If empty, retrieves by type only.

get_service_resource_by_name

std::shared_ptr<Resource> holoscan::Application::get_service_resource_by_name(
std::string_view id
) const override

Retrieve a resource registered as a fragment service by name.

Returns: The shared pointer to the service resource, or nullptr if not found.

Parameters

id
std::string_view

The service id (name) used during service registration.

get_services_by_id

std::vector<std::shared_ptr<FragmentService>> holoscan::Application::get_services_by_id(
std::string_view id
) const override

Retrieve all fragment services with a matching id, regardless of registered type.

This method is used as a fallback when exact type lookup fails, enabling retrieval of services registered with a derived type when looking up by a base type.

Returns: A vector of shared_ptrs to matching FragmentServices. Empty if none found.

Parameters

id
std::string_view

The service id (name) used during service registration.

register_service

template <typename ServiceT>
bool holoscan::Application::register_service(
const std::shared_ptr<ServiceT> &svc,
std::string_view id = ""
)

Register an existing fragment service instance.

Registers an already created fragment service instance with the specified identifier. This allows the fragment service to be retrieved later using the service() method.

Returns: true if the service was successfully registered, false otherwise.

Template parameters

ServiceT
typename

The type of the fragment service.

Parameters

svc
const std::shared_ptr<ServiceT> &

The shared pointer to the fragment service instance to register.

id
std::string_viewDefaults to ""

The identifier for the fragment service registration. If empty, uses the fragment service type as identifier.

register_service_from

virtual bool holoscan::Application::register_service_from(
Fragment *fragment,
std::string_view id
)

service

template <typename ServiceT = DefaultFragmentService>
std::shared_ptr<ServiceT> holoscan::Application::service(
std::string_view id = ""
) const

Retrieve a registered fragment service or resource.

Retrieves a previously registered fragment service or resource by its type and optional identifier. Returns nullptr if no service/resource is found with the specified type and identifier.

Note that any changes to the service retrieval logic in this method should be synchronized with the implementation in ComponentBase::service() method to maintain consistency.

Returns: The shared pointer to the service/resource, or nullptr if not found or if type casting fails.

Template parameters

ServiceT
typename

The type of the service/resource to retrieve. Must inherit from either Resource or FragmentService. Defaults to DefaultFragmentService if not specified.

Parameters

id
std::string_viewDefaults to ""

The identifier of the service/resource. If empty, retrieves by type only.

get_service_by_type_info

std::shared_ptr<FragmentService> holoscan::Application::get_service_by_type_info(
const std::type_info &service_type,
std::string_view id = ""
) const

Retrieve a registered fragment service or resource for Python bindings.

This is a helper method for Python bindings to retrieve a service by its C++ type info.

Returns: The shared pointer to the base service, or nullptr if not found.

Parameters

service_type
const std::type_info &

The type info of the service/resource to retrieve.

id
std::string_viewDefaults to ""

The identifier of the service/resource. If empty, retrieves by type only.

fragment_services_by_key

const std::unordered_map<ServiceKey, std::shared_ptr<FragmentService>, ServiceKeyHash> & holoscan::Application::fragment_services_by_key() const

Get the fragment services by key.

Returns: The fragment services by key.

start_op

virtual const std::shared_ptr<Operator> & holoscan::Application::start_op()

Get or create the start operator for this fragment.

This operator is nothing but the first operator that was added to the fragment. It has the name of <|start|> and has a condition of CountCondition(1). This Operator is used to start the execution of the fragment. Entry operators who want to start the execution of the fragment should connect to this operator.

If this method is not called, no start operator is created. Otherwise, the start operator is created if it does not exist, and the shared pointer to the start operator is returned.

Returns: The shared pointer to the start operator.

add_operator

virtual void holoscan::Application::add_operator(
const std::shared_ptr<Operator> &op
)

Add an operator to the graph.

The information of the operator is stored in the OperatorFlowGraph object. If the operator is already added, this method does nothing.

Parameters

op
const std::shared_ptr<Operator> &

The operator to be added.

add_subgraph

virtual void holoscan::Application::add_subgraph(
const std::shared_ptr<Subgraph> &subgraph
)

Add a subgraph to the fragment, taking ownership.

This method takes ownership of the subgraph by storing the shared pointer, registers the subgraph name for duplicate detection, and ensures the subgraph is composed.

This is the recommended way to add a pre-constructed subgraph (e.g. from a factory method) to a Fragment. The Fragment will keep the subgraph alive for the duration of its lifetime.

This method is also called automatically by add_flow() overloads that take Subgraph arguments, so explicit calls are only needed when a subgraph has no flows (self-contained).

Calling this on a subgraph that is already owned (e.g. after make_subgraph) is a safe no-op.

Throws: std::runtime_error if a subgraph with the same name has already been added.

Parameters

subgraph
const std::shared_ptr<Subgraph> &

The subgraph to be added.

set_dynamic_flows

virtual void holoscan::Application::set_dynamic_flows(
const std::shared_ptr<Operator> &op,
const std::function<void(const std::shared_ptr<Operator> &)> &dynamic_flow_func
)

Set a callback function to define dynamic flows for an operator at runtime.

This method allows operators to modify their connections with other operators during execution. The callback function is called after the operator executes and can add dynamic flows using the operator’s add_dynamic_flow() methods.

Parameters

op
const std::shared_ptr<Operator> &

The operator to set dynamic flows for

dynamic_flow_func
const std::function<void(const std::shared_ptr<Operator> &)> &

The callback function that defines the dynamic flows. Takes a shared pointer to the operator as input and returns void.

make_subgraph

template <typename SubgraphT, typename... ArgsT>
std::shared_ptr<SubgraphT> holoscan::Application::make_subgraph(
const std::string &name,
ArgsT &&... args
)

Create and compose a Subgraph.

Creates a Subgraph that directly populates this Fragment’s operator graph. The Subgraph is composed immediately and its operators are added with qualified names to the Fragment’s main graph.

Returns: Shared pointer to the composed Subgraph

Template parameters

SubgraphT
typename

The subgraph class type (must inherit from Subgraph)

Parameters

name
const std::string &

Unique name for this instance (used for operator qualification)

args
ArgsT &&...

Additional arguments to pass to the subgraph constructor

compose

virtual void holoscan::Application::compose()

Compose a graph.

The graph is composed by adding operators and flows in this method.

track

DataFlowTracker & holoscan::Application::track(
uint64_t num_start_messages_to_skip = kDefaultNumStartMessagesToSkip,
uint64_t num_last_messages_to_discard = kDefaultNumLastMessagesToDiscard,
int latency_threshold = kDefaultLatencyThreshold,
bool is_limited_tracking = false
)

Turn on data frame flow tracking.

A reference to a DataFlowTracker object is returned rather than a pointer so that the developers can use it as an object without unnecessary pointer dereferencing.

Returns: A reference to the DataFlowTracker object in which results will be stored.

Parameters

num_start_messages_to_skip
uint64_tDefaults to kDefaultNumStartMessagesToSkip

The number of messages to skip at the beginning.

num_last_messages_to_discard
uint64_tDefaults to kDefaultNumLastMessagesToDiscard

The number of messages to discard at the end.

latency_threshold
intDefaults to kDefaultLatencyThreshold

The minimum end-to-end latency in milliseconds to account for in the end-to-end latency metric calculations.

is_limited_tracking
boolDefaults to false

If true, the tracking is limited to root and leaf nodes, minimizing the timestamps by avoiding intermediate operators.

data_flow_tracker

DataFlowTracker * holoscan::Application::data_flow_tracker()

Get the DataFlowTracker object for this fragment.

Returns: The pointer to the DataFlowTracker object.

port_info

FragmentPortMap holoscan::Application::port_info() const

Get an easily serializable summary of port information.

The FragmentPortMap class is used by distributed applications to send port information between application workers and the driver.

Returns: An unordered_map of the fragment’s port information where the keys are operator names and the values are a 3-tuple. The first two elements of the tuple are the set of input and output port names, respectively. The third element of the tuple is the set of “receiver” parameters (those with type std::vector<IOSpec*>).

stop_execution

virtual void holoscan::Application::stop_execution(
const std::string &op_name = ""
)

Stop the execution of all operators in the fragment.

This method is used to stop the execution of all operators in the fragment by setting the internal async condition of each operator to EVENT_NEVER state, which sets the scheduling condition to NEVER. Once stopped, the operators will not be scheduled for execution (the compute() method will not be called), which may lead to application termination depending on the application’s design.

Note that executing this method does not trigger the operators’ stop() method. The stop() method is called only when the scheduler deactivates all operators together.

Parameters

op_name
const std::string &Defaults to ""

The name of the operator to stop. If empty, all operators will be stopped.

data_loggers

const std::vector<std::shared_ptr<DataLogger>> & holoscan::Application::data_loggers() const

Get the data loggers associated with this fragment.

Returns: A const reference to the vector of data loggers.

subgraphs

const std::vector<std::shared_ptr<Subgraph>> & holoscan::Application::subgraphs() const

Get the top-level subgraphs owned by this fragment.

Returns subgraphs added via make_subgraph() or add_subgraph(). Nested subgraphs within these are accessible via Subgraph::nested_subgraphs().

Returns: A const reference to the vector of owned subgraphs.

is_gpu_resident

bool holoscan::Application::is_gpu_resident() const

Check if the fragment has GPU-resident operators.

Returns: True if the fragment has GPU-resident operators, false otherwise.

gpu_resident

GPUResidentAccessor holoscan::Application::gpu_resident()

Get an accessor for GPU-resident specific functions.

This method returns a GPUResidentAccessor object that provides convenient access to GPU-resident specific functionality. For example:

Returns: A GPUResidentAccessor object for accessing GPU-resident functions.

Throws: RuntimeError if the fragment does not have GPU-resident operators.

Example

fragment->gpu_resident().timeout_ms(1000);
fragment->gpu_resident().sync_with_host();
fragment->gpu_resident().data_ready();
fragment->gpu_resident().result_ready();
fragment->gpu_resident().is_launched();
fragment->gpu_resident().tear_down();

setup_component_internals

void holoscan::Application::setup_component_internals(
ComponentBase *component
)

Set up internal state for a component.

Configures the component’s internal references to this fragment and its service provider. This method is called internally when creating operators, resources, conditions, and other components to ensure they have proper access to fragment services.

Parameters

component
ComponentBase *

Pointer to the ComponentBase instance to configure. Must not be nullptr.

driver

AppDriver & holoscan::Application::driver()

Get the application driver.

Returns: The reference to the application driver.

worker

AppWorker & holoscan::Application::worker()

Get the application worker.

Returns: The reference to the application worker.

process_arguments

void holoscan::Application::process_arguments()

reset_state

void holoscan::Application::reset_state() override

Reset internal application state to allow for multiple run calls.

This method resets the necessary internal state to allow multiple consecutive calls to run() or run_async() without requiring manual cleanup.

attach_services_to_fragment

virtual void holoscan::Application::attach_services_to_fragment(
const std::shared_ptr<Fragment> &fragment
)

Attach application services to a specified fragment.

Parameters

fragment
const std::shared_ptr<Fragment> &

The fragment to which services will be attached.

make_config

template <typename ConfigT, typename... ArgsT>
std::shared_ptr<Config> holoscan::Application::make_config(
ArgsT &&... args
)

make_graph

template <typename GraphT>
std::shared_ptr<GraphT> holoscan::Application::make_graph()

make_executor

template <typename ExecutorT, typename... ArgsT>
std::shared_ptr<Executor> holoscan::Application::make_executor(
ArgsT &&... args
)

Create and assign an Executor to the fragment.

reset_backend_objects

void holoscan::Application::reset_backend_objects()

Cleanup helper that will be called by the executor prior to destroying any backend context.

shutdown_data_loggers

void holoscan::Application::shutdown_data_loggers()

Shutdown data loggers to ensure async loggers complete before GXF context destruction.

This method is thread-safe and idempotent - multiple calls will block until the first completes, then return immediately. This ensures proper synchronization between signal handlers and normal shutdown paths.

load_extensions_from_config

void holoscan::Application::load_extensions_from_config()

Load the GXF extensions specified in the configuration.

thread_pools

std::vector<std::shared_ptr<ThreadPool>> & holoscan::Application::thread_pools()

resolve_subgraph_port

std::pair<std::shared_ptr<Operator>, std::string> holoscan::Application::resolve_subgraph_port(
const std::shared_ptr<Subgraph> &subgraph,
const std::string &interface_port
)

Resolve Subgraph interface port to actual operator and port.

Returns: Pair of (operator, actual_port_name) or (nullptr, "") if not found

Parameters

subgraph
const std::shared_ptr<Subgraph> &

The Subgraph to resolve the port in

interface_port
const std::string &

The interface port name

get_operator_output_ports

std::vector<std::string> holoscan::Application::get_operator_output_ports(
const std::shared_ptr<Operator> &op
)

Get output port names from an operator.

get_operator_input_ports

std::vector<std::string> holoscan::Application::get_operator_input_ports(
const std::shared_ptr<Operator> &op
)

Get input port names from an operator.

get_subgraph_output_ports

std::vector<std::string> holoscan::Application::get_subgraph_output_ports(
const std::shared_ptr<Subgraph> &subgraph
)

Get output interface port names from a subgraph.

get_subgraph_input_ports

std::vector<std::string> holoscan::Application::get_subgraph_input_ports(
const std::shared_ptr<Subgraph> &subgraph
)

Get input interface port names from a subgraph.

try_auto_resolve_ports

void holoscan::Application::try_auto_resolve_ports(
const std::vector<std::string> &upstream_ports,
const std::vector<std::string> &downstream_ports,
const std::string &upstream_name,
const std::string &downstream_name,
std::set<std::pair<std::string, std::string>> &port_pairs
)

Attempt auto-resolution of port pairs between two entities.

Throws: std::runtime_error if auto-resolution fails

Parameters

upstream_ports
const std::vector<std::string> &

Output ports from upstream entity

downstream_ports
const std::vector<std::string> &

Input ports from downstream entity

upstream_name
const std::string &

Name of upstream entity (for error messages)

downstream_name
const std::string &

Name of downstream entity (for error messages)

port_pairs
std::set<std::pair<std::string, std::string>> &

Output parameter: will contain the resolved port pair if successful

resolve_and_create_op_to_subgraph_flows

void holoscan::Application::resolve_and_create_op_to_subgraph_flows(
const std::shared_ptr<Operator> &upstream_op,
const std::shared_ptr<Subgraph> &downstream_subgraph,
const std::set<std::pair<std::string, std::string>> &port_pairs,
const IOSpec::ConnectorType connector_type
)

Resolve and create flows for operator-to-subgraph connections.

resolve_and_create_subgraph_to_op_flows

void holoscan::Application::resolve_and_create_subgraph_to_op_flows(
const std::shared_ptr<Subgraph> &upstream_subgraph,
const std::shared_ptr<Operator> &downstream_op,
const std::set<std::pair<std::string, std::string>> &port_pairs,
const IOSpec::ConnectorType connector_type
)

Resolve and create flows for subgraph-to-operator connections.

resolve_and_create_subgraph_to_subgraph_flows

void holoscan::Application::resolve_and_create_subgraph_to_subgraph_flows(
const std::shared_ptr<Subgraph> &upstream_subgraph,
const std::shared_ptr<Subgraph> &downstream_subgraph,
const std::set<std::pair<std::string, std::string>> &port_pairs,
const IOSpec::ConnectorType connector_type
)

Resolve and create flows for subgraph-to-subgraph connections.

validate_control_flow_prerequisites

bool holoscan::Application::validate_control_flow_prerequisites(
const std::shared_ptr<Operator> &upstream_op,
const std::shared_ptr<Operator> &downstream_op,
const IOSpec::ConnectorType connector_type
)

Validate prerequisites for establishing a control flow connection.

Returns: true if validation passes, false otherwise (error message will be logged)

Parameters

upstream_op
const std::shared_ptr<Operator> &

The upstream operator

downstream_op
const std::shared_ptr<Operator> &

The downstream operator

connector_type
const IOSpec::ConnectorType

The connector type (cannot be kAsyncBuffer for control flow)

create_control_flow_connection

void holoscan::Application::create_control_flow_connection(
const std::shared_ptr<Operator> &upstream_op,
const std::shared_ptr<Operator> &downstream_op
)

Create and register a control flow connection between two operators.

This helper creates the port map, sets self_shared on both operators, adds the flow to the graph, and registers it with the executor.

Parameters

upstream_op
const std::shared_ptr<Operator> &

The upstream operator

downstream_op
const std::shared_ptr<Operator> &

The downstream operator

initiate_local_app_shutdown

void holoscan::Application::initiate_local_app_shutdown(
const std::string &fragment_name
)

Initiate shutdown of a local multi-fragment application.

This method initiates an orderly shutdown of fragments running in local mode (multiple fragments in one process). Fragments are terminated in topological order (root/upstream fragments first) to avoid connection errors.

Parameters

fragment_name
const std::string &

The name of the fragment initiating the shutdown (currently unused but kept for API consistency).

is_any_fragment_gpu_resident

bool holoscan::Application::is_any_fragment_gpu_resident()

Check if any fragment in the application’s fragment graph is GPU-resident.

Returns: true if any fragment in the application’s fragment graph is GPU-resident, false otherwise.

set_ucx_env

void holoscan::Application::set_ucx_env()

Configure UCX environment variables.

set_v4l2_env

void holoscan::Application::set_v4l2_env()

check_stack_size

void holoscan::Application::check_stack_size()

Check stack size and warn if below recommended minimum.


Static methods

get_distributed_app_scheduler_env

static expected<SchedulerType, ErrorCode> holoscan::Application::get_distributed_app_scheduler_env()

get_stop_on_deadlock_env

static expected<bool, ErrorCode> holoscan::Application::get_stop_on_deadlock_env()

get_stop_on_deadlock_timeout_env

static expected<int64_t, ErrorCode> holoscan::Application::get_stop_on_deadlock_timeout_env()

get_ucx_network_connection_timeout_env

static expected<int64_t, ErrorCode> holoscan::Application::get_ucx_network_connection_timeout_env()

get_max_duration_ms_env

static expected<int64_t, ErrorCode> holoscan::Application::get_max_duration_ms_env()

get_check_recession_period_ms_env

static expected<double, ErrorCode> holoscan::Application::get_check_recession_period_ms_env()

set_scheduler_for_fragments

static void holoscan::Application::set_scheduler_for_fragments(
std::vector<FragmentNodeType> &target_fragments,
const std::shared_ptr<Scheduler> &app_scheduler = nullptr
)

Set the scheduler for fragments object.

Set scheduler for each fragment to use multi-thread scheduler by default because UcxTransmitter/UcxReceiver doesn’t work with GreedyScheduler with the following graph.

  • Fragment (fragment1) Operator (op1) Output port: out

Operator (op2) Output port: out

  • Operator (op1) Output port: out
    • Output port: out
  • Operator (op2) Output port: out
    • Output port: out
  • Fragment (fragment2) Operator (op3) Input ports in1 in2
    • Operator (op3) Input ports in1 in2
      • Input ports in1 in2
        • in1
        • in2

With the following graph connections, due to how UcxTransmitter/UcxReceiver works, UCX connections between op1 and op3 and between op2 and op3 are not established (resulting in a deadlock).

  • op1.out -> op3.in1
  • op2.out -> op3.in2

Parameters

target_fragments
std::vector<FragmentNodeType> &

The fragments to set the scheduler.

app_scheduler
const std::shared_ptr<Scheduler> &Defaults to nullptr

Optional scheduler set on the Application. If provided and a fragment doesn’t have its own scheduler set, this scheduler will be used for that fragment.


Member variables

NameTypeDescription
app_description_std::stringThe description of the application.
app_version_std::stringThe version of the application.
cli_parser_CLIParserThe command line parser.
argv_std::vector< std::string >The command line arguments after processing flags.
fragment_graph_std::shared_ptr< FragmentFlowGraph >The fragment connection graph.
app_driver_std::shared_ptr< AppDriver >The application driver.
app_worker_std::shared_ptr< AppWorker >The application worker.
is_fragment_graph_composed_bool
name_std::stringThe name of the fragment.
app_Application *The application that this fragment belongs to.
config_std::shared_ptr< Config >The configuration of the fragment.
executor_std::shared_ptr< Executor >The executor for the fragment.
graph_std::shared_ptr< OperatorFlowGraph >The graph of the fragment.
scheduler_std::shared_ptr< Scheduler >Lazily initialized scheduler (mutable for const access).
network_context_std::shared_ptr< NetworkContext >The network_context used by the executor.
data_flow_tracker_std::shared_ptr< DataFlowTracker >The DataFlowTracker for the fragment.
thread_pools_std::vector< std::shared_ptr< ThreadPool > >Any thread pools used by the fragment.
is_composed_boolWhether the graph is composed or not.
is_run_called_boolWhether run() or run_async() has been called.
start_op_std::shared_ptr< Operator >The start operator of the fragment (optional).
data_loggers_std::vector< std::shared_ptr< DataLogger > >Data loggers (optional).
data_loggers_shutdown_mutex_std::mutexMutex to serialize shutdown_data_loggers() calls.
data_loggers_shutdown_complete_boolFlag to track if shutdown has completed.
fragment_service_registry_mutex_std::shared_mutexMutex for thread-safe service registry access.
fragment_services_by_key_std::unordered_map< ServiceKey, std::shared_ptr< FragmentService >, ServiceKeyHash >service registry map
fragment_resource_services_by_name_std::unordered_map< std::string, std::shared_ptr< Resource > >service resource registry map
fragment_resource_to_service_key_map_std::unordered_map< std::shared_ptr< Resource >, ServiceKey >service resource registry map
green_context_pools_std::vector< std::shared_ptr< CudaGreenContextPool > >
subgraph_names_std::unordered_set< std::string >
subgraphs_std::vector< std::shared_ptr< Subgraph > >
metadata_policy_MetadataPolicy
is_metadata_enabled_bool