OR-Tools  9.1
gscip_event_handler.cc
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 
15 
16 #include <string>
17 #include <vector>
18 
19 #include "absl/status/status.h"
20 #include "ortools/base/logging.h"
21 #include "ortools/gscip/gscip.h"
23 #include "scip/def.h"
24 #include "scip/scip.h"
25 #include "scip/scip_event.h"
26 #include "scip/type_event.h"
27 
31 };
32 
33 // SCIP callback implementation
34 
35 static SCIP_DECL_EVENTEXEC(EventExec) {
36  VLOG(3) << "EventExec";
37  CHECK_NE(scip, nullptr);
38  CHECK_NE(eventhdlr, nullptr);
39  CHECK_NE(event, nullptr);
40 
41  SCIP_EVENTHDLRDATA* const event_handler_data =
42  SCIPeventhdlrGetData(eventhdlr);
43  CHECK_NE(event_handler_data, nullptr);
44 
45  return event_handler_data->handler->Execute(
46  {event_handler_data->gscip, SCIPeventGetType(event)});
47 }
48 
49 static SCIP_DECL_EVENTINIT(EventInit) {
50  VLOG(3) << "EventInit";
51  CHECK_NE(scip, nullptr);
52  CHECK_NE(eventhdlr, nullptr);
53 
54  SCIP_EVENTHDLRDATA* const event_handler_data =
55  SCIPeventhdlrGetData(eventhdlr);
56  CHECK_NE(event_handler_data, nullptr);
57 
58  return event_handler_data->handler->Init(event_handler_data->gscip);
59 }
60 
61 static SCIP_DECL_EVENTEXIT(EventExit) {
62  VLOG(3) << "EventExit";
63  CHECK_NE(scip, nullptr);
64  CHECK_NE(eventhdlr, nullptr);
65 
66  SCIP_EVENTHDLRDATA* const event_handler_data =
67  SCIPeventhdlrGetData(eventhdlr);
68  CHECK_NE(event_handler_data, nullptr);
69 
70  SCIP_CALL(DropAllEvents(*event_handler_data->handler));
71 
72  return event_handler_data->handler->Exit(event_handler_data->gscip);
73 }
74 
75 static SCIP_DECL_EVENTFREE(EventFree) {
76  VLOG(3) << "EventFree";
77  CHECK_NE(scip, nullptr);
78  CHECK_NE(eventhdlr, nullptr);
79 
80  SCIP_EVENTHDLRDATA* const event_handler_data =
81  SCIPeventhdlrGetData(eventhdlr);
82  CHECK_NE(event_handler_data, nullptr);
83 
84  delete event_handler_data;
85  SCIPeventhdlrSetData(eventhdlr, nullptr);
86 
87  return SCIP_OKAY;
88 }
89 
90 namespace operations_research {
91 
92 void GScipEventHandler::Register(GScip* const gscip) {
93  CHECK_EQ(gscip_, nullptr) << "Already registered.";
94  CHECK_EQ(event_handler_, nullptr);
95 
96  gscip_ = gscip;
97 
98  // event_handler_data is freed in EventFree.
99  SCIP_EVENTHDLRDATA* const event_handler_data = new SCIP_EVENTHDLRDATA;
100  event_handler_data->gscip = gscip;
101  event_handler_data->handler = this;
102 
103  CHECK_OK(SCIP_TO_STATUS(SCIPincludeEventhdlrBasic(
104  gscip->scip(), &event_handler_, description_.name.c_str(),
105  description_.description.c_str(), EventExec, event_handler_data)));
106  CHECK_NE(event_handler_, nullptr);
107 
109  SCIPsetEventhdlrInit(gscip->scip(), event_handler_, EventInit)));
111  SCIPsetEventhdlrExit(gscip->scip(), event_handler_, EventExit)));
113  SCIPsetEventhdlrFree(gscip->scip(), event_handler_, EventFree)));
114 }
115 
116 SCIP_RETCODE GScipEventHandler::CatchEvent(const SCIP_EVENTTYPE event_type) {
117  int filter_pos = -1;
118 
119  SCIP_CALL(SCIPcatchEvent(gscip_->scip(), event_type, event_handler_,
120  /*eventdata=*/nullptr, &filter_pos));
121  CHECK_GE(filter_pos, 0);
122 
123  caught_events_.emplace_back(event_type, filter_pos);
124 
125  return SCIP_OKAY;
126 }
127 
128 SCIP_RETCODE DropAllEvents(GScipEventHandler& handler) {
129  for (const GScipEventHandler::CaughtEvent& caught_event :
130  handler.caught_events_) {
131  SCIP_CALL(SCIPdropEvent(handler.gscip_->scip(), caught_event.event_type,
132  handler.event_handler_,
133  /*eventdata=*/nullptr, caught_event.filter_pos));
134  }
135 
136  handler.caught_events_.clear();
137 
138  return SCIP_OKAY;
139 }
140 
141 } // namespace operations_research
static SCIP_DECL_EVENTEXIT(EventExit)
#define CHECK_GE(val1, val2)
Definition: base/logging.h:702
static SCIP_DECL_EVENTFREE(EventFree)
#define CHECK_OK(x)
Definition: base/logging.h:42
#define VLOG(verboselevel)
Definition: base/logging.h:979
#define SCIP_TO_STATUS(x)
SCIP_RETCODE DropAllEvents(GScipEventHandler &handler)
static SCIP_DECL_EVENTINIT(EventInit)
SCIP_RETCODE CatchEvent(SCIP_EVENTTYPE event_type)
#define CHECK_EQ(val1, val2)
Definition: base/logging.h:698
Collection of objects used to extend the Constraint Solver library.
#define CHECK_NE(val1, val2)
Definition: base/logging.h:699
operations_research::GScip * gscip
operations_research::GScipEventHandler * handler
static SCIP_DECL_EVENTEXEC(EventExec)