Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
152 changes: 115 additions & 37 deletions cpp/include/cugraph/graph_functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,15 +412,58 @@ decompress_to_edgelist(

/**
* @ingroup graph_functions_cpp
* @brief Symmetrize edgelist.

* @brief Identify if an edge property is part of the uniqueness of the edge, or just a value to be
combined.
*/
enum class edge_key_selector_t {
KEY, /** This property is part of the uniqueness key of the edge. */
VALUE /** This property is a value to be combined. */
};

/**
* @ingroup graph_functions_cpp
* @brief Rule for combining edge properties when merging reciprocal edges.
*
* Each edge property in the edge tuple can have a different combining rule.
* For example, the weight of an edge can be combined differently than the edge type.
*
* @param SUM Sum the values of the edge properties.
* @param MAX Take the maximum of the values of the edge properties.
* @param MIN Take the minimum of the values of the edge properties.
* @param MEAN Take the mean of the values of the edge properties.
* @param FIRST Use the value of the first edge property based on the original order of the edges in
* the input data. For an inverse edge things will be ordered based on the order of the
* original edge that the inverse edge was created from.
* @param LAST Use the value of the last edge property based on the original order of the edges in
* the input data. For an inverse edge things will be ordered based on the order of the
* original edge that the inverse edge was created from.
* @param NONE Do not combine the values, so the edge property will be unchanged, so the edge
* properties will potentially be different in each direction. If NONE is specified and there are
* multiple values in the same direction, then we will not remove any edge tuples from the edgelist
* and the resulting edge list can have duplicate edges.
*/
enum class edge_value_combining_rule_t {
SUM, /** Sum the values of the two edge properties. */
MAX, /** Take the maximum of the values of the two edge properties. */
MIN, /** Take the minimum of the values of the two edge properties. */
MEAN, /** Take the mean of the values of the two edge properties. */
FIRST, /** Use the value of the first edge property. */
LAST, /** Use the value of the last edge property. */
ANY, /** Use the value of any edge property. */
NONE /** Do not combine the values. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just to keep the original values, right? Should we explain this in little more detail?

I initially thought we don't need NONE here as we now have edge_key_selector_t. But now I think this is still necessary as we may consider two different edges with the matching source/destination pairs as reciprocal but in some cases, we don't want to combine there edge properties. This may not be clear to everyone from the beginning.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add some text to clarify the different use cases.

};

/**
* @ingroup graph_functions_cpp
* @brief Add reciprocal edges and merge the edges. This was formerly called symmetrize_edgelist
* with reciprocal set to false.
*
* The input edge list is replicated as reciprocal edges. Then the original edges and the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering we should use "reciprocal" here or use "inverse" instead. I am not sure what "reciprocal" exactly means. Some quick search says it is a pair of edges going in both directions between a pair of vertices.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine switching to inverse here if that's more intuitive to you. I suppose by the definition you found we're really creating reciprocal edges here by adding the inverse edge. So that's probably more correct.

* reciprocal edges are merged based on the provided @p edge_key_selector and @p
* edge_value_combining_rule.
*
* @tparam vertex_t Type of vertex identifiers. Needs to be an integral type.
* @tparam edge_t Type of edge identifiers. Needs to be an integral type.
* @tparam weight_t Type of edge weights. Needs to be a floating point type.
* @tparam edge_type_t Type of edge type identifiers. Needs to be an integral type.
* @tparam edge_time_t Type of edge time. Needs to be an integral type.
* @tparam store_transposed Flag indicating whether to use sources (if false) or destinations (if
* true) as major indices in storing edges using a 2D sparse matrix.
* @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false)
* or multi-GPU (true).
*
Expand All @@ -430,39 +473,74 @@ decompress_to_edgelist(
* compute_gpu_id_from_ext_edge_endpoints_t to every edge should return the local GPU ID for this
* function to work (edges should be pre-shuffled).
* @param edgelist_dsts Vector of edge destination vertex IDs.
* @param edgelist_weights Vector of edge weights.
* @param edgelist_edge_ids Vector of edge ids
* @param edgelist_edge_types Vector of edge types
* @param edgelist_edge_start_times Vector of edge start times
* @param edgelist_edge_end_times Vector of edge end times
* @param reciprocal Flag indicating whether to keep (if set to `false`) or discard (if set to
* `true`) edges that appear only in one direction.
* @return Tuple of symmetrized sources, destinations, optional weights, optional edge ids, optional
* edge types, optional edge start times and optional edge end times
* @param edgelist_edge_properties Vector of edge properties.
* @param edge_key_selector Vector of selectors for selecting the key of the edge properties.
* @param edge_value_combining_rule Vector of rules for combining edge values when merging
* reciprocal edges. reciprocal edges.
* @param store_transposed Flag indicating whether to use sources (if false) or destinations (if
* true) as major indices in storing edges using a 2D sparse matrix.
* @return Tuple of symmetrized sources, destinations, and edge properties.
*/
template <typename vertex_t,
typename edge_t,
typename weight_t,
typename edge_type_t,
typename edge_time_t,
bool store_transposed,
bool multi_gpu>
template <typename vertex_t, bool multi_gpu>
std::tuple<rmm::device_uvector<vertex_t>,
rmm::device_uvector<vertex_t>,
std::optional<rmm::device_uvector<weight_t>>,
std::optional<rmm::device_uvector<edge_t>>,
std::optional<rmm::device_uvector<edge_type_t>>,
std::optional<rmm::device_uvector<edge_time_t>>,
std::optional<rmm::device_uvector<edge_time_t>>>
symmetrize_edgelist(raft::handle_t const& handle,
rmm::device_uvector<vertex_t>&& edgelist_srcs,
rmm::device_uvector<vertex_t>&& edgelist_dsts,
std::optional<rmm::device_uvector<weight_t>>&& edgelist_weights,
std::optional<rmm::device_uvector<edge_t>>&& edgelist_edge_ids,
std::optional<rmm::device_uvector<edge_type_t>>&& edgelist_edge_types,
std::optional<rmm::device_uvector<edge_time_t>>&& edgelist_edge_start_times,
std::optional<rmm::device_uvector<edge_time_t>>&& edgelist_edge_end_times,
bool reciprocal);
std::vector<arithmetic_device_uvector_t>>
add_reciprocals_and_merge_edge_tuples(
raft::handle_t const& handle,
rmm::device_uvector<vertex_t>&& edgelist_srcs,
rmm::device_uvector<vertex_t>&& edgelist_dsts,
std::vector<arithmetic_device_uvector_t>&& edgelist_edge_properties,
std::vector<edge_key_selector_t> const& edge_key_selector,
std::vector<edge_value_combining_rule_t> const& edge_value_combining_rule,
bool store_transposed);

/**
* @ingroup graph_functions_cpp
* @brief Drop non-reciprocal edge tuples from the edgelist. This was formerly called
* symmetrize_edgelist with reciprocal set to true.
*
* The input edge list scanned, each edge tuple that does not have a matching reciprocal edge is
* dropped. @p edge_key_selector is used to determine if an edge property is part of the uniqueness
* key of the edge. If it is part of the uniqueness key, the edge tuple is removed if it does not
* have a matching reciprocal edge. If it is not part of the uniqueness key, the edge property is
* ignored in the comparison.
*
* @p edge_value_combining_rule is used to combine the edge values when merging reciprocal edges.
* Specifically, if the edge tuple has a matching reciprocal edge, the edge values could be
* different, so we need a rule to combine the edge values. If NONE is specified as the value
* combining rule, the edge property will be unchanged, so will potentially be different in each
* direction. Otherwise the edge property will be combined according to the specified rule so that
* both directions match.
*
* @tparam vertex_t Type of vertex identifiers. Needs to be an integral type.
* @tparam multi_gpu Flag indicating whether template instantiation should target single-GPU (false)
* or multi-GPU (true).
* @param handle RAFT handle object to encapsulate resources (e.g. CUDA stream, communicator, and
* handles to various CUDA libraries) to run graph algorithms.
* @param edgelist_srcs Vector of edge source vertex IDs. If multi-GPU, applying the
* compute_gpu_id_from_ext_edge_endpoints_t to every edge should return the local GPU ID for this
* function to work (edges should be pre-shuffled).
* @param edgelist_dsts Vector of edge destination vertex IDs.
* @param edgelist_edge_properties Vector of edge properties.
* @param edge_key_selector Vector of selectors for selecting the key of the edge properties.
* @param edge_value_combining_rule Vector of rules for combining edge values when merging
* reciprocal edges. reciprocal edges.
* @param store_transposed Flag indicating whether to use sources (if false) or destinations (if
* true) as major indices in storing edges using a 2D sparse matrix.
* @return Tuple of non-reciprocal sources, destinations, and edge properties.
*/
template <typename vertex_t, bool multi_gpu>
std::tuple<rmm::device_uvector<vertex_t>,
rmm::device_uvector<vertex_t>,
std::vector<arithmetic_device_uvector_t>>
drop_nonreciprocal_edge_tuples(
raft::handle_t const& handle,
rmm::device_uvector<vertex_t>&& edgelist_srcs,
rmm::device_uvector<vertex_t>&& edgelist_dsts,
std::vector<arithmetic_device_uvector_t>&& edgelist_edge_properties,
std::vector<edge_key_selector_t> const& edge_key_selector,
std::vector<edge_value_combining_rule_t> const& edge_value_combining_rule,
bool store_transposed);

/**
* @ingroup graph_functions_cpp
Expand Down
Loading