OR-Tools  9.3
gscip_solver_callback.h
Go to the documentation of this file.
1// Copyright 2010-2021 Google LLC
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#ifndef OR_TOOLS_MATH_OPT_SOLVERS_GSCIP_SOLVER_CALLBACK_H_
15#define OR_TOOLS_MATH_OPT_SOLVERS_GSCIP_SOLVER_CALLBACK_H_
16
17#include <memory>
18#include <optional>
19
20#include "absl/base/thread_annotations.h"
21#include "absl/status/status.h"
22#include "absl/synchronization/mutex.h"
23#include "absl/time/time.h"
24#include "ortools/math_opt/callback.pb.h"
26#include "scip/type_scip.h"
27
28namespace operations_research {
29namespace math_opt {
30
31// Handler for user callbacks for GScipSolver.
32//
33// It deals with solve interruption when the user request it or when an error
34// occurs during the call of the user callback. Any such error is returned by
35// Flush().
36//
37// TODO(b/193537362): see if we need to share code with the handling of
38// SolveInterrupter. It is likely that it could the case to make sure the
39// `userinterrupt` flag is not lost. It may require sharing the same SCIP event
40// handler to make sure the user callback is called first; but maybe that is not
41// necessary.
43 public:
44 // Returns a non null handler if needed (there are supported events that we
45 // register to).
46 //
47 // The caller will also have to use MessageHandler() when calling
48 // GScip::Solve() when the result is not nullptr.
49 //
50 // At the end of the solve, Flush() must be called (when everything else
51 // succeeded) to make the final user callback calls and return the first error
52 // that occurred when calling the user callback.
53 static std::unique_ptr<GScipSolverCallbackHandler> RegisterIfNeeded(
54 const CallbackRegistrationProto& callback_registration,
55 SolverInterface::Callback callback, absl::Time solve_start, SCIP* scip);
56
59 delete;
60
61 // Makes any last pending calls and returns the first error that occurred
62 // while calling the user callback. Returns OkStatus if no error has occurred.
63 absl::Status Flush();
64
65 private:
67 absl::Time solve_start, SCIP* scip);
68
69 // Makes a call to the user callback, updating the status_ and interrupting
70 // the solve if needed (in case of error or if requested by the user).
71 //
72 // This function will ignores calls when status_ is not ok. It returns the
73 // result of the call of the callback when the call has successfully been made
74 // and the user has not requested the termination of the solve.
75 //
76 // This function will hold the callback_mutex_ while making the call to the
77 // user callback to serialize calls.
78 std::optional<CallbackResultProto> CallUserCallback(
79 const CallbackDataProto& callback_data)
80 ABSL_LOCKS_EXCLUDED(callback_mutex_);
81
82 // The user callback. Should be called via CallUserCallback().
83 const SolverInterface::Callback callback_;
84
85 // Start time of the solve.
86 const absl::Time solve_start_;
87
88 // The SCIP solver, used for interruptions.
89 SCIP* const scip_;
90
91 // Mutex serializing calls to the user callback and the access to status_.
92 absl::Mutex callback_mutex_;
93
94 // The first error status returned by the user callback.
95 absl::Status status_ ABSL_GUARDED_BY(callback_mutex_);
96};
97
98} // namespace math_opt
99} // namespace operations_research
100
101#endif // OR_TOOLS_MATH_OPT_SOLVERS_GSCIP_SOLVER_CALLBACK_H_
GScipSolverCallbackHandler & operator=(const GScipSolverCallbackHandler &)=delete
static std::unique_ptr< GScipSolverCallbackHandler > RegisterIfNeeded(const CallbackRegistrationProto &callback_registration, SolverInterface::Callback callback, absl::Time solve_start, SCIP *scip)
GScipSolverCallbackHandler(const GScipSolverCallbackHandler &)=delete
std::function< absl::StatusOr< CallbackResultProto >(const CallbackDataProto &)> Callback
MPCallback * callback
Collection of objects used to extend the Constraint Solver library.