|
| 1 | +#pragma once |
| 2 | +#include <iostream> |
| 3 | +#include <vector> |
| 4 | +#include <memory> |
| 5 | + |
| 6 | +#include "cc_sketch_alg.h" |
| 7 | +#include "edge_store.h" |
| 8 | + |
| 9 | + |
| 10 | +// Configuration options for the minimum cut sketch algorithm |
| 11 | +class MCAlgConfiguration { |
| 12 | + private: |
| 13 | + // How large to make update batches as factor of sketch size |
| 14 | + double _batch_factor = 1; |
| 15 | + |
| 16 | + // Returned min-cut guaranteed to be a +/- epsilon multiplicative approx of the true min cut. |
| 17 | + double _epsilon = 0.5; |
| 18 | + |
| 19 | + // Number of subgraphs for which we use a delta sketch |
| 20 | + // When applying sketch updates to other subgraphs, apply updates directly to sketch |
| 21 | + size_t _num_subgraphs_use_delta = 2; |
| 22 | + |
| 23 | + friend class MinCutSketchAlg; |
| 24 | + public: |
| 25 | + // setters |
| 26 | + MCAlgConfiguration& batch_factor(double batch_factor) { |
| 27 | + if (batch_factor <= 0) { |
| 28 | + std::cerr << "WARNING: Batch factor in MCAlgConfiguration must be > 0." << std::endl; |
| 29 | + std::cerr << " Setting to default value: " << _batch_factor << std::endl; |
| 30 | + } else { |
| 31 | + _batch_factor = batch_factor; |
| 32 | + } |
| 33 | + return *this; |
| 34 | + } |
| 35 | + MCAlgConfiguration& epsilon(double epsilon) { |
| 36 | + if (epsilon <= 0 || epsilon > 1) { |
| 37 | + std::cerr << "WARNING: MCAlgConfiguration epsilon must be in range (0, 1]." << std::endl; |
| 38 | + std::cerr << " Setting to default value: " << _epsilon << std::endl; |
| 39 | + } else { |
| 40 | + _epsilon = epsilon; |
| 41 | + } |
| 42 | + return *this; |
| 43 | + } |
| 44 | + MCAlgConfiguration& num_subgraphs_use_delta(size_t num_subgraphs) { |
| 45 | + _num_subgraphs_use_delta = num_subgraphs; |
| 46 | + return *this; |
| 47 | + } |
| 48 | + |
| 49 | + // getters |
| 50 | + double get_batch_factor() { return _batch_factor; } |
| 51 | + double get_epsilon() { return _epsilon; } |
| 52 | + size_t get_num_subgraphs_use_delta() { return _num_subgraphs_use_delta; } |
| 53 | + |
| 54 | + friend std::ostream& operator<< (std::ostream &out, const MCAlgConfiguration &conf) { |
| 55 | + out << "Minimum Cut Algorithm Configuration:" << std::endl; |
| 56 | + out << " batch_factor = " << conf._batch_factor << std::endl; |
| 57 | + return out; |
| 58 | + } |
| 59 | +}; |
| 60 | + |
| 61 | +// Minimum cut sketch algorithm class |
| 62 | +class MinCutSketchAlg { |
| 63 | + private: |
| 64 | + const node_id_t num_vertices; |
| 65 | + const size_t seed; |
| 66 | + MCAlgConfiguration config; |
| 67 | + const size_t max_subgraphs; |
| 68 | + size_t cur_subgraphs; |
| 69 | + |
| 70 | + const double sketch_factor; |
| 71 | + const size_t sketch_samples; |
| 72 | + |
| 73 | + CCSketchAlg **cc_sketches; |
| 74 | + EdgeStore edge_store; |
| 75 | + |
| 76 | + Sketch *delta_sketches = nullptr; |
| 77 | + node_id_t **update_buffers = nullptr; |
| 78 | + size_t num_delta_sketches = 0; |
| 79 | + size_t num_upd_buffers = 0; |
| 80 | + |
| 81 | +#ifdef VERIFY_SAMPLES_F |
| 82 | + std::unique_ptr<GraphVerifier> verifier; |
| 83 | +#endif |
| 84 | + |
| 85 | + CCAlgConfiguration cc_config; |
| 86 | + public: |
| 87 | + /** |
| 88 | + * Construct an instance of the Minimum Cut Sketching Algorithm |
| 89 | + * param _num_vertices number of graph vertices |
| 90 | + * param _seed seed to hash functions |
| 91 | + * param _config Configuration options for minimum cut sketch algorithm |
| 92 | + */ |
| 93 | + MinCutSketchAlg(node_id_t _num_vertices, size_t _seed, |
| 94 | + MCAlgConfiguration _config = MCAlgConfiguration()); |
| 95 | + |
| 96 | + ~MinCutSketchAlg(); |
| 97 | + |
| 98 | + /** |
| 99 | + * Allocate memory for the worker threads to use when updating this algorithm's sketches |
| 100 | + */ |
| 101 | + void allocate_worker_memory(size_t num_workers); |
| 102 | + |
| 103 | + /** |
| 104 | + * Returns the number of buffered updates we would like to have in the update batches |
| 105 | + */ |
| 106 | + size_t get_desired_updates_per_batch() { |
| 107 | + return config._batch_factor; // TODO: Fill in correctly |
| 108 | + } |
| 109 | + |
| 110 | + /** |
| 111 | + * Action to take on an update before inserting it to the guttering system. |
| 112 | + * We use this function to manage the eager dsu. |
| 113 | + */ |
| 114 | + void pre_insert(GraphUpdate upd, node_id_t thr_id); |
| 115 | + |
| 116 | + |
| 117 | + /** |
| 118 | + * Update all the sketches for a vertex, given a batch of updates. |
| 119 | + * param thr_id The id of the thread performing the update [0, num_threads) |
| 120 | + * param src_vertex The vertex where the edges originate. |
| 121 | + * param dst_vertices A vector of destinations. |
| 122 | + */ |
| 123 | + void apply_update_batch(size_t thr_id, node_id_t src_vertex, |
| 124 | + const std::vector<node_id_t> &dst_vertices); |
| 125 | + |
| 126 | + /** |
| 127 | + * Set the verifier this algorithm will use to check its correctness |
| 128 | + * TODO: What is the right way to use verifier for minimum cut? |
| 129 | + */ |
| 130 | +#ifdef VERIFY_SAMPLES_F |
| 131 | + void set_verifier(std::unique_ptr<GraphVerifier> verifier) { |
| 132 | + this->verifier = std::move(verifier); |
| 133 | + } |
| 134 | +#endif |
| 135 | + |
| 136 | + /** |
| 137 | + * Main query routine of this algorithm. |
| 138 | + * Returns an approximation of the minimum cut of the graph defined by the graph stream |
| 139 | + * seen thus far. This approximation is guaranteed to be within 1 +/- epsilon of the true |
| 140 | + * minimum cut. |
| 141 | + */ |
| 142 | + size_t calc_minimum_cut(); |
| 143 | + |
| 144 | + /** |
| 145 | + * Return if we have cached an answer to query. |
| 146 | + * This allows the driver to avoid flushing the gutters before calling query functions. |
| 147 | + * TODO: Is there something intelligent we can do here for mincut/k-conn |
| 148 | + */ |
| 149 | + bool has_cached_query(int query_type) { |
| 150 | + if (query_type != MINIMUMCUT) return cc_sketches[0]->has_cached_query(query_type); |
| 151 | + return false; |
| 152 | + } |
| 153 | + |
| 154 | + /** |
| 155 | + * Print the configuration of minimum cut graph sketching algorithm. |
| 156 | + */ |
| 157 | + void print_configuration() { |
| 158 | + std::cout << config << std::endl; |
| 159 | + } |
| 160 | + |
| 161 | + node_id_t get_num_vertices() { return num_vertices; } |
| 162 | +}; |
0 commit comments