Beyond ament_auto
#3491
Replies: 5 comments 9 replies
-
Thank you for your work and proposal! @xmfcx @mitsudome-r @yukkysaito What do you think? |
Beta Was this translation helpful? Give feedback.
-
Just to add a few details, I don't only propose to move away from So, implementing an ament_auto "v2" (whether it is a fork or a new package) would also be the opportunity to add "missing" features, or improve the macros behavior. A few examples:
find_package(PCL REQUIRED)
target_include_directories(myTarget ${PCL_INCLUDE_DIRS})
target_link_libraries(myTarget ${PCL_LIBRARIES}) and forget about
|
Beta Was this translation helpful? Give feedback.
-
Wow this was a lot to take in lol. So, a lot of time is spent on:
And also you've created this ament_cmake_extension package and also modified your fork of Autoware Universe to make use of it. Since I'm not too experienced with CMake that much, replacing ament_cmake_auto with ament_cmake_extension which is built from ground up scares me a bit.
What about something between 3 and 4?
This is because I find it risky to make such a drastic change. What do you think @VRichardJP @kenji-miyake ? |
Beta Was this translation helpful? Give feedback.
-
I've also tried to do the same and ended up with the same result. Do you think is it possible to speed up the |
Beta Was this translation helpful? Give feedback.
-
From all the discussion, I came to realize maybe the fork option is the simplest and the least scary solution (from autoware project PoV) Now Iron is about to be released, I guess there is a chance some of the key features can be pushed to the
Because the |
Beta Was this translation helpful? Give feedback.
-
Context
Autoware uses extensively the
ament_auto
macros. Unfortunately, these macros are slow when packages have a lot of dependencies, which is the case of many Autoware packages. For example, this is what cmake execution onbehavior_path_planner
looks like:This problem could be fixed upstream, however a fix would not land until the next next release of ROS2 (not Iron, but J release). In other words, we can't expect an upstream fix before the next 1~2 years :(
How much time is spent in CMake exactly?
You can build Autoware with
--profiling-format=google-trace --profiling-output=cmake_profile.json
to trace cmake execution on each package. There are a lot of packages, so you can use this simple script to quickly find which packages are slow:Reported value is ~CPU time in microseconds:
$ ./min_max_profile.sh | sort -k2 -n build/autoware_lint_common/cmake_profile.json 353345 build/autoware_cmake/cmake_profile.json 492184 build/tier4_planning_launch/cmake_profile.json 671057 build/livox_description/cmake_profile.json 695467 build/map4_localization_launch/cmake_profile.json 705889 ... build/eagleye_rt/cmake_profile.json 57116249 build/behavior_path_planner/cmake_profile.json 65776780 build/behavior_velocity_planner/cmake_profile.json 77437622 build/trajectory_follower_node/cmake_profile.json 89506475 build/static_centerline_optimizer/cmake_profile.json 120522910
In total, that is 2528 seconds (~42 minutes) of ~CPU time spent in CMake on my machine (if you have 8 cores on your machine and live in a perfect world, that is at least 5 minutes). Of course it is not possible to reduce this time to 0, but I hope I can convince everyone there might be some room for improvement on the cmake side. As reported on the
ament_cmake
github issue, CMake is slowed down by 2 things:find_package
: this is a tricky problem to solve, because dependencies are always added, never removed. So the deeper a package is, the longer it will take to find all dependencies. Essentially, the only way to make this faster is for ament to generate faster FindXXX.cmake files. I have recently made a PR that drastically reducefind_package()
processing time.ament_auto_add_library
/ament_auto_add_executable
: this is due to the ament auto macros going through the same dependencies over and over. It does not have to be like this, and it could be easily fixed by using modern CMake targets.For the slow
find_package
, there is a some chance the fix will land on humble. But for the slowament_auto
macros, the fix would not be available until J ROS2 release.Ok, so what do we do?
Option 1: bear with the long cmake time until
ament_auto
macros are fixed.Option 2: get rid of
ament_auto
macros, and use baseament_cmake
macros instead.Option 3: fork of
ament_auto
, and fix the fork.Option 4: use an alternative to "ament_auto" macros, that would be simple, fast and perfectly fit autoware's use case.
Option 1 is simple, but you can guess it is not my favorite.
Option 2 would be a regression in my opinion. It would solve the speed issue, but would also inflate all cmake files and increase the chances of messing up packages (i.e. most likely require more maintenance).
Option 3 could be a decent option. However, changing the behavior of "ament_auto" macros would impact all packages, not just autoware packages, so it would mean maintaining backward compatibility (the reason the upstream "ament_auto" would not add breaking changes to its humble release in the first place).
I let you guess which option I worked on :-)
An alternative to ament_auto
Over the last few days, I have written a PoC
ament_cmake_extension
package. It serves the same purpose thanament_cmake_auto
: to provide an easy-to-use abstraction layer on top ofament_cmake
base macros. Its API is very close toament_cmake_auto
, so transitioning fromament_cmake_auto
is often just a matter of a fewsed
. In my opinion, it provides a simpler, faster and more foolproof API than "ament_auto" macros. One key difference is that it uses exclusively modern CMake targets instead of the classic_LIBRARIES
,_INCLUDE_DIRS
and_DEFINITIONS
variables, which makes cmake files both cleaner and faster.It creates valid ament packages, so it is possible to mix packages created with
ament_cmake_auto
andament_cmake_extension
. In order to test it in Autoware, I have added a simple option toautoware_cmake()
macros, so that it is simple to switch between the two APIs:To use
ament_ex
macros instead ofament_auto
, just addUSE_AMENT_EX
flag toautoware_package()
:As I reported in the original issue, a few adjustments are necessary on autoware cmake files side. This is because many packages create ill-formed targets, or rely on dirty hacks that break as soon as you try to export/import targets. Fixing the cmake files is a bit boring but not difficult. Once it's done, we end up with very clean cmake files and of course fast build!
Is it really faster?
As proof-of-concept, I have applied this PR, sed-ed all autoware.universe packages to make use of
ament_ex
macros, then spent a couple hours fixing all the build issues. If you are curious howament_ex
macros are used, I have pushed my changes here: https://github.com/VRichardJP/autoware.universe/tree/ament_exUsing the same script to report each cmake invocation time, now I get:
$ ./min_max_profile.sh | sort -k2 -n build/autoware_lint_common/cmake_profile.json 321976 build/ament_cmake_extension/cmake_profile.json 365491 build/map4_localization_launch/cmake_profile.json 631369 build/tier4_planning_launch/cmake_profile.json 658787 build/autoware_cmake/cmake_profile.json 688222 ... build/tensorrt_yolox/cmake_profile.json 12911722 build/heatmap_visualizer/cmake_profile.json 13489099 build/static_centerline_optimizer/cmake_profile.json 15131815 build/tensorrt_yolo/cmake_profile.json 20309413 build/obstacle_velocity_limiter/cmake_profile.json 36402255
The total CPU time is now 1057 seconds (~18 minutes), more than twice as fast!.
Note: For this experimentation I have only modified autoware.universe packages. Other packages would gain from using
ament_ex
macros, but maybe not as much.This is what the cmake trace looks like on
behavior_path_planner
now (to compare with the old one above):And clean build are of course faster:
It's more than 10% faster. Not only CMake execution is faster, but also the compilation itself.
A transition would takes some time (~250 packages...), but I think the long term gain is worth it.
What do you think?
Beta Was this translation helpful? Give feedback.
All reactions