Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions cpp/src/mip/diversity/diversity_manager.cu
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <mip/presolve/probing_cache.cuh>
#include <mip/presolve/trivial_presolve.cuh>

#include <utilities/scope_guard.hpp>

#include "cuda_profiler_api.h"

namespace cuopt::linear_programming::detail {
Expand Down Expand Up @@ -308,6 +310,10 @@ solution_t<i_t, f_t> diversity_manager_t<i_t, f_t>::run_solver()
constexpr f_t max_time_on_lp = 30;
const f_t lp_time_limit = min(max_time_on_lp, time_limit * time_ratio_on_init_lp);

// to automatically compute the solving time on scope exit
auto timer_raii_guard =
cuopt::scope_guard([&]() { stats.total_solve_time = timer.elapsed_time(); });

// after every change to the problem, we should resize all the relevant vars
// we need to encapsulate that to prevent repetitions
lp_optimal_solution.resize(problem_ptr->n_variables, problem_ptr->handle_ptr->get_stream());
Expand Down Expand Up @@ -371,12 +377,8 @@ solution_t<i_t, f_t> diversity_manager_t<i_t, f_t>::run_solver()
if (check_b_b_preemption()) { return population.best_feasible(); }
// generate a population with 5 solutions(FP+FJ)
generate_initial_solutions();
if (timer.check_time_limit()) {
stats.total_solve_time = timer.elapsed_time();
return population.best_feasible();
}
if (timer.check_time_limit()) { return population.best_feasible(); }
main_loop();
stats.total_solve_time = timer.elapsed_time();
return population.best_feasible();
};

Expand Down
40 changes: 40 additions & 0 deletions cpp/src/utilities/scope_guard.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <utility>

namespace cuopt {

template <typename Func>
class scope_guard {
public:
explicit scope_guard(Func cleanup) : cleanup_(std::move(cleanup)) {}

~scope_guard() { cleanup_(); }

scope_guard(const scope_guard&) = delete;
scope_guard& operator=(const scope_guard&) = delete;
scope_guard(scope_guard&&) = delete;
scope_guard& operator=(scope_guard&&) = delete;

private:
Func cleanup_;
};

} // namespace cuopt
13 changes: 13 additions & 0 deletions cpp/tests/linear_programming/c_api_tests/c_api_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,19 @@ TEST(c_api, iteration_limit)
EXPECT_EQ(termination_status, CUOPT_TERIMINATION_STATUS_ITERATION_LIMIT);
}

TEST(c_api, solve_time_bb_preemption)
{
const std::string& rapidsDatasetRootDir = cuopt::test::get_rapids_dataset_root_dir();
std::string filename = rapidsDatasetRootDir + "/mip/" + "bb_optimality.mps";
int termination_status;
double solve_time = std::numeric_limits<double>::quiet_NaN();
EXPECT_EQ(solve_mps_file(filename.c_str(), 5, CUOPT_INFINITY, &termination_status, &solve_time),
CUOPT_SUCCESS);
EXPECT_EQ(termination_status, CUOPT_TERIMINATION_STATUS_OPTIMAL);
EXPECT_GT(solve_time, 0); // solve time should not be equal to 0, even on very simple instances
// solved by B&B before the diversity solver has time to run
}

TEST(c_api, bad_parameter_name) { EXPECT_EQ(test_bad_parameter_name(), CUOPT_INVALID_ARGUMENT); }

TEST(c_api, burglar) { EXPECT_EQ(burglar_problem(), CUOPT_SUCCESS); }
Expand Down