Giter Site home page Giter Site logo

ros-acceleration / adaptive_component Goto Github PK

View Code? Open in Web Editor NEW
10.0 3.0 5.0 35 KB

A composable container for Adaptive ROS 2 Node computations. Select between FPGA, CPU or GPU at run-time.

License: Apache License 2.0

CMake 14.01% C++ 85.99%
ros ros2 hardware-acceleration adaptive som robotics component node fpga gpu cpu

adaptive_component's Introduction

adaptive_component

A composable stateless container for Adaptive ROS 2 Node computations. Select between FPGA, CPU or GPU at run-time.

Nodes using hardware acceleration are able to perform computations faster relying on FPGAs or GPUs, improving performance. Adaptive ROS 2 Nodes leverage hardware acceleration at run-time, allowing robotics engineers to select which computational resource the Node uses on-the-go, giving roboticists a finer-grained control over the resources their computional graphs use in the underlying hardware.

This ROS 2 package provides a composable stateless container for Adaptive ROS 2 Node computations: adaptive_component. It allows building Nodes that can select between FPGA, CPU or GPU, at run-time.

Technically, it's a ROS 2 Node1 subclass programmed as a Component2 and including its own single threaded executor to build adaptive computations. Adaptive ROS 2 Nodes can then be built easily and are able to perform computations in the CPU, the FPGA or the GPU. Adaptive behavior is controlled through the adaptive ROS 2 parameter, with the following values allowed:

  • 0: Hardware::CPU
  • 1: Hardware::FPGA
  • 2: Hardware::GPU

adaptive_component is stateless by default, if you need your Adaptive Nodes to be stateful, feel free to inherit from composition::AdaptiveComponent and create your own stateful subclasses3.

How does it work?

asciicast

using NodeCPU = composition::DoubleVaddComponent;
using NodeFPGA = composition::DoubleVaddComponentFPGA;

rclcpp::NodeOptions options;

// Create an executor
rclcpp::executors::MultiThreadedExecutor exec;

// Create an adaptive ROS 2 Node using "components", the resulting
// Node is also programed as a "component", retaining composability
auto adaptive_node = std::make_shared<composition::AdaptiveComponent>(
      "doublevadd_publisher_adaptive",        
      options,                                
                                              // CPU
      std::make_shared<NodeCPU>("_doublevadd_publisher_adaptive_cpu", options),
                                              // FPGA
      std::make_shared<NodeFPGA>("_doublevadd_publisher_adaptive_fpga", options),
                                              // GPU
      nullptr);

exec.add_node(adaptive_node);  // fill up the executor
exec.spin();  // spin the executor

Then, dynamically, one could switch from CPU to FPGA by setting the adaptive parameter in the /doublevadd_publisher_adaptive Node:

  • To run in the CPU: ros2 param set /doublevadd_publisher_adaptive adaptive 0
  • To run in the FPGA: ros2 param set /doublevadd_publisher_adaptive adaptive 1

Why should I care as a ROS package maintainer?

The integration of hardware acceleration into ROS often requires rewriting parts of the Node computations to further exploit parallelism. These changes often conflict with CPU-centric architectures and as a maintainer, you're likely to care for "not breaking" CPU-centric implementations.

To consistently integrate hardware acceleration, avoid unnecessary forks and discourage package fragmentation, composition::AdaptiveComponent allows to extend ROS 2 CPU-centric Nodes4 with their computational counterparts separating concerns at build-time. From a package-maintenance perspective, each Node (across computation options) is written in a separated file and as a separated Component. These can live either within the same package, or in totally different (disconnected) ones. adaptive_component takes care of putting them together at launch time and no dependency with the package is required at build-time5.

From an execution perspective, developers can easily create Adaptive ROS 2 Nodes and compose them together as desired at launch-time, with capabilities to adaptively switch between compute alternatives at run-time.

Some examples

Examples of using adaptive_component:

Conventions and recommendations

The following conventions and recommendations are meant to facilitate the integration of hardware acceleration in existing ROS packages

  1. Component-oriented: AdaptiveComponent is built as a component and should be used as such to maintain composability of Nodes.
  2. Naming: The Adaptive Node should be suffix with _adaptive to identify in the computational graph which Nodes have adaptive capabilities and which do not.
  3. Hidden sub-Nodes: Adaptive Node components (compute-specific ones e.g. CPU's or FPGA's) should be named with a hyphen (_) as a prefix, which will make them hidden Nodes by default.
  4. File names: When possible, source code file names should adhere to the following guidelines:
    • CPU-based computational Nodes can optionally add the _cpu suffix
    • FPGA-based computational Nodes shall add the _fpga suffix
    • GPU-based computational Nodes shall add the _gpu suffix

Quality Declaration

This package claims to be in the Quality Level 4 category, see the Quality Declaration for more details.

Footnotes

  1. A Node is a process that performs computations. ROS 2 is designed to be modular at a fine-grained scale; a robot control system usually comprises many nodes. Nodes execute arbitrary logic that contribute to the overall robotics behavior.

  2. A ROS 2 Component is a Node compiled into a shared library which is then loaded at runtime by a container process. This offers roboticists additional flexibility while building their computational graphs, making the layout process a deploy-time decision. A Component is commonly a subclass of rclcpp::Node. To maintain flexibility and modularity, Components shouldn’t perform any long running or blocking tasks in their constructors. Instead, they can use timers to get periodic notifications and use callbacks for publishers, subscribers, servers, or clients.

  3. See this example (ROS 2 component).

  4. Assumes Nodes are written as components, but it they are not, it's a great chance to do so ;).

  5. Though adaptive_component allows to disconnect nodes across packages, to facilitate source code maintenance across CPU-centric implementations and counterparts, it should be encouraged to keep the source code within the same ROS 2 package with suffixes indicating of the compute substrate (e.g. _fpga.cpp, etc.). This will facilitate maintaining implementations across different compute substrates, avoid versioning issues and fragmentation issues.

adaptive_component's People

Contributors

methyldragon avatar vmayoral avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

adaptive_component's Issues

Question: Sharing of Parameters

If I understood correctly, this adaptive component is a way to expose an interface to swap between node components dynamically.

What is the intended interaction with the parameter system for the implemented nodes for the different architectures? Are parameters meant to be bound to the adaptive component (essentially the node manager), or is the intention to have the parameters bound to the architecture specific nodes instead?

Question: Multiple Nodes of a Single Architecture

Is there a case where a user might want to have multiple sub-nodes of a similar architecture? (e.g. two GPUs, swapping between them.)

It doesn't look like this adaptive component is able to handle that case, since it manages swapping of architectures only. Is this intended?

Release Process! (RELEASED! PENDING SYNC) :green_circle:

[STATUS: PENDING SYNC PR UPDATE]

Buildfarm Status

  • Build Status dev (ubuntu_jammy_amd64)
  • Build Status doc (ubuntu_jammy_amd64)
  • Build Status src (rhel_8)
  • Build Status src (ubuntu_jammy)
  • Build Status bin (ubuntu_jammy_amd64)
  • Build Status bin (rhel_8_x86_64)
  • Build Status bin (ubuntu_jammy_arm64)

Description

This issue tracks the status for the release of this repository into rosdistro and making it available for installation as .deb via the ROS 2 repositories.

It will detail the steps that need to be taken, and what recommended changes are good to have.

Release Process

Steps

Recommendations

  • RELYING ON DOCS INSTEAD: Implement parameter sharing functionality #2
  • Export targets

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.