GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/util/resource_manager.h Lines: 2 2 100.0 %
Date: 2021-09-10 Branches: 2 4 50.0 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Gereon Kremer, Mathias Preiner, Liana Hadarean
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * This file provides the ResourceManager class. It can be used to impose
14
 * (cumulative and per-call) resource limits on the solver, as well as per-call
15
 * time limits.
16
 */
17
18
#include "cvc5_public.h"
19
20
#ifndef CVC5__RESOURCE_MANAGER_H
21
#define CVC5__RESOURCE_MANAGER_H
22
23
#include <stdint.h>
24
25
#include <array>
26
#include <chrono>
27
#include <memory>
28
#include <vector>
29
30
#include "theory/inference_id.h"
31
32
namespace cvc5 {
33
34
class Listener;
35
class Options;
36
class StatisticsRegistry;
37
38
/**
39
 * This class implements a easy to use wall clock timer based on std::chrono.
40
 */
41
13182
class WallClockTimer
42
{
43
  /**
44
   * The underlying clock that is used.
45
   * std::chrono::system_clock represents wall clock time.
46
   */
47
  using clock = std::chrono::system_clock;
48
  /** A time point of the clock we use. */
49
  using time_point = std::chrono::time_point<clock>;
50
51
 public:
52
  /** Checks whether this timer is active. */
53
  bool on() const;
54
  /**
55
   * Activates this timer with a timeout in milliseconds.
56
   * If millis is zero, the timer is deactivated.
57
   */
58
  void set(uint64_t millis);
59
  /** Returns the number of elapsed milliseconds since the last call to set().
60
   */
61
  uint64_t elapsed() const;
62
  /** Checks whether the current timeout has expired. */
63
  bool expired() const;
64
65
 private:
66
  /** The start of this timer. */
67
  time_point d_start;
68
  /** The point in time when this timer expires. */
69
  time_point d_limit;
70
};
71
72
/** Types of resources. */
73
enum class Resource
74
{
75
  ArithPivotStep,
76
  ArithNlLemmaStep,
77
  BitblastStep,
78
  BvEagerAssertStep,
79
  BvPropagationStep,
80
  BvSatConflictsStep,
81
  BvSatPropagateStep,
82
  BvSatSimplifyStep,
83
  CnfStep,
84
  DecisionStep,
85
  LemmaStep,
86
  NewSkolemStep,
87
  ParseStep,
88
  PreprocessStep,
89
  QuantifierStep,
90
  RestartStep,
91
  RewriteStep,
92
  SatConflictStep,
93
  TheoryCheckStep,
94
  Unknown
95
};
96
97
const char* toString(Resource r);
98
std::ostream& operator<<(std::ostream& os, Resource r);
99
100
namespace resman_detail {
101
/** The upper bound of values from the theory::InferenceId enum */
102
constexpr std::size_t InferenceIdMax =
103
    static_cast<std::size_t>(theory::InferenceId::UNKNOWN);
104
/** The upper bound of values from the Resource enum */
105
constexpr std::size_t ResourceMax = static_cast<std::size_t>(Resource::Unknown);
106
};  // namespace resman_detail
107
108
/**
109
 * This class manages resource limits (cumulative or per call) and (per call)
110
 * time limits. The available resources are listed in Resource and their individual
111
 * costs are configured via command line options.
112
 */
113
class ResourceManager
114
{
115
 public:
116
  /** Construct a resource manager. */
117
  ResourceManager(StatisticsRegistry& statistics_registry,
118
                  const Options& options);
119
  /** Default destructor. */
120
  ~ResourceManager();
121
  /** Can not be copied. */
122
  ResourceManager(const ResourceManager&) = delete;
123
  /** Can not be moved. */
124
  ResourceManager(ResourceManager&&) = delete;
125
  /** Can not be copied. */
126
  ResourceManager& operator=(const ResourceManager&) = delete;
127
  /** Can not be moved. */
128
  ResourceManager& operator=(ResourceManager&&) = delete;
129
130
  /** Checks whether any limit is active. */
131
  bool limitOn() const;
132
133
  /** Checks whether resources have been exhausted. */
134
  bool outOfResources() const;
135
  /** Checks whether time has been exhausted. */
136
  bool outOfTime() const;
137
  /** Checks whether any limit has been exhausted. */
138
86754291
  bool out() const { return outOfResources() || outOfTime(); }
139
140
  /** Retrieves amount of resources used overall. */
141
  uint64_t getResourceUsage() const;
142
  /** Retrieves time used over all calls. */
143
  uint64_t getTimeUsage() const;
144
  /** Retrieves the remaining number of cumulative resources. */
145
  uint64_t getResourceRemaining() const;
146
147
  /**
148
   * Spends a given resource. Throws an UnsafeInterruptException if there are
149
   * no remaining resources.
150
   */
151
  void spendResource(Resource r);
152
  /**
153
   * Spends a given resource. Throws an UnsafeInterruptException if there are
154
   * no remaining resources.
155
   */
156
  void spendResource(theory::InferenceId iid);
157
158
  /**
159
   * Resets perCall limits to mark the start of a new call,
160
   * updates budget for current call and starts the timer
161
   */
162
  void beginCall();
163
164
  /**
165
   * Marks the end of a SmtEngine check call, stops the per
166
   * call timer.
167
   */
168
  void endCall();
169
170
  /**
171
   * Registers a listener that is notified on a resource out or (per-call)
172
   * timeout.
173
   */
174
  void registerListener(Listener* listener);
175
176
 private:
177
  const Options& d_options;
178
  /** The per-call wall clock timer. */
179
  WallClockTimer d_perCallTimer;
180
181
  /** The total number of milliseconds used. */
182
  uint64_t d_cumulativeTimeUsed;
183
  /** The total amount of resources used. */
184
  uint64_t d_cumulativeResourceUsed;
185
186
  /** The amount of resources used during this call. */
187
  uint64_t d_thisCallResourceUsed;
188
189
  /**
190
   * The resource budget for this call (min between per call
191
   * budget and left-over cumulative budget.)
192
   */
193
  uint64_t d_thisCallResourceBudget;
194
195
  /** Receives a notification on reaching a limit. */
196
  std::vector<Listener*> d_listeners;
197
198
  void spendResource(uint64_t amount);
199
200
  /** Weights for InferenceId resources */
201
  std::array<uint64_t, resman_detail::InferenceIdMax + 1> d_infidWeights;
202
  /** Weights for Resource resources */
203
  std::array<uint64_t, resman_detail::ResourceMax + 1> d_resourceWeights;
204
205
  struct Statistics;
206
  /** The statistics object */
207
  std::unique_ptr<Statistics> d_statistics;
208
}; /* class ResourceManager */
209
210
}  // namespace cvc5
211
212
#endif /* CVC5__RESOURCE_MANAGER_H */