OR-Tools  9.6
gscip_solver_callback.h
Go to the documentation of this file.
1 // Copyright 2010-2022 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 
28 namespace operations_research {
29 namespace 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_
static std::unique_ptr< GScipSolverCallbackHandler > RegisterIfNeeded(const CallbackRegistrationProto &callback_registration, SolverInterface::Callback callback, absl::Time solve_start, SCIP *scip)
GScipSolverCallbackHandler & operator=(const GScipSolverCallbackHandler &)=delete
GScipSolverCallbackHandler(const GScipSolverCallbackHandler &)=delete
std::function< absl::StatusOr< CallbackResultProto >(const CallbackDataProto &)> Callback
MPCallback * callback
Collection of objects used to extend the Constraint Solver library.