The bliss C++ API 0.77 (Debian 0.77-3)
partition.hh
1#pragma once
2
3/*
4 Copyright (c) 2003-2021 Tommi Junttila
5 Released under the GNU Lesser General Public License version 3.
6
7 This file is part of bliss.
8
9 bliss is free software: you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation, version 3 of the License.
12
13 bliss is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with bliss. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22namespace bliss {
23 class Partition;
24}
25
26#include <vector>
27#include <climits>
28#include <bliss/kqueue.hh>
29#include <bliss/abstractgraph.hh>
30
31
32namespace bliss {
33
45{
46public:
50 class Cell
51 {
52 friend class Partition;
53 public:
54 unsigned int length;
55 /* Index of the first element of the cell in
56 the Partition::elements array */
57 unsigned int first;
58 unsigned int max_ival;
59 unsigned int max_ival_count;
60 private:
61 bool in_splitting_queue;
62 public:
63 bool in_neighbour_heap;
64 /* Pointer to the next cell, null if this is the last one. */
65 Cell* next;
66 Cell* prev;
67 Cell* next_nonsingleton;
68 Cell* prev_nonsingleton;
69 unsigned int split_level;
71 bool is_unit() const {return(length == 1); }
73 bool is_in_splitting_queue() const {return(in_splitting_queue); }
74 };
75
76
77private:
78
83 class RefInfo {
84 public:
85 unsigned int split_cell_first;
86 int prev_nonsingleton_first;
87 int next_nonsingleton_first;
88 };
92 std::vector<RefInfo> refinement_stack;
93
94 class BacktrackInfo {
95 public:
96 unsigned int refinement_stack_size;
97 unsigned int cr_backtrack_point;
98 };
99
103 std::vector<BacktrackInfo> bt_stack;
104
105public:
106 AbstractGraph* graph;
107
108 /* Used during equitable partition refinement */
109 KQueue<Cell*> splitting_queue;
110 void splitting_queue_add(Cell* const cell);
111 Cell* splitting_queue_pop();
112 bool splitting_queue_is_empty() const;
113 void splitting_queue_clear();
114
115
117 typedef unsigned int BacktrackPoint;
118
123
128
137 Cell* individualize(Cell* const cell,
138 const unsigned int element);
139
140 Cell* aux_split_in_two(Cell* const cell,
141 const unsigned int first_half_size);
142
143
144private:
145 unsigned int N;
146 Cell* cells;
147 Cell* free_cells;
148 unsigned int discrete_cell_count;
149public:
150 Cell* first_cell;
151 Cell* first_nonsingleton_cell;
152 unsigned int *elements;
153 /* invariant_values[e] gives the invariant value of the element e */
154 unsigned int *invariant_values;
155 /* element_to_cell_map[e] gives the cell of the element e */
156 Cell **element_to_cell_map;
158 Cell* get_cell(const unsigned int e) const {
159 assert(e < N);
160 return element_to_cell_map[e];
161 }
162 /* in_pos[e] points to the elements array s.t. *in_pos[e] = e */
163 unsigned int **in_pos;
164
165 Partition();
166 ~Partition();
167
172 void init(const unsigned int N);
173
178 bool is_discrete() const {return(free_cells == 0); }
179
180 unsigned int nof_discrete_cells() const {return(discrete_cell_count); }
181
185 size_t print(FILE* const fp, const bool add_newline = true) const;
186
190 size_t print_signature(FILE* const fp, const bool add_newline = true) const;
191
192 /*
193 * Splits the Cell \a cell into [cell_1,...,cell_n]
194 * according to the invariant_values of the elements in \a cell.
195 * After splitting, cell_1 == \a cell.
196 * Returns the pointer to the Cell cell_n;
197 * cell_n != cell iff the Cell \a cell was actually splitted.
198 * The flag \a max_ival_info_ok indicates whether the max_ival and
199 * max_ival_count fields of the Cell \a cell have consistent values
200 * when the method is called.
201 * Clears the invariant values of the elements in the Cell \a cell as well as
202 * the max_ival and max_ival_count fields of the Cell \a cell.
203 */
204 Cell *zplit_cell(Cell * const cell, const bool max_ival_info_ok);
205
206 /*
207 * Routines for component recursion
208 */
209 void cr_init();
210 void cr_free();
211 unsigned int cr_get_level(const unsigned int cell_index) const;
212 unsigned int cr_split_level(const unsigned int level,
213 const std::vector<unsigned int>& cells);
214
216 void clear_ivs(Cell* const cell);
217
218private:
219 /*
220 * Component recursion data structures
221 */
222
223 /* Is component recursion support in use? */
224 bool cr_enabled;
225
226 class CRCell {
227 public:
228 unsigned int level;
229 CRCell* next;
230 CRCell** prev_next_ptr;
231 void detach() {
232 if(next)
233 next->prev_next_ptr = prev_next_ptr;
234 *(prev_next_ptr) = next;
235 level = UINT_MAX;
236 next = nullptr;
237 prev_next_ptr = nullptr;
238 }
239 };
240 CRCell* cr_cells;
241 CRCell** cr_levels;
242 class CR_BTInfo {
243 public:
244 unsigned int created_trail_index;
245 unsigned int splitted_level_trail_index;
246 };
247 std::vector<unsigned int> cr_created_trail;
248 std::vector<unsigned int> cr_splitted_level_trail;
249 std::vector<CR_BTInfo> cr_bt_info;
250 unsigned int cr_max_level;
251 void cr_create_at_level(const unsigned int cell_index, unsigned int level);
252 void cr_create_at_level_trailed(const unsigned int cell_index, unsigned int level);
253 unsigned int cr_get_backtrack_point();
254 void cr_goto_backtrack_point(const unsigned int btpoint);
255
256
257 /*
258 *
259 * Auxiliary routines for sorting and splitting cells
260 *
261 */
262 Cell* sort_and_split_cell1(Cell* cell);
263 Cell* sort_and_split_cell255(Cell* const cell, const unsigned int max_ival);
264 bool shellsort_cell(Cell* cell);
265 Cell* split_cell(Cell* const cell);
266
267 /*
268 * Some auxiliary stuff needed for distribution count sorting.
269 * To make the code thread-safe (modulo the requirement that each graph is
270 * only accessed in one thread at a time), the arrays are owned by
271 * the partition instance, not statically defined.
272 */
273 unsigned int dcs_count[256];
274 unsigned int dcs_start[256];
275 void dcs_cumulate_count(const unsigned int max);
276};
277
278
279inline Partition::Cell*
280Partition::splitting_queue_pop()
281{
282 assert(!splitting_queue.is_empty());
283 Cell* const cell = splitting_queue.pop_front();
284 assert(cell->in_splitting_queue);
285 cell->in_splitting_queue = false;
286 return cell;
287}
288
289inline bool
290Partition::splitting_queue_is_empty() const
291{
292 return splitting_queue.is_empty();
293}
294
295
296inline unsigned int
297Partition::cr_get_level(const unsigned int cell_index) const
298{
299 assert(cr_enabled);
300 assert(cell_index < N);
301 assert(cr_cells[cell_index].level != UINT_MAX);
302 return(cr_cells[cell_index].level);
303}
304
305} // namespace bliss
Data structure for holding information about a cell in a Partition.
Definition: partition.hh:51
bool is_in_splitting_queue() const
Definition: partition.hh:73
bool is_unit() const
Definition: partition.hh:71
A class for refinable, backtrackable ordered partitions.
Definition: partition.hh:45
Cell * get_cell(const unsigned int e) const
Definition: partition.hh:158
bool is_discrete() const
Definition: partition.hh:178
void goto_backtrack_point(BacktrackPoint p)
Definition: partition.cc:161
size_t print(FILE *const fp, const bool add_newline=true) const
Definition: partition.cc:353
void clear_ivs(Cell *const cell)
Definition: partition.cc:822
Cell * individualize(Cell *const cell, const unsigned int element)
Definition: partition.cc:254
void init(const unsigned int N)
Definition: partition.cc:64
size_t print_signature(FILE *const fp, const bool add_newline=true) const
Definition: partition.cc:379
BacktrackPoint set_backtrack_point()
Definition: partition.cc:147
unsigned int BacktrackPoint
Definition: partition.hh:117
Definition: abstractgraph.cc:35