Skip to content

Commit

Permalink
update to master
Browse files Browse the repository at this point in the history
  • Loading branch information
mschimek committed Oct 25, 2024
2 parents bb39cd5 + c37de78 commit 1d2c3d1
Show file tree
Hide file tree
Showing 27 changed files with 498 additions and 115 deletions.
1 change: 0 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
endif ()
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
list(APPEND KAGEN_WARNING_FLAGS
"-Wnoexcept"
"-Wsuggest-override"
"-fdiagnostics-color=always"
"-Wcast-qual"
Expand Down
15 changes: 14 additions & 1 deletion app/KaGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ This is mostly useful for experimental graph generators or when using KaGen to l
"automatically");
app.add_flag("-C,--coordinates", config.coordinates, "Generate coordinates (geometric generators only)");

// Edge weight generator parameters
app.add_option(
"--edgeweights-generator", config.edge_weights.generator_type,
"Generator type to use for generating edge weights.")
Expand All @@ -177,9 +178,21 @@ This is mostly useful for experimental graph generators or when using KaGen to l
"--edgeweights-range-begin", config.edge_weights.weight_range_begin,
"(Included) begin of weight range used for edge weights, i.e., minimum edge weight.");
app.add_option(
"--edgeweights-range-end", config.edge_weights.weight_range_begin,
"--edgeweights-range-end", config.edge_weights.weight_range_end,
"(Excluded) end of weight range to be used for edge weights.");

// Vertex weight generator parameters
app.add_option(
"--vertexweights-generator", config.vertex_weights.generator_type,
"Generator type to use for generating vertex weights.")
->transform(CLI::CheckedTransformer(GetVertexWeightGeneratorTypeMap(), CLI::ignore_case));
app.add_option(
"--vertexweights-range-begin", config.vertex_weights.weight_range_begin,
"(Included) begin of weight range used for vertex weights, i.e., minimum vertex weight.");
app.add_option(
"--vertexweights-range-end", config.vertex_weights.weight_range_end,
"(Excluded) end of weight range to be used for vertex weights.");

