Class Subgraph
Defined in File subgraph.hpp
-
class Subgraph
A reusable subgraph that directly populates a Fragment’s operator graph.
Subgraph receives Fragment* during construction and directly adds operators and flows to the Fragment’s main graph during compose().
Usage example:
class CameraSubgraph : public Subgraph { public: CameraSubgraph(Fragment* fragment, const std::string& name) : Subgraph(fragment, name) {} void compose() override { auto source = make_operator<V4L2VideoOp>("source", from_config("v4l2")); auto converter = make_operator<FormatConverterOp>("converter", from_config("format_converter")); add_flow(source, converter); // Directly added to Fragment's main graph // Expose interface ports for external connections // The "tensor" output port of converter will be exposed as "video_out" add_output_interface_port("video_out", converter, "tensor"); } }; // In Fragment::compose(): // Note that for subgraph name "camera1" and "camera2", the operator names will become // "camera1_source", "camera2_source", "camera1_converter", "camera2_converter". auto camera1 = make_subgraph<CameraSubgraph>("camera1"); auto camera2 = make_subgraph<CameraSubgraph>("camera2"); auto visualizer = make_operator<HolovizOp>("visualizer", from_config("holoviz")); // Direct connection to other operators (or subgraphs) via interface ports add_flow(camera1, visualizer, {{"video_out", "receivers"}}); add_flow(camera2, visualizer, {{"video_out", "receivers"}});
Public Functions
-
Subgraph(Fragment *fragment, const std::string &name, const std::string &config_file = "")
Construct Subgraph with target Fragment.
- Parameters
fragment – Target Fragment to populate with operators
name – Unique instance name for operator qualification
config_file – Optional path to a YAML configuration file for this subgraph. If provided, the configuration is loaded before compose() is called, making from_config() available during composition.
-
virtual ~Subgraph() = default
-
virtual void compose() = 0
Define the internal structure of the subgraph.
This method should create operators and flows, which will be directly added to the Fragment’s main graph with qualified names.
-
inline const std::string &name() const
Get the name for this subgraph.
-
inline const std::string &instance_name() const
Get the instance name for this subgraph.
- Deprecated:
Use name() instead. This method will be removed in a future release.
-
inline Fragment *fragment()
Get the Fragment that this subgraph belongs to.
- Returns
Pointer to the fragment this subgraph belongs to
-
inline const Fragment *fragment() const
Get the Fragment that this subgraph belongs to (const version)
- Returns
Const pointer to the fragment this subgraph belongs to
-
inline std::string get_qualified_name(const std::string &object_name, const std::string &type_name = "operator") const
Create qualified operator name: subgraph_name + “_” + operator_name.
Register an existing service instance with the fragment.
Registers an already created service instance with the fragment. This allows the service to be retrieved later using Fragment::service().
- Template Parameters
ServiceT – The type of the service (must inherit from Resource or FragmentService).
- Parameters
svc – The shared pointer to the service instance to register.
id – The identifier for the service registration. If empty, uses the service type or resource name as identifier.
- Returns
true if the service was successfully registered, false otherwise.
Create a nested subgraph within this subgraph.
This enables hierarchical Subgraph composition. The nested Subgraph will use the same Fragment* and will have its operators added directly to the Fragment’s main graph with hierarchical qualified names (parent_name_child_name_operator).
- Template Parameters
SubgraphT – The nested subgraph class type
- Parameters
child_name – Name for the nested subgraph
args – Additional arguments for the nested subgraph constructor
- Returns
Shared pointer to the nested subgraph
Add an operator to the Fragment’s main graph with qualified name.
This directly calls fragment_->add_operator() with a qualified name, eliminating the need for intermediate graph storage.
Add a subgraph to the Fragment.
This method ensures the subgraph is composed and its operators are added to the fragment. Use this method when a nested subgraph has no interface ports and doesn’t need to be connected to other operators or subgraphs via add_flow.
- Parameters
subgraph – The subgraph to be added.
Add a flow between two operators directly in the Fragment’s main graph.
This directly calls fragment_->add_flow(), eliminating the need for intermediate flow storage.
Connect Operator to Subgraph within this Subgraph.
- Parameters
upstream_op – The upstream operator
downstream_subgraph – The downstream subgraph
port_pairs – Port connections: {upstream_port, subgraph_interface_port}
Connect Subgraph to Operator within this Subgraph.
- Parameters
upstream_subgraph – The upstream subgraph
downstream_op – The downstream operator
port_pairs – Port connections: {subgraph_interface_port, downstream_port}
Connect Subgraph to Subgraph within this Subgraph.
- Parameters
upstream_subgraph – The upstream subgraph
downstream_subgraph – The downstream subgraph
port_pairs – Port connections: {upstream_interface_port, downstream_interface_port}
Connect Operator to Subgraph with connector type.
- Parameters
upstream_op – The upstream operator
downstream_subgraph – The downstream subgraph
connector_type – The connector type
Connect Operator to Subgraph with port pairs and connector type.
- Parameters
upstream_op – The upstream operator
downstream_subgraph – The downstream subgraph
port_pairs – Port connections: {upstream_port, subgraph_interface_port}
connector_type – The connector type
Connect Subgraph to Operator with connector type.
- Parameters
upstream_subgraph – The upstream subgraph
downstream_op – The downstream operator
connector_type – The connector type
Connect Subgraph to Operator with port pairs and connector type.
- Parameters
upstream_subgraph – The upstream subgraph
downstream_op – The downstream operator
port_pairs – Port connections: {subgraph_interface_port, downstream_port}
connector_type – The connector type
Connect Subgraph to Subgraph with connector type.
- Parameters
upstream_subgraph – The upstream subgraph
downstream_subgraph – The downstream subgraph
connector_type – The connector type
Connect Subgraph to Subgraph with port pairs and connector type.
- Parameters
upstream_subgraph – The upstream subgraph
downstream_subgraph – The downstream subgraph
port_pairs – Port connections: {upstream_interface_port, downstream_interface_port}
connector_type – The connector type
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 – The operator to set dynamic flows for
dynamic_flow_func – The callback function that defines the dynamic flows. Takes a shared pointer to the operator as input and returns void.
Add a data logger to the fragment.
This method dispatches to the fragment’s add_data_logger method.
- Parameters
logger – The data logger to add.
Add an interface port that can be connected from external Subgraphs/Operators.
Validates that the internal operator has the specified port. If is_input is not specified, the method automatically detects whether the port is an input or output. If the port name exists in both inputs and outputs, a runtime_error is thrown requiring explicit specification.
- Parameters
external_name – The name of the interface port (used in add_flow calls)
internal_op – The internal operator that owns the actual port
internal_port – The port name on the internal operator (defaults to external_name if not specified)
is_input – Whether this is an input port (true) or output port (false). If not specified, the port direction is auto-detected from the operator’s port definitions.
Add an input interface port (convenience method)
- Parameters
external_name – The name of the interface port (used in add_flow calls)
internal_op – The internal operator that owns the actual port
internal_port – The port name on the internal operator (defaults to external_name if not specified)
Add an output interface port (convenience method)
- Parameters
external_name – The name of the interface port (used in add_flow calls)
internal_op – The internal operator that owns the actual port
internal_port – The port name on the internal operator (defaults to external_name if not specified)
Add an interface port that exposes a nested subgraph’s interface port.
This method enables hierarchical port composition by exposing an interface port from a nested subgraph as an external interface port of the current subgraph. The nested subgraph’s interface port is resolved to find the underlying operator and port, which are then registered as the current subgraph’s interface port.
If is_input is not specified, the port direction is auto-detected from the nested subgraph’s interface port definition.
- Parameters
external_name – The name of the interface port (used in add_flow calls)
internal_subgraph – The nested subgraph whose interface port to expose
internal_interface_port – The interface port name on the nested subgraph (defaults to external_name if not specified)
is_input – Whether this is an input port (true) or output port (false). If not specified, the port direction is auto-detected from the nested subgraph’s interface port.
Add an input interface port from a nested subgraph (convenience method)
- Parameters
external_name – The name of the interface port (used in add_flow calls)
internal_subgraph – The nested subgraph whose interface port to expose
internal_interface_port – The interface port name on the nested subgraph (defaults to external_name if not specified)
Add an output interface port from a nested subgraph (convenience method)
- Parameters
external_name – The name of the interface port (used in add_flow calls)
internal_subgraph – The nested subgraph whose interface port to expose
internal_interface_port – The interface port name on the nested subgraph (defaults to external_name if not specified)
Add an input execution interface port for control flow.
Exposes an execution port from an internal operator for control flow connections. The internal operator must be a Native operator with an input execution spec.
- Parameters
external_name – The name of the interface port (used in add_flow calls)
internal_op – The internal operator that has the execution port
Add an output execution interface port for control flow.
Exposes an execution port from an internal operator for control flow connections. The internal operator must be a Native operator with an output execution spec.
- Parameters
external_name – The name of the interface port (used in add_flow calls)
internal_op – The internal operator that has the execution port
Add an input execution interface port from a nested subgraph.
Exposes an execution interface port from a nested subgraph as this subgraph’s execution interface port, enabling hierarchical control flow composition.
- Parameters
external_name – The name of the interface port (used in add_flow calls)
internal_subgraph – The nested subgraph whose exec interface port to expose
internal_interface_port – The exec interface port name on the nested subgraph (defaults to external_name if not specified)
Add an output execution interface port from a nested subgraph.
Exposes an execution interface port from a nested subgraph as this subgraph’s execution interface port, enabling hierarchical control flow composition.
- Parameters
external_name – The name of the interface port (used in add_flow calls)
internal_subgraph – The nested subgraph whose exec interface port to expose
internal_interface_port – The exec interface port name on the nested subgraph (defaults to external_name if not specified)
-
inline const std::unordered_map<std::string, InterfacePort> &interface_ports() const
Get data interface ports.
Returns a map of interface port names to InterfacePort objects. Each InterfacePort can contain multiple mappings for broadcast input ports.
-
inline const std::unordered_map<std::string, InterfacePort> &exec_interface_ports() const
Get execution interface ports.
-
std::pair<std::shared_ptr<Operator>, std::string> get_interface_operator_port(const std::string &port_name) const
Get the first operator/port for a data interface port name.
This method first checks local interface ports, then recursively checks nested subgraphs for hierarchical port resolution.
For broadcast input ports that have multiple mappings, this returns only the first mapping. Access the InterfacePort directly via interface_ports() to get all mappings.
- Parameters
port_name – The interface port name
- Returns
Pair of (operator, actual_port_name) or (nullptr, “”) if not found
-
std::pair<std::shared_ptr<Operator>, std::string> get_exec_interface_operator_port(const std::string &port_name) const
Get the operator/port for an execution interface port name.
This method first checks local exec interface ports, then recursively checks nested subgraphs for hierarchical port resolution.
- Parameters
port_name – The exec interface port name
- Returns
Pair of (operator, actual_port_name) or (nullptr, “”) if not found
-
inline bool is_composed() const
Check if the subgraph has been composed.
-
inline void set_composed(bool composed)
Set the composed state of the subgraph.
-
std::vector<std::shared_ptr<Operator>> operators() const
Get all operators belonging to this subgraph and its nested subgraphs.
This method returns all operators whose names are prefixed with this subgraph’s name followed by an underscore. This includes operators from nested subgraphs since their names are also prefixed with the parent subgraph’s name.
- Returns
Vector of shared pointers to the operators.
-
Config &config()
Get the configuration of the subgraph.
- Returns
The reference to the configuration of the subgraph (
Configobject.)
Get the shared pointer to the configuration of the subgraph.
- Returns
The shared pointer to the configuration of the subgraph.
-
ArgList from_config(const std::string &key)
Get the value of a configuration key as an ArgList.
This method retrieves the value from the subgraph’s configuration for the given key. You can use ‘.’ (dot) to access nested fields. The returned ArgList can be passed directly to make_operator() or other methods that accept configuration arguments.
Example usage:
auto op = make_operator<MyOp>("my_op", from_config("my_op"));
- Parameters
key – The key of the configuration.
- Returns
The argument list of the configuration for the key.
-
std::unordered_set<std::string> config_keys()
Determine the set of keys present in the subgraph’s config.
- Returns
The set of valid keys.
Protected Functions
-
void config(const std::string &config_file, const std::string &prefix = "")
Set the configuration of the subgraph from a file.
The configuration file is a YAML file that contains parameter values that can be accessed via from_config(). This is useful when a subgraph needs its own configuration separate from the main application configuration.
NoteNoteLoading GXF extensions is not supported from the subgraph config file. GXF extensions should be loaded via the application-level configuration only.
- Parameters
config_file – The path to the configuration file.
prefix – The prefix string that is prepended to the key of the configuration.
- Throws
RuntimeError – if the config_file is non-empty and the file doesn’t exist.
-
Subgraph(Fragment *fragment, const std::string &name, const std::string &config_file = "")