Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[REVIEW] Cascaded dispatch for type-erased API #1711

Merged
merged 31 commits into from
Jul 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
acf15bc
Merge pull request #37 from rapidsai/branch-0.17
aschaffer Nov 30, 2020
a584e0b
Merge pull request #38 from rapidsai/branch-0.18
aschaffer Dec 9, 2020
338b2d4
Merge pull request #39 from rapidsai/branch-0.18
aschaffer Dec 30, 2020
efd7e9a
Merge pull request #40 from rapidsai/branch-0.18
aschaffer Jan 12, 2021
a23ce0d
Merge pull request #41 from rapidsai/branch-0.19
aschaffer Feb 25, 2021
22b32d8
Merge pull request #42 from rapidsai/branch-0.19
aschaffer Mar 1, 2021
e5042fc
Merge pull request #43 from rapidsai/branch-0.19
aschaffer Mar 20, 2021
ca02ee4
Merge pull request #44 from rapidsai/branch-0.19
aschaffer Apr 7, 2021
79409e7
Merge pull request #45 from rapidsai/branch-0.20
aschaffer Apr 13, 2021
360c293
Merge pull request #46 from rapidsai/branch-0.20
aschaffer Apr 28, 2021
e57f261
Merge pull request #47 from rapidsai/branch-0.20
aschaffer May 6, 2021
1745ee3
Updates for device_scalar changes
harrism Jun 1, 2021
1342580
Fix narrowing conversion warning
harrism Jun 1, 2021
bc36d8e
Merge branch 'branch-21.08' into fea-device_scalar-refactor
harrism Jun 8, 2021
a63cdea
Merge pull request #48 from rapidsai/branch-21.08
aschaffer Jun 9, 2021
070122c
Update cpp/src/traversal/tsp.cu
harrism Jun 9, 2021
fa9b367
mv dask installation
ajschmidt8 Jun 11, 2021
417c083
Merge branch 'fea-device_scalar-refactor' of github.com:harrism/cugra…
aschaffer Jun 11, 2021
359c78b
Merge branch 'branch-21.08' of github.com:rapidsai/cugraph into enh_e…
aschaffer Jun 14, 2021
75e592f
Merge branch 'branch-21.08' of github.com:rapidsai/cugraph into enh_e…
aschaffer Jul 6, 2021
7742bc4
Added visitor artifacts.
aschaffer Jul 8, 2021
e4768b7
Fixed issues related to newest graph cnstr.
aschaffer Jul 12, 2021
596e6cd
Removed now useless indirection.
aschaffer Jul 12, 2021
9b88b47
BFS visitor clean-up.
aschaffer Jul 12, 2021
1baaa40
BFS visitor test.
aschaffer Jul 13, 2021
5898f85
BFS visitor test clean-up.
aschaffer Jul 13, 2021
ba0a340
Renamed bfs_visitor cu -> cpp.
aschaffer Jul 15, 2021
f0ecab0
Merge branch 'branch-21.08' of github.com:rapidsai/cugraph into enh_e…
aschaffer Jul 15, 2021
b1316fc
Fixed clang-format issues.
aschaffer Jul 15, 2021
5c7a313
Addressed code review request: added CDD to its own namespace visitors.
aschaffer Jul 19, 2021
170d92c
Addressed code review request: isolated type-erased in its own header…
aschaffer Jul 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,9 @@ add_library(cugraph SHARED
src/components/weakly_connected_components.cu
src/structure/create_graph_from_edgelist.cu
src/utilities/host_barrier.cpp
src/visitors/graph_envelope.cpp
aschaffer marked this conversation as resolved.
Show resolved Hide resolved
src/visitors/visitors_factory.cpp
src/visitors/bfs_visitor.cpp
)

set_target_properties(cugraph
Expand Down
15 changes: 13 additions & 2 deletions cpp/include/cugraph/experimental/graph_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#include <cugraph/utilities/error.hpp>
#include <cugraph/vertex_partition_view.hpp>

// visitor logic:
//
#include <cugraph/visitors/graph_envelope.hpp>

#include <raft/handle.hpp>
#include <rmm/device_uvector.hpp>

Expand Down Expand Up @@ -218,6 +222,8 @@ struct graph_properties_t {

namespace detail {

using namespace cugraph::visitors;

// FIXME: threshold values require tuning
// use the hypersparse format (currently, DCSR or DCSC) for the vertices with their degrees smaller
// than col_comm_size * hypersparse_threshold_ratio, should be less than 1.0
Expand All @@ -228,9 +234,9 @@ size_t constexpr num_sparse_segments_per_vertex_partition{3};

// Common for both graph_view_t & graph_t and both single-GPU & multi-GPU versions
template <typename vertex_t, typename edge_t, typename weight_t>
class graph_base_t {
class graph_base_t : public graph_envelope_t::base_graph_t /*<- visitor logic*/ {
aschaffer marked this conversation as resolved.
Show resolved Hide resolved
public:
graph_base_t() = default;
graph_base_t() = default; // Note: required by visitor logic

graph_base_t(raft::handle_t const& handle,
vertex_t number_of_vertices,
Expand Down Expand Up @@ -259,6 +265,11 @@ class graph_base_t {
bool is_symmetric() const { return properties_.is_symmetric; }
bool is_multigraph() const { return properties_.is_multigraph; }

void apply(visitor_t& v) const override // <- visitor logic
{
v.visit_graph(*this);
}

protected:
friend class cugraph::serializer::serializer_t;

Expand Down
82 changes: 82 additions & 0 deletions cpp/include/cugraph/visitors/bfs_visitor.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (c) 2021, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Andrei Schaffer, [email protected]
//

#pragma once
#include "erased_pack.hpp"
#include "graph_envelope.hpp"
#include "ret_terased.hpp"

namespace cugraph {
namespace visitors {

using namespace cugraph::experimental;

// macro option: MAKE_VISITOR(bfs)

// primary empty template:
//
template <typename vertex_t,
typename edge_t,
typename weight_t,
bool st,
bool mg,
typename Enable = void>
struct bfs_visitor;

// dummy out non-candidate instantiation paths:
//
template <typename vertex_t, typename edge_t, typename weight_t, bool st, bool mg>
struct bfs_visitor<vertex_t,
edge_t,
weight_t,
st,
mg,
std::enable_if_t<(!is_candidate<vertex_t, edge_t, weight_t>::value)>>
: visitor_t {
void visit_graph(graph_envelope_t::base_graph_t const&) override
{
// purposely empty
}
return_t const& get_result(void) const override
{
static return_t r{};
return r;
}
};

template <typename vertex_t, typename edge_t, typename weight_t, bool st, bool mg>
struct bfs_visitor<vertex_t,
edge_t,
weight_t,
st,
mg,
std::enable_if_t<is_candidate<vertex_t, edge_t, weight_t>::value>> : visitor_t {
bfs_visitor(erased_pack_t& ep) : ep_(ep) {}

void visit_graph(graph_envelope_t::base_graph_t const&) override;

return_t const& get_result(void) const override { return result_; }

private:
erased_pack_t& ep_;
return_t result_;
};

} // namespace visitors
} // namespace cugraph
254 changes: 254 additions & 0 deletions cpp/include/cugraph/visitors/cascaded_dispatch.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
/*
* Copyright (c) 2021, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// Andrei Schaffer, [email protected]
//

#pragma once

#include <array>
#include <functional>
#include <sstream>
#include <stdexcept>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>

#include "enum_mapping.hpp"
#include "graph_enum_mapping.hpp"

#include <cugraph/utilities/graph_traits.hpp>
#include "graph_factory.hpp"

namespace cugraph {
namespace visitors {

using namespace cugraph::experimental;
using pair_uniques_t = graph_envelope_t::pair_uniques_t;

// dummy-out non-candidate paths:
//
template <typename vertex_t,
typename edge_t,
typename weight_t,
bool tr,
bool mg,
std::enable_if_t<!is_candidate<vertex_t, edge_t, weight_t>::value, void*> = nullptr>
constexpr pair_uniques_t graph_dispatcher(GTypes graph_type, erased_pack_t& ep)
{
/// return nullptr;
return pair_uniques_t{nullptr, nullptr};
}

// final step of cascading: calls factory on erased pack:
//
template <typename vertex_t,
typename edge_t,
typename weight_t,
bool tr,
bool mg,
std::enable_if_t<is_candidate<vertex_t, edge_t, weight_t>::value, void*> = nullptr>
constexpr pair_uniques_t graph_dispatcher(GTypes graph_type, erased_pack_t& ep)
{
switch (graph_type) {
case GTypes::GRAPH_T: {
using graph_t = typename GMapType<vertex_t, edge_t, weight_t, tr, mg, GTypes::GRAPH_T>::type;
graph_factory_t<graph_t> factory;

pair_uniques_t p_uniques =
std::make_pair(factory.make_graph(ep),
std::make_unique<dependent_factory_t<vertex_t, edge_t, weight_t, tr, mg>>());

return p_uniques;
} break;

default: {
std::stringstream ss;
ss << "ERROR: Unknown type enum:" << static_cast<int>(graph_type);
throw std::runtime_error(ss.str());
}
}
}

// multi_gpu bool dispatcher:
// resolves bool `multi_gpu`
// and using template arguments vertex_t, edge_t, weight_t, store_transpose
// cascades into next level
// graph_dispatcher()
//
template <typename vertex_t, typename edge_t, typename weight_t, bool store_transposed>
constexpr decltype(auto) multi_gpu_dispatcher(bool multi_gpu, GTypes graph_type, erased_pack_t& ep)
{
switch (multi_gpu) {
case true: {
return graph_dispatcher<vertex_t, edge_t, weight_t, store_transposed, true>(graph_type, ep);
} break;
case false: {
return graph_dispatcher<vertex_t, edge_t, weight_t, store_transposed, false>(graph_type, ep);
}
}
}

// transpose bool dispatcher:
// resolves bool `store_transpose`
// and using template arguments vertex_t, edge_t, weight_t
// cascades into next level
// multi_gpu_dispatcher()
//
template <typename vertex_t, typename edge_t, typename weight_t>
constexpr decltype(auto) transp_dispatcher(bool store_transposed,
bool multi_gpu,
GTypes graph_type,
erased_pack_t& ep)
{
switch (store_transposed) {
case true: {
return multi_gpu_dispatcher<vertex_t, edge_t, weight_t, true>(multi_gpu, graph_type, ep);
} break;
case false: {
return multi_gpu_dispatcher<vertex_t, edge_t, weight_t, false>(multi_gpu, graph_type, ep);
}
}
}

// weight type dispatcher:
// resolves weigth_t from weight_type enum
// and using template arguments vertex_t, edge_t
// cascades into next level
// transp_dispatcher()
//
template <typename vertex_t, typename edge_t>
constexpr decltype(auto) weight_dispatcher(
DTypes weight_type, bool store_transposed, bool multi_gpu, GTypes graph_type, erased_pack_t& ep)
{
switch (weight_type) {
case DTypes::INT32: {
using weight_t = typename DMapType<DTypes::INT32>::type;
return transp_dispatcher<vertex_t, edge_t, weight_t>(
store_transposed, multi_gpu, graph_type, ep);
} break;
case DTypes::INT64: {
using weight_t = typename DMapType<DTypes::INT64>::type;
return transp_dispatcher<vertex_t, edge_t, weight_t>(
store_transposed, multi_gpu, graph_type, ep);
} break;
case DTypes::FLOAT32: {
using weight_t = typename DMapType<DTypes::FLOAT32>::type;
return transp_dispatcher<vertex_t, edge_t, weight_t>(
store_transposed, multi_gpu, graph_type, ep);
} break;
case DTypes::FLOAT64: {
using weight_t = typename DMapType<DTypes::FLOAT64>::type;
return transp_dispatcher<vertex_t, edge_t, weight_t>(
store_transposed, multi_gpu, graph_type, ep);
} break;
default: {
std::stringstream ss;
ss << "ERROR: Unknown type enum:" << static_cast<int>(weight_type);
throw std::runtime_error(ss.str());
}
}
}

// edge type dispatcher:
// resolves edge_t from edge_type enum
// and using template argument vertex_t
// cascades into the next level
// weight_dispatcher();
//
template <typename vertex_t>
constexpr decltype(auto) edge_dispatcher(DTypes edge_type,
DTypes weight_type,
bool store_transposed,
bool multi_gpu,
GTypes graph_type,
erased_pack_t& ep)
{
switch (edge_type) {
case DTypes::INT32: {
using edge_t = typename DMapType<DTypes::INT32>::type;
return weight_dispatcher<vertex_t, edge_t>(
weight_type, store_transposed, multi_gpu, graph_type, ep);
} break;
case DTypes::INT64: {
using edge_t = typename DMapType<DTypes::INT64>::type;
return weight_dispatcher<vertex_t, edge_t>(
weight_type, store_transposed, multi_gpu, graph_type, ep);
} break;
case DTypes::FLOAT32: {
using edge_t = typename DMapType<DTypes::FLOAT32>::type;
return weight_dispatcher<vertex_t, edge_t>(
weight_type, store_transposed, multi_gpu, graph_type, ep);
} break;
case DTypes::FLOAT64: {
using edge_t = typename DMapType<DTypes::FLOAT64>::type;
return weight_dispatcher<vertex_t, edge_t>(
weight_type, store_transposed, multi_gpu, graph_type, ep);
} break;
default: {
std::stringstream ss;
ss << "ERROR: Unknown type enum:" << static_cast<int>(edge_type);
throw std::runtime_error(ss.str());
}
}
}

// vertex type dispatcher:
// entry point,
// resolves vertex_t from vertex_type enum
// and cascades into the next level
// edge_dispatcher();
//
inline decltype(auto) vertex_dispatcher(DTypes vertex_type,
DTypes edge_type,
DTypes weight_type,
bool store_transposed,
bool multi_gpu,
GTypes graph_type,
erased_pack_t& ep)
{
switch (vertex_type) {
case DTypes::INT32: {
using vertex_t = typename DMapType<DTypes::INT32>::type;
return edge_dispatcher<vertex_t>(
edge_type, weight_type, store_transposed, multi_gpu, graph_type, ep);
} break;
case DTypes::INT64: {
using vertex_t = typename DMapType<DTypes::INT64>::type;
return edge_dispatcher<vertex_t>(
edge_type, weight_type, store_transposed, multi_gpu, graph_type, ep);
} break;
case DTypes::FLOAT32: {
using vertex_t = typename DMapType<DTypes::FLOAT32>::type;
return edge_dispatcher<vertex_t>(
edge_type, weight_type, store_transposed, multi_gpu, graph_type, ep);
} break;
case DTypes::FLOAT64: {
using vertex_t = typename DMapType<DTypes::FLOAT64>::type;
return edge_dispatcher<vertex_t>(
edge_type, weight_type, store_transposed, multi_gpu, graph_type, ep);
} break;
default: {
std::stringstream ss;
ss << "ERROR: Unknown type enum:" << static_cast<int>(vertex_type);
throw std::runtime_error(ss.str());
}
}
}

} // namespace visitors
} // namespace cugraph
Loading