{ // Options string
auto* cmd = app.add_subcommand(
"options",
Expand Down
34 changes: 25 additions & 9 deletions kagen/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,9 @@ PGeneratorConfig CreateConfigFromString(const std::string& options_str, PGenerat
config.grid_x = get_sint_or_default("grid_x", get_sint_or_default("x"));
config.grid_y = get_sint_or_default("grid_y", get_sint_or_default("y"));
config.grid_z = get_sint_or_default("grid_z", get_sint_or_default("z"));
config.rmat_a = get_hpfloat_or_default("rmat_a", get_hpfloat_or_default("a"));
config.rmat_b = get_hpfloat_or_default("rmat_b", get_hpfloat_or_default("b"));
config.rmat_c = get_hpfloat_or_default("rmat_c", get_hpfloat_or_default("c"));
config.rmat_a = get_hpfloat_or_default("rmat_a", get_hpfloat_or_default("a", Graph500RMATDefaults::a));
config.rmat_b = get_hpfloat_or_default("rmat_b", get_hpfloat_or_default("b", Graph500RMATDefaults::b));
config.rmat_c = get_hpfloat_or_default("rmat_c", get_hpfloat_or_default("c", Graph500RMATDefaults::c));
config.coordinates = get_bool_or_default("coordinates");
config.permute = get_bool_or_default("permute");

Expand Down Expand Up @@ -404,20 +404,36 @@ PGeneratorConfig CreateConfigFromString(const std::string& options_str, PGenerat

{
// edge weight generation
const std::string weight_generator_name =
const std::string edge_weight_generator_name =
get_string_or_default("edgeweights_generator", StringifyEnum(config.edge_weights.generator_type));

const auto weight_generators = GetEdgeWeightGeneratorTypeMap();
const auto weight_generator_it = weight_generators.find(weight_generator_name);
if (weight_generator_it == weight_generators.end()) {
throw std::runtime_error("invalid graph distribution");
const auto edge_weight_generators = GetEdgeWeightGeneratorTypeMap();
const auto edge_weight_generator_it = edge_weight_generators.find(edge_weight_generator_name);
if (edge_weight_generator_it == edge_weight_generators.end()) {
throw std::runtime_error("invalid edge weight generator type");
}
config.edge_weights.generator_type = weight_generator_it->second;
config.edge_weights.generator_type = edge_weight_generator_it->second;
config.edge_weights.weight_range_begin =
get_sint_or_default("edgeweights_range_begin", config.edge_weights.weight_range_begin);
config.edge_weights.weight_range_end =
get_sint_or_default("edgeweights_range_end", config.edge_weights.weight_range_end);
}
{
// vertex weight generation
const std::string vertex_weight_generator_name =
get_string_or_default("vertexweights_generator", StringifyEnum(config.vertex_weights.generator_type));

const auto vertex_weight_generators = GetVertexWeightGeneratorTypeMap();
const auto vertex_weight_generator_it = vertex_weight_generators.find(vertex_weight_generator_name);
if (vertex_weight_generator_it == vertex_weight_generators.end()) {
throw std::runtime_error("invalid vertex weight generator type");
}
config.vertex_weights.generator_type = vertex_weight_generator_it->second;
config.vertex_weights.weight_range_begin =
get_sint_or_default("vertexweights_range_begin", config.vertex_weights.weight_range_begin);
config.vertex_weights.weight_range_end =
get_sint_or_default("vertexweights_range_end", config.vertex_weights.weight_range_end);
}

int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
Expand Down
25 changes: 21 additions & 4 deletions kagen/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,14 @@ struct InputGraphConfig {
bool drop_edge_weights = false;
};

struct VertexWeightConfig {
VertexWeightGeneratorType generator_type = VertexWeightGeneratorType::DEFAULT;
SInt weight_range_begin = 1;
SInt weight_range_end = 100;
};

struct EdgeWeightConfig {
EdgeWeightGeneratorType generator_type = EdgeWeightGeneratorType::NONE;
EdgeWeightGeneratorType generator_type = EdgeWeightGeneratorType::DEFAULT;
SInt weight_range_begin = 1;
SInt weight_range_end = 100;
};
Expand Down Expand Up @@ -88,6 +94,14 @@ struct ExternalMemoryConfig {
bool refuse_external_mode = false;
};

// Probabilities used in the Graph500 benchmark
// https://graph500.org/?page_id=12
struct Graph500RMATDefaults {
static constexpr double a = 0.57;
static constexpr double b = 0.19;
static constexpr double c = 0.19;
};

// Configuration for the generator.
struct PGeneratorConfig {
// General settings
Expand Down Expand Up @@ -118,9 +132,9 @@ struct PGeneratorConfig {
SInt grid_z = 0; // Grid z dimension (Grid3D)
bool periodic = false; // Use periodic boundary (Grid2D, Grid3D)
int hp_floats = 0; // Use 80 bit floating point numbers for RHG generator, 0 for auto
double rmat_a = 0.0;
double rmat_b = 0.0;
double rmat_c = 0.0;
double rmat_a = Graph500RMATDefaults::a;
double rmat_b = Graph500RMATDefaults::b;
double rmat_c = Graph500RMATDefaults::c;
bool directed = false;
bool permute = false; // Permute node vertices

Expand All @@ -137,6 +151,9 @@ struct PGeneratorConfig {
// Settings for edge weight generation
EdgeWeightConfig edge_weights{};

// Settings for vertex weight generation
VertexWeightConfig vertex_weights{};

// Hashing / sampling settings
int seed = 1; // Seed for PRNG
bool hash_sample = false; // Use hash tryagain sampling
Expand Down
16 changes: 16 additions & 0 deletions kagen/edgeweight_generators/default_generator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include "kagen/context.h"
#include "kagen/edgeweight_generators/edge_weight_generator.h"
#include "kagen/kagen.h"

namespace kagen {
class DefaultEdgeWeightGenerator : public EdgeWeightGenerator {
public:
DefaultEdgeWeightGenerator(EdgeWeightConfig) {}

void GenerateEdgeWeights(const Edgelist&, EdgeWeights&) final {}

void GenerateEdgeWeights(const XadjArray&, const AdjncyArray&, EdgeWeights&) final {}
};
} // namespace kagen
7 changes: 3 additions & 4 deletions kagen/edgeweight_generators/edge_weight_generator.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
#pragma once

#include "kagen/context.h"
#include "kagen/kagen.h"

namespace kagen {
class EdgeWeightGenerator {
public:
virtual ~EdgeWeightGenerator() = default;

virtual EdgeWeights GenerateEdgeWeights(const Edgelist& edgelist) = 0;
virtual void GenerateEdgeWeights(const Edgelist& edgelist, EdgeWeights& weights) = 0;

virtual EdgeWeights
GenerateEdgeWeights(const XadjArray& xadj, const AdjncyArray& adjncy) = 0;
virtual void GenerateEdgeWeights(const XadjArray& xadj, const AdjncyArray& adjncy, EdgeWeights& weights) = 0;
};
} // namespace kagen
22 changes: 15 additions & 7 deletions kagen/edgeweight_generators/hashing_based_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,26 @@
#include "kagen/context.h"
#include "kagen/kagen.h"

#include "xxhash.h"
#ifdef KAGEN_XXHASH_FOUND
#include "xxhash.h"
#else // KAGEN_XXHASH_FOUND
#include <stdexcept>
#endif // KAGEN_XXHASH_FOUND

namespace kagen {
HashingBasedEdgeWeightGenerator::HashingBasedEdgeWeightGenerator(EdgeWeightConfig config) : config_(config) {}

SSInt HashingBasedEdgeWeightGenerator::GenerateEdgeWeight(SInt u, SInt v) {
SSInt hash1, hash2;

hash1 = XXH64(&u, 1, 0);
hash2 = XXH64(&v, 1, 0);
SSInt combined_value =
#ifdef KAGEN_XXHASH_FOUND
const SInt hash1 = XXH64(&u, 1, 0);
const SInt hash2 = XXH64(&v, 1, 0);
const SSInt combined =
(hash1 ^ hash2) % (config_.weight_range_end - config_.weight_range_begin) + config_.weight_range_begin;
return combined_value;
return combined;
#else // KAGEN_XXHASH_FOUND
((void)u);
((void)v);
throw std::runtime_error("xxHash is required for hashing based edge weights");
#endif // KAGEN_XXHASH_FOUND
}
} // namespace kagen
20 changes: 0 additions & 20 deletions kagen/edgeweight_generators/none_generator.h

This file was deleted.

12 changes: 3 additions & 9 deletions kagen/edgeweight_generators/per_edge_weight_generator.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,26 @@ namespace kagen {
template <typename Derived>
class PerEdgeWeightGenerator : public EdgeWeightGenerator {
public:
EdgeWeights GenerateEdgeWeights(const Edgelist& edgelist) final {
EdgeWeights weights;
void GenerateEdgeWeights(const Edgelist& edgelist, EdgeWeights& weights) final {
weights.reserve(edgelist.size());

for (const auto& [u, v]: edgelist) {
SSInt weight = static_cast<Derived*>(this)->GenerateEdgeWeight(u, v);
weights.push_back(weight);
}
return weights;
}

EdgeWeights
GenerateEdgeWeights(const XadjArray& xadj, const AdjncyArray& adjncy) final {
EdgeWeights weights;
void GenerateEdgeWeights(const XadjArray& xadj, const AdjncyArray& adjncy, EdgeWeights& weights) final {
weights.reserve(adjncy.size());

for (SInt u = 0; u + 1 < xadj.size(); ++u) {
for (SInt e = xadj[u]; e < xadj[u + 1]; ++e) {
SInt v = adjncy[e];
SInt v = adjncy[e];
SSInt weight = static_cast<Derived*>(this)->GenerateEdgeWeight(u, v);
weights.push_back(weight);
weights.push_back(weight);
}
}

return weights;
}
};
} // namespace kagen
49 changes: 27 additions & 22 deletions kagen/edgeweight_generators/uniform_random_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "kagen/tools/converter.h"
#include "kagen/tools/utils.h"

#include "xxhash.h"
#include <random>
#include <unordered_map>

namespace kagen {
Expand All @@ -17,12 +17,14 @@ struct EdgeData {
SInt v;
SSInt randomness;
SSInt weight;

EdgeData() = default;

EdgeData(SInt u_param, SInt v_param, SSInt randomness_param, SSInt weight_param)
: u{u_param},
v{v_param},
randomness{randomness_param},
weight{weight_param} {}
: u(u_param),
v(v_param),
randomness(randomness_param),
weight(weight_param) {}
};

// Stores edge (u,v) together with an associated random integer and an edge weight.
Expand All @@ -35,27 +37,27 @@ class EdgeWeightStorage {

public:
void InsertOrReplace(const Edge& key, const RandInt_Weight& value) {
auto it = edge_to_weightdata.find(key);
if (it != edge_to_weightdata.end() && value < it->second) {
// if edge is already present (due to duplicate edges) store edge weight with smaller (rand_int, weight)
const auto it = edge_to_weight_data.find(key);
if (it != edge_to_weight_data.end() && value < it->second) {
// If edge is already present (due to duplicate edges) store edge weight with smaller (rand_int, weight)
// pair.
it->second = value;
} else {
edge_to_weightdata.emplace(key, value);
edge_to_weight_data.emplace(key, value);
}
}

// Use weight with smaller associated random integer.
SSInt AgreeOnEdgeWeight(const Edge& edge) {
const auto& reversed_edge = std::make_pair(edge.second, edge.first);
auto edge_it = edge_to_weightdata.find(edge);
if (edge_it == edge_to_weightdata.end()) {
auto edge_it = edge_to_weight_data.find(edge);
if (edge_it == edge_to_weight_data.end()) {
throw std::runtime_error("edge should have been inserted into map!");
}
const auto& edge_value = edge_it->second;
SSInt weight = edge_value.second; // use this value as default
auto reveresed_edge_it = edge_to_weightdata.find(reversed_edge);
if (reveresed_edge_it != edge_to_weightdata.end() && reveresed_edge_it->second < edge_value) {
const auto reveresed_edge_it = edge_to_weight_data.find(reversed_edge);
if (reveresed_edge_it != edge_to_weight_data.end() && reveresed_edge_it->second < edge_value) {
const auto& reversed_edge_value = reveresed_edge_it->second;
weight = reversed_edge_value.second;
}
Expand All @@ -68,28 +70,32 @@ class EdgeWeightStorage {
return edge.first ^ (edge.second << 1);
}
};
std::unordered_map<Edge, std::pair<SSInt, SSInt>, EdgeHasher> edge_to_weightdata;

std::unordered_map<Edge, std::pair<SSInt, SSInt>, EdgeHasher> edge_to_weight_data;
};
} // namespace

UniformRandomEdgeWeightGenerator::UniformRandomEdgeWeightGenerator(
EdgeWeightConfig config, MPI_Comm comm, VertexRange vertex_range)
: config_(config),
comm_{comm},
vertex_range_{vertex_range} {
comm_(comm),
vertex_range_(vertex_range) {
if (config_.weight_range_begin >= config_.weight_range_end) {
throw std::runtime_error("Weight causes undefined behavior, need weight_range_begin > weight_range_end.");
throw std::runtime_error("Weight causes undefined behavior, need weight_range_begin < weight_range_end.");
}
}

EdgeWeights UniformRandomEdgeWeightGenerator::GenerateEdgeWeights(const XadjArray& xadj, const AdjncyArray& adjncy) {
void UniformRandomEdgeWeightGenerator::GenerateEdgeWeights(
//TODO add more native implementation
const XadjArray& xadj, const AdjncyArray& adjncy, EdgeWeights& weights) {
const auto edge_list = BuildEdgeListFromCSR(vertex_range_, xadj, adjncy);
return GenerateEdgeWeights(edge_list);
GenerateEdgeWeights(edge_list, weights);
}

EdgeWeights UniformRandomEdgeWeightGenerator::GenerateEdgeWeights(const Edgelist& edgelist) {
void UniformRandomEdgeWeightGenerator::GenerateEdgeWeights(const Edgelist& edgelist, EdgeWeights& weights) {
PEID rank;
MPI_Comm_rank(comm_, &rank);

std::mt19937 gen((rank + 42) * 3);
std::uniform_int_distribution<SSInt> weight_dist(config_.weight_range_begin, config_.weight_range_end - 1);

Expand Down Expand Up @@ -130,11 +136,10 @@ EdgeWeights UniformRandomEdgeWeightGenerator::GenerateEdgeWeights(const Edgelist
}

// agree on which weight to choose
EdgeWeights weights(edgelist.size());
weights.resize(edgelist.size());
for (size_t i = 0; i < edgelist.size(); ++i) {
const auto& edge = edgelist[i];
weights[i] = edge_weight_storage.AgreeOnEdgeWeight(edge);
}
return weights;
}
} // namespace kagen
Loading

0 comments on commit 1d2c3d1

Please sign in to comment.