@@ -12,7 +12,7 @@ constexpr int log2_constexpr(size_t num) {
1212 return power;
1313}
1414
15- class CacheGuttering : public GutteringSystem {
15+ class PipelineHyperTree {
1616 private:
1717 const size_t inserters;
1818 const node_id_t num_nodes;
@@ -102,7 +102,7 @@ class CacheGuttering : public GutteringSystem {
102102
103103 class SharedGutter {
104104 private:
105- CacheGuttering &CGsystem;
105+ PipelineHyperTree &CGsystem;
106106 public:
107107 update_t *data;
108108 std::atomic<size_t > insert_pos;
@@ -112,7 +112,7 @@ class CacheGuttering : public GutteringSystem {
112112 const size_t level;
113113
114114 // true init
115- SharedGutter (CacheGuttering &CGsystem, size_t size, size_t level, size_t index)
115+ SharedGutter (PipelineHyperTree &CGsystem, size_t size, size_t level, size_t index)
116116 : CGsystem(CGsystem),
117117 data (new update_t [size]),
118118 insert_pos(0 ),
@@ -124,31 +124,31 @@ class CacheGuttering : public GutteringSystem {
124124 delete[] data;
125125 }
126126
127- bool batch_insert (CacheGuttering ::InsertThread &thr, SharedGutter *&gut_ptr,
127+ bool batch_insert (PipelineHyperTree ::InsertThread &thr, SharedGutter *&gut_ptr,
128128 const std::vector<update_t > &updates);
129129 void flush (InsertThread &thr, SharedGutter *&gut_ptr, size_t num_upd_flush,
130130 const std::vector<update_t > &updates);
131131 };
132132
133133 class LeafGutter {
134134 private:
135- CacheGuttering &CGsystem;
135+ PipelineHyperTree &CGsystem;
136136 public:
137137 std::vector<node_id_t > data;
138138 std::atomic<size_t > insert_pos;
139139 std::atomic<int > active_inserts;
140140 node_id_t index;
141141 const size_t capacity;
142142
143- LeafGutter (CacheGuttering &CGsystem, size_t size, size_t index)
143+ LeafGutter (PipelineHyperTree &CGsystem, size_t size, size_t index)
144144 : CGsystem(CGsystem),
145145 data (size),
146146 insert_pos(0 ),
147147 active_inserts(0 ),
148148 index(index),
149149 capacity(size) {}
150150
151- bool batch_insert (CacheGuttering ::InsertThread &thr, LeafGutter *&gut_ptr,
151+ bool batch_insert (PipelineHyperTree ::InsertThread &thr, LeafGutter *&gut_ptr,
152152 const std::vector<node_id_t > &updates);
153153 void flush (InsertThread &thr, LeafGutter *&gut_ptr, size_t num_upd_flush,
154154 const std::vector<node_id_t > &updates);
@@ -163,15 +163,15 @@ class CacheGuttering : public GutteringSystem {
163163 private:
164164 static constexpr size_t root_buffer_capacity = 256 ;
165165 size_t root_buffer_size = 0 ;
166- CacheGuttering &CGsystem; // reference to associated CacheGuttering system
166+ PipelineHyperTree &CGsystem; // reference to associated PipelineHyperTree system
167167
168168 // thread local gutters
169169 update_t root_buffer[root_buffer_capacity];
170170 std::array<LocalGutter<level1_elms_per_buf>, level1_bufs> level1_gutters;
171171 std::array<LocalGutter<level2_elms_per_buf>, level2_bufs> level2_gutters;
172172
173173 public:
174- InsertThread (CacheGuttering &CGsystem)
174+ InsertThread (PipelineHyperTree &CGsystem)
175175 : CGsystem(CGsystem),
176176 l3_insert_bufs (local_fanout),
177177 l4_insert_bufs(global_fanout),
@@ -239,6 +239,9 @@ class CacheGuttering : public GutteringSystem {
239239 InsertThread (InsertThread &&) = default ;
240240 };
241241
242+ void flush_leaf (PipelineHyperTree::InsertThread &thr, LeafGutter *&gut_ptr,
243+ const std::vector<node_id_t > &updates);
244+
242245 // buffers shared amongst all threads
243246 SharedGutter **level3_gutters = nullptr ;
244247 SharedGutter **level4_gutters = nullptr ;
@@ -249,48 +252,44 @@ class CacheGuttering : public GutteringSystem {
249252 friend class InsertThread ;
250253
251254 std::vector<InsertThread> insert_threads; // vector of InsertThreads
255+ VertexBatchQueue &wq;
252256 public:
253257 /* *
254258 * Constructs a new guttering systems using a tree like structure for cache efficiency.
255259 * @param nodes number of nodes in the graph.
256260 * @param workers the number of workers which will be removing batches
257261 * @param inserters the number of inserter buffers
258262 */
259- CacheGuttering (node_id_t nodes, uint32_t workers, uint32_t inserters,
260- GutteringConfiguration conf);
261- CacheGuttering (node_id_t nodes, uint32_t workers, uint32_t inserters) :
262- CacheGuttering(nodes, workers, inserters, GutteringConfiguration()) {};
263+ PipelineHyperTree (node_id_t nodes, size_t inserters, GutteringConfiguration &conf,
264+ VertexBatchQueue &wq);
263265
264- ~CacheGuttering ();
266+ ~PipelineHyperTree ();
265267
266268 /* *
267269 * Puts an update into the data structure.
268- * @param upd the edge update.1
270+ * @param upd the edge update.
269271 * @param which, which thread is inserting this update
270272 * @return nothing.
271273 */
272- insert_ret_t insert (const update_t &upd, size_t which) override {
274+ insert_ret_t insert (const update_t &upd, size_t which) {
273275 assert (which < inserters);
274276 insert_threads[which].insert (upd);
275277 }
276278
277- insert_ret_t batch_insert (const update_t *batch, size_t num_updates, size_t which) override {
279+ insert_ret_t batch_insert (const update_t *batch, size_t num_updates, size_t which) {
278280 assert (which < inserters);
279281 insert_threads[which].batch_insert (batch, num_updates);
280282 }
281283
282284 insert_ret_t process_stream_upd_batch (const GraphStreamUpdate *batch, size_t num_updates,
283- size_t which) override {
285+ size_t which) {
284286 assert (which < inserters);
285287 insert_threads[which].process_stream_upd_batch (batch, num_updates);
286288 }
287289
288290 // pure virtual functions don't like default params, so default to 'which' of 0
289291 insert_ret_t insert (const update_t &upd) { insert_threads[0 ].insert (upd); }
290292
291- void flush_leaf (CacheGuttering::InsertThread &thr, LeafGutter *&gut_ptr,
292- const std::vector<node_id_t > &updates);
293-
294293 /* *
295294 * Flushes all pending buffers. When this function returns there are no more updates in the
296295 * guttering system
@@ -304,14 +303,69 @@ class CacheGuttering : public GutteringSystem {
304303 * distributed guttering. If you don't know what that means, don't use this function!
305304 *
306305 * @param offset
307- * @return a reference to the parent CacheGuttering object.
306+ * @return a reference to the parent PipelineHyperTree object.
308307 */
309- CacheGuttering& set_offset (node_id_t offset) { relabelling_offset = offset; return * this ; }
308+ void set_offset (node_id_t offset) { relabelling_offset = offset; }
310309
311310 /*
312311 * Helper function for tracing a root to leaf path. Prints path to stdout
313312 * @param src the node id to trace
314313 */
315314 void print_r_to_l (node_id_t src);
316315 void print_fanouts ();
316+
317+ // number of batches per work queue element
318+ const size_t wq_batch_per_elm;
319+ const size_t leaf_gutter_size;
320+ };
321+
322+ // The CacheGuttering class adds the GutteringSystem base class to the PipelineHyperTree
323+ class CacheGuttering : public GutteringSystem {
324+ private:
325+ PipelineHyperTree pht;
326+ public:
327+ CacheGuttering (node_id_t nodes, size_t workers, size_t inserters, GutteringConfiguration conf)
328+ : GutteringSystem(nodes, workers, conf), pht(nodes, inserters, conf, wq){};
329+
330+
331+ /* *
332+ * Puts an update into the data structure.
333+ * @param upd the edge update.
334+ * @param which, which thread is inserting this update
335+ * @return nothing.
336+ */
337+ insert_ret_t insert (const update_t &upd, size_t which) override {
338+ pht.insert (upd, which);
339+ }
340+
341+ insert_ret_t batch_insert (const update_t *batch, size_t num_updates, size_t which) override {
342+ pht.batch_insert (batch, num_updates, which);
343+ }
344+
345+ insert_ret_t process_stream_upd_batch (const GraphStreamUpdate *batch, size_t num_updates,
346+ size_t which) override {
347+ pht.process_stream_upd_batch (batch, num_updates, which);
348+ }
349+
350+ // pure virtual functions don't like default params, so default to 'which' of 0
351+ insert_ret_t insert (const update_t &upd) { pht.insert (upd); }
352+
353+ /* *
354+ * Flushes all pending buffers. When this function returns there are no more updates in the
355+ * guttering system
356+ * @return nothing.
357+ */
358+ flush_ret_t force_flush () {
359+ pht.force_flush ();
360+ }
361+
362+ /* *
363+ * Set the "offset" for incoming edges. That is, if we set an offset of x, an incoming edge
364+ * {i,j} will be stored internally as an edge {i - x, j}. Use only for integration with
365+ * distributed guttering. If you don't know what that means, don't use this function!
366+ *
367+ * @param offset
368+ * @return a reference to the parent PipelineHyperTree object.
369+ */
370+ void set_offset (node_id_t offset) { pht.set_offset (offset); }
317371};
0 commit comments