From 7e548e7e29766ac246f3d0a90cf37bf3fdfe02c9 Mon Sep 17 00:00:00 2001 From: Victor Reijgwart Date: Thu, 14 Nov 2024 18:33:05 +0100 Subject: [PATCH 01/12] Report CPU, wall time and RAM usage when rosbag_processor completes --- .../ros1/wavemap_ros/app/rosbag_processor.cc | 18 ++++- .../impl/publish_map_operation_inl.h | 2 +- .../src/inputs/depth_image_topic_input.cc | 2 +- .../src/inputs/pointcloud_topic_input.cc | 2 +- .../map_operations/publish_map_operation.cc | 2 +- .../publish_pointcloud_operation.cc | 2 +- .../src/utils/pointcloud_undistorter.cc | 2 +- .../wavemap_ros/src/utils/rosbag_processor.cc | 2 +- .../src/map_msg_conversions.cc | 2 +- .../src/visuals/voxel_visual.cc | 2 +- .../src/wavemap_map_display.cc | 2 +- .../utils/{ => profile}/profiler_interface.h | 6 +- .../utils/profile/resource_usage_monitor.h | 41 ++++++++++ .../wavemap/core/utils/time/stopwatch.h | 2 +- library/cpp/src/core/CMakeLists.txt | 1 + .../hashed_chunked_wavelet_integrator.cc | 2 +- .../hashed_wavelet_integrator.cc | 2 +- .../projective/projective_integrator.cc | 2 +- .../core/map/hashed_chunked_wavelet_octree.cc | 2 +- .../hashed_chunked_wavelet_octree_block.cc | 2 +- .../cpp/src/core/map/hashed_wavelet_octree.cc | 2 +- .../core/map/hashed_wavelet_octree_block.cc | 2 +- .../utils/profile/resource_usage_monitor.cc | 75 +++++++++++++++++++ .../src/core/utils/query/classified_map.cc | 2 +- .../utils/sdf/full_euclidean_sdf_generator.cc | 2 +- .../sdf/quasi_euclidean_sdf_generator.cc | 2 +- library/cpp/src/core/utils/thread_pool.cc | 2 +- library/cpp/src/core/utils/time/stopwatch.cc | 8 +- 28 files changed, 163 insertions(+), 30 deletions(-) rename library/cpp/include/wavemap/core/utils/{ => profile}/profiler_interface.h (75%) create mode 100644 library/cpp/include/wavemap/core/utils/profile/resource_usage_monitor.h create mode 100644 library/cpp/src/core/utils/profile/resource_usage_monitor.cc diff --git a/interfaces/ros1/wavemap_ros/app/rosbag_processor.cc b/interfaces/ros1/wavemap_ros/app/rosbag_processor.cc index 295889dfb..438b75d76 100644 --- a/interfaces/ros1/wavemap_ros/app/rosbag_processor.cc +++ b/interfaces/ros1/wavemap_ros/app/rosbag_processor.cc @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "wavemap_ros/inputs/depth_image_topic_input.h" @@ -75,13 +76,28 @@ int main(int argc, char** argv) { rosbag_processor.enableSimulatedClock(nh); } + // Start measuring resource usage + ResourceMonitor resource_monitor; + resource_monitor.start(); + // Process the rosbag if (!rosbag_processor.processAll()) { return -1; } - wavemap_server.getMap()->prune(); + // Finish processing the map wavemap_server.getPipeline().runOperations(/*force_run_all*/ true); + wavemap_server.getMap()->prune(); + + // Report the resource usage + resource_monitor.stop(); + LOG(INFO) << "Processing complete.\nResource usage:\n* RAM total: " + << ResourceMonitor::getCurrentRamUsageInKB().value_or(0u) + << " kB\n* Map size: " + << wavemap_server.getMap()->getMemoryUsage() / 1000 + << " kB\n* CPU time: " << resource_monitor.getLastEpisodeCpuTime() + << " s\n* Wall time: " << resource_monitor.getLastEpisodeWallTime() + << " s\n"; if (nh_private.param("keep_alive", false)) { ros::spin(); diff --git a/interfaces/ros1/wavemap_ros/include/wavemap_ros/map_operations/impl/publish_map_operation_inl.h b/interfaces/ros1/wavemap_ros/include/wavemap_ros/map_operations/impl/publish_map_operation_inl.h index 73010269b..7aa1d1f0d 100644 --- a/interfaces/ros1/wavemap_ros/include/wavemap_ros/map_operations/impl/publish_map_operation_inl.h +++ b/interfaces/ros1/wavemap_ros/include/wavemap_ros/map_operations/impl/publish_map_operation_inl.h @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include diff --git a/interfaces/ros1/wavemap_ros/src/inputs/depth_image_topic_input.cc b/interfaces/ros1/wavemap_ros/src/inputs/depth_image_topic_input.cc index 0b8d8d45d..8b168bf88 100644 --- a/interfaces/ros1/wavemap_ros/src/inputs/depth_image_topic_input.cc +++ b/interfaces/ros1/wavemap_ros/src/inputs/depth_image_topic_input.cc @@ -13,7 +13,7 @@ #include #include #include -#include +#include namespace wavemap { DECLARE_CONFIG_MEMBERS(DepthImageTopicInputConfig, diff --git a/interfaces/ros1/wavemap_ros/src/inputs/pointcloud_topic_input.cc b/interfaces/ros1/wavemap_ros/src/inputs/pointcloud_topic_input.cc index 2cedb59bd..3044f5863 100644 --- a/interfaces/ros1/wavemap_ros/src/inputs/pointcloud_topic_input.cc +++ b/interfaces/ros1/wavemap_ros/src/inputs/pointcloud_topic_input.cc @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include namespace wavemap { diff --git a/interfaces/ros1/wavemap_ros/src/map_operations/publish_map_operation.cc b/interfaces/ros1/wavemap_ros/src/map_operations/publish_map_operation.cc index d2f07fe6c..e44f48a53 100644 --- a/interfaces/ros1/wavemap_ros/src/map_operations/publish_map_operation.cc +++ b/interfaces/ros1/wavemap_ros/src/map_operations/publish_map_operation.cc @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include diff --git a/interfaces/ros1/wavemap_ros/src/map_operations/publish_pointcloud_operation.cc b/interfaces/ros1/wavemap_ros/src/map_operations/publish_pointcloud_operation.cc index 0cb1c3457..4928d232e 100644 --- a/interfaces/ros1/wavemap_ros/src/map_operations/publish_pointcloud_operation.cc +++ b/interfaces/ros1/wavemap_ros/src/map_operations/publish_pointcloud_operation.cc @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include namespace wavemap { diff --git a/interfaces/ros1/wavemap_ros/src/utils/pointcloud_undistorter.cc b/interfaces/ros1/wavemap_ros/src/utils/pointcloud_undistorter.cc index a93c3e2f9..d7e3106a2 100644 --- a/interfaces/ros1/wavemap_ros/src/utils/pointcloud_undistorter.cc +++ b/interfaces/ros1/wavemap_ros/src/utils/pointcloud_undistorter.cc @@ -2,7 +2,7 @@ #include -#include +#include #include #include diff --git a/interfaces/ros1/wavemap_ros/src/utils/rosbag_processor.cc b/interfaces/ros1/wavemap_ros/src/utils/rosbag_processor.cc index fafbcbd0d..158fb0319 100644 --- a/interfaces/ros1/wavemap_ros/src/utils/rosbag_processor.cc +++ b/interfaces/ros1/wavemap_ros/src/utils/rosbag_processor.cc @@ -2,7 +2,7 @@ #include -#include +#include namespace wavemap { RosbagProcessor::~RosbagProcessor() { diff --git a/interfaces/ros1/wavemap_ros_conversions/src/map_msg_conversions.cc b/interfaces/ros1/wavemap_ros_conversions/src/map_msg_conversions.cc index d29fda8b5..441aec583 100644 --- a/interfaces/ros1/wavemap_ros_conversions/src/map_msg_conversions.cc +++ b/interfaces/ros1/wavemap_ros_conversions/src/map_msg_conversions.cc @@ -7,7 +7,7 @@ #include #include -#include +#include namespace wavemap::convert { bool mapToRosMsg(const MapBase& map, const std::string& frame_id, diff --git a/interfaces/ros1/wavemap_rviz_plugin/src/visuals/voxel_visual.cc b/interfaces/ros1/wavemap_rviz_plugin/src/visuals/voxel_visual.cc index b32973a97..1b7fe412c 100644 --- a/interfaces/ros1/wavemap_rviz_plugin/src/visuals/voxel_visual.cc +++ b/interfaces/ros1/wavemap_rviz_plugin/src/visuals/voxel_visual.cc @@ -10,7 +10,7 @@ #include #include #include -#include +#include namespace wavemap::rviz_plugin { VoxelVisual::VoxelVisual(Ogre::SceneManager* scene_manager, diff --git a/interfaces/ros1/wavemap_rviz_plugin/src/wavemap_map_display.cc b/interfaces/ros1/wavemap_rviz_plugin/src/wavemap_map_display.cc index 948ce16df..a9452c92e 100644 --- a/interfaces/ros1/wavemap_rviz_plugin/src/wavemap_map_display.cc +++ b/interfaces/ros1/wavemap_rviz_plugin/src/wavemap_map_display.cc @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include diff --git a/library/cpp/include/wavemap/core/utils/profiler_interface.h b/library/cpp/include/wavemap/core/utils/profile/profiler_interface.h similarity index 75% rename from library/cpp/include/wavemap/core/utils/profiler_interface.h rename to library/cpp/include/wavemap/core/utils/profile/profiler_interface.h index 9362b4938..000976857 100644 --- a/library/cpp/include/wavemap/core/utils/profiler_interface.h +++ b/library/cpp/include/wavemap/core/utils/profile/profiler_interface.h @@ -1,5 +1,5 @@ -#ifndef WAVEMAP_CORE_UTILS_PROFILER_INTERFACE_H_ -#define WAVEMAP_CORE_UTILS_PROFILER_INTERFACE_H_ +#ifndef WAVEMAP_CORE_UTILS_PROFILE_PROFILER_INTERFACE_H_ +#define WAVEMAP_CORE_UTILS_PROFILE_PROFILER_INTERFACE_H_ #ifdef TRACY_ENABLE @@ -29,4 +29,4 @@ #endif -#endif // WAVEMAP_CORE_UTILS_PROFILER_INTERFACE_H_ +#endif // WAVEMAP_CORE_UTILS_PROFILE_PROFILER_INTERFACE_H_ diff --git a/library/cpp/include/wavemap/core/utils/profile/resource_usage_monitor.h b/library/cpp/include/wavemap/core/utils/profile/resource_usage_monitor.h new file mode 100644 index 000000000..1816621e2 --- /dev/null +++ b/library/cpp/include/wavemap/core/utils/profile/resource_usage_monitor.h @@ -0,0 +1,41 @@ +#ifndef WAVEMAP_CORE_UTILS_PROFILE_RESOURCE_USAGE_MONITOR_H_ +#define WAVEMAP_CORE_UTILS_PROFILE_RESOURCE_USAGE_MONITOR_H_ + +#include +#include +#include + +#include "wavemap/core/common.h" +#include "wavemap/core/utils/time/time.h" + +namespace wavemap { +class ResourceMonitor { + public: + void start(); + void stop(); + + double getLastEpisodeCpuTime() const { + return time::to_seconds(last_episode_cpu_duration_); + } + double getLastEpisodeWallTime() const { + return time::to_seconds(last_episode_wall_duration_); + } + static std::optional getCurrentRamUsageInKB(); + + private: + bool running_ = false; + + timespec episode_start_cpu_time_{}; + timespec episode_start_wall_time_{}; + + Duration last_episode_cpu_duration_{}; + Duration last_episode_wall_duration_{}; + + Duration total_cpu_duration_{}; + Duration total_wall_duration_{}; + + static Duration computeDuration(const timespec& start, const timespec& stop); +}; +} // namespace wavemap + +#endif // WAVEMAP_CORE_UTILS_PROFILE_RESOURCE_USAGE_MONITOR_H_ diff --git a/library/cpp/include/wavemap/core/utils/time/stopwatch.h b/library/cpp/include/wavemap/core/utils/time/stopwatch.h index 2021ceb46..3d4754d2d 100644 --- a/library/cpp/include/wavemap/core/utils/time/stopwatch.h +++ b/library/cpp/include/wavemap/core/utils/time/stopwatch.h @@ -17,7 +17,7 @@ class Stopwatch { } private: - bool running = false; + bool running_ = false; Timestamp episode_start_time_{}; Duration last_episode_duration_{}; diff --git a/library/cpp/src/core/CMakeLists.txt b/library/cpp/src/core/CMakeLists.txt index 9835c4d8e..4f32f4492 100644 --- a/library/cpp/src/core/CMakeLists.txt +++ b/library/cpp/src/core/CMakeLists.txt @@ -42,6 +42,7 @@ target_sources(wavemap_core PRIVATE map/wavelet_octree.cc map/map_base.cc map/map_factory.cc + utils/profile/resource_usage_monitor.cc utils/query/classified_map.cc utils/query/query_accelerator.cc utils/query/point_sampler.cc diff --git a/library/cpp/src/core/integrator/projective/coarse_to_fine/hashed_chunked_wavelet_integrator.cc b/library/cpp/src/core/integrator/projective/coarse_to_fine/hashed_chunked_wavelet_integrator.cc index 6d42c34e4..3352217c9 100644 --- a/library/cpp/src/core/integrator/projective/coarse_to_fine/hashed_chunked_wavelet_integrator.cc +++ b/library/cpp/src/core/integrator/projective/coarse_to_fine/hashed_chunked_wavelet_integrator.cc @@ -5,7 +5,7 @@ #include #include -#include +#include namespace wavemap { void HashedChunkedWaveletIntegrator::updateMap() { diff --git a/library/cpp/src/core/integrator/projective/coarse_to_fine/hashed_wavelet_integrator.cc b/library/cpp/src/core/integrator/projective/coarse_to_fine/hashed_wavelet_integrator.cc index 515ccd3cd..9168b35cd 100644 --- a/library/cpp/src/core/integrator/projective/coarse_to_fine/hashed_wavelet_integrator.cc +++ b/library/cpp/src/core/integrator/projective/coarse_to_fine/hashed_wavelet_integrator.cc @@ -5,7 +5,7 @@ #include #include -#include +#include namespace wavemap { void HashedWaveletIntegrator::updateMap() { diff --git a/library/cpp/src/core/integrator/projective/projective_integrator.cc b/library/cpp/src/core/integrator/projective/projective_integrator.cc index b61b169d5..cadd3cdc8 100644 --- a/library/cpp/src/core/integrator/projective/projective_integrator.cc +++ b/library/cpp/src/core/integrator/projective/projective_integrator.cc @@ -1,7 +1,7 @@ #include "wavemap/core/integrator/projective/projective_integrator.h" #include -#include +#include namespace wavemap { DECLARE_CONFIG_MEMBERS(ProjectiveIntegratorConfig, diff --git a/library/cpp/src/core/map/hashed_chunked_wavelet_octree.cc b/library/cpp/src/core/map/hashed_chunked_wavelet_octree.cc index 6f33b017f..702a0eba6 100644 --- a/library/cpp/src/core/map/hashed_chunked_wavelet_octree.cc +++ b/library/cpp/src/core/map/hashed_chunked_wavelet_octree.cc @@ -2,7 +2,7 @@ #include -#include +#include namespace wavemap { DECLARE_CONFIG_MEMBERS(HashedChunkedWaveletOctreeConfig, diff --git a/library/cpp/src/core/map/hashed_chunked_wavelet_octree_block.cc b/library/cpp/src/core/map/hashed_chunked_wavelet_octree_block.cc index 888f0c9b6..d9aea9bb8 100644 --- a/library/cpp/src/core/map/hashed_chunked_wavelet_octree_block.cc +++ b/library/cpp/src/core/map/hashed_chunked_wavelet_octree_block.cc @@ -3,7 +3,7 @@ #include #include -#include +#include namespace wavemap { void HashedChunkedWaveletOctreeBlock::threshold() { diff --git a/library/cpp/src/core/map/hashed_wavelet_octree.cc b/library/cpp/src/core/map/hashed_wavelet_octree.cc index 7d9a9abf2..91c468527 100644 --- a/library/cpp/src/core/map/hashed_wavelet_octree.cc +++ b/library/cpp/src/core/map/hashed_wavelet_octree.cc @@ -2,7 +2,7 @@ #include -#include +#include namespace wavemap { DECLARE_CONFIG_MEMBERS(HashedWaveletOctreeConfig, diff --git a/library/cpp/src/core/map/hashed_wavelet_octree_block.cc b/library/cpp/src/core/map/hashed_wavelet_octree_block.cc index e5e982a5d..7ab3ec524 100644 --- a/library/cpp/src/core/map/hashed_wavelet_octree_block.cc +++ b/library/cpp/src/core/map/hashed_wavelet_octree_block.cc @@ -3,7 +3,7 @@ #include #include -#include +#include namespace wavemap { void HashedWaveletOctreeBlock::threshold() { diff --git a/library/cpp/src/core/utils/profile/resource_usage_monitor.cc b/library/cpp/src/core/utils/profile/resource_usage_monitor.cc new file mode 100644 index 000000000..039a62224 --- /dev/null +++ b/library/cpp/src/core/utils/profile/resource_usage_monitor.cc @@ -0,0 +1,75 @@ +#include "wavemap/core/utils/profile/resource_usage_monitor.h" + +#include + +namespace wavemap { +void ResourceMonitor::start() { + if (running_) { + LOG(WARNING) << "Tried to start timer that was already running."; + return; + } + + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &episode_start_cpu_time_); + clock_gettime(CLOCK_MONOTONIC, &episode_start_wall_time_); + running_ = true; +} + +void ResourceMonitor::stop() { + if (!running_) { + LOG(WARNING) << "Tried to stop timer that was not running."; + return; + } + + timespec episode_stop_cpu_time{}; + timespec episode_stop_wall_time{}; + clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &episode_stop_cpu_time); + clock_gettime(CLOCK_MONOTONIC, &episode_stop_wall_time); + running_ = false; + + last_episode_cpu_duration_ = + computeDuration(episode_start_cpu_time_, episode_stop_cpu_time); + last_episode_wall_duration_ = + computeDuration(episode_start_wall_time_, episode_stop_wall_time); + total_cpu_duration_ += last_episode_cpu_duration_; + total_wall_duration_ += last_episode_wall_duration_; +} + +std::optional ResourceMonitor::getCurrentRamUsageInKB() { + std::ifstream file("/proc/self/status"); + std::string line; + while (std::getline(file, line)) { + if (line.rfind("VmRSS", 0) == 0) { + break; + } + } + if (file.eof()) { + LOG(ERROR) << "Failed to read RAM usage. Could not find VmRSS entry in " + "\"/proc/self/status\"."; + return std::nullopt; + } + + std::string quantity; + size_t ram_usage; + std::string unit; + if (std::istringstream iss(line); !(iss >> quantity >> ram_usage >> unit)) { + LOG(ERROR) << "Failed to read RAM usage. Could not parse VmRSS line " + "in \"/proc/self/status\"."; + return std::nullopt; + } + + if (unit != "kB") { + LOG(ERROR) << "Failed to read RAM usage. Expected VmRSS entry in " + "\"/proc/self/status\" to be specified in kB, got " + << unit << "."; + return std::nullopt; + } + + return ram_usage; +} + +Duration ResourceMonitor::computeDuration(const timespec& start, + const timespec& stop) { + return std::chrono::seconds(stop.tv_sec - start.tv_sec) + + std::chrono::nanoseconds(stop.tv_nsec - start.tv_nsec); +} +} // namespace wavemap diff --git a/library/cpp/src/core/utils/query/classified_map.cc b/library/cpp/src/core/utils/query/classified_map.cc index 7eadb489b..7ebd9e4b3 100644 --- a/library/cpp/src/core/utils/query/classified_map.cc +++ b/library/cpp/src/core/utils/query/classified_map.cc @@ -5,7 +5,7 @@ #include #include -#include +#include namespace wavemap { ClassifiedMap::ClassifiedMap(FloatingPoint min_cell_width, diff --git a/library/cpp/src/core/utils/sdf/full_euclidean_sdf_generator.cc b/library/cpp/src/core/utils/sdf/full_euclidean_sdf_generator.cc index 4cb414aaf..a91ae4406 100644 --- a/library/cpp/src/core/utils/sdf/full_euclidean_sdf_generator.cc +++ b/library/cpp/src/core/utils/sdf/full_euclidean_sdf_generator.cc @@ -1,6 +1,6 @@ #include "wavemap/core/utils/sdf/full_euclidean_sdf_generator.h" -#include +#include #include "wavemap/core/utils/iterate/grid_iterator.h" #include "wavemap/core/utils/query/query_accelerator.h" diff --git a/library/cpp/src/core/utils/sdf/quasi_euclidean_sdf_generator.cc b/library/cpp/src/core/utils/sdf/quasi_euclidean_sdf_generator.cc index 675203cbe..c97ff72a1 100644 --- a/library/cpp/src/core/utils/sdf/quasi_euclidean_sdf_generator.cc +++ b/library/cpp/src/core/utils/sdf/quasi_euclidean_sdf_generator.cc @@ -2,7 +2,7 @@ #include -#include +#include #include "wavemap/core/utils/iterate/grid_iterator.h" #include "wavemap/core/utils/query/query_accelerator.h" diff --git a/library/cpp/src/core/utils/thread_pool.cc b/library/cpp/src/core/utils/thread_pool.cc index 2d48bdf05..25a651ca9 100644 --- a/library/cpp/src/core/utils/thread_pool.cc +++ b/library/cpp/src/core/utils/thread_pool.cc @@ -3,7 +3,7 @@ #include #include -#include +#include namespace wavemap { ThreadPool::ThreadPool(size_t thread_count) diff --git a/library/cpp/src/core/utils/time/stopwatch.cc b/library/cpp/src/core/utils/time/stopwatch.cc index c023dc506..24957d71d 100644 --- a/library/cpp/src/core/utils/time/stopwatch.cc +++ b/library/cpp/src/core/utils/time/stopwatch.cc @@ -4,21 +4,21 @@ namespace wavemap { void Stopwatch::start() { - if (running) { + if (running_) { LOG(WARNING) << "Tried to start timer that was already running."; return; } episode_start_time_ = Time::now(); - running = true; + running_ = true; } void Stopwatch::stop() { - if (!running) { + if (!running_) { LOG(WARNING) << "Tried to stop timer that was not running."; return; } const Timestamp stop_wall_time = Time::now(); - running = false; + running_ = false; last_episode_duration_ = stop_wall_time - episode_start_time_; total_duration_ += last_episode_duration_; From 0d7650c2ea29fb830da56b71e25121ae6fff51bb Mon Sep 17 00:00:00 2001 From: Victor Reijgwart Date: Thu, 24 Oct 2024 14:06:39 +0200 Subject: [PATCH 02/12] Fix for schema validation warning resulting from CLion bug IJPL-63581 --- interfaces/ros1/wavemap_ros/config/wavemap_ouster_os0.yaml | 2 -- tooling/schemas/wavemap/map/map_base.json | 2 +- tooling/schemas/wavemap/map_operations/map_operation_base.json | 2 +- .../wavemap/measurement_integrators/integration_method.json | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/interfaces/ros1/wavemap_ros/config/wavemap_ouster_os0.yaml b/interfaces/ros1/wavemap_ros/config/wavemap_ouster_os0.yaml index c9752d0e9..3f9d71236 100644 --- a/interfaces/ros1/wavemap_ros/config/wavemap_ouster_os0.yaml +++ b/interfaces/ros1/wavemap_ros/config/wavemap_ouster_os0.yaml @@ -50,5 +50,3 @@ inputs: undistort_motion: true topic_queue_length: 10 max_wait_for_pose: { seconds: 1.0 } - # reprojected_pointcloud_topic_name: "/wavemap/reprojected_pointcloud" - # projected_range_image_topic_name: "/wavemap/projected_range_image" diff --git a/tooling/schemas/wavemap/map/map_base.json b/tooling/schemas/wavemap/map/map_base.json index 754438bdb..f97c463a7 100644 --- a/tooling/schemas/wavemap/map/map_base.json +++ b/tooling/schemas/wavemap/map/map_base.json @@ -18,7 +18,7 @@ ] } }, - "oneOf": [ + "anyOf": [ { "$ref": "hashed_blocks.json" }, diff --git a/tooling/schemas/wavemap/map_operations/map_operation_base.json b/tooling/schemas/wavemap/map_operations/map_operation_base.json index 3d573e55a..23a053d81 100644 --- a/tooling/schemas/wavemap/map_operations/map_operation_base.json +++ b/tooling/schemas/wavemap/map_operations/map_operation_base.json @@ -18,7 +18,7 @@ ] } }, - "oneOf": [ + "anyOf": [ { "$ref": "threshold_map_operation.json" }, diff --git a/tooling/schemas/wavemap/measurement_integrators/integration_method.json b/tooling/schemas/wavemap/measurement_integrators/integration_method.json index 8b522f020..6859ea8a9 100644 --- a/tooling/schemas/wavemap/measurement_integrators/integration_method.json +++ b/tooling/schemas/wavemap/measurement_integrators/integration_method.json @@ -71,7 +71,7 @@ "required": [ "type" ], - "oneOf": [ + "anyOf": [ { "$ref": "#/$defs/ray_tracing_integrator" }, From 7c16b49e08797739300fa8a05f80fb29877f6dd2 Mon Sep 17 00:00:00 2001 From: Victor Reijgwart Date: Mon, 18 Nov 2024 13:34:30 +0100 Subject: [PATCH 03/12] Update the repository's general pull request template --- .github/pull_request_template.md | 99 +++++++++++++++++++++----------- 1 file changed, 65 insertions(+), 34 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 53cbedf13..2c63f5fab 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,50 +1,81 @@ # Description - -Thank you for opening a PR. Please summarize the changes in 1 or 2 sentences. +Thank you for opening a PR! Please summarize the changes in 1–2 sentences. ## Type of change - -Delete options that are not relevant. - +Delete options that are not relevant: - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] Breaking change (fix or feature that causes existing functionality to not work as expected) +- [ ] Other (please describe): -## Detailed summary +## Detailed Summary +Provide the motivation, context, and links to any related issues, PRs, or documentation: +- Motivation: Why is this change necessary? +- Context: How does it fit into wavemap's functionality? +- Related issues/PRs: Fixes # (issue) / Links to other PRs -Please describe the motivation, context and a link to related issues (if appropriate). List any dependencies that are required for this change. +## API Changes +List any changes to wavemap's APIs to help users update their code. Write "None" if there are no changes. -Feel free to summarize the changes as a list of bullet points. - -Fixes # (issue) - -# Testing +### C++ API: +* -If possible, verify that the changes produce the desired results by extending the unit tests. If you would like us to help you with this, feel free to open the pull request already and let us know. +### Python API: +* -If manual tests were performed to verify these changes, please describe them here and provide instructions to reproduce them. Please also list any relevant details for your test configuration below. +### ROS1 Interface: +* -If the changes are performance related, this is a good place to list the metrics that were used and the improvements that have been achieved. - -**System information (please complete if relevant):** -- CPU: [e.g. Intel i9-9900K] -- GPU: [e.g. Nvidia RTX 2080Ti] # Only for visualization-related issues -- RAM: [e.g. 32GB] -- OS: [e.g. Ubuntu 20.04] -- Installation: [e.g., Native (ROS with catkin); or Docker] - -**Runtime information (please complete if relevant):** -- Launch file: [e.g. Link to the launch file you used] -- Config file: [e.g. Link to the config file you used] -- Dataset name [e.g. Newer College Cloister sequence] # For public datasets -- Custom setup: # For online use or personal datasets - - Depth sensor: [e.g. Livox MID360 LiDAR] - - Pose source: [e.g. Odometry from FastLIO2] - -# Checklist: +## Review Notes +Is there anything specific the reviewers should focus on, or are there unresolved questions? Mention them here. +# Testing +### Automated Tests +Have you added or modified unit tests to verify these changes? If not, let us know if you'd like assistance. + +### Manual Tests +If manual tests were performed to verify these changes, describe them here and include instructions to reproduce them. +Describe test configurations where applicable. + +**System information (optional):** +- CPU: [e.g., Intel i9-9900K] +- GPU: [e.g., Nvidia RTX 2080Ti] +- RAM: [e.g., 32GB] +- OS: [e.g., Ubuntu 20.04] +- API: [e.g., C++, Python, ROS1] +- Installation: [e.g., pre-built Docker, local CMake, Pip, catkin] + +**Runtime information (optional):** +- Launch file: [e.g., Link or GitHub Gist] +- Config file: [e.g., Link or GitHub Gist] +- Dataset name (if public): [e.g., Newer College Cloister] +- Custom setup (for private datasets, or live usage): + - Depth sensor: [e.g., Livox MID360 LiDAR] + - Pose source: [e.g., Odometry from FastLIO2] + +For performance or accuracy-related changes, include the above system and runtime information and describe: +- **Performance (optional)** + - Measured operation: [e.g. serializing the map, performing 1M queries, processing dataset X] + - Metrics [e.g., CPU time, wall time, total RAM usage] +- **Accuracy (optional)** + - Metrics: [e.g., AUC, accuracy, recall] +- **Summary of changes** + - What metrics improved and by how much? + - Did any metrics worsen? + +### Benchmarks (To be completed by maintainers) +We will rerun wavemap's benchmarks and report the results here to validate there are no general performance/accuracy regressions. + +# Checklist +General - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas -- [ ] I have made corresponding changes to the documentation +- [ ] I have added or updated tests as required - [ ] Any required changes in dependencies have been committed and pushed + +Documentation (where applicable) +- [ ] I have updated the installation instructions (in docs/pages/installation) +- [ ] I have updated the code's inline API documentation (e.g., docstrings) +- [ ] I have updated the parameter documentation (in docs/pages/parameters) +- [ ] I have updated/extended the tutorials (in docs/pages/tutorials) From 076cb48cfb4a7f5a0b08729eea07a32ef52f5471 Mon Sep 17 00:00:00 2001 From: Victor Reijgwart Date: Tue, 19 Nov 2024 11:16:06 +0100 Subject: [PATCH 04/12] Reformat pull request template --- .github/pull_request_template.md | 34 +++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2c63f5fab..d850d559f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,43 +1,57 @@ # Description + Thank you for opening a PR! Please summarize the changes in 1–2 sentences. ## Type of change + Delete options that are not relevant: + - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that causes existing functionality to not work as expected) - [ ] Other (please describe): ## Detailed Summary + Provide the motivation, context, and links to any related issues, PRs, or documentation: + - Motivation: Why is this change necessary? - Context: How does it fit into wavemap's functionality? - Related issues/PRs: Fixes # (issue) / Links to other PRs ## API Changes + List any changes to wavemap's APIs to help users update their code. Write "None" if there are no changes. ### C++ API: + * ### Python API: + * ### ROS1 Interface: + * ## Review Notes + Is there anything specific the reviewers should focus on, or are there unresolved questions? Mention them here. # Testing + ### Automated Tests + Have you added or modified unit tests to verify these changes? If not, let us know if you'd like assistance. ### Manual Tests + If manual tests were performed to verify these changes, describe them here and include instructions to reproduce them. Describe test configurations where applicable. **System information (optional):** + - CPU: [e.g., Intel i9-9900K] - GPU: [e.g., Nvidia RTX 2080Ti] - RAM: [e.g., 32GB] @@ -46,28 +60,33 @@ Describe test configurations where applicable. - Installation: [e.g., pre-built Docker, local CMake, Pip, catkin] **Runtime information (optional):** + - Launch file: [e.g., Link or GitHub Gist] - Config file: [e.g., Link or GitHub Gist] - Dataset name (if public): [e.g., Newer College Cloister] - Custom setup (for private datasets, or live usage): - - Depth sensor: [e.g., Livox MID360 LiDAR] - - Pose source: [e.g., Odometry from FastLIO2] + - Depth sensor: [e.g., Livox MID360 LiDAR] + - Pose source: [e.g., Odometry from FastLIO2] For performance or accuracy-related changes, include the above system and runtime information and describe: + - **Performance (optional)** - - Measured operation: [e.g. serializing the map, performing 1M queries, processing dataset X] - - Metrics [e.g., CPU time, wall time, total RAM usage] + - Measured operation: [e.g. serializing the map, performing 1M queries, processing dataset X] + - Metrics [e.g., CPU time, wall time, total RAM usage] - **Accuracy (optional)** - - Metrics: [e.g., AUC, accuracy, recall] + - Metrics: [e.g., AUC, accuracy, recall] - **Summary of changes** - - What metrics improved and by how much? - - Did any metrics worsen? + - What metrics improved and by how much? + - Did any metrics worsen? ### Benchmarks (To be completed by maintainers) + We will rerun wavemap's benchmarks and report the results here to validate there are no general performance/accuracy regressions. # Checklist + General + - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas @@ -75,6 +94,7 @@ General - [ ] Any required changes in dependencies have been committed and pushed Documentation (where applicable) + - [ ] I have updated the installation instructions (in docs/pages/installation) - [ ] I have updated the code's inline API documentation (e.g., docstrings) - [ ] I have updated the parameter documentation (in docs/pages/parameters) From 3b63ea879141de4838fb689828becf950aa475a7 Mon Sep 17 00:00:00 2001 From: Victor Reijgwart Date: Tue, 19 Nov 2024 12:02:01 +0100 Subject: [PATCH 05/12] Minor cleanup to prepare PR --- .github/pull_request_template.md | 2 -- interfaces/ros1/wavemap_ros/app/rosbag_processor.cc | 2 +- .../{resource_usage_monitor.h => resource_monitor.h} | 6 +++--- library/cpp/src/core/CMakeLists.txt | 2 +- .../{resource_usage_monitor.cc => resource_monitor.cc} | 2 +- 5 files changed, 6 insertions(+), 8 deletions(-) rename library/cpp/include/wavemap/core/utils/profile/{resource_usage_monitor.h => resource_monitor.h} (82%) rename library/cpp/src/core/utils/profile/{resource_usage_monitor.cc => resource_monitor.cc} (97%) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index d850d559f..3c6449050 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -4,8 +4,6 @@ Thank you for opening a PR! Please summarize the changes in 1–2 sentences. ## Type of change -Delete options that are not relevant: - - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that causes existing functionality to not work as expected) diff --git a/interfaces/ros1/wavemap_ros/app/rosbag_processor.cc b/interfaces/ros1/wavemap_ros/app/rosbag_processor.cc index 438b75d76..6c0da7d50 100644 --- a/interfaces/ros1/wavemap_ros/app/rosbag_processor.cc +++ b/interfaces/ros1/wavemap_ros/app/rosbag_processor.cc @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include "wavemap_ros/inputs/depth_image_topic_input.h" diff --git a/library/cpp/include/wavemap/core/utils/profile/resource_usage_monitor.h b/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h similarity index 82% rename from library/cpp/include/wavemap/core/utils/profile/resource_usage_monitor.h rename to library/cpp/include/wavemap/core/utils/profile/resource_monitor.h index 1816621e2..e0f23c7e0 100644 --- a/library/cpp/include/wavemap/core/utils/profile/resource_usage_monitor.h +++ b/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h @@ -1,5 +1,5 @@ -#ifndef WAVEMAP_CORE_UTILS_PROFILE_RESOURCE_USAGE_MONITOR_H_ -#define WAVEMAP_CORE_UTILS_PROFILE_RESOURCE_USAGE_MONITOR_H_ +#ifndef WAVEMAP_CORE_UTILS_PROFILE_RESOURCE_MONITOR_H_ +#define WAVEMAP_CORE_UTILS_PROFILE_RESOURCE_MONITOR_H_ #include #include @@ -38,4 +38,4 @@ class ResourceMonitor { }; } // namespace wavemap -#endif // WAVEMAP_CORE_UTILS_PROFILE_RESOURCE_USAGE_MONITOR_H_ +#endif // WAVEMAP_CORE_UTILS_PROFILE_RESOURCE_MONITOR_H_ diff --git a/library/cpp/src/core/CMakeLists.txt b/library/cpp/src/core/CMakeLists.txt index 4f32f4492..a48abab05 100644 --- a/library/cpp/src/core/CMakeLists.txt +++ b/library/cpp/src/core/CMakeLists.txt @@ -42,7 +42,7 @@ target_sources(wavemap_core PRIVATE map/wavelet_octree.cc map/map_base.cc map/map_factory.cc - utils/profile/resource_usage_monitor.cc + utils/profile/resource_monitor.cc utils/query/classified_map.cc utils/query/query_accelerator.cc utils/query/point_sampler.cc diff --git a/library/cpp/src/core/utils/profile/resource_usage_monitor.cc b/library/cpp/src/core/utils/profile/resource_monitor.cc similarity index 97% rename from library/cpp/src/core/utils/profile/resource_usage_monitor.cc rename to library/cpp/src/core/utils/profile/resource_monitor.cc index 039a62224..4df8171a8 100644 --- a/library/cpp/src/core/utils/profile/resource_usage_monitor.cc +++ b/library/cpp/src/core/utils/profile/resource_monitor.cc @@ -1,4 +1,4 @@ -#include "wavemap/core/utils/profile/resource_usage_monitor.h" +#include "wavemap/core/utils/profile/resource_monitor.h" #include From 0c0e35d4cffa1084a9e0fbc5257c39175c67b888 Mon Sep 17 00:00:00 2001 From: Victor Reijgwart Date: Tue, 19 Nov 2024 12:03:27 +0100 Subject: [PATCH 06/12] Additional fixes for schema validation warning from CLion bug IJPL-63581 --- tooling/schemas/wavemap/inputs/input_base.json | 2 +- .../wavemap/measurement_integrators/measurement_model.json | 2 +- .../wavemap/measurement_integrators/projection_model.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tooling/schemas/wavemap/inputs/input_base.json b/tooling/schemas/wavemap/inputs/input_base.json index 9682e779e..5e61a1392 100644 --- a/tooling/schemas/wavemap/inputs/input_base.json +++ b/tooling/schemas/wavemap/inputs/input_base.json @@ -15,7 +15,7 @@ ] } }, - "oneOf": [ + "anyOf": [ { "$ref": "pointcloud_input.json" }, diff --git a/tooling/schemas/wavemap/measurement_integrators/measurement_model.json b/tooling/schemas/wavemap/measurement_integrators/measurement_model.json index 15078c295..3965dea11 100644 --- a/tooling/schemas/wavemap/measurement_integrators/measurement_model.json +++ b/tooling/schemas/wavemap/measurement_integrators/measurement_model.json @@ -95,7 +95,7 @@ ] } }, - "oneOf": [ + "anyOf": [ { "$ref": "#/$defs/constant_ray" }, diff --git a/tooling/schemas/wavemap/measurement_integrators/projection_model.json b/tooling/schemas/wavemap/measurement_integrators/projection_model.json index 0f727a631..b842f5d61 100644 --- a/tooling/schemas/wavemap/measurement_integrators/projection_model.json +++ b/tooling/schemas/wavemap/measurement_integrators/projection_model.json @@ -111,7 +111,7 @@ ] } }, - "oneOf": [ + "anyOf": [ { "$ref": "#/$defs/spherical_projector" }, From 3db531906bbf45ec271c11c7e217e9d17a66c48e Mon Sep 17 00:00:00 2001 From: Victor Reijgwart Date: Tue, 19 Nov 2024 13:27:01 +0100 Subject: [PATCH 07/12] Document Stopwatch and ResourceMonitor classes and add tests --- .../core/utils/profile/resource_monitor.h | 108 ++++++++++++++++++ .../wavemap/core/utils/time/stopwatch.h | 62 ++++++++++ library/cpp/test/src/core/CMakeLists.txt | 2 + .../core/utils/profile/test_usage_monitor.cc | 99 ++++++++++++++++ .../src/core/utils/time/test_stopwatch.cc | 85 ++++++++++++++ 5 files changed, 356 insertions(+) create mode 100644 library/cpp/test/src/core/utils/profile/test_usage_monitor.cc create mode 100644 library/cpp/test/src/core/utils/time/test_stopwatch.cc diff --git a/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h b/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h index e0f23c7e0..3ec156ee6 100644 --- a/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h +++ b/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h @@ -9,33 +9,141 @@ #include "wavemap/core/utils/time/time.h" namespace wavemap { +/** + * @brief Monitors system resource usage, including CPU time, wall time, + * and RAM usage. + * + * The `ResourceMonitor` class tracks CPU and wall clock time over timed + * episodes, much like wavemap's Stopwatch class. It also provides functionality + * to retrieve the total RAM usage of the current process. + */ class ResourceMonitor { public: + /** + * @brief Starts a new CPU and wall time monitoring episode. + * + * Records the CPU and wall clock start times for the current episode. + * If monitoring is already running, calling `start()` has no effect. + */ void start(); + + /** + * @brief Stops timing the current episode. + * + * Records the end CPU and wall clock times for the current episode, + * updating the last episode duration and total accumulated duration. + * If monitoring is not running, calling `stop()` has no effect. + */ void stop(); + /** + * @brief Checks if the stopwatch is currently running. + * + * @return `true` if the stopwatch is running, `false` otherwise. + */ + bool isRunning() const { return running_; } + + /** + * @brief Gets the CPU time duration of the last episode. + * + * @return The CPU time duration of the last episode in seconds. + * + * The value represents the CPU time elapsed between the most recent + * `start()` and `stop()` calls. If no episode has been monitored, this + * returns 0. + */ double getLastEpisodeCpuTime() const { return time::to_seconds(last_episode_cpu_duration_); } + + /** + * @brief Gets the wall clock time duration of the last episode. + * + * @return The wall clock time duration of the last episode in seconds. + * + * The value represents the real-world time elapsed between the most recent + * `start()` and `stop()` calls. If no episode has been monitored, this + * returns 0. + */ double getLastEpisodeWallTime() const { return time::to_seconds(last_episode_wall_duration_); } + + /** + * @brief Gets the total accumulated CPU time of all episodes. + * + * @return The total CPU time in seconds. + * + * The value represents the sum of the CPU times of all episodes that have + * been timed since the creation of the resource monitor or since it was last + * reset. + */ + double getTotalCpuTime() const { + return time::to_seconds(total_cpu_duration_); + } + + /** + * @brief Gets the total accumulated wall clock time of all episodes. + * + * @return The total wall time in seconds. + * + * The value represents the sum of the wall times of all episodes that have + * been timed since the creation of the resource monitor or since it was last + * reset. + */ + double getTotalWallTime() const { + return time::to_seconds(total_wall_duration_); + } + + /** + * @brief Gets the current RAM usage of the application. + * + * @return The current RAM usage in kilobytes, or `std::nullopt` (an empty + * optional) if retrieving RAM usage is not supported on the given + * platform. + */ static std::optional getCurrentRamUsageInKB(); + /** + * @brief Resets the stopwatch to its initial state. + * + * This method resets all member variables by reassigning the object to a + * default-constructed instance. + */ + void reset() { *this = ResourceMonitor{}; } + private: + /// @brief Indicates whether resource monitoring is currently running. bool running_ = false; + /// @brief Stores the CPU time at the start of the current episode. timespec episode_start_cpu_time_{}; + + /// @brief Stores the wall clock time at the start of the current episode. timespec episode_start_wall_time_{}; + /// @brief Stores the CPU time duration of the last completed episode. Duration last_episode_cpu_duration_{}; + + /// @brief Stores the wall clock time duration of the last completed episode. Duration last_episode_wall_duration_{}; + /// @brief Accumulates the total CPU time duration of all episodes. Duration total_cpu_duration_{}; + + /// @brief Accumulates the total wall clock time duration of all episodes. Duration total_wall_duration_{}; + /** + * @brief Computes the duration between two POSIX timestamps. + * + * @param start The starting POSIX timestamp. + * @param stop The ending POSIX timestamp. + * @return The computed duration as a wavemap::Duration. + */ static Duration computeDuration(const timespec& start, const timespec& stop); }; + } // namespace wavemap #endif // WAVEMAP_CORE_UTILS_PROFILE_RESOURCE_MONITOR_H_ diff --git a/library/cpp/include/wavemap/core/utils/time/stopwatch.h b/library/cpp/include/wavemap/core/utils/time/stopwatch.h index 3d4754d2d..f554e1812 100644 --- a/library/cpp/include/wavemap/core/utils/time/stopwatch.h +++ b/library/cpp/include/wavemap/core/utils/time/stopwatch.h @@ -4,23 +4,85 @@ #include "wavemap/core/utils/time/time.h" namespace wavemap { +/** + * @brief A simple utility class for measuring elapsed time across episodes. + * + * The `Stopwatch` class allows tracking the duration of multiple timed + * episodes. It provides functionality to start, stop, and retrieve timing + * information for the last episode as well as the total duration of all + * episodes. + */ class Stopwatch { public: + /** + * @brief Starts the stopwatch for a new timing episode. + * + * Records the start time for the current episode. If the stopwatch is + * already running, calling `start()` has no effect. + */ void start(); + + /** + * @brief Stops the stopwatch for the current timing episode. + * + * Records the end time for the current episode and updates the + * total accumulated duration. If the stopwatch is not running, + * calling `stop()` has no effect. + */ void stop(); + /** + * @brief Checks if the stopwatch is currently running. + * + * @return `true` if the stopwatch is running, `false` otherwise. + */ + bool isRunning() const { return running_; } + + /** + * @brief Gets the duration of the last timing episode. + * + * @return The duration of the last episode in seconds as a `double`. + * + * The value represents the time elapsed between the most recent + * `start()` and `stop()` calls. If no episode has been timed, + * this returns 0. + */ double getLastEpisodeDuration() const { return time::to_seconds(last_episode_duration_); } + + /** + * @brief Gets the total accumulated duration of all episodes. + * + * @return The total duration in seconds as a `double`. + * + * The value represents the sum of the durations of all episodes + * that have been timed since the creation of the stopwatch or + * since it was last reset. + */ double getTotalDuration() const { return time::to_seconds(total_duration_); } + /** + * @brief Resets the stopwatch to its initial state. + * + * This method resets all member variables by reassigning + * the object to a default-constructed instance. + */ + void reset() { *this = Stopwatch{}; } + private: + /// @brief Indicates whether the stopwatch is currently running. bool running_ = false; + /// @brief Stores the start time of the current episode. Timestamp episode_start_time_{}; + + /// @brief Stores the duration of the last completed episode. Duration last_episode_duration_{}; + + /// @brief Accumulates the total duration of all episodes. Duration total_duration_{}; }; } // namespace wavemap diff --git a/library/cpp/test/src/core/CMakeLists.txt b/library/cpp/test/src/core/CMakeLists.txt index e0a8e94a0..57d38b435 100644 --- a/library/cpp/test/src/core/CMakeLists.txt +++ b/library/cpp/test/src/core/CMakeLists.txt @@ -34,12 +34,14 @@ target_sources(test_wavemap_core PRIVATE utils/neighbors/test_grid_adjacency.cc utils/neighbors/test_grid_neighborhood.cc utils/neighbors/test_ndtree_adjacency.cc + utils/profile/test_usage_monitor.cc utils/query/test_classified_map.cc utils/query/test_map_interpolator.cpp utils/query/test_occupancy_classifier.cc utils/query/test_probability_conversions.cc utils/query/test_query_accelerator.cc utils/sdf/test_sdf_generators.cc + utils/time/test_stopwatch.cc utils/test_thread_pool.cc) set_wavemap_target_properties(test_wavemap_core) diff --git a/library/cpp/test/src/core/utils/profile/test_usage_monitor.cc b/library/cpp/test/src/core/utils/profile/test_usage_monitor.cc new file mode 100644 index 000000000..7501b532d --- /dev/null +++ b/library/cpp/test/src/core/utils/profile/test_usage_monitor.cc @@ -0,0 +1,99 @@ +#include + +#include + +#include "wavemap/core/utils/profile/resource_monitor.h" + +namespace wavemap { +class ResourceMonitorTest : public ::testing::Test { + protected: + ResourceMonitor resource_monitor; +}; + +TEST_F(ResourceMonitorTest, InitialState) { + EXPECT_FALSE(resource_monitor.isRunning()); + EXPECT_EQ(resource_monitor.getLastEpisodeCpuTime(), 0.0); + EXPECT_EQ(resource_monitor.getLastEpisodeWallTime(), 0.0); + EXPECT_EQ(resource_monitor.getTotalCpuTime(), 0.0); + EXPECT_EQ(resource_monitor.getTotalWallTime(), 0.0); +} + +TEST_F(ResourceMonitorTest, Start) { + resource_monitor.start(); + EXPECT_TRUE(resource_monitor.isRunning()); +} + +TEST_F(ResourceMonitorTest, Stop) { + resource_monitor.start(); + resource_monitor.stop(); + EXPECT_FALSE(resource_monitor.isRunning()); +} + +TEST_F(ResourceMonitorTest, Reset) { + resource_monitor.start(); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + resource_monitor.stop(); + + resource_monitor.reset(); + EXPECT_FALSE(resource_monitor.isRunning()); + EXPECT_EQ(resource_monitor.getLastEpisodeCpuTime(), 0.0); + EXPECT_EQ(resource_monitor.getLastEpisodeWallTime(), 0.0); + EXPECT_EQ(resource_monitor.getTotalCpuTime(), 0.0); + EXPECT_EQ(resource_monitor.getTotalWallTime(), 0.0); +} + +TEST_F(ResourceMonitorTest, DurationTracking) { + resource_monitor.start(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + resource_monitor.stop(); + + const double first_wall_time = resource_monitor.getLastEpisodeWallTime(); + EXPECT_GT(first_wall_time, 0.09); // Allow for small timing inaccuracies + EXPECT_LT(first_wall_time, 0.11); // Tolerance of ±10ms + + const double first_cpu_time = resource_monitor.getLastEpisodeCpuTime(); + EXPECT_GT(first_cpu_time, 0.0); // CPU time should be non-zero + + EXPECT_EQ(resource_monitor.getTotalWallTime(), first_wall_time); + EXPECT_EQ(resource_monitor.getTotalCpuTime(), first_cpu_time); + + resource_monitor.start(); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + resource_monitor.stop(); + + const double second_wall_time = resource_monitor.getLastEpisodeWallTime(); + EXPECT_GT(second_wall_time, 0.04); // Allow for small timing inaccuracies + EXPECT_LT(second_wall_time, 0.06); // Tolerance of ±10ms + + const double second_cpu_time = resource_monitor.getLastEpisodeCpuTime(); + EXPECT_DOUBLE_EQ(resource_monitor.getTotalWallTime(), + first_wall_time + second_wall_time); + EXPECT_DOUBLE_EQ(resource_monitor.getTotalCpuTime(), + first_cpu_time + second_cpu_time); +} + +TEST_F(ResourceMonitorTest, StopWithoutStart) { + resource_monitor.stop(); + EXPECT_FALSE(resource_monitor.isRunning()); + EXPECT_EQ(resource_monitor.getLastEpisodeCpuTime(), 0.0); + EXPECT_EQ(resource_monitor.getLastEpisodeWallTime(), 0.0); +} + +TEST_F(ResourceMonitorTest, MultipleStarts) { + resource_monitor.start(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + resource_monitor.start(); // Should have no effect + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + resource_monitor.stop(); + + const double wall_time = resource_monitor.getLastEpisodeWallTime(); + EXPECT_GT(wall_time, 0.14); // Combined duration + EXPECT_LT(wall_time, 0.16); // Tolerance of ±10ms +} + +TEST_F(ResourceMonitorTest, RamUsage) { + const auto ram_usage = ResourceMonitor::getCurrentRamUsageInKB(); + ASSERT_TRUE(ram_usage.has_value()); // Check if the optional contains a value + EXPECT_GT(ram_usage.value(), 0); // RAM usage should be a positive value +} +} // namespace wavemap diff --git a/library/cpp/test/src/core/utils/time/test_stopwatch.cc b/library/cpp/test/src/core/utils/time/test_stopwatch.cc new file mode 100644 index 000000000..8b968129d --- /dev/null +++ b/library/cpp/test/src/core/utils/time/test_stopwatch.cc @@ -0,0 +1,85 @@ +#include + +#include + +#include "wavemap/core/utils/time/stopwatch.h" + +namespace wavemap { +class StopwatchTest : public ::testing::Test { + protected: + Stopwatch stopwatch; +}; + +TEST_F(StopwatchTest, InitialState) { + EXPECT_FALSE(stopwatch.isRunning()); + EXPECT_EQ(stopwatch.getLastEpisodeDuration(), 0.0); + EXPECT_EQ(stopwatch.getTotalDuration(), 0.0); +} + +TEST_F(StopwatchTest, Start) { + stopwatch.start(); + EXPECT_TRUE(stopwatch.isRunning()); +} + +TEST_F(StopwatchTest, Stop) { + stopwatch.start(); + stopwatch.stop(); + EXPECT_FALSE(stopwatch.isRunning()); +} + +TEST_F(StopwatchTest, Reset) { + stopwatch.start(); + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + stopwatch.stop(); + + stopwatch.reset(); + EXPECT_FALSE(stopwatch.isRunning()); + EXPECT_EQ(stopwatch.getLastEpisodeDuration(), 0.0); + EXPECT_EQ(stopwatch.getTotalDuration(), 0.0); +} + +TEST_F(StopwatchTest, DurationTracking) { + stopwatch.start(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + stopwatch.stop(); + + const double first_episode_duration = stopwatch.getLastEpisodeDuration(); + EXPECT_GT(first_episode_duration, + 0.09); // Allow for small timing inaccuracies + EXPECT_LT(first_episode_duration, 0.11); // Tolerance of ±10ms + + const double total_duration = stopwatch.getTotalDuration(); + EXPECT_DOUBLE_EQ(first_episode_duration, total_duration); + + stopwatch.start(); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + stopwatch.stop(); + + const double second_episode_duration = stopwatch.getLastEpisodeDuration(); + EXPECT_GT(second_episode_duration, + 0.04); // Allow for small timing inaccuracies + EXPECT_LT(second_episode_duration, 0.06); // Tolerance of ±10ms + + EXPECT_DOUBLE_EQ(stopwatch.getTotalDuration(), + first_episode_duration + second_episode_duration); +} + +TEST_F(StopwatchTest, StopWithoutStart) { + stopwatch.stop(); + EXPECT_FALSE(stopwatch.isRunning()); + EXPECT_EQ(stopwatch.getLastEpisodeDuration(), 0.0); + EXPECT_EQ(stopwatch.getTotalDuration(), 0.0); +} + +TEST_F(StopwatchTest, MultipleStarts) { + stopwatch.start(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + stopwatch.start(); // Should have no effect + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + stopwatch.stop(); + + const double episode_duration = stopwatch.getLastEpisodeDuration(); + EXPECT_GT(episode_duration, 0.14); // Combined duration + EXPECT_LT(episode_duration, 0.16); // Tolerance of ±10ms +} +} // namespace wavemap From 6e6aced7d176b8cf5e424bc573593e9fb1d7dfcc Mon Sep 17 00:00:00 2001 From: Victor Reijgwart Date: Tue, 19 Nov 2024 13:27:12 +0100 Subject: [PATCH 08/12] Extend ThreadPool tests --- .../test/src/core/utils/test_thread_pool.cc | 65 ++++++++++++++++--- 1 file changed, 57 insertions(+), 8 deletions(-) diff --git a/library/cpp/test/src/core/utils/test_thread_pool.cc b/library/cpp/test/src/core/utils/test_thread_pool.cc index 6b1ab5dda..631e98644 100644 --- a/library/cpp/test/src/core/utils/test_thread_pool.cc +++ b/library/cpp/test/src/core/utils/test_thread_pool.cc @@ -4,17 +4,66 @@ #include #include "wavemap/core/utils/thread_pool.h" +#include "wavemap/core/utils/time/stopwatch.h" +namespace wavemap { TEST(ThreadPoolTest, WaitAll) { - auto dummy_fn = []() { - std::this_thread::sleep_for(std::chrono::milliseconds(1)); - }; + constexpr Duration kSleepTime = std::chrono::milliseconds{10}; + auto dummy_fn = [kSleepTime]() { std::this_thread::sleep_for(kSleepTime); }; - wavemap::ThreadPool pool(2); - pool.add_task(dummy_fn); - pool.add_task(dummy_fn); - pool.add_task(dummy_fn); - pool.add_task(dummy_fn); + // Create the thread pool + constexpr int kNumThreads = 2; + ThreadPool pool(kNumThreads); + // Start measuring time + Stopwatch stopwatch; + stopwatch.start(); + + // Add the tasks to the pool + constexpr int kNumTasks = 4; + std::vector> futures; + futures.reserve(kNumTasks); + for (int task_idx = 0; task_idx < kNumTasks; ++task_idx) { + auto future = pool.add_task(dummy_fn); + futures.emplace_back(std::move(future)); + } pool.wait_all(); + stopwatch.stop(); + + // Check that all futures are available after calling wait_all + for (int task_idx = 0; task_idx < kNumTasks; ++task_idx) { + auto& future = futures[task_idx]; + EXPECT_TRUE(future.valid()); + } + + // Check that executing the tasks took as long as expected + EXPECT_GE(stopwatch.getLastEpisodeDuration(), + time::to_seconds(kSleepTime * kNumTasks / kNumThreads)); +} + +TEST(ThreadPoolTest, FutureResults) { + constexpr int kNumThreads = 2; + ThreadPool pool(kNumThreads); + + // Add the tasks to the pool + constexpr int kNumTasks = 4; + std::vector> futures; + futures.reserve(kNumTasks); + for (int task_idx = 0; task_idx < kNumTasks; ++task_idx) { + const auto sleep_time = std::chrono::milliseconds(kNumTasks - task_idx); + auto future = pool.add_task([task_idx, sleep_time]() { + std::this_thread::sleep_for(sleep_time); + return task_idx; + }); + futures.emplace_back(std::move(future)); + } + + // Wait for the futures one by one and check their results + for (int task_idx = 0; task_idx < kNumTasks; ++task_idx) { + auto& future = futures[task_idx]; + future.wait(); + EXPECT_TRUE(future.valid()); + EXPECT_EQ(future.get(), task_idx); + } } +} // namespace wavemap From 5e353ce12d235ea8d04b721ac10d8d9797bf77bd Mon Sep 17 00:00:00 2001 From: Victor Reijgwart Date: Tue, 19 Nov 2024 14:51:36 +0100 Subject: [PATCH 09/12] Address errors caught by CI --- .../cpp/include/wavemap/core/utils/profile/resource_monitor.h | 1 + library/cpp/test/src/core/utils/test_thread_pool.cc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h b/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h index 3ec156ee6..8885973af 100644 --- a/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h +++ b/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "wavemap/core/common.h" diff --git a/library/cpp/test/src/core/utils/test_thread_pool.cc b/library/cpp/test/src/core/utils/test_thread_pool.cc index 631e98644..5e60c67ac 100644 --- a/library/cpp/test/src/core/utils/test_thread_pool.cc +++ b/library/cpp/test/src/core/utils/test_thread_pool.cc @@ -1,5 +1,7 @@ #include #include +#include +#include #include From 5cb37ee3559b7a6776c9a9a877d3398eacdc5d42 Mon Sep 17 00:00:00 2001 From: Victor Reijgwart Date: Tue, 19 Nov 2024 20:39:01 +0100 Subject: [PATCH 10/12] Address comments on PR#83 --- .../ros1/wavemap_ros/app/rosbag_processor.cc | 11 ++-- .../core/utils/profile/resource_monitor.h | 62 +++++++++++++------ .../wavemap/core/utils/time/stopwatch.h | 20 +++--- .../core/utils/profile/resource_monitor.cc | 30 ++++++++- library/cpp/test/src/core/CMakeLists.txt | 2 +- ...ge_monitor.cc => test_resource_monitor.cc} | 0 6 files changed, 88 insertions(+), 37 deletions(-) rename library/cpp/test/src/core/utils/profile/{test_usage_monitor.cc => test_resource_monitor.cc} (100%) diff --git a/interfaces/ros1/wavemap_ros/app/rosbag_processor.cc b/interfaces/ros1/wavemap_ros/app/rosbag_processor.cc index 6c0da7d50..c7a809a43 100644 --- a/interfaces/ros1/wavemap_ros/app/rosbag_processor.cc +++ b/interfaces/ros1/wavemap_ros/app/rosbag_processor.cc @@ -91,13 +91,10 @@ int main(int argc, char** argv) { // Report the resource usage resource_monitor.stop(); - LOG(INFO) << "Processing complete.\nResource usage:\n* RAM total: " - << ResourceMonitor::getCurrentRamUsageInKB().value_or(0u) - << " kB\n* Map size: " - << wavemap_server.getMap()->getMemoryUsage() / 1000 - << " kB\n* CPU time: " << resource_monitor.getLastEpisodeCpuTime() - << " s\n* Wall time: " << resource_monitor.getLastEpisodeWallTime() - << " s\n"; + LOG(INFO) << "Processing complete.\nResource usage:\n" + << resource_monitor.getLastEpisodeResourceUsageStats() + << "\n* Map size: " + << wavemap_server.getMap()->getMemoryUsage() / 1024 << " kB\n"; if (nh_private.param("keep_alive", false)) { ros::spin(); diff --git a/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h b/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h index 8885973af..9929ef65e 100644 --- a/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h +++ b/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h @@ -2,9 +2,8 @@ #define WAVEMAP_CORE_UTILS_PROFILE_RESOURCE_MONITOR_H_ #include -#include #include -#include +#include #include "wavemap/core/common.h" #include "wavemap/core/utils/time/time.h" @@ -15,8 +14,8 @@ namespace wavemap { * and RAM usage. * * The `ResourceMonitor` class tracks CPU and wall clock time over timed - * episodes, much like wavemap's Stopwatch class. It also provides functionality - * to retrieve the total RAM usage of the current process. + * episodes, much like wavemap's Stopwatch class. It also provides + * functionality to retrieve the total RAM usage of the current process. */ class ResourceMonitor { public: @@ -31,9 +30,9 @@ class ResourceMonitor { /** * @brief Stops timing the current episode. * - * Records the end CPU and wall clock times for the current episode, - * updating the last episode duration and total accumulated duration. - * If monitoring is not running, calling `stop()` has no effect. + * Records the end CPU and wall clock times for the current episode, updating + * the last episode duration and total accumulated duration. If no episode is + * in progress, calling `stop()` has no effect. */ void stop(); @@ -44,14 +43,23 @@ class ResourceMonitor { */ bool isRunning() const { return running_; } + /** + * @brief Gets the current RAM usage of the application. + * + * @return The current RAM usage in kilobytes, or `std::nullopt` (an empty + * optional) if retrieving RAM usage is not supported on the given + * platform. + */ + static std::optional getCurrentRamUsageInKB(); + /** * @brief Gets the CPU time duration of the last episode. * * @return The CPU time duration of the last episode in seconds. * - * The value represents the CPU time elapsed between the most recent - * `start()` and `stop()` calls. If no episode has been monitored, this - * returns 0. + * The value represents the CPU time elapsed during the most recently + * completed pair of `start()` and `stop()` calls. If no episode has been + * completed, this returns 0. */ double getLastEpisodeCpuTime() const { return time::to_seconds(last_episode_cpu_duration_); @@ -62,14 +70,27 @@ class ResourceMonitor { * * @return The wall clock time duration of the last episode in seconds. * - * The value represents the real-world time elapsed between the most recent - * `start()` and `stop()` calls. If no episode has been monitored, this - * returns 0. + * The value represents the real-world time elapsed during the most recently + * completed pair of `start()` and `stop()` calls. If no episode has been + * completed, this returns 0. */ double getLastEpisodeWallTime() const { return time::to_seconds(last_episode_wall_duration_); } + /** + * @brief Get the last episode's resource usage stats formatted as a string. + * + * @return A string with the CPU time, wall time, and RAM usage statistics. + * + * The returned string provides a human-readable summary of the resource + * usage for the most recently completed episode. CPU and wall times are + * displayed in seconds with two decimal places, while RAM usage is reported + * in kilobytes. If RAM usage information is unavailable, it will be labeled + * as "Unknown". Each statistic is printed on a new line, with a leading `*`. + */ + std::string getLastEpisodeResourceUsageStats() const; + /** * @brief Gets the total accumulated CPU time of all episodes. * @@ -97,13 +118,18 @@ class ResourceMonitor { } /** - * @brief Gets the current RAM usage of the application. + * @brief Get the total accumulated resource usage stats formatted as a + * string. * - * @return The current RAM usage in kilobytes, or `std::nullopt` (an empty - * optional) if retrieving RAM usage is not supported on the given - * platform. + * @return A string with the CPU time, wall time, and RAM usage statistics. + * + * The returned string provides a human-readable summary of the total resource + * usage for all episodes. CPU and wall times are displayed in seconds with + * two decimal places, while RAM usage is reported in kilobytes. If RAM usage + * information is unavailable, it will be labeled as "Unknown". Each statistic + * is printed on a new line, with a leading `*`. */ - static std::optional getCurrentRamUsageInKB(); + std::string getTotalResourceUsageStats() const; /** * @brief Resets the stopwatch to its initial state. diff --git a/library/cpp/include/wavemap/core/utils/time/stopwatch.h b/library/cpp/include/wavemap/core/utils/time/stopwatch.h index f554e1812..ffbdb0690 100644 --- a/library/cpp/include/wavemap/core/utils/time/stopwatch.h +++ b/library/cpp/include/wavemap/core/utils/time/stopwatch.h @@ -25,9 +25,9 @@ class Stopwatch { /** * @brief Stops the stopwatch for the current timing episode. * - * Records the end time for the current episode and updates the - * total accumulated duration. If the stopwatch is not running, - * calling `stop()` has no effect. + * Records the end time for the current episode and updates the total + * accumulated duration. If the stopwatch is not running, calling `stop()` + * has no effect. */ void stop(); @@ -43,8 +43,8 @@ class Stopwatch { * * @return The duration of the last episode in seconds as a `double`. * - * The value represents the time elapsed between the most recent - * `start()` and `stop()` calls. If no episode has been timed, + * The value represents the time elapsed during the most recently completed + * pair of `start()` and `stop()` calls. If no episode has been completed, * this returns 0. */ double getLastEpisodeDuration() const { @@ -56,9 +56,9 @@ class Stopwatch { * * @return The total duration in seconds as a `double`. * - * The value represents the sum of the durations of all episodes - * that have been timed since the creation of the stopwatch or - * since it was last reset. + * The value represents the sum of the durations of all episodes that have + * been completed since the creation of the stopwatch or since it was last + * reset. */ double getTotalDuration() const { return time::to_seconds(total_duration_); @@ -67,8 +67,8 @@ class Stopwatch { /** * @brief Resets the stopwatch to its initial state. * - * This method resets all member variables by reassigning - * the object to a default-constructed instance. + * This method resets all member variables by reassigning the object to a + * default-constructed instance. */ void reset() { *this = Stopwatch{}; } diff --git a/library/cpp/src/core/utils/profile/resource_monitor.cc b/library/cpp/src/core/utils/profile/resource_monitor.cc index 4df8171a8..de2fe606c 100644 --- a/library/cpp/src/core/utils/profile/resource_monitor.cc +++ b/library/cpp/src/core/utils/profile/resource_monitor.cc @@ -1,6 +1,8 @@ #include "wavemap/core/utils/profile/resource_monitor.h" -#include +#include +#include +#include namespace wavemap { void ResourceMonitor::start() { @@ -67,6 +69,32 @@ std::optional ResourceMonitor::getCurrentRamUsageInKB() { return ram_usage; } +std::string ResourceMonitor::getLastEpisodeResourceUsageStats() const { + std::ostringstream oss; + oss << std::fixed << std::setprecision(2); // Print with two decimals + oss << "* CPU time: " << getLastEpisodeCpuTime() << " s\n" + << "* Wall time: " << getLastEpisodeWallTime() << " s\n"; + if (const auto ram_usage = getCurrentRamUsageInKB(); ram_usage) { + oss << "* RAM total: " << *ram_usage << " kB"; + } else { + oss << "* RAM total: Unknown"; + } + return oss.str(); +} + +std::string ResourceMonitor::getTotalResourceUsageStats() const { + std::ostringstream oss; + oss << std::fixed << std::setprecision(2); // Print with two decimals + oss << "* CPU time: " << getTotalCpuTime() << " s\n" + << "* Wall time: " << getTotalWallTime() << " s\n"; + if (const auto ram_usage = getCurrentRamUsageInKB(); ram_usage) { + oss << "* RAM total: " << *ram_usage << " kB"; + } else { + oss << "* RAM total: Unknown"; + } + return oss.str(); +} + Duration ResourceMonitor::computeDuration(const timespec& start, const timespec& stop) { return std::chrono::seconds(stop.tv_sec - start.tv_sec) + diff --git a/library/cpp/test/src/core/CMakeLists.txt b/library/cpp/test/src/core/CMakeLists.txt index 57d38b435..cb246e0ec 100644 --- a/library/cpp/test/src/core/CMakeLists.txt +++ b/library/cpp/test/src/core/CMakeLists.txt @@ -34,7 +34,7 @@ target_sources(test_wavemap_core PRIVATE utils/neighbors/test_grid_adjacency.cc utils/neighbors/test_grid_neighborhood.cc utils/neighbors/test_ndtree_adjacency.cc - utils/profile/test_usage_monitor.cc + utils/profile/test_resource_monitor.cc utils/query/test_classified_map.cc utils/query/test_map_interpolator.cpp utils/query/test_occupancy_classifier.cc diff --git a/library/cpp/test/src/core/utils/profile/test_usage_monitor.cc b/library/cpp/test/src/core/utils/profile/test_resource_monitor.cc similarity index 100% rename from library/cpp/test/src/core/utils/profile/test_usage_monitor.cc rename to library/cpp/test/src/core/utils/profile/test_resource_monitor.cc From 1a5416f48490993b0a8f4b7f8b5eea79181f80d3 Mon Sep 17 00:00:00 2001 From: Victor Reijgwart Date: Wed, 20 Nov 2024 13:38:54 +0100 Subject: [PATCH 11/12] Avoid compilation errors in the ResourceMonitor on non-Linux platforms --- .../core/utils/profile/resource_monitor.h | 7 +++-- .../core/utils/profile/resource_monitor.cc | 28 ++++++++++++++++--- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h b/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h index 9929ef65e..1e979509b 100644 --- a/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h +++ b/library/cpp/include/wavemap/core/utils/profile/resource_monitor.h @@ -144,10 +144,10 @@ class ResourceMonitor { bool running_ = false; /// @brief Stores the CPU time at the start of the current episode. - timespec episode_start_cpu_time_{}; + std::timespec episode_start_cpu_time_{}; /// @brief Stores the wall clock time at the start of the current episode. - timespec episode_start_wall_time_{}; + std::timespec episode_start_wall_time_{}; /// @brief Stores the CPU time duration of the last completed episode. Duration last_episode_cpu_duration_{}; @@ -168,7 +168,8 @@ class ResourceMonitor { * @param stop The ending POSIX timestamp. * @return The computed duration as a wavemap::Duration. */ - static Duration computeDuration(const timespec& start, const timespec& stop); + static Duration computeDuration(const std::timespec& start, + const std::timespec& stop); }; } // namespace wavemap diff --git a/library/cpp/src/core/utils/profile/resource_monitor.cc b/library/cpp/src/core/utils/profile/resource_monitor.cc index de2fe606c..86b0b4ce8 100644 --- a/library/cpp/src/core/utils/profile/resource_monitor.cc +++ b/library/cpp/src/core/utils/profile/resource_monitor.cc @@ -2,7 +2,17 @@ #include #include +#include #include +#include + +// Borrowed from BOOST_HAS_CLOCK_GETTIME +// NOTE: This is predicated on _POSIX_TIMERS (also on _XOPEN_REALTIME +// but at least one platform - linux - defines that flag without +// defining clock_gettime): +#if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS + 0 >= 0)) +#define HAS_CLOCK_GETTIME +#endif namespace wavemap { void ResourceMonitor::start() { @@ -11,8 +21,13 @@ void ResourceMonitor::start() { return; } +#ifdef HAS_CLOCK_GETTIME clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &episode_start_cpu_time_); clock_gettime(CLOCK_MONOTONIC, &episode_start_wall_time_); +#else + LOG(WARNING) << "Measuring CPU time has not yet been implemented for the " + "current platform."; +#endif running_ = true; } @@ -22,10 +37,15 @@ void ResourceMonitor::stop() { return; } - timespec episode_stop_cpu_time{}; - timespec episode_stop_wall_time{}; + std::timespec episode_stop_cpu_time{}; + std::timespec episode_stop_wall_time{}; +#ifdef HAS_CLOCK_GETTIME clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &episode_stop_cpu_time); clock_gettime(CLOCK_MONOTONIC, &episode_stop_wall_time); +#else + LOG(WARNING) << "Measuring CPU time has not yet been implemented for the " + "current platform."; +#endif running_ = false; last_episode_cpu_duration_ = @@ -95,8 +115,8 @@ std::string ResourceMonitor::getTotalResourceUsageStats() const { return oss.str(); } -Duration ResourceMonitor::computeDuration(const timespec& start, - const timespec& stop) { +Duration ResourceMonitor::computeDuration(const std::timespec& start, + const std::timespec& stop) { return std::chrono::seconds(stop.tv_sec - start.tv_sec) + std::chrono::nanoseconds(stop.tv_nsec - start.tv_nsec); } From f8cfa965d85d973ed622af2d4337fd80f351dafa Mon Sep 17 00:00:00 2001 From: Victor Reijgwart Date: Wed, 20 Nov 2024 14:06:26 +0100 Subject: [PATCH 12/12] Update changelogs --- examples/cpp/CHANGELOG.rst | 3 +++ examples/cpp/CMakeLists.txt | 2 +- examples/python/CHANGELOG.rst | 3 +++ examples/ros1/CHANGELOG.rst | 3 +++ examples/ros1/package.xml | 2 +- interfaces/ros1/wavemap/CHANGELOG.rst | 3 +++ interfaces/ros1/wavemap/package.xml | 2 +- interfaces/ros1/wavemap_all/CHANGELOG.rst | 3 +++ interfaces/ros1/wavemap_all/package.xml | 2 +- interfaces/ros1/wavemap_msgs/CHANGELOG.rst | 3 +++ interfaces/ros1/wavemap_msgs/package.xml | 2 +- interfaces/ros1/wavemap_ros/CHANGELOG.rst | 6 ++++++ interfaces/ros1/wavemap_ros/package.xml | 2 +- interfaces/ros1/wavemap_ros_conversions/CHANGELOG.rst | 5 +++++ interfaces/ros1/wavemap_ros_conversions/package.xml | 2 +- interfaces/ros1/wavemap_rviz_plugin/CHANGELOG.rst | 5 +++++ interfaces/ros1/wavemap_rviz_plugin/package.xml | 2 +- library/cpp/CHANGELOG.rst | 7 +++++++ library/cpp/CMakeLists.txt | 2 +- library/python/CHANGELOG.rst | 3 +++ library/python/CMakeLists.txt | 2 +- library/python/pyproject.toml | 2 +- tooling/packages/catkin_setup/CHANGELOG.rst | 3 +++ tooling/packages/catkin_setup/package.xml | 2 +- 24 files changed, 59 insertions(+), 12 deletions(-) diff --git a/examples/cpp/CHANGELOG.rst b/examples/cpp/CHANGELOG.rst index 2c1e759b7..980f322fe 100644 --- a/examples/cpp/CHANGELOG.rst +++ b/examples/cpp/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package wavemap_examples_cpp ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2.1.2 (2024-11-20) +------------------ + 2.1.1 (2024-10-24) ------------------ diff --git a/examples/cpp/CMakeLists.txt b/examples/cpp/CMakeLists.txt index 6bbc58bfe..914e98fe0 100644 --- a/examples/cpp/CMakeLists.txt +++ b/examples/cpp/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(wavemap_examples_cpp VERSION 2.1.1 LANGUAGES CXX) +project(wavemap_examples_cpp VERSION 2.1.2 LANGUAGES CXX) # Load the wavemap library # First, try to load it from sources diff --git a/examples/python/CHANGELOG.rst b/examples/python/CHANGELOG.rst index a8308ff95..092fa7365 100644 --- a/examples/python/CHANGELOG.rst +++ b/examples/python/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package wavemap_examples_python ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2.1.2 (2024-11-20) +------------------ + 2.1.1 (2024-10-24) ------------------ diff --git a/examples/ros1/CHANGELOG.rst b/examples/ros1/CHANGELOG.rst index ac0f48b72..7cd810a50 100644 --- a/examples/ros1/CHANGELOG.rst +++ b/examples/ros1/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package wavemap_examples_ros1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2.1.2 (2024-11-20) +------------------ + 2.1.1 (2024-10-24) ------------------ * Address warnings from new cpplint version (v2.0) diff --git a/examples/ros1/package.xml b/examples/ros1/package.xml index 03717ebf2..21da126fd 100644 --- a/examples/ros1/package.xml +++ b/examples/ros1/package.xml @@ -1,7 +1,7 @@ wavemap_examples_ros1 - 2.1.1 + 2.1.2 Usages examples for wavemap's ROS1 interface. Victor Reijgwart diff --git a/interfaces/ros1/wavemap/CHANGELOG.rst b/interfaces/ros1/wavemap/CHANGELOG.rst index 0b812bf47..93efbefd8 100644 --- a/interfaces/ros1/wavemap/CHANGELOG.rst +++ b/interfaces/ros1/wavemap/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package wavemap ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2.1.2 (2024-11-20) +------------------ + 2.1.1 (2024-10-24) ------------------ diff --git a/interfaces/ros1/wavemap/package.xml b/interfaces/ros1/wavemap/package.xml index 72df3d4c2..25212d864 100644 --- a/interfaces/ros1/wavemap/package.xml +++ b/interfaces/ros1/wavemap/package.xml @@ -1,7 +1,7 @@ wavemap - 2.1.1 + 2.1.2 Base library for wavemap. Victor Reijgwart diff --git a/interfaces/ros1/wavemap_all/CHANGELOG.rst b/interfaces/ros1/wavemap_all/CHANGELOG.rst index 0b295957b..fb1abe52c 100644 --- a/interfaces/ros1/wavemap_all/CHANGELOG.rst +++ b/interfaces/ros1/wavemap_all/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package wavemap_all ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2.1.2 (2024-11-20) +------------------ + 2.1.1 (2024-10-24) ------------------ diff --git a/interfaces/ros1/wavemap_all/package.xml b/interfaces/ros1/wavemap_all/package.xml index 037f217d7..dbf7e1380 100644 --- a/interfaces/ros1/wavemap_all/package.xml +++ b/interfaces/ros1/wavemap_all/package.xml @@ -1,7 +1,7 @@ wavemap_all - 2.1.1 + 2.1.2 Metapackage that builds all wavemap packages. Victor Reijgwart diff --git a/interfaces/ros1/wavemap_msgs/CHANGELOG.rst b/interfaces/ros1/wavemap_msgs/CHANGELOG.rst index 16625b8ea..a58fdfba4 100644 --- a/interfaces/ros1/wavemap_msgs/CHANGELOG.rst +++ b/interfaces/ros1/wavemap_msgs/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package wavemap_msgs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2.1.2 (2024-11-20) +------------------ + 2.1.1 (2024-10-24) ------------------ diff --git a/interfaces/ros1/wavemap_msgs/package.xml b/interfaces/ros1/wavemap_msgs/package.xml index 554e3e30b..105e124bb 100644 --- a/interfaces/ros1/wavemap_msgs/package.xml +++ b/interfaces/ros1/wavemap_msgs/package.xml @@ -1,7 +1,7 @@ wavemap_msgs - 2.1.1 + 2.1.2 Message definitions for wavemap's ROS interfaces. Victor Reijgwart diff --git a/interfaces/ros1/wavemap_ros/CHANGELOG.rst b/interfaces/ros1/wavemap_ros/CHANGELOG.rst index 8a99adf3c..f5f4c64bf 100644 --- a/interfaces/ros1/wavemap_ros/CHANGELOG.rst +++ b/interfaces/ros1/wavemap_ros/CHANGELOG.rst @@ -2,6 +2,12 @@ Changelog for package wavemap_ros ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2.1.2 (2024-11-20) +------------------ +* Report CPU, wall time and RAM usage when rosbag_processor completes +* Adjust wavemap config schemas to resolve false positive validation warnings caused by CLion bug IJPL-63581 +* Contributors: Victor Reijgwart + 2.1.1 (2024-10-24) ------------------ * Address warnings from new cpplint version (v2.0) diff --git a/interfaces/ros1/wavemap_ros/package.xml b/interfaces/ros1/wavemap_ros/package.xml index 71ec27eb9..2fb3dc6be 100644 --- a/interfaces/ros1/wavemap_ros/package.xml +++ b/interfaces/ros1/wavemap_ros/package.xml @@ -1,7 +1,7 @@ wavemap_ros - 2.1.1 + 2.1.2 ROS interface for wavemap. Victor Reijgwart diff --git a/interfaces/ros1/wavemap_ros_conversions/CHANGELOG.rst b/interfaces/ros1/wavemap_ros_conversions/CHANGELOG.rst index 47e890b14..b8f49bfce 100644 --- a/interfaces/ros1/wavemap_ros_conversions/CHANGELOG.rst +++ b/interfaces/ros1/wavemap_ros_conversions/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package wavemap_ros_conversions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2.1.2 (2024-11-20) +------------------ +* Update include path for profiler_interface.h +* Contributors: Victor Reijgwart + 2.1.1 (2024-10-24) ------------------ * Address warnings from new cpplint version (v2.0) diff --git a/interfaces/ros1/wavemap_ros_conversions/package.xml b/interfaces/ros1/wavemap_ros_conversions/package.xml index b708238fd..abc5ec026 100644 --- a/interfaces/ros1/wavemap_ros_conversions/package.xml +++ b/interfaces/ros1/wavemap_ros_conversions/package.xml @@ -1,7 +1,7 @@ wavemap_ros_conversions - 2.1.1 + 2.1.2 Conversions between wavemap and ROS types. Victor Reijgwart diff --git a/interfaces/ros1/wavemap_rviz_plugin/CHANGELOG.rst b/interfaces/ros1/wavemap_rviz_plugin/CHANGELOG.rst index fe1e92ca6..25fe911ce 100644 --- a/interfaces/ros1/wavemap_rviz_plugin/CHANGELOG.rst +++ b/interfaces/ros1/wavemap_rviz_plugin/CHANGELOG.rst @@ -2,6 +2,11 @@ Changelog for package wavemap_rviz_plugin ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2.1.2 (2024-11-20) +------------------ +* Report CPU, wall time and RAM usage when rosbag_processor completes +* Contributors: Victor Reijgwart + 2.1.1 (2024-10-24) ------------------ * Address warnings from new cpplint version (v2.0) diff --git a/interfaces/ros1/wavemap_rviz_plugin/package.xml b/interfaces/ros1/wavemap_rviz_plugin/package.xml index 212539e10..043783900 100644 --- a/interfaces/ros1/wavemap_rviz_plugin/package.xml +++ b/interfaces/ros1/wavemap_rviz_plugin/package.xml @@ -1,7 +1,7 @@ wavemap_rviz_plugin - 2.1.1 + 2.1.2 Plugin to interactively visualize maps published in wavemap's native format. diff --git a/library/cpp/CHANGELOG.rst b/library/cpp/CHANGELOG.rst index 2a2d4aa57..9b4fc340a 100644 --- a/library/cpp/CHANGELOG.rst +++ b/library/cpp/CHANGELOG.rst @@ -2,6 +2,13 @@ Changelog for package wavemap ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2.1.2 (2024-11-20) +------------------ +* Adds a ResourceMonitor class for measuring CPU time, wall time, and RAM usage during macro-benchmarking +* Document and add unit tests for the Stopwatch and ResourceMonitor classes +* Extend ThreadPool unit tests +* Contributors: Victor Reijgwart + 2.1.1 (2024-10-24) ------------------ * Address warnings from new cpplint version (v2.0) diff --git a/library/cpp/CMakeLists.txt b/library/cpp/CMakeLists.txt index 4935ffdc1..39c81ec8d 100644 --- a/library/cpp/CMakeLists.txt +++ b/library/cpp/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project(wavemap VERSION 2.1.1 LANGUAGES CXX) +project(wavemap VERSION 2.1.2 LANGUAGES CXX) # General options cmake_policy(SET CMP0077 NEW) diff --git a/library/python/CHANGELOG.rst b/library/python/CHANGELOG.rst index f53ecc405..58898d3ec 100644 --- a/library/python/CHANGELOG.rst +++ b/library/python/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package pywavemap ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2.1.2 (2024-11-20) +------------------ + 2.1.1 (2024-10-24) ------------------ * Address warnings from new cpplint version (v2.0) diff --git a/library/python/CMakeLists.txt b/library/python/CMakeLists.txt index 0133b8f7c..fae701f9c 100644 --- a/library/python/CMakeLists.txt +++ b/library/python/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.18) -project(pywavemap VERSION 2.1.1 LANGUAGES CXX) +project(pywavemap VERSION 2.1.2 LANGUAGES CXX) # Warn if the user invokes CMake directly if (NOT SKBUILD AND NOT $ENV{CLION_IDE}) diff --git a/library/python/pyproject.toml b/library/python/pyproject.toml index b8c9e7899..c4fe49030 100644 --- a/library/python/pyproject.toml +++ b/library/python/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build" [project] name = "pywavemap" -version = "2.1.1" +version = "2.1.2" description = "A fast, efficient and accurate multi-resolution, multi-sensor 3D occupancy mapping framework." readme = "../../README.md" requires-python = ">=3.8" diff --git a/tooling/packages/catkin_setup/CHANGELOG.rst b/tooling/packages/catkin_setup/CHANGELOG.rst index e0c79c994..a8ff8a2e1 100644 --- a/tooling/packages/catkin_setup/CHANGELOG.rst +++ b/tooling/packages/catkin_setup/CHANGELOG.rst @@ -2,6 +2,9 @@ Changelog for package catkin_setup ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +2.1.2 (2024-11-20) +------------------ + 2.1.1 (2024-10-24) ------------------ diff --git a/tooling/packages/catkin_setup/package.xml b/tooling/packages/catkin_setup/package.xml index d02b5bd8e..8e75b5deb 100644 --- a/tooling/packages/catkin_setup/package.xml +++ b/tooling/packages/catkin_setup/package.xml @@ -1,7 +1,7 @@ catkin_setup - 2.1.1 + 2.1.2 Dummy package to make it easy to setup the workspace and generate the setup.[sh|bash|zsh] scripts in CI. Victor Reijgwart