From de95781fc79fb02fc992784a1aee9525416b0cda Mon Sep 17 00:00:00 2001 From: Hugo Linsenmaier Date: Wed, 2 Jul 2025 07:56:12 -0700 Subject: [PATCH 1/6] Disable IX for PDP --- cpp/src/routing/diversity/diverse_solver.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cpp/src/routing/diversity/diverse_solver.hpp b/cpp/src/routing/diversity/diverse_solver.hpp index 94031c89c..b0a2c4cb3 100644 --- a/cpp/src/routing/diversity/diverse_solver.hpp +++ b/cpp/src/routing/diversity/diverse_solver.hpp @@ -1129,7 +1129,9 @@ struct solve { if (consider_expensive_recombiners) { recombine_options.insert(recombiner_t::EAX); recombine_options.insert(recombiner_t::AEAX); - if (!a.problem->is_tsp) { recombine_options.insert(recombiner_t::IX); } + if (solution::request_type != request_t::VRP && !a.problem->is_tsp) { + recombine_options.insert(recombiner_t::IX); + } } if (recombine_options.size() == 0) { return false; } } From 4b8483a00e9c1cf205557345aa1e298dba7d3cee Mon Sep 17 00:00:00 2001 From: Hugo Linsenmaier Date: Thu, 3 Jul 2025 05:32:26 -0700 Subject: [PATCH 2/6] Enable IX and add unserviced nodes to b --- cpp/src/routing/adapters/adapted_modifier.cu | 7 +++++-- cpp/src/routing/adapters/adapted_modifier.cuh | 3 ++- cpp/src/routing/diversity/diverse_solver.hpp | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cpp/src/routing/adapters/adapted_modifier.cu b/cpp/src/routing/adapters/adapted_modifier.cu index 16f28fa48..be3f09759 100644 --- a/cpp/src/routing/adapters/adapted_modifier.cu +++ b/cpp/src/routing/adapters/adapted_modifier.cu @@ -127,7 +127,8 @@ template void adapted_modifier_t::equalize_routes_and_nodes( adapted_sol_t& sol_a, adapted_sol_t& sol_b, - costs final_weight) + costs final_weight, + bool skip_adding_nodes_to_a) { raft::common::nvtx::range fun_scope("equalize_routes_and_nodes"); @@ -164,7 +165,9 @@ void adapted_modifier_t::equalize_routes_and_nodes( // If there are no mutually exclusive requests, take an early exit if (missing_in_a.empty() && missing_in_b.empty()) { return; } - add_selected_unserviced_requests(sol_a, missing_in_a, final_weight); + if (!skip_adding_nodes_to_a) { + add_selected_unserviced_requests(sol_a, missing_in_a, final_weight); + } add_selected_unserviced_requests(sol_b, missing_in_b, final_weight); } diff --git a/cpp/src/routing/adapters/adapted_modifier.cuh b/cpp/src/routing/adapters/adapted_modifier.cuh index 5b39e54b1..545bddb98 100644 --- a/cpp/src/routing/adapters/adapted_modifier.cuh +++ b/cpp/src/routing/adapters/adapted_modifier.cuh @@ -48,7 +48,8 @@ struct adapted_modifier_t { void equalize_routes_and_nodes(adapted_sol_t& sol_a, adapted_sol_t& sol_b, - costs final_weight); + costs final_weight, + bool skip_adding_nodes_to_a = false); void insert_infeasible_nodes(adapted_sol_t& sol, costs& weights); diff --git a/cpp/src/routing/diversity/diverse_solver.hpp b/cpp/src/routing/diversity/diverse_solver.hpp index b0a2c4cb3..fdd127f07 100644 --- a/cpp/src/routing/diversity/diverse_solver.hpp +++ b/cpp/src/routing/diversity/diverse_solver.hpp @@ -1168,8 +1168,10 @@ struct solve { } case recombiner_t::IX: { + auto skip_adding_nodes_to_a = true; + lm.equalize_routes_and_nodes(a, b, weights, skip_adding_nodes_to_a); success = inversion.recombine(a, b); - if (success) recombine_stats.add_success(); + if (success) { recombine_stats.add_success(); } break; } From f4998f4a1ef4d5745c5d2ef8553a92d5fbd5cd31 Mon Sep 17 00:00:00 2001 From: Hugo Linsenmaier Date: Thu, 3 Jul 2025 06:07:04 -0700 Subject: [PATCH 3/6] Add pdp check for initial sols --- cpp/src/routing/diversity/injection_info.hpp | 20 ++++++++++++++++--- .../routing/util_kernels/runtime_checks.cu | 2 +- cpp/src/utilities/copy_helpers.hpp | 14 +++++++++++-- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/cpp/src/routing/diversity/injection_info.hpp b/cpp/src/routing/diversity/injection_info.hpp index 76024d8f9..f5bbf922f 100644 --- a/cpp/src/routing/diversity/injection_info.hpp +++ b/cpp/src/routing/diversity/injection_info.hpp @@ -1,6 +1,6 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 + * SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. + * All rights reserved. SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -40,6 +40,7 @@ struct injection_info_t { std::vector load_solutions() { + std::cout << "Inside load_solutions" << std::endl; auto stream = pool_allocator.sol_handles[0]->get_stream(); auto [d_vehicle_ids, d_routes, d_types, d_sol_offsets] = p->data_view_ptr->get_initial_solutions(); @@ -47,7 +48,8 @@ struct injection_info_t { auto tmp_routes = cuopt::host_copy(d_routes, stream); auto vehicle_ids = cuopt::host_copy(d_vehicle_ids, stream); auto node_types = cuopt::host_copy(d_types, stream); - n_sol = sol_offsets.size() - 1; + + n_sol = sol_offsets.size() - 1; accepted.resize(n_sol, -1); @@ -87,6 +89,17 @@ struct injection_info_t { added_node_ids.insert(tmp_routes[j]); } + if (p->order_info.is_pdp()) { + for (int node_id : added_node_ids) { + int brother_id = p->get_brother_node_info(p->get_node_info_of_node(node_id)).node(); + auto cond = added_node_ids.count(brother_id) > 0; + if (!cond) { + std::cout << "node_id: " << node_id << " brother_id: " << brother_id << std::endl; + } + cuopt_expects(cond, error_type_t::ValidationError, "Brother node is not served"); + } + } + desired_vehicle_ids.push_back(curr_vehicle_id); sol_routes.push_back({sol_n_routes++, new_route}); cuopt_expects(sol_n_routes <= p->get_fleet_size(), @@ -113,6 +126,7 @@ struct injection_info_t { std::iota(sequence.begin(), sequence.end(), 0); S.remove_routes(sequence); S.add_new_routes(sol_routes); + S.sol.global_runtime_checks(false, false, "Check Sol after injection"); solutions.emplace_back(std::move(S)); } return solutions; diff --git a/cpp/src/routing/util_kernels/runtime_checks.cu b/cpp/src/routing/util_kernels/runtime_checks.cu index bc50c5cc5..bb730465c 100644 --- a/cpp/src/routing/util_kernels/runtime_checks.cu +++ b/cpp/src/routing/util_kernels/runtime_checks.cu @@ -292,7 +292,7 @@ void solution_t::global_runtime_checks( [[maybe_unused]] bool check_feasible, [[maybe_unused]] const std::string_view where) { - // #define DEBUG_RUNTIME_CHECKS 1 +#define DEBUG_RUNTIME_CHECKS 1 #ifdef DEBUG_RUNTIME_CHECKS // Enable this print for debugging diff --git a/cpp/src/utilities/copy_helpers.hpp b/cpp/src/utilities/copy_helpers.hpp index 5f39013e3..611e7811a 100644 --- a/cpp/src/utilities/copy_helpers.hpp +++ b/cpp/src/utilities/copy_helpers.hpp @@ -1,6 +1,6 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights - * reserved. SPDX-License-Identifier: Apache-2.0 + * SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & + * AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -173,6 +173,16 @@ inline auto device_copy(std::vector const& host_vec, rmm::cuda_stream_view return device_vec; } +template +void print(std::string_view const name, std::vector const& container) +{ + std::cout << name << "=["; + for (auto const& item : container) { + std::cout << item << ","; + } + std::cout << "]\n"; +} + template void print(std::string_view const name, rmm::device_uvector const& container) { From a094a33ce2663b5a9799125d6a14fca9c52100c2 Mon Sep 17 00:00:00 2001 From: Hugo Linsenmaier Date: Thu, 3 Jul 2025 07:03:05 -0700 Subject: [PATCH 4/6] Disable runtime checks --- cpp/src/routing/util_kernels/runtime_checks.cu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/src/routing/util_kernels/runtime_checks.cu b/cpp/src/routing/util_kernels/runtime_checks.cu index bb730465c..bc50c5cc5 100644 --- a/cpp/src/routing/util_kernels/runtime_checks.cu +++ b/cpp/src/routing/util_kernels/runtime_checks.cu @@ -292,7 +292,7 @@ void solution_t::global_runtime_checks( [[maybe_unused]] bool check_feasible, [[maybe_unused]] const std::string_view where) { -#define DEBUG_RUNTIME_CHECKS 1 + // #define DEBUG_RUNTIME_CHECKS 1 #ifdef DEBUG_RUNTIME_CHECKS // Enable this print for debugging From 9c628c402d2f762b55d58159e0949aad4b18c796 Mon Sep 17 00:00:00 2001 From: Hugo Linsenmaier Date: Thu, 3 Jul 2025 07:41:11 -0700 Subject: [PATCH 5/6] Remove print --- cpp/src/routing/diversity/injection_info.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cpp/src/routing/diversity/injection_info.hpp b/cpp/src/routing/diversity/injection_info.hpp index f5bbf922f..09923fb64 100644 --- a/cpp/src/routing/diversity/injection_info.hpp +++ b/cpp/src/routing/diversity/injection_info.hpp @@ -40,7 +40,6 @@ struct injection_info_t { std::vector load_solutions() { - std::cout << "Inside load_solutions" << std::endl; auto stream = pool_allocator.sol_handles[0]->get_stream(); auto [d_vehicle_ids, d_routes, d_types, d_sol_offsets] = p->data_view_ptr->get_initial_solutions(); @@ -126,7 +125,7 @@ struct injection_info_t { std::iota(sequence.begin(), sequence.end(), 0); S.remove_routes(sequence); S.add_new_routes(sol_routes); - S.sol.global_runtime_checks(false, false, "Check Sol after injection"); + S.sol.global_runtime_checks(false, false, "Check solution after injection"); solutions.emplace_back(std::move(S)); } return solutions; From 9a9da024d11ed6e5c41436496621ee6f4b87bcb4 Mon Sep 17 00:00:00 2001 From: Hugo Linsenmaier Date: Thu, 3 Jul 2025 09:01:09 -0700 Subject: [PATCH 6/6] Do not remove requests from a if we skip a in equalize nodes --- cpp/src/routing/adapters/adapted_modifier.cu | 2 +- cpp/src/routing/diversity/diverse_solver.hpp | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cpp/src/routing/adapters/adapted_modifier.cu b/cpp/src/routing/adapters/adapted_modifier.cu index be3f09759..a99981776 100644 --- a/cpp/src/routing/adapters/adapted_modifier.cu +++ b/cpp/src/routing/adapters/adapted_modifier.cu @@ -154,7 +154,7 @@ void adapted_modifier_t::equalize_routes_and_nodes( } } - if (sol_a.sol.get_n_routes() > sol_b.sol.get_n_routes()) { + if (!skip_adding_nodes_to_a && sol_a.sol.get_n_routes() > sol_b.sol.get_n_routes()) { auto removed_nodes = sol_a.priority_remove_diff_routes(sol_b); missing_in_a.insert(missing_in_a.end(), removed_nodes.begin(), removed_nodes.end()); } else if (sol_b.sol.get_n_routes() > sol_a.sol.get_n_routes()) { diff --git a/cpp/src/routing/diversity/diverse_solver.hpp b/cpp/src/routing/diversity/diverse_solver.hpp index 971343411..5f4fc1c6b 100644 --- a/cpp/src/routing/diversity/diverse_solver.hpp +++ b/cpp/src/routing/diversity/diverse_solver.hpp @@ -1130,9 +1130,7 @@ struct solve { if (consider_expensive_recombiners) { recombine_options.insert(recombiner_t::EAX); recombine_options.insert(recombiner_t::AEAX); - if (solution::request_type != request_t::VRP && !a.problem->is_tsp) { - recombine_options.insert(recombiner_t::IX); - } + if (!a.problem->is_tsp) { recombine_options.insert(recombiner_t::IX); } } if (recombine_options.size() == 0) { return false; } }