Skip to content
Merged
189 changes: 115 additions & 74 deletions tests/edge_range.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,106 +2,147 @@

#include "kagen/kagen.h"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include <functional>
#include <numeric>
#include <string>

#include "tests/gather.h"
#include "tests/utils.h"
#include "tools/converter.h"

using namespace kagen;

void check_edge_range(const Graph& graph) {
Edgelist edgelist = graph.edges;
if (graph.representation == GraphRepresentation::CSR) {
edgelist = BuildEdgeListFromCSR(graph.vertex_range, graph.xadj, graph.adjncy);
}
EdgeRange edge_range(graph);
using GeneratorFunc = std::function<Graph(KaGen&, SInt, SInt)>;

{
std::size_t expected_index = 0;
for (auto it = edge_range.begin(); it != edge_range.end(); ++it) {
auto edge = *it;
EXPECT_EQ(it.edge_index(), expected_index);
EXPECT_EQ(*it, edge);
++expected_index;
}
}

{
EXPECT_EQ(edge_range.size(), edgelist.size());
for (std::size_t i = 0; auto elem: edge_range) {
EXPECT_EQ(elem, edgelist[i]);
++i;
}
}
MATCHER(EdgeIndexMatches, "") {
auto [iter, expected_idx] = arg;
return iter.edge_index() == expected_idx;
}

void check_edge_range(KaGen& generator, SInt n, SInt m) {
// GNM
{
kagen::Graph graph = generator.GenerateUndirectedGNM(n, m);
check_edge_range(graph);
}
// RMAT
{
kagen::Graph graph = generator.GenerateRMAT(n, m, 0.56, 0.19, 0.19);
check_edge_range(graph);
}
// RGG2D
{
kagen::Graph graph = generator.GenerateRGG2D_NM(n, m);
check_edge_range(graph);
}
// RGG3D
{
kagen::Graph graph = generator.GenerateRGG3D_NM(n, m);
check_edge_range(graph);
}
// RHG
{
kagen::Graph graph = generator.GenerateRHG_NM(2.6, n, m);
check_edge_range(graph);
}
// GRID2D
{
kagen::Graph graph = generator.GenerateGrid2D_NM(n, m);
check_edge_range(graph);
}
// GRID3D
{
kagen::Graph graph = generator.GenerateGrid3D_NM(n, m);
check_edge_range(graph);
}
}
struct EdgeRangeTestFixture : public ::testing::TestWithParam<std::tuple<std::string, GeneratorFunc>> {};

TEST(EdgeRangeTest, iterate_edgelist_representation) {
kagen::KaGen generator(MPI_COMM_WORLD);
generator.UseEdgeListRepresentation();

INSTANTIATE_TEST_SUITE_P(
EdgeRangeTests, EdgeRangeTestFixture,
::testing::Values(
std::make_tuple("GNM", GeneratorFunc([](KaGen& gen, SInt n, SInt m) { return gen.GenerateUndirectedGNM(n, m); })),
std::make_tuple("RMAT", GeneratorFunc([](KaGen& gen, SInt n, SInt m) { return gen.GenerateRMAT(n, m, 0.56, 0.19, 0.19); })),
std::make_tuple("RGG2D", GeneratorFunc([](KaGen& gen, SInt n, SInt m) { return gen.GenerateRGG2D_NM(n, m); })),
std::make_tuple("RGG3D", GeneratorFunc([](KaGen& gen, SInt n, SInt m) { return gen.GenerateRGG3D_NM(n, m); })),
std::make_tuple("RHG", GeneratorFunc([](KaGen& gen, SInt n, SInt m) { return gen.GenerateRHG_NM(2.6, n, m); })),
std::make_tuple("Grid2D", GeneratorFunc([](KaGen& gen, SInt n, SInt m) { return gen.GenerateGrid2D_NM(n, m); })),
std::make_tuple("Grid3D", GeneratorFunc([](KaGen& gen, SInt n, SInt m) { return gen.GenerateGrid3D_NM(n, m); }))),
[](const ::testing::TestParamInfo<EdgeRangeTestFixture::ParamType>& info) {
return std::get<0>(info.param);
});

TEST_P(EdgeRangeTestFixture, iterate_edgelist_representation) {
using ::testing::ElementsAreArray;
using ::testing::Pointwise;

auto [name, generate] = GetParam();
const SInt n = 1000;
const SInt m = 16 * n;
check_edge_range(generator, n, m);
}

TEST(EdgeRangeTest, iterate_sparse_edgelist_representation) {
kagen::KaGen generator(MPI_COMM_WORLD);
generator.UseEdgeListRepresentation();
Graph graph = generate(generator, n, m);

Edgelist expected = graph.edges;
EdgeRange edge_range(graph);

// Check edges match and indices are consecutive
EXPECT_THAT(std::vector(edge_range.begin(), edge_range.end()), ElementsAreArray(expected));

std::vector<EdgeRange::iterator> iterators;
for (auto it = edge_range.begin(); it != edge_range.end(); ++it) {
iterators.push_back(it);
}
std::vector<std::size_t> expected_indices(edge_range.size());
std::iota(expected_indices.begin(), expected_indices.end(), 0);
EXPECT_THAT(iterators, Pointwise(EdgeIndexMatches(), expected_indices));
}

TEST_P(EdgeRangeTestFixture, iterate_sparse_edgelist_representation) {
using ::testing::ElementsAreArray;
using ::testing::Pointwise;

auto [name, generate] = GetParam();
const SInt n = 1000;
const SInt m = 2 * n;
check_edge_range(generator, n, m);
}

TEST(EdgeRangeTest, iterate_csr_representation) {
kagen::KaGen generator(MPI_COMM_WORLD);
generator.UseCSRRepresentation();
generator.UseEdgeListRepresentation();
Graph graph = generate(generator, n, m);

Edgelist expected = graph.edges;
EdgeRange edge_range(graph);

// Check edges match and indices are consecutive
EXPECT_THAT(std::vector(edge_range.begin(), edge_range.end()), ElementsAreArray(expected));

std::vector<EdgeRange::iterator> iterators;
for (auto it = edge_range.begin(); it != edge_range.end(); ++it) {
iterators.push_back(it);
}
std::vector<std::size_t> expected_indices(edge_range.size());
std::iota(expected_indices.begin(), expected_indices.end(), 0);
EXPECT_THAT(iterators, Pointwise(EdgeIndexMatches(), expected_indices));
}

TEST_P(EdgeRangeTestFixture, iterate_csr_representation) {
using ::testing::ElementsAreArray;
using ::testing::Pointwise;

auto [name, generate] = GetParam();
const SInt n = 1000;
const SInt m = 16 * n;
check_edge_range(generator, n, m);
}

TEST(EdgeRangeTest, iterate_sparse_csr_representation) {
kagen::KaGen generator(MPI_COMM_WORLD);
generator.UseCSRRepresentation();
Graph graph = generate(generator, n, m);

Edgelist expected = BuildEdgeListFromCSR(graph.vertex_range, graph.xadj, graph.adjncy);
EdgeRange edge_range(graph);

// Check edges match and indices are consecutive
EXPECT_THAT(std::vector(edge_range.begin(), edge_range.end()), ElementsAreArray(expected));

std::vector<EdgeRange::iterator> iterators;
for (auto it = edge_range.begin(); it != edge_range.end(); ++it) {
iterators.push_back(it);
}
std::vector<std::size_t> expected_indices(edge_range.size());
std::iota(expected_indices.begin(), expected_indices.end(), 0);
EXPECT_THAT(iterators, Pointwise(EdgeIndexMatches(), expected_indices));
}

TEST_P(EdgeRangeTestFixture, iterate_sparse_csr_representation) {
using ::testing::ElementsAreArray;
using ::testing::Pointwise;

auto [name, generate] = GetParam();
const SInt n = 1000;
const SInt m = 2 * n;
check_edge_range(generator, n, m);

kagen::KaGen generator(MPI_COMM_WORLD);
generator.UseCSRRepresentation();
Graph graph = generate(generator, n, m);

Edgelist expected = BuildEdgeListFromCSR(graph.vertex_range, graph.xadj, graph.adjncy);
EdgeRange edge_range(graph);

// Check edges match and indices are consecutive
EXPECT_THAT(std::vector(edge_range.begin(), edge_range.end()), ElementsAreArray(expected));

std::vector<EdgeRange::iterator> iterators;
for (auto it = edge_range.begin(); it != edge_range.end(); ++it) {
iterators.push_back(it);
}
std::vector<std::size_t> expected_indices(edge_range.size());
std::iota(expected_indices.begin(), expected_indices.end(), 0);
EXPECT_THAT(iterators, Pointwise(EdgeIndexMatches(), expected_indices));
}