From 0adc558ea57ee4d07957dda589770d73d5d514cb Mon Sep 17 00:00:00 2001 From: Seunghwa Kang <45857425+seunghwak@users.noreply.github.com> Date: Mon, 1 Mar 2021 14:02:33 -0500 Subject: [PATCH] Update C++ MG PageRank test (#1419) - [x] Add tests using graphs with isolated vertices - [x] Add personalized PageRank tests - [x] Test code refactoring - [x] Create libcugraphtestutil.a This PR fixes FIXMEs added in https://github.com/rapidsai/cugraph/pull/1361 to address https://github.com/rapidsai/cugraph/issues/1136 Authors: - Seunghwa Kang (@seunghwak) Approvers: - Rick Ratzel (@rlratzel) - Andrei Schaffer (@aschaffer) - Brad Rees (@BradReesWork) URL: https://github.com/rapidsai/cugraph/pull/1419 --- cpp/include/algorithms.hpp | 8 +- cpp/include/experimental/graph.hpp | 8 + cpp/include/experimental/graph_view.hpp | 4 + cpp/src/experimental/katz_centrality.cu | 28 +- cpp/src/experimental/pagerank.cu | 84 +- cpp/src/experimental/renumber_edgelist.cu | 9 +- cpp/tests/CMakeLists.txt | 102 +-- cpp/tests/community/egonet_test.cu | 8 +- cpp/tests/experimental/bfs_test.cpp | 9 +- cpp/tests/experimental/coarsen_graph_test.cpp | 8 +- cpp/tests/experimental/graph_test.cpp | 60 +- .../experimental/induced_subgraph_test.cpp | 8 +- .../experimental/katz_centrality_test.cpp | 7 +- cpp/tests/experimental/louvain_test.cu | 7 +- cpp/tests/experimental/pagerank_test.cpp | 11 +- cpp/tests/experimental/sssp_test.cpp | 9 +- cpp/tests/pagerank/mg_pagerank_test.cpp | 296 +++++++ cpp/tests/pagerank/pagerank_mg_test.cpp | 229 ----- cpp/tests/utilities/base_fixture.hpp | 71 +- cpp/tests/utilities/mg_test_utilities.cu | 180 ---- cpp/tests/utilities/mg_test_utilities.hpp | 77 -- cpp/tests/utilities/test_utilities.cpp | 442 ---------- cpp/tests/utilities/test_utilities.cu | 788 ++++++++++++++++++ cpp/tests/utilities/test_utilities.hpp | 41 +- 24 files changed, 1337 insertions(+), 1157 deletions(-) create mode 100644 cpp/tests/pagerank/mg_pagerank_test.cpp delete mode 100644 cpp/tests/pagerank/pagerank_mg_test.cpp delete mode 100644 cpp/tests/utilities/mg_test_utilities.cu delete mode 100644 cpp/tests/utilities/mg_test_utilities.hpp delete mode 100644 cpp/tests/utilities/test_utilities.cpp create mode 100644 cpp/tests/utilities/test_utilities.cu diff --git a/cpp/include/algorithms.hpp b/cpp/include/algorithms.hpp index c666bce23ad..0b8bd59587f 100644 --- a/cpp/include/algorithms.hpp +++ b/cpp/include/algorithms.hpp @@ -1100,9 +1100,9 @@ void sssp(raft::handle_t const &handle, template void pagerank(raft::handle_t const &handle, graph_view_t const &graph_view, - weight_t *adj_matrix_row_out_weight_sums, - vertex_t *personalization_vertices, - result_t *personalization_values, + weight_t const *adj_matrix_row_out_weight_sums, + vertex_t const *personalization_vertices, + result_t const *personalization_values, vertex_t personalization_vector_size, result_t *pageranks, result_t alpha, @@ -1148,7 +1148,7 @@ void pagerank(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - result_t *betas, + result_t const *betas, result_t *katz_centralities, result_t alpha, result_t beta, diff --git a/cpp/include/experimental/graph.hpp b/cpp/include/experimental/graph.hpp index cc21f7c5013..6a10256e6f4 100644 --- a/cpp/include/experimental/graph.hpp +++ b/cpp/include/experimental/graph.hpp @@ -61,6 +61,8 @@ class graph_t() {} + graph_t(raft::handle_t const &handle, std::vector> const &edgelists, partition_t const &partition, @@ -123,6 +125,12 @@ class graph_t(), + offsets_(0, handle.get_stream()), + indices_(0, handle.get_stream()), + weights_(0, handle.get_stream()){}; + graph_t(raft::handle_t const &handle, edgelist_t const &edgelist, vertex_t number_of_vertices, diff --git a/cpp/include/experimental/graph_view.hpp b/cpp/include/experimental/graph_view.hpp index 7598841fc1a..5d3d09bb087 100644 --- a/cpp/include/experimental/graph_view.hpp +++ b/cpp/include/experimental/graph_view.hpp @@ -82,6 +82,8 @@ namespace experimental { template class partition_t { public: + partition_t() = default; + partition_t(std::vector const& vertex_partition_offsets, bool hypergraph_partitioned, int row_comm_size, @@ -247,6 +249,8 @@ size_t constexpr num_segments_per_vertex_partition{3}; template class graph_base_t { public: + graph_base_t() = default; + graph_base_t(raft::handle_t const& handle, vertex_t number_of_vertices, edge_t number_of_edges, diff --git a/cpp/src/experimental/katz_centrality.cu b/cpp/src/experimental/katz_centrality.cu index 1ab824f1c91..7ffef5053af 100644 --- a/cpp/src/experimental/katz_centrality.cu +++ b/cpp/src/experimental/katz_centrality.cu @@ -38,7 +38,7 @@ namespace detail { template void katz_centrality(raft::handle_t const &handle, GraphViewType const &pull_graph_view, - result_t *betas, + result_t const *betas, result_t *katz_centralities, result_t alpha, result_t beta, // relevant only if betas == nullptr @@ -173,7 +173,7 @@ void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - result_t *betas, + result_t const *betas, result_t *katz_centralities, result_t alpha, result_t beta, // relevant only if beta == nullptr @@ -200,7 +200,7 @@ void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - float *betas, + float const *betas, float *katz_centralities, float alpha, float beta, @@ -212,7 +212,7 @@ template void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - double *betas, + double const *betas, double *katz_centralities, double alpha, double beta, @@ -224,7 +224,7 @@ template void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - float *betas, + float const *betas, float *katz_centralities, float alpha, float beta, @@ -236,7 +236,7 @@ template void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - double *betas, + double const *betas, double *katz_centralities, double alpha, double beta, @@ -248,7 +248,7 @@ template void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - float *betas, + float const *betas, float *katz_centralities, float alpha, float beta, @@ -260,7 +260,7 @@ template void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - double *betas, + double const *betas, double *katz_centralities, double alpha, double beta, @@ -272,7 +272,7 @@ template void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - float *betas, + float const *betas, float *katz_centralities, float alpha, float beta, @@ -284,7 +284,7 @@ template void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - double *betas, + double const *betas, double *katz_centralities, double alpha, double beta, @@ -296,7 +296,7 @@ template void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - float *betas, + float const *betas, float *katz_centralities, float alpha, float beta, @@ -308,7 +308,7 @@ template void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - double *betas, + double const *betas, double *katz_centralities, double alpha, double beta, @@ -320,7 +320,7 @@ template void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - float *betas, + float const *betas, float *katz_centralities, float alpha, float beta, @@ -332,7 +332,7 @@ template void katz_centrality(raft::handle_t const &handle, template void katz_centrality(raft::handle_t const &handle, graph_view_t const &graph_view, - double *betas, + double const *betas, double *katz_centralities, double alpha, double beta, diff --git a/cpp/src/experimental/pagerank.cu b/cpp/src/experimental/pagerank.cu index c498d2864b4..e5874acb04f 100644 --- a/cpp/src/experimental/pagerank.cu +++ b/cpp/src/experimental/pagerank.cu @@ -44,9 +44,9 @@ namespace detail { template void pagerank(raft::handle_t const& handle, GraphViewType const& pull_graph_view, - typename GraphViewType::weight_type* precomputed_vertex_out_weight_sums, - typename GraphViewType::vertex_type* personalization_vertices, - result_t* personalization_values, + typename GraphViewType::weight_type const* precomputed_vertex_out_weight_sums, + typename GraphViewType::vertex_type const* personalization_vertices, + result_t const* personalization_values, typename GraphViewType::vertex_type personalization_vector_size, result_t* pageranks, result_t alpha, @@ -279,9 +279,9 @@ void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - weight_t* precomputed_vertex_out_weight_sums, - vertex_t* personalization_vertices, - result_t* personalization_values, + weight_t const* precomputed_vertex_out_weight_sums, + vertex_t const* personalization_vertices, + result_t const* personalization_values, vertex_t personalization_vector_size, result_t* pageranks, result_t alpha, @@ -308,9 +308,9 @@ void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - float* precomputed_vertex_out_weight_sums, - int32_t* personalization_vertices, - float* personalization_values, + float const* precomputed_vertex_out_weight_sums, + int32_t const* personalization_vertices, + float const* personalization_values, int32_t personalization_vector_size, float* pageranks, float alpha, @@ -321,9 +321,9 @@ template void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - double* precomputed_vertex_out_weight_sums, - int32_t* personalization_vertices, - double* personalization_values, + double const* precomputed_vertex_out_weight_sums, + int32_t const* personalization_vertices, + double const* personalization_values, int32_t personalization_vector_size, double* pageranks, double alpha, @@ -334,9 +334,9 @@ template void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - float* precomputed_vertex_out_weight_sums, - int32_t* personalization_vertices, - float* personalization_values, + float const* precomputed_vertex_out_weight_sums, + int32_t const* personalization_vertices, + float const* personalization_values, int32_t personalization_vector_size, float* pageranks, float alpha, @@ -347,9 +347,9 @@ template void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - double* precomputed_vertex_out_weight_sums, - int32_t* personalization_vertices, - double* personalization_values, + double const* precomputed_vertex_out_weight_sums, + int32_t const* personalization_vertices, + double const* personalization_values, int32_t personalization_vector_size, double* pageranks, double alpha, @@ -360,9 +360,9 @@ template void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - float* precomputed_vertex_out_weight_sums, - int64_t* personalization_vertices, - float* personalization_values, + float const* precomputed_vertex_out_weight_sums, + int64_t const* personalization_vertices, + float const* personalization_values, int64_t personalization_vector_size, float* pageranks, float alpha, @@ -373,9 +373,9 @@ template void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - double* precomputed_vertex_out_weight_sums, - int64_t* personalization_vertices, - double* personalization_values, + double const* precomputed_vertex_out_weight_sums, + int64_t const* personalization_vertices, + double const* personalization_values, int64_t personalization_vector_size, double* pageranks, double alpha, @@ -386,9 +386,9 @@ template void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - float* precomputed_vertex_out_weight_sums, - int32_t* personalization_vertices, - float* personalization_values, + float const* precomputed_vertex_out_weight_sums, + int32_t const* personalization_vertices, + float const* personalization_values, int32_t personalization_vector_size, float* pageranks, float alpha, @@ -399,9 +399,9 @@ template void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - double* precomputed_vertex_out_weight_sums, - int32_t* personalization_vertices, - double* personalization_values, + double const* precomputed_vertex_out_weight_sums, + int32_t const* personalization_vertices, + double const* personalization_values, int32_t personalization_vector_size, double* pageranks, double alpha, @@ -412,9 +412,9 @@ template void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - float* precomputed_vertex_out_weight_sums, - int32_t* personalization_vertices, - float* personalization_values, + float const* precomputed_vertex_out_weight_sums, + int32_t const* personalization_vertices, + float const* personalization_values, int32_t personalization_vector_size, float* pageranks, float alpha, @@ -425,9 +425,9 @@ template void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - double* precomputed_vertex_out_weight_sums, - int32_t* personalization_vertices, - double* personalization_values, + double const* precomputed_vertex_out_weight_sums, + int32_t const* personalization_vertices, + double const* personalization_values, int32_t personalization_vector_size, double* pageranks, double alpha, @@ -438,9 +438,9 @@ template void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - float* precomputed_vertex_out_weight_sums, - int64_t* personalization_vertices, - float* personalization_values, + float const* precomputed_vertex_out_weight_sums, + int64_t const* personalization_vertices, + float const* personalization_values, int64_t personalization_vector_size, float* pageranks, float alpha, @@ -451,9 +451,9 @@ template void pagerank(raft::handle_t const& handle, template void pagerank(raft::handle_t const& handle, graph_view_t const& graph_view, - double* precomputed_vertex_out_weight_sums, - int64_t* personalization_vertices, - double* personalization_values, + double const* precomputed_vertex_out_weight_sums, + int64_t const* personalization_vertices, + double const* personalization_values, int64_t personalization_vector_size, double* pageranks, double alpha, diff --git a/cpp/src/experimental/renumber_edgelist.cu b/cpp/src/experimental/renumber_edgelist.cu index b093a9adb22..a8847167b87 100644 --- a/cpp/src/experimental/renumber_edgelist.cu +++ b/cpp/src/experimental/renumber_edgelist.cu @@ -547,11 +547,10 @@ renumber_edgelist(raft::handle_t const& handle, return std::make_tuple( std::move(renumber_map_labels), partition, number_of_vertices, number_of_edges); #else - return std::make_tuple( - rmm::device_uvector(0, handle.get_stream()), - partition_t(std::vector(), false, int{0}, int{0}, int{0}, int{0}), - vertex_t{0}, - edge_t{0}); + return std::make_tuple(rmm::device_uvector(0, handle.get_stream()), + partition_t{}, + vertex_t{0}, + edge_t{0}); #endif } diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt index 68b277871b1..a93aa0cfabb 100644 --- a/cpp/tests/CMakeLists.txt +++ b/cpp/tests/CMakeLists.txt @@ -16,6 +16,43 @@ # #============================================================================= +################################################################################################### +# - common test utils ----------------------------------------------------------------------------- + +add_library(cugraphtestutil STATIC + "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cu" + "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c") + +set_property(TARGET cugraphtestutil PROPERTY POSITION_INDEPENDENT_CODE ON) + +target_include_directories(cugraphtestutil + PRIVATE + "${CUB_INCLUDE_DIR}" + "${THRUST_INCLUDE_DIR}" + "${CUCO_INCLUDE_DIR}" + "${LIBCUDACXX_INCLUDE_DIR}" + "${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}" + "${RMM_INCLUDE}" + "${NCCL_INCLUDE_DIRS}" + "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio" + "${CMAKE_CURRENT_SOURCE_DIR}/../include" + "${CMAKE_CURRENT_SOURCE_DIR}" + "${RAFT_DIR}/cpp/include" +) + +target_link_libraries(cugraphtestutil cugraph) + +# CUDA_ARCHITECTURES=OFF implies cmake will not pass arch flags to the +# compiler. CUDA_ARCHITECTURES must be set to a non-empty value to prevent +# cmake warnings about policy CMP0104. With this setting, arch flags must be +# manually set! ("evaluate_gpu_archs(GPU_ARCHS)" is the current mechanism +# used in cpp/CMakeLists.txt for setting arch options). +# Run "cmake --help-policy CMP0104" for policy details. +# NOTE: the CUDA_ARCHITECTURES=OFF setting may be removed after migrating to +# the findcudatoolkit features in cmake 3.17+ +set_target_properties(cugraphtestutil PROPERTIES + CUDA_ARCHITECTURES OFF) + ################################################################################################### # - compiler function ----------------------------------------------------------------------------- @@ -31,8 +68,6 @@ function(ConfigureTest CMAKE_TEST_NAME CMAKE_TEST_SRC) "${LIBCUDACXX_INCLUDE_DIR}" "${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}" "${RMM_INCLUDE}" - "${CUDF_INCLUDE}" - "${CUDF_INCLUDE}/libcudf/libcudacxx" "${NCCL_INCLUDE_DIRS}" "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio" "${CMAKE_CURRENT_SOURCE_DIR}/../include" @@ -49,6 +84,7 @@ function(ConfigureTest CMAKE_TEST_NAME CMAKE_TEST_SRC) target_link_libraries(${CMAKE_TEST_NAME} PRIVATE + cugraphtestutil cugraph GTest::GTest GTest::Main @@ -140,16 +176,10 @@ endif(RAPIDS_DATASET_ROOT_DIR) ### test sources ################################################################################## ################################################################################################### -# FIXME: consider adding a "add_library(cugraph_testing SHARED ...) instead of -# adding the same test utility sources to each test target. There may need to be -# an additional cugraph_mg_testing lib due to the optional inclusion of MPI. - ################################################################################################### # - katz centrality tests ------------------------------------------------------------------------- set(KATZ_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/centrality/katz_centrality_test.cu") ConfigureTest(KATZ_TEST "${KATZ_TEST_SRC}") @@ -158,15 +188,11 @@ set(KATZ_TEST_SRC # - betweenness centrality tests ------------------------------------------------------------------ set(BETWEENNESS_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/centrality/betweenness_centrality_test.cu") ConfigureTest(BETWEENNESS_TEST "${BETWEENNESS_TEST_SRC}") set(EDGE_BETWEENNESS_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/centrality/edge_betweenness_centrality_test.cu") ConfigureTest(EDGE_BETWEENNESS_TEST "${EDGE_BETWEENNESS_TEST_SRC}") @@ -175,8 +201,6 @@ set(EDGE_BETWEENNESS_TEST_SRC # - SSSP tests ------------------------------------------------------------------------------------ set(SSSP_TEST_SRCS - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/traversal/sssp_test.cu") ConfigureTest(SSSP_TEST "${SSSP_TEST_SRCS}") @@ -185,8 +209,6 @@ ConfigureTest(SSSP_TEST "${SSSP_TEST_SRCS}") # - BFS tests ------------------------------------------------------------------------------------- set(BFS_TEST_SRCS - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/traversal/bfs_test.cu") ConfigureTest(BFS_TEST "${BFS_TEST_SRCS}") @@ -195,8 +217,6 @@ ConfigureTest(BFS_TEST "${BFS_TEST_SRCS}") # - LOUVAIN tests --------------------------------------------------------------------------------- set(LOUVAIN_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/community/louvain_test.cpp") ConfigureTest(LOUVAIN_TEST "${LOUVAIN_TEST_SRC}") @@ -205,8 +225,6 @@ ConfigureTest(LOUVAIN_TEST "${LOUVAIN_TEST_SRC}") # - LEIDEN tests --------------------------------------------------------------------------------- set(LEIDEN_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/community/leiden_test.cpp") ConfigureTest(LEIDEN_TEST "${LEIDEN_TEST_SRC}") @@ -215,8 +233,6 @@ ConfigureTest(LEIDEN_TEST "${LEIDEN_TEST_SRC}") # - ECG tests --------------------------------------------------------------------------------- set(ECG_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/community/ecg_test.cpp") ConfigureTest(ECG_TEST "${ECG_TEST_SRC}") @@ -225,8 +241,6 @@ ConfigureTest(ECG_TEST "${ECG_TEST_SRC}") # - Balanced cut clustering tests ----------------------------------------------------------------- set(BALANCED_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/community/balanced_edge_test.cpp") ConfigureTest(BALANCED_TEST "${BALANCED_TEST_SRC}") @@ -235,8 +249,6 @@ ConfigureTest(BALANCED_TEST "${BALANCED_TEST_SRC}") # - TRIANGLE tests -------------------------------------------------------------------------------- set(TRIANGLE_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/community/triangle_test.cu") ConfigureTest(TRIANGLE_TEST "${TRIANGLE_TEST_SRC}") @@ -245,8 +257,6 @@ ConfigureTest(TRIANGLE_TEST "${TRIANGLE_TEST_SRC}") # - EGO tests -------------------------------------------------------------------------------- set(EGO_TEST_SRC - "${CMAKE_SOURCE_DIR}/../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/community/egonet_test.cu") ConfigureTest(EGO_TEST "${EGO_TEST_SRC}" "") @@ -254,8 +264,6 @@ ConfigureTest(EGO_TEST "${EGO_TEST_SRC}" "") # - RENUMBERING tests ----------------------------------------------------------------------------- set(RENUMBERING_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/renumber/renumber_test.cu") ConfigureTest(RENUMBERING_TEST "${RENUMBERING_TEST_SRC}") @@ -264,8 +272,6 @@ ConfigureTest(RENUMBERING_TEST "${RENUMBERING_TEST_SRC}") # - FORCE ATLAS 2 tests -------------------------------------------------------------------------- set(FA2_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/layout/force_atlas2_test.cu") ConfigureTest(FA2_TEST "${FA2_TEST_SRC}") @@ -274,8 +280,6 @@ ConfigureTest(FA2_TEST "${FA2_TEST_SRC}") # - TSP tests -------------------------------------------------------------------------- set(TSP_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/traversal/tsp_test.cu") ConfigureTest(TSP_TEST "${TSP_TEST_SRC}" "") @@ -284,8 +288,6 @@ set(TSP_TEST_SRC # - CONNECTED COMPONENTS tests ------------------------------------------------------------------- set(CONNECT_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/components/con_comp_test.cu") ConfigureTest(CONNECT_TEST "${CONNECT_TEST_SRC}") @@ -294,8 +296,6 @@ ConfigureTest(CONNECT_TEST "${CONNECT_TEST_SRC}") # - STRONGLY CONNECTED COMPONENTS tests ---------------------------------------------------------- set(SCC_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/components/scc_test.cu") ConfigureTest(SCC_TEST "${SCC_TEST_SRC}") @@ -304,8 +304,6 @@ ConfigureTest(SCC_TEST "${SCC_TEST_SRC}") #-Hungarian (Linear Assignment Problem) tests --------------------------------------------------------------------- set(HUNGARIAN_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/linear_assignment/hungarian_test.cu") ConfigureTest(HUNGARIAN_TEST "${HUNGARIAN_TEST_SRC}") @@ -314,8 +312,6 @@ ConfigureTest(HUNGARIAN_TEST "${HUNGARIAN_TEST_SRC}") # - MST tests ---------------------------------------------------------------------------- set(MST_TEST_SRC - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/tree/mst_test.cu") ConfigureTest(MST_TEST "${MST_TEST_SRC}") @@ -325,8 +321,6 @@ ConfigureTest(MST_TEST "${MST_TEST_SRC}") # - Experimental Graph tests ---------------------------------------------------------------------- set(EXPERIMENTAL_GRAPH_TEST_SRCS - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/experimental/graph_test.cpp") ConfigureTest(EXPERIMENTAL_GRAPH_TEST "${EXPERIMENTAL_GRAPH_TEST_SRCS}") @@ -355,8 +349,6 @@ ConfigureTest(EXPERIMENTAL_DEGREE_TEST "${EXPERIMENTAL_DEGREE_TEST_SRCS}") # - Experimental coarsening tests ----------------------------------------------------------------- set(EXPERIMENTAL_COARSEN_GRAPH_TEST_SRCS - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/experimental/coarsen_graph_test.cpp") ConfigureTest(EXPERIMENTAL_COARSEN_GRAPH_TEST "${EXPERIMENTAL_COARSEN_GRAPH_TEST_SRCS}") @@ -365,8 +357,6 @@ ConfigureTest(EXPERIMENTAL_COARSEN_GRAPH_TEST "${EXPERIMENTAL_COARSEN_GRAPH_TEST # - Experimental induced subgraph tests ----------------------------------------------------------- set(EXPERIMENTAL_INDUCED_SUBGRAPH_TEST_SRCS - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/experimental/induced_subgraph_test.cpp") ConfigureTest(EXPERIMENTAL_INDUCED_SUBGRAPH_TEST "${EXPERIMENTAL_INDUCED_SUBGRAPH_TEST_SRCS}") @@ -375,8 +365,6 @@ ConfigureTest(EXPERIMENTAL_INDUCED_SUBGRAPH_TEST "${EXPERIMENTAL_INDUCED_SUBGRAP # - Experimental BFS tests ------------------------------------------------------------------------ set(EXPERIMENTAL_BFS_TEST_SRCS - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/experimental/bfs_test.cpp") ConfigureTest(EXPERIMENTAL_BFS_TEST "${EXPERIMENTAL_BFS_TEST_SRCS}") @@ -385,8 +373,6 @@ ConfigureTest(EXPERIMENTAL_BFS_TEST "${EXPERIMENTAL_BFS_TEST_SRCS}") # - Experimental SSSP tests ----------------------------------------------------------------------- set(EXPERIMENTAL_SSSP_TEST_SRCS - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/experimental/sssp_test.cpp") ConfigureTest(EXPERIMENTAL_SSSP_TEST "${EXPERIMENTAL_SSSP_TEST_SRCS}") @@ -395,8 +381,6 @@ ConfigureTest(EXPERIMENTAL_SSSP_TEST "${EXPERIMENTAL_SSSP_TEST_SRCS}") # - Experimental PAGERANK tests ------------------------------------------------------------------- set(EXPERIMENTAL_PAGERANK_TEST_SRCS - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/experimental/pagerank_test.cpp") ConfigureTest(EXPERIMENTAL_PAGERANK_TEST "${EXPERIMENTAL_PAGERANK_TEST_SRCS}") @@ -405,8 +389,6 @@ ConfigureTest(EXPERIMENTAL_PAGERANK_TEST "${EXPERIMENTAL_PAGERANK_TEST_SRCS}") # - Experimental LOUVAIN tests ------------------------------------------------------------------- set(EXPERIMENTAL_LOUVAIN_TEST_SRCS - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/experimental/louvain_test.cu") ConfigureTest(EXPERIMENTAL_LOUVAIN_TEST "${EXPERIMENTAL_LOUVAIN_TEST_SRCS}") @@ -415,8 +397,6 @@ ConfigureTest(EXPERIMENTAL_LOUVAIN_TEST "${EXPERIMENTAL_LOUVAIN_TEST_SRCS}") # - Experimental KATZ_CENTRALITY tests ------------------------------------------------------------ set(EXPERIMENTAL_KATZ_CENTRALITY_TEST_SRCS - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/experimental/katz_centrality_test.cpp") ConfigureTest(EXPERIMENTAL_KATZ_CENTRALITY_TEST "${EXPERIMENTAL_KATZ_CENTRALITY_TEST_SRCS}") @@ -424,16 +404,14 @@ ConfigureTest(EXPERIMENTAL_KATZ_CENTRALITY_TEST "${EXPERIMENTAL_KATZ_CENTRALITY_ ################################################################################################### # - MG tests -------------------------------------------------------------------------------------- + if(BUILD_CUGRAPH_MG_TESTS) if(MPI_CXX_FOUND) ########################################################################################### # - MG PAGERANK tests --------------------------------------------------------------------- set(MG_PAGERANK_TEST_SRCS - "${CMAKE_CURRENT_SOURCE_DIR}/../../thirdparty/mmio/mmio.c" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/test_utilities.cpp" - "${CMAKE_CURRENT_SOURCE_DIR}/utilities/mg_test_utilities.cu" - "${CMAKE_CURRENT_SOURCE_DIR}/pagerank/pagerank_mg_test.cpp") + "${CMAKE_CURRENT_SOURCE_DIR}/pagerank/mg_pagerank_test.cpp") ConfigureTest(MG_PAGERANK_TEST "${MG_PAGERANK_TEST_SRCS}") target_link_libraries(MG_PAGERANK_TEST PRIVATE MPI::MPI_C MPI::MPI_CXX) diff --git a/cpp/tests/community/egonet_test.cu b/cpp/tests/community/egonet_test.cu index ec031228998..ef2699bd1d0 100644 --- a/cpp/tests/community/egonet_test.cu +++ b/cpp/tests/community/egonet_test.cu @@ -69,9 +69,11 @@ class Tests_InducedEgo : public ::testing::TestWithParam { { raft::handle_t handle{}; - auto graph = cugraph::test:: - read_graph_from_matrix_market_file( - handle, configuration.graph_file_full_path, configuration.test_weighted); + cugraph::experimental::graph_t graph( + handle); + std::tie(graph, std::ignore) = cugraph::test:: + read_graph_from_matrix_market_file( + handle, configuration.graph_file_full_path, configuration.test_weighted, false); auto graph_view = graph.view(); rmm::device_uvector d_ego_sources(configuration.ego_sources.size(), diff --git a/cpp/tests/experimental/bfs_test.cpp b/cpp/tests/experimental/bfs_test.cpp index 82286b1e2fa..5b8add98560 100644 --- a/cpp/tests/experimental/bfs_test.cpp +++ b/cpp/tests/experimental/bfs_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. + * Copyright (c) 2020-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. @@ -102,9 +102,10 @@ class Tests_BFS : public ::testing::TestWithParam { raft::handle_t handle{}; - auto graph = - cugraph::test::read_graph_from_matrix_market_file( - handle, configuration.graph_file_full_path, false); + cugraph::experimental::graph_t graph(handle); + std::tie(graph, std::ignore) = + cugraph::test::read_graph_from_matrix_market_file( + handle, configuration.graph_file_full_path, false, false); auto graph_view = graph.view(); std::vector h_offsets(graph_view.get_number_of_vertices() + 1); diff --git a/cpp/tests/experimental/coarsen_graph_test.cpp b/cpp/tests/experimental/coarsen_graph_test.cpp index b790dfffa69..941b33e5661 100644 --- a/cpp/tests/experimental/coarsen_graph_test.cpp +++ b/cpp/tests/experimental/coarsen_graph_test.cpp @@ -273,9 +273,11 @@ class Tests_CoarsenGraph : public ::testing::TestWithParam return; } - auto graph = cugraph::test:: - read_graph_from_matrix_market_file( - handle, configuration.graph_file_full_path, configuration.test_weighted); + cugraph::experimental::graph_t graph( + handle); + std::tie(graph, std::ignore) = cugraph::test:: + read_graph_from_matrix_market_file( + handle, configuration.graph_file_full_path, configuration.test_weighted, false); auto graph_view = graph.view(); if (graph_view.get_number_of_vertices() == 0) { return; } diff --git a/cpp/tests/experimental/graph_test.cpp b/cpp/tests/experimental/graph_test.cpp index b80de68f95c..949f6d2e08e 100644 --- a/cpp/tests/experimental/graph_test.cpp +++ b/cpp/tests/experimental/graph_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. + * Copyright (c) 2020-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. @@ -91,10 +91,28 @@ class Tests_Graph : public ::testing::TestWithParam { template void run_current_test(Graph_Usecase const& configuration) { - auto mm_graph = - cugraph::test::read_edgelist_from_matrix_market_file( - configuration.graph_file_full_path); - edge_t number_of_edges = static_cast(mm_graph.h_rows.size()); + raft::handle_t handle{}; + + rmm::device_uvector d_rows(0, handle.get_stream()); + rmm::device_uvector d_cols(0, handle.get_stream()); + rmm::device_uvector d_weights(0, handle.get_stream()); + vertex_t number_of_vertices{}; + bool is_symmetric{}; + std::tie(d_rows, d_cols, d_weights, number_of_vertices, is_symmetric) = + cugraph::test::read_edgelist_from_matrix_market_file( + handle, configuration.graph_file_full_path, configuration.test_weighted); + edge_t number_of_edges = static_cast(d_rows.size()); + + std::vector h_rows(number_of_edges); + std::vector h_cols(number_of_edges); + std::vector h_weights(configuration.test_weighted ? number_of_edges : edge_t{0}); + + raft::update_host(h_rows.data(), d_rows.data(), number_of_edges, handle.get_stream()); + raft::update_host(h_cols.data(), d_cols.data(), number_of_edges, handle.get_stream()); + if (configuration.test_weighted) { + raft::update_host(h_weights.data(), d_weights.data(), number_of_edges, handle.get_stream()); + } + CUDA_TRY(cudaStreamSynchronize(handle.get_stream())); std::vector h_reference_offsets{}; std::vector h_reference_indices{}; @@ -102,28 +120,12 @@ class Tests_Graph : public ::testing::TestWithParam { std::tie(h_reference_offsets, h_reference_indices, h_reference_weights) = graph_reference( - mm_graph.h_rows.data(), - mm_graph.h_cols.data(), - configuration.test_weighted ? mm_graph.h_weights.data() : nullptr, - mm_graph.number_of_vertices, + h_rows.data(), + h_cols.data(), + configuration.test_weighted ? h_weights.data() : static_cast(nullptr), + number_of_vertices, number_of_edges); - raft::handle_t handle{}; - - rmm::device_uvector d_rows(number_of_edges, handle.get_stream()); - rmm::device_uvector d_cols(number_of_edges, handle.get_stream()); - rmm::device_uvector d_weights(configuration.test_weighted ? number_of_edges : 0, - handle.get_stream()); - - raft::update_device( - d_rows.data(), mm_graph.h_rows.data(), number_of_edges, handle.get_stream()); - raft::update_device( - d_cols.data(), mm_graph.h_cols.data(), number_of_edges, handle.get_stream()); - if (configuration.test_weighted) { - raft::update_device( - d_weights.data(), mm_graph.h_weights.data(), number_of_edges, handle.get_stream()); - } - cugraph::experimental::edgelist_t edgelist{ d_rows.data(), d_cols.data(), @@ -136,8 +138,8 @@ class Tests_Graph : public ::testing::TestWithParam { cugraph::experimental::graph_t( handle, edgelist, - mm_graph.number_of_vertices, - cugraph::experimental::graph_properties_t{mm_graph.is_symmetric, false}, + number_of_vertices, + cugraph::experimental::graph_properties_t{is_symmetric, false}, false, true); @@ -145,7 +147,7 @@ class Tests_Graph : public ::testing::TestWithParam { CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement - ASSERT_EQ(graph_view.get_number_of_vertices(), mm_graph.number_of_vertices); + ASSERT_EQ(graph_view.get_number_of_vertices(), number_of_vertices); ASSERT_EQ(graph_view.get_number_of_edges(), number_of_edges); std::vector h_cugraph_offsets(graph_view.get_number_of_vertices() + 1); @@ -174,7 +176,7 @@ class Tests_Graph : public ::testing::TestWithParam { std::equal(h_reference_offsets.begin(), h_reference_offsets.end(), h_cugraph_offsets.begin())) << "Graph compressed sparse format offsets do not match with the reference values."; ASSERT_EQ(h_reference_weights.size(), h_cugraph_weights.size()); - for (vertex_t i = 0; i < mm_graph.number_of_vertices; ++i) { + for (vertex_t i = 0; i < number_of_vertices; ++i) { auto start = h_reference_offsets[i]; auto degree = h_reference_offsets[i + 1] - start; if (configuration.test_weighted) { diff --git a/cpp/tests/experimental/induced_subgraph_test.cpp b/cpp/tests/experimental/induced_subgraph_test.cpp index 72894a9349f..4e0ca9e7d92 100644 --- a/cpp/tests/experimental/induced_subgraph_test.cpp +++ b/cpp/tests/experimental/induced_subgraph_test.cpp @@ -113,9 +113,11 @@ class Tests_InducedSubgraph : public ::testing::TestWithParam( - handle, configuration.graph_file_full_path, configuration.test_weighted); + cugraph::experimental::graph_t graph( + handle); + std::tie(graph, std::ignore) = cugraph::test:: + read_graph_from_matrix_market_file( + handle, configuration.graph_file_full_path, configuration.test_weighted, false); auto graph_view = graph.view(); std::vector h_offsets(graph_view.get_number_of_vertices() + 1); diff --git a/cpp/tests/experimental/katz_centrality_test.cpp b/cpp/tests/experimental/katz_centrality_test.cpp index 3e9f0b478a0..945248cc4de 100644 --- a/cpp/tests/experimental/katz_centrality_test.cpp +++ b/cpp/tests/experimental/katz_centrality_test.cpp @@ -117,9 +117,10 @@ class Tests_KatzCentrality : public ::testing::TestWithParam( - handle, configuration.graph_file_full_path, configuration.test_weighted); + cugraph::experimental::graph_t graph(handle); + std::tie(graph, std::ignore) = + cugraph::test::read_graph_from_matrix_market_file( + handle, configuration.graph_file_full_path, configuration.test_weighted, false); auto graph_view = graph.view(); std::vector h_offsets(graph_view.get_number_of_vertices() + 1); diff --git a/cpp/tests/experimental/louvain_test.cu b/cpp/tests/experimental/louvain_test.cu index 35a26923df6..56fb2c109bf 100644 --- a/cpp/tests/experimental/louvain_test.cu +++ b/cpp/tests/experimental/louvain_test.cu @@ -69,9 +69,10 @@ class Tests_Louvain : public ::testing::TestWithParam { std::cout << "read graph file: " << configuration.graph_file_full_path << std::endl; - auto graph = - cugraph::test::read_graph_from_matrix_market_file( - handle, configuration.graph_file_full_path, configuration.test_weighted); + cugraph::experimental::graph_t graph(handle); + std::tie(graph, std::ignore) = + cugraph::test::read_graph_from_matrix_market_file( + handle, configuration.graph_file_full_path, configuration.test_weighted, false); auto graph_view = graph.view(); diff --git a/cpp/tests/experimental/pagerank_test.cpp b/cpp/tests/experimental/pagerank_test.cpp index 53143bf0bf3..514f73e3311 100644 --- a/cpp/tests/experimental/pagerank_test.cpp +++ b/cpp/tests/experimental/pagerank_test.cpp @@ -155,9 +155,10 @@ class Tests_PageRank : public ::testing::TestWithParam { { raft::handle_t handle{}; - auto graph = - cugraph::test::read_graph_from_matrix_market_file( - handle, configuration.graph_file_full_path, configuration.test_weighted); + cugraph::experimental::graph_t graph(handle); + std::tie(graph, std::ignore) = + cugraph::test::read_graph_from_matrix_market_file( + handle, configuration.graph_file_full_path, configuration.test_weighted, false); auto graph_view = graph.view(); std::vector h_offsets(graph_view.get_number_of_vertices() + 1); @@ -225,11 +226,11 @@ class Tests_PageRank : public ::testing::TestWithParam { handle.get_stream()); } - std::vector h_reference_pageranks(graph_view.get_number_of_vertices()); - result_t constexpr alpha{0.85}; result_t constexpr epsilon{1e-6}; + std::vector h_reference_pageranks(graph_view.get_number_of_vertices()); + pagerank_reference(h_offsets.data(), h_indices.data(), h_weights.size() > 0 ? h_weights.data() : static_cast(nullptr), diff --git a/cpp/tests/experimental/sssp_test.cpp b/cpp/tests/experimental/sssp_test.cpp index 2f7cc499d35..7fd59d49a25 100644 --- a/cpp/tests/experimental/sssp_test.cpp +++ b/cpp/tests/experimental/sssp_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, NVIDIA CORPORATION. + * Copyright (c) 2020-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. @@ -106,9 +106,10 @@ class Tests_SSSP : public ::testing::TestWithParam { { raft::handle_t handle{}; - auto graph = - cugraph::test::read_graph_from_matrix_market_file( - handle, configuration.graph_file_full_path, true); + cugraph::experimental::graph_t graph(handle); + std::tie(graph, std::ignore) = + cugraph::test::read_graph_from_matrix_market_file( + handle, configuration.graph_file_full_path, true, false); auto graph_view = graph.view(); std::vector h_offsets(graph_view.get_number_of_vertices() + 1); diff --git a/cpp/tests/pagerank/mg_pagerank_test.cpp b/cpp/tests/pagerank/mg_pagerank_test.cpp new file mode 100644 index 00000000000..cf9f452162b --- /dev/null +++ b/cpp/tests/pagerank/mg_pagerank_test.cpp @@ -0,0 +1,296 @@ +/* + * 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. + */ + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include + +typedef struct Pagerank_Usecase_t { + std::string graph_file_full_path{}; + double personalization_ratio{0.0}; + bool test_weighted{false}; + + Pagerank_Usecase_t(std::string const& graph_file_path, + double personalization_ratio, + bool test_weighted) + : personalization_ratio(personalization_ratio), test_weighted(test_weighted) + { + if ((graph_file_path.length() > 0) && (graph_file_path[0] != '/')) { + graph_file_full_path = cugraph::test::get_rapids_dataset_root_dir() + "/" + graph_file_path; + } else { + graph_file_full_path = graph_file_path; + } + }; +} Pagerank_Usecase; + +class Tests_MGPageRank : public ::testing::TestWithParam { + public: + Tests_MGPageRank() {} + static void SetupTestCase() {} + static void TearDownTestCase() {} + + virtual void SetUp() {} + virtual void TearDown() {} + + // Compare the results of running pagerank on multiple GPUs to that of a single-GPU run + template + void run_current_test(Pagerank_Usecase const& configuration) + { + // 1. initialize handle + + raft::handle_t handle{}; + + raft::comms::initialize_mpi_comms(&handle, MPI_COMM_WORLD); + auto& comm = handle.get_comms(); + auto const comm_size = comm.get_size(); + auto const comm_rank = comm.get_rank(); + + auto row_comm_size = static_cast(sqrt(static_cast(comm_size))); + while (comm_size % row_comm_size != 0) { --row_comm_size; } + cugraph::partition_2d::subcomm_factory_t + subcomm_factory(handle, row_comm_size); + + // 2. create SG & MG graphs + + cugraph::experimental::graph_t sg_graph(handle); + rmm::device_uvector d_sg_renumber_map_labels(0, handle.get_stream()); + std::tie(sg_graph, d_sg_renumber_map_labels) = + cugraph::test::read_graph_from_matrix_market_file( + handle, configuration.graph_file_full_path, configuration.test_weighted, true); + + auto sg_graph_view = sg_graph.view(); + + cugraph::experimental::graph_t mg_graph(handle); + rmm::device_uvector d_mg_renumber_map_labels(0, handle.get_stream()); + std::tie(mg_graph, d_mg_renumber_map_labels) = + cugraph::test::read_graph_from_matrix_market_file( + handle, configuration.graph_file_full_path, configuration.test_weighted, true); + + auto mg_graph_view = mg_graph.view(); + + std::vector h_sg_renumber_map_labels(d_sg_renumber_map_labels.size()); + raft::update_host(h_sg_renumber_map_labels.data(), + d_sg_renumber_map_labels.data(), + d_sg_renumber_map_labels.size(), + handle.get_stream()); + + std::vector h_mg_renumber_map_labels(mg_graph_view.get_number_of_local_vertices()); + raft::update_host(h_mg_renumber_map_labels.data(), + d_mg_renumber_map_labels.data(), + d_mg_renumber_map_labels.size(), + handle.get_stream()); + + CUDA_TRY(cudaStreamSynchronize(handle.get_stream())); + + // 2. generate personalization vertex/value pairs + + std::vector h_personalization_vertices{}; + std::vector h_personalization_values{}; + if (configuration.personalization_ratio > 0.0) { + std::default_random_engine generator{}; + std::uniform_real_distribution distribution{0.0, 1.0}; + h_personalization_vertices.resize(sg_graph_view.get_number_of_vertices()); + std::iota(h_personalization_vertices.begin(), h_personalization_vertices.end(), vertex_t{0}); + h_personalization_vertices.erase( + std::remove_if(h_personalization_vertices.begin(), + h_personalization_vertices.end(), + [&generator, &distribution, configuration](auto v) { + return distribution(generator) >= configuration.personalization_ratio; + }), + h_personalization_vertices.end()); + h_personalization_values.resize(h_personalization_vertices.size()); + std::for_each(h_personalization_values.begin(), + h_personalization_values.end(), + [&distribution, &generator](auto& val) { val = distribution(generator); }); + } + + result_t constexpr alpha{0.85}; + result_t constexpr epsilon{1e-6}; + + // 3. run SG pagerank + + std::vector h_sg_personalization_vertices{}; + std::vector h_sg_personalization_values{}; + if (h_personalization_vertices.size() > 0) { + for (vertex_t i = 0; i < sg_graph_view.get_number_of_vertices(); ++i) { + auto it = std::lower_bound(h_personalization_vertices.begin(), + h_personalization_vertices.end(), + h_sg_renumber_map_labels[i]); + if (*it == h_sg_renumber_map_labels[i]) { + h_sg_personalization_vertices.push_back(i); + h_sg_personalization_values.push_back( + h_personalization_values[std::distance(h_personalization_vertices.begin(), it)]); + } + } + } + + rmm::device_uvector d_sg_personalization_vertices( + h_sg_personalization_vertices.size(), handle.get_stream()); + rmm::device_uvector d_sg_personalization_values(d_sg_personalization_vertices.size(), + handle.get_stream()); + if (d_sg_personalization_vertices.size() > 0) { + raft::update_device(d_sg_personalization_vertices.data(), + h_sg_personalization_vertices.data(), + h_sg_personalization_vertices.size(), + handle.get_stream()); + raft::update_device(d_sg_personalization_values.data(), + h_sg_personalization_values.data(), + h_sg_personalization_values.size(), + handle.get_stream()); + } + + rmm::device_uvector d_sg_pageranks(sg_graph_view.get_number_of_vertices(), + handle.get_stream()); + + cugraph::experimental::pagerank(handle, + sg_graph_view, + static_cast(nullptr), + d_sg_personalization_vertices.data(), + d_sg_personalization_values.data(), + static_cast(d_sg_personalization_vertices.size()), + d_sg_pageranks.begin(), + alpha, + epsilon, + std::numeric_limits::max(), // max_iterations + false, + false); + + std::vector h_sg_pageranks(sg_graph_view.get_number_of_vertices()); + raft::update_host( + h_sg_pageranks.data(), d_sg_pageranks.data(), d_sg_pageranks.size(), handle.get_stream()); + CUDA_TRY(cudaStreamSynchronize(handle.get_stream())); + + // 4. run MG pagerank + + std::vector h_mg_personalization_vertices{}; + std::vector h_mg_personalization_values{}; + if (h_personalization_vertices.size() > 0) { + for (vertex_t i = 0; i < mg_graph_view.get_number_of_local_vertices(); ++i) { + auto it = std::lower_bound(h_personalization_vertices.begin(), + h_personalization_vertices.end(), + h_mg_renumber_map_labels[i]); + if (*it == h_mg_renumber_map_labels[i]) { + h_mg_personalization_vertices.push_back(mg_graph_view.get_local_vertex_first() + i); + h_mg_personalization_values.push_back( + h_personalization_values[std::distance(h_personalization_vertices.begin(), it)]); + } + } + } + + rmm::device_uvector d_mg_personalization_vertices( + h_mg_personalization_vertices.size(), handle.get_stream()); + rmm::device_uvector d_mg_personalization_values(d_mg_personalization_vertices.size(), + handle.get_stream()); + if (d_mg_personalization_vertices.size() > 0) { + raft::update_device(d_mg_personalization_vertices.data(), + h_mg_personalization_vertices.data(), + h_mg_personalization_vertices.size(), + handle.get_stream()); + raft::update_device(d_mg_personalization_values.data(), + h_mg_personalization_values.data(), + h_mg_personalization_values.size(), + handle.get_stream()); + } + + rmm::device_uvector d_mg_pageranks(mg_graph_view.get_number_of_local_vertices(), + handle.get_stream()); + + CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement + + cugraph::experimental::pagerank(handle, + mg_graph_view, + static_cast(nullptr), + d_mg_personalization_vertices.data(), + d_mg_personalization_values.data(), + static_cast(d_mg_personalization_vertices.size()), + d_mg_pageranks.begin(), + alpha, + epsilon, + std::numeric_limits::max(), + false, + false); + + CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement + + std::vector h_mg_pageranks(mg_graph_view.get_number_of_local_vertices()); + raft::update_host( + h_mg_pageranks.data(), d_mg_pageranks.data(), d_mg_pageranks.size(), handle.get_stream()); + CUDA_TRY(cudaStreamSynchronize(handle.get_stream())); + + // 5. copmare SG & MG results + + std::vector h_sg_shuffled_pageranks(sg_graph_view.get_number_of_vertices(), + result_t{0.0}); + for (size_t i = 0; i < h_sg_pageranks.size(); ++i) { + h_sg_shuffled_pageranks[h_sg_renumber_map_labels[i]] = h_sg_pageranks[i]; + } + + auto threshold_ratio = 1e-3; + auto threshold_magnitude = + (1.0 / static_cast(mg_graph_view.get_number_of_vertices())) * + threshold_ratio; // skip comparison for low PageRank verties (lowly ranked vertices) + auto nearly_equal = [threshold_ratio, threshold_magnitude](auto lhs, auto rhs) { + return std::abs(lhs - rhs) < + std::max(std::max(lhs, rhs) * threshold_ratio, threshold_magnitude); + }; + + for (vertex_t i = 0; i < mg_graph_view.get_number_of_local_vertices(); ++i) { + auto mapped_vertex = h_mg_renumber_map_labels[i]; + ASSERT_TRUE(nearly_equal(h_mg_pageranks[i], h_sg_shuffled_pageranks[mapped_vertex])) + << "MG PageRank value for vertex: " << i << " in rank: " << comm_rank + << " has value: " << h_mg_pageranks[i] + << " which exceeds the error margin for comparing to SG value: " + << h_sg_shuffled_pageranks[mapped_vertex]; + } + } +}; + +TEST_P(Tests_MGPageRank, CheckInt32Int32FloatFloat) +{ + run_current_test(GetParam()); +} + +INSTANTIATE_TEST_CASE_P( + simple_test, + Tests_MGPageRank, + ::testing::Values(Pagerank_Usecase("test/datasets/karate.mtx", 0.0, false), + Pagerank_Usecase("test/datasets/karate.mtx", 0.5, false), + Pagerank_Usecase("test/datasets/karate.mtx", 0.0, true), + Pagerank_Usecase("test/datasets/karate.mtx", 0.5, true), + Pagerank_Usecase("test/datasets/web-Google.mtx", 0.0, false), + Pagerank_Usecase("test/datasets/web-Google.mtx", 0.5, false), + Pagerank_Usecase("test/datasets/web-Google.mtx", 0.0, true), + Pagerank_Usecase("test/datasets/web-Google.mtx", 0.5, true), + Pagerank_Usecase("test/datasets/ljournal-2008.mtx", 0.0, false), + Pagerank_Usecase("test/datasets/ljournal-2008.mtx", 0.5, false), + Pagerank_Usecase("test/datasets/ljournal-2008.mtx", 0.0, true), + Pagerank_Usecase("test/datasets/ljournal-2008.mtx", 0.5, true), + Pagerank_Usecase("test/datasets/webbase-1M.mtx", 0.0, false), + Pagerank_Usecase("test/datasets/webbase-1M.mtx", 0.5, false), + Pagerank_Usecase("test/datasets/webbase-1M.mtx", 0.0, true), + Pagerank_Usecase("test/datasets/webbase-1M.mtx", 0.5, true))); + +CUGRAPH_MG_TEST_PROGRAM_MAIN() diff --git a/cpp/tests/pagerank/pagerank_mg_test.cpp b/cpp/tests/pagerank/pagerank_mg_test.cpp deleted file mode 100644 index 7f789226bf1..00000000000 --- a/cpp/tests/pagerank/pagerank_mg_test.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* - * 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. - */ - -#include -#include -#include - -#include -#include - -#include - -#include - -//////////////////////////////////////////////////////////////////////////////// -// Test param object. This defines the input and expected output for a test, and -// will be instantiated as the parameter to the tests defined below using -// INSTANTIATE_TEST_CASE_P() -// -typedef struct Pagerank_Testparams_t { - std::string graph_file_full_path{}; - double personalization_ratio{0.0}; - bool test_weighted{false}; - - Pagerank_Testparams_t(std::string const& graph_file_path, - double personalization_ratio, - bool test_weighted) - : personalization_ratio(personalization_ratio), test_weighted(test_weighted) - { - if ((graph_file_path.length() > 0) && (graph_file_path[0] != '/')) { - graph_file_full_path = cugraph::test::get_rapids_dataset_root_dir() + "/" + graph_file_path; - } else { - graph_file_full_path = graph_file_path; - } - }; -} Pagerank_Testparams_t; - -//////////////////////////////////////////////////////////////////////////////// -// Parameterized test fixture, to be used with TEST_P(). This defines common -// setup and teardown steps as well as common utilities used by each E2E MG -// test. In this case, each test is identical except for the inputs and -// expected outputs, so the entire test is defined in the run_test() method. -// -class Pagerank_E2E_MG_Testfixture_t : public cugraph::test::MG_TestFixture_t, - public ::testing::WithParamInterface { - public: - Pagerank_E2E_MG_Testfixture_t() {} - - // Run once for each test instance - virtual void SetUp() {} - virtual void TearDown() {} - - // Return the results of running pagerank on a single GPU for the dataset in - // graph_file_path. - template - std::vector get_sg_results(raft::handle_t& handle, - const std::string& graph_file_path, - const result_t alpha, - const result_t epsilon) - { - auto graph = - cugraph::test::read_graph_from_matrix_market_file( - handle, graph_file_path, true); // FIXME: should use param.test_weighted instead of true - - auto graph_view = graph.view(); - cudaStream_t stream = handle.get_stream(); - rmm::device_uvector d_pageranks(graph_view.get_number_of_vertices(), stream); - - cugraph::experimental::pagerank( - handle, - graph_view, - static_cast(nullptr), // adj_matrix_row_out_weight_sums - static_cast(nullptr), // personalization_vertices - static_cast(nullptr), // personalization_values - static_cast(0), // personalization_vector_size - d_pageranks.begin(), // pageranks - alpha, // alpha (damping factor) - epsilon, // error tolerance for convergence - std::numeric_limits::max(), // max_iterations - false, // has_initial_guess - true); // do_expensive_check - - std::vector h_pageranks(graph_view.get_number_of_vertices()); - raft::update_host(h_pageranks.data(), d_pageranks.data(), d_pageranks.size(), stream); - - return h_pageranks; - } - - // Compare the results of running pagerank on multiple GPUs to that of a - // single-GPU run for the configuration in param. - template - void run_test(const Pagerank_Testparams_t& param) - { - result_t constexpr alpha{0.85}; - result_t constexpr epsilon{1e-6}; - - raft::handle_t handle; - raft::comms::initialize_mpi_comms(&handle, MPI_COMM_WORLD); - const auto& comm = handle.get_comms(); - - cudaStream_t stream = handle.get_stream(); - - // Assuming 2 GPUs which means 1 row, 2 cols. 2 cols = row_comm_size of 2. - // FIXME: DO NOT ASSUME 2 GPUs, add code to compute prows, pcols - size_t row_comm_size{2}; - cugraph::partition_2d::subcomm_factory_t - subcomm_factory(handle, row_comm_size); - - int my_rank = comm.get_rank(); - - // FIXME: graph must be weighted! - std::unique_ptr> // store_transposed=true, - // multi_gpu=true - mg_graph_ptr{}; - rmm::device_uvector d_renumber_map_labels(0, handle.get_stream()); - - std::tie(mg_graph_ptr, d_renumber_map_labels) = cugraph::test:: - create_graph_for_gpu // store_transposed=true - (handle, param.graph_file_full_path); - - auto mg_graph_view = mg_graph_ptr->view(); - - rmm::device_uvector d_mg_pageranks(mg_graph_view.get_number_of_vertices(), stream); - CUDA_TRY(cudaDeviceSynchronize()); // for consistent performance measurement - - cugraph::experimental::pagerank( - handle, - mg_graph_view, - static_cast(nullptr), // adj_matrix_row_out_weight_sums - static_cast(nullptr), // personalization_vertices - static_cast(nullptr), // personalization_values - static_cast(0), // personalization_vector_size - d_mg_pageranks.begin(), // pageranks - alpha, // alpha (damping factor) - epsilon, // error tolerance for convergence - std::numeric_limits::max(), // max_iterations - false, // has_initial_guess - true); // do_expensive_check - - std::vector h_mg_pageranks(mg_graph_view.get_number_of_vertices()); - - raft::update_host(h_mg_pageranks.data(), d_mg_pageranks.data(), d_mg_pageranks.size(), stream); - - std::vector h_renumber_map_labels(mg_graph_view.get_number_of_vertices()); - raft::update_host(h_renumber_map_labels.data(), - d_renumber_map_labels.data(), - d_renumber_map_labels.size(), - stream); - - // Compare MG to SG - // Each GPU will have pagerank values for their range, so ech GPU must - // compare to specific SG results for their respective range. - - auto h_sg_pageranks = get_sg_results( - handle, param.graph_file_full_path, alpha, epsilon); - - // For this test, each GPU will have the full set of vertices and - // therefore the pageranks vectors should be equal in size. - ASSERT_EQ(h_sg_pageranks.size(), h_mg_pageranks.size()); - - auto threshold_ratio = 1e-3; - auto threshold_magnitude = - (1.0 / static_cast(mg_graph_view.get_number_of_vertices())) * - threshold_ratio; // skip comparison for low PageRank verties (lowly ranked vertices) - auto nearly_equal = [threshold_ratio, threshold_magnitude](auto lhs, auto rhs) { - return std::abs(lhs - rhs) < - std::max(std::max(lhs, rhs) * threshold_ratio, threshold_magnitude); - }; - - vertex_t mapped_vertex{0}; - for (vertex_t i = 0; - i + mg_graph_view.get_local_vertex_first() < mg_graph_view.get_local_vertex_last(); - ++i) { - mapped_vertex = h_renumber_map_labels[i]; - ASSERT_TRUE(nearly_equal(h_mg_pageranks[i], h_sg_pageranks[mapped_vertex])) - << "MG PageRank value for vertex: " << i << " in rank: " << my_rank - << " has value: " << h_mg_pageranks[i] - << " which exceeds the error margin for comparing to SG value: " << h_sg_pageranks[i]; - } - } -}; - -//////////////////////////////////////////////////////////////////////////////// -TEST_P(Pagerank_E2E_MG_Testfixture_t, CheckInt32Int32FloatFloat) -{ - run_test(GetParam()); -} - -INSTANTIATE_TEST_CASE_P( - e2e, - Pagerank_E2E_MG_Testfixture_t, - - // FIXME: the personalization_ratio and use_weighted boo are not used - // (personilization vectors are not used, and all datasets are assumed - // weighted). update this to use personilization vectors and non-weighted - // graphs. - ::testing::Values(Pagerank_Testparams_t("test/datasets/karate.mtx", 0.0, true), - // FIXME: The commented datasets contain isolate vertices - // which result in a different number of vertices in the - // renumbered MG graph (because the renumbering function - // does not include them) vs. the SG graph object used for - // the pagerank comparison because the SG graph reads the - // COO as-is without renumbering. Update the utility that - // reads a .mtx and constructs a SG graph object to also - // renumber and return the renumber vertices vector. This - // will result in a comparison of an equal number of - // pagerank values. - // - // Pagerank_Testparams_t("test/datasets/web-Google.mtx", 0.0, true), - // Pagerank_Testparams_t("test/datasets/ljournal-2008.mtx", 0.0, true), - Pagerank_Testparams_t("test/datasets/webbase-1M.mtx", 0.0, true))); - -// FIXME: Enable proper RMM configuration by using CUGRAPH_TEST_PROGRAM_MAIN(). -// Currently seeing a RMM failure during init, need to investigate. -// CUGRAPH_TEST_PROGRAM_MAIN() diff --git a/cpp/tests/utilities/base_fixture.hpp b/cpp/tests/utilities/base_fixture.hpp index 3525db73425..e8f11acfbf4 100644 --- a/cpp/tests/utilities/base_fixture.hpp +++ b/cpp/tests/utilities/base_fixture.hpp @@ -32,18 +32,17 @@ namespace cugraph { namespace test { -// FIXME: The BaseFixture class is not used in any tests. This file is only -// needed for the CUGRAPH_TEST_PROGRAM_MAIN macro and the code that it calls, so -// consider removing the BaseFixture class and renaming this file, or moving -// CUGRAPH_TEST_PROGRAM_MAIN to the test_utilities.hpp file and removing this -// file completely. +// FIXME: The BaseFixture class is not used in any tests. This file is only needed for the +// CUGRAPH_TEST_PROGRAM_MAIN macro and the code that it calls, so consider removing the BaseFixture +// class and renaming this file, or moving CUGRAPH_TEST_PROGRAM_MAIN to the test_utilities.hpp file +// and removing this file completely. /** - * @brief Base test fixture class from which all libcudf tests should inherit. + * @brief Base test fixture class from which all libcugraph tests should inherit. * * Example: * ``` - * class MyTestFixture : public cudf::test::BaseFixture {}; + * class MyTestFixture : public cugraph::test::BaseFixture {}; * ``` **/ class BaseFixture : public ::testing::Test { @@ -51,8 +50,8 @@ class BaseFixture : public ::testing::Test { public: /** - * @brief Returns pointer to `device_memory_resource` that should be used for - * all tests inheriting from this fixture + * @brief Returns pointer to `device_memory_resource` that should be used for all tests inheriting + *from this fixture **/ rmm::mr::device_memory_resource *mr() { return _mr; } }; @@ -77,15 +76,14 @@ inline auto make_binning() } /** - * @brief Creates a memory resource for the unit test environment - * given the name of the allocation mode. + * @brief Creates a memory resource for the unit test environment given the name of the allocation + * mode. * - * The returned resource instance must be kept alive for the duration of - * the tests. Attaching the resource to a TestEnvironment causes - * issues since the environment objects are not destroyed until + * The returned resource instance must be kept alive for the duration of the tests. Attaching the + * resource to a TestEnvironment causes issues since the environment objects are not destroyed until * after the runtime is shutdown. * - * @throw cudf::logic_error if the `allocation_mode` is unsupported. + * @throw cugraph::logic_error if the `allocation_mode` is unsupported. * * @param allocation_mode String identifies which resource type. * Accepted types are "pool", "cuda", and "managed" only. @@ -105,17 +103,17 @@ inline std::shared_ptr create_memory_resource( } // namespace cugraph /** - * @brief Parses the cuDF test command line options. + * @brief Parses the cuGraph test command line options. * - * Currently only supports 'rmm_mode' string paramater, which set the rmm - * allocation mode. The default value of the parameter is 'pool'. + * Currently only supports 'rmm_mode' string paramater, which set the rmm allocation mode. The + * default value of the parameter is 'pool'. * * @return Parsing results in the form of cxxopts::ParseResult */ inline auto parse_test_options(int argc, char **argv) { try { - cxxopts::Options options(argv[0], " - cuDF tests command line options"); + cxxopts::Options options(argv[0], " - cuGraph tests command line options"); options.allow_unrecognised_options().add_options()( "rmm_mode", "RMM allocation mode", cxxopts::value()->default_value("pool")); @@ -128,13 +126,11 @@ inline auto parse_test_options(int argc, char **argv) /** * @brief Macro that defines main function for gtest programs that use rmm * - * Should be included in every test program that uses rmm allocators since - * it maintains the lifespan of the rmm default memory resource. - * This `main` function is a wrapper around the google test generated `main`, - * maintaining the original functionality. In addition, this custom `main` - * function parses the command line to customize test behavior, like the - * allocation mode used for creating the default memory resource. - * + * Should be included in every test program that uses rmm allocators since it maintains the lifespan + * of the rmm default memory resource. This `main` function is a wrapper around the google test + * generated `main`, maintaining the original functionality. In addition, this custom `main` + * function parses the command line to customize test behavior, like the allocation mode used for + * creating the default memory resource. */ #define CUGRAPH_TEST_PROGRAM_MAIN() \ int main(int argc, char **argv) \ @@ -146,3 +142,26 @@ inline auto parse_test_options(int argc, char **argv) rmm::mr::set_current_device_resource(resource.get()); \ return RUN_ALL_TESTS(); \ } + +#define CUGRAPH_MG_TEST_PROGRAM_MAIN() \ + int main(int argc, char **argv) \ + { \ + MPI_TRY(MPI_Init(&argc, &argv)); \ + int comm_rank{}; \ + int comm_size{}; \ + MPI_TRY(MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank)); \ + MPI_TRY(MPI_Comm_size(MPI_COMM_WORLD, &comm_size)); \ + int num_gpus{}; \ + CUDA_TRY(cudaGetDeviceCount(&num_gpus)); \ + CUGRAPH_EXPECTS( \ + comm_size <= num_gpus, "# MPI ranks (%d) > # GPUs (%d).", comm_size, num_gpus); \ + CUDA_TRY(cudaSetDevice(comm_rank)); \ + ::testing::InitGoogleTest(&argc, argv); \ + auto const cmd_opts = parse_test_options(argc, argv); \ + auto const rmm_mode = cmd_opts["rmm_mode"].as(); \ + auto resource = cugraph::test::create_memory_resource(rmm_mode); \ + rmm::mr::set_current_device_resource(resource.get()); \ + auto ret = RUN_ALL_TESTS(); \ + MPI_TRY(MPI_Finalize()); \ + return ret; \ + } diff --git a/cpp/tests/utilities/mg_test_utilities.cu b/cpp/tests/utilities/mg_test_utilities.cu deleted file mode 100644 index 26f2450b589..00000000000 --- a/cpp/tests/utilities/mg_test_utilities.cu +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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. - */ - -#include -#include - -#include -#include -#include -#include - -namespace cugraph { -namespace test { - -// Given a raft handle and a path to a dataset (must be a .mtx file), returns a -// tuple containing: -// * graph_t instance for the partition accesible from the raft handle -// * vector of indices representing the original unrenumberd vertices -// -// This function creates a graph_t instance appropriate for MG graph -// applications from the edgelist graph data file passed in by filtering out the -// vertices not to be assigned to the GPU in this rank, then renumbering the -// vertices appropriately. The returned vector of vertices contains the original -// vertex IDs, ordered by the new sequential renumbered IDs (this is needed for -// unrenumbering). -template -std::tuple< - std::unique_ptr>, // multi_gpu=true - rmm::device_uvector> -create_graph_for_gpu(raft::handle_t& handle, const std::string& graph_file_path) -{ - const auto& comm = handle.get_comms(); - auto& row_comm = handle.get_subcomm(cugraph::partition_2d::key_naming_t().row_name()); - auto& col_comm = handle.get_subcomm(cugraph::partition_2d::key_naming_t().col_name()); - - int my_rank = comm.get_rank(); - - auto edgelist_from_mm = - ::cugraph::test::read_edgelist_from_matrix_market_file( - graph_file_path); - - edge_t total_number_edges = static_cast(edgelist_from_mm.h_rows.size()); - - ////////// - // Copy COO to device - rmm::device_uvector d_edgelist_rows(total_number_edges, handle.get_stream()); - rmm::device_uvector d_edgelist_cols(total_number_edges, handle.get_stream()); - rmm::device_uvector d_edgelist_weights(total_number_edges, handle.get_stream()); - - raft::update_device(d_edgelist_rows.data(), - edgelist_from_mm.h_rows.data(), - total_number_edges, - handle.get_stream()); - raft::update_device(d_edgelist_cols.data(), - edgelist_from_mm.h_cols.data(), - total_number_edges, - handle.get_stream()); - raft::update_device(d_edgelist_weights.data(), - edgelist_from_mm.h_weights.data(), - total_number_edges, - handle.get_stream()); - - ////////// - // Filter out edges that are not to be associated with this rank - // - // Create a edge_gpu_identifier, which will be used by the individual jobs to - // identify if a edge belongs to a particular rank - cugraph::experimental::detail::compute_gpu_id_from_edge_t edge_gpu_identifier{ - false, comm.get_size(), row_comm.get_size(), col_comm.get_size()}; - - auto edgelist_zip_it_begin = thrust::make_zip_iterator(thrust::make_tuple( - d_edgelist_rows.begin(), d_edgelist_cols.begin(), d_edgelist_weights.begin())); - bool is_transposed{store_transposed}; - - // Do the removal - note: remove_if does not delete items, it moves "removed" - // items to the back of the vector and returns the iterator (new_end) that - // represents the items kept. Actual removal of items can be done by - // resizing (see below). - auto new_end = thrust::remove_if( - rmm::exec_policy(handle.get_stream())->on(handle.get_stream()), - edgelist_zip_it_begin, - edgelist_zip_it_begin + total_number_edges, - [my_rank, is_transposed, edge_gpu_identifier] __device__(auto tup) { - if (is_transposed) { - return (edge_gpu_identifier(thrust::get<1>(tup), thrust::get<0>(tup)) != my_rank); - } else { - return (edge_gpu_identifier(thrust::get<0>(tup), thrust::get<1>(tup)) != my_rank); - } - }); - - edge_t local_number_edges = thrust::distance(edgelist_zip_it_begin, new_end); - // Free the memory used for the items remove_if "removed". This not only - // frees memory, but keeps the actual vector sizes consistent with the data - // being used from this point forward. - d_edgelist_rows.resize(local_number_edges, handle.get_stream()); - d_edgelist_rows.shrink_to_fit(handle.get_stream()); - d_edgelist_cols.resize(local_number_edges, handle.get_stream()); - d_edgelist_cols.shrink_to_fit(handle.get_stream()); - d_edgelist_weights.resize(local_number_edges, handle.get_stream()); - d_edgelist_weights.shrink_to_fit(handle.get_stream()); - - ////////// - // renumber filtered edgelist_from_mm - vertex_t* major_vertices{nullptr}; - vertex_t* minor_vertices{nullptr}; - if (is_transposed) { - major_vertices = d_edgelist_cols.data(); - minor_vertices = d_edgelist_rows.data(); - } else { - major_vertices = d_edgelist_rows.data(); - minor_vertices = d_edgelist_cols.data(); - } - - rmm::device_uvector renumber_map_labels(0, handle.get_stream()); - cugraph::experimental::partition_t partition( - std::vector(comm.get_size() + 1, 0), - false, // is_hypergraph_partitioned() - row_comm.get_size(), - col_comm.get_size(), - row_comm.get_rank(), - col_comm.get_rank()); - vertex_t number_of_vertices{}; - edge_t number_of_edges{}; - std::tie(renumber_map_labels, partition, number_of_vertices, number_of_edges) = - ::cugraph::experimental::renumber_edgelist // multi_gpu=true - (handle, - major_vertices, // edgelist_major_vertices, INOUT of vertex_t* - minor_vertices, // edgelist_minor_vertices, INOUT of vertex_t* - local_number_edges, - false, // is_hypergraph_partitioned - true); // do_expensive_check - - cugraph::experimental::edgelist_t edgelist{ - d_edgelist_rows.data(), d_edgelist_cols.data(), d_edgelist_weights.data(), local_number_edges}; - - std::vector> edgelist_vect; - edgelist_vect.push_back(edgelist); - cugraph::experimental::graph_properties_t properties; - properties.is_symmetric = edgelist_from_mm.is_symmetric; - properties.is_multigraph = false; - - // Finally, create instance of graph_t using filtered & renumbered edgelist - return std::make_tuple( - std::make_unique< - cugraph::experimental::graph_t>( - handle, - edgelist_vect, - partition, - number_of_vertices, - total_number_edges, - properties, - false, // sorted_by_global_degree_within_vertex_partition - true), // do_expensive_check - std::move(renumber_map_labels)); -} - -// explicit instantiation -template std::tuple< - std::unique_ptr< - cugraph::experimental::graph_t>, // store_transposed=true - // multi_gpu=true - rmm::device_uvector> -create_graph_for_gpu(raft::handle_t& handle, const std::string& graph_file_path); - -} // namespace test -} // namespace cugraph diff --git a/cpp/tests/utilities/mg_test_utilities.hpp b/cpp/tests/utilities/mg_test_utilities.hpp deleted file mode 100644 index c23f6c43a6d..00000000000 --- a/cpp/tests/utilities/mg_test_utilities.hpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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. - */ -#pragma once - -#include - -#include - -#include - -namespace cugraph { -namespace test { - -// Given a raft handle and a path to a dataset (must be a .mtx file), returns a -// tuple containing: -// * graph_t instance for the partition accesible from the raft handle -// * 4-tuple containing renumber info resulting from renumbering the -// edgelist for the partition -template -std::tuple< - std::unique_ptr>, // multi_gpu=true - rmm::device_uvector> -create_graph_for_gpu(raft::handle_t& handle, const std::string& graph_file_path); - -/** - * @brief Base test fixture class, responsible for handling common operations - * needed by all MG tests. - * - * It's expected this class will be built out and refactored often as new MG C++ - * tests are added and new patterns evolve. - * - * Example: - * ``` - * class MyTestFixture : public cugraph::test::MG_TestFixture_t {}; - * ``` - **/ - -// FIXME: consider moving this to a separate file? (eg. mg_test_fixture.cpp)? - -class MG_TestFixture_t : public ::testing::Test { - public: - static void SetUpTestCase() - { - MPI_TRY(MPI_Init(NULL, NULL)); - - int rank, size; - MPI_TRY(MPI_Comm_rank(MPI_COMM_WORLD, &rank)); - MPI_TRY(MPI_Comm_size(MPI_COMM_WORLD, &size)); - - int nGpus; - CUDA_CHECK(cudaGetDeviceCount(&nGpus)); - - ASSERT( - nGpus >= size, "Number of GPUs are lesser than MPI ranks! ngpus=%d, nranks=%d", nGpus, size); - - CUDA_CHECK(cudaSetDevice(rank)); - } - - static void TearDownTestCase() { MPI_TRY(MPI_Finalize()); } -}; - -} // namespace test -} // namespace cugraph diff --git a/cpp/tests/utilities/test_utilities.cpp b/cpp/tests/utilities/test_utilities.cpp deleted file mode 100644 index abb416a632d..00000000000 --- a/cpp/tests/utilities/test_utilities.cpp +++ /dev/null @@ -1,442 +0,0 @@ -/* - * 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. - */ -#include - -#include -#include -#include - -#include - -extern "C" { -#include "mmio.h" -} - -#include - -#include -#include -#include -#include - -namespace cugraph { -namespace test { - -std::string getFileName(const std::string& s) -{ - char sep = '/'; -#ifdef _WIN32 - sep = '\\'; -#endif - size_t i = s.rfind(sep, s.length()); - if (i != std::string::npos) { return (s.substr(i + 1, s.length() - i)); } - return (""); -} - -/// Read matrix properties from Matrix Market file -/** Matrix Market file is assumed to be a sparse matrix in coordinate - * format. - * - * @param f File stream for Matrix Market file. - * @param tg Boolean indicating whether to convert matrix to general - * format (from symmetric, Hermitian, or skew symmetric format). - * @param t (Output) MM_typecode with matrix properties. - * @param m (Output) Number of matrix rows. - * @param n (Output) Number of matrix columns. - * @param nnz (Output) Number of non-zero matrix entries. - * @return Zero if properties were read successfully. Otherwise - * non-zero. - */ -template -int mm_properties(FILE* f, int tg, MM_typecode* t, IndexType_* m, IndexType_* n, IndexType_* nnz) -{ - // Read matrix properties from file - int mint, nint, nnzint; - if (fseek(f, 0, SEEK_SET)) { - fprintf(stderr, "Error: could not set position in file\n"); - return -1; - } - if (mm_read_banner(f, t)) { - fprintf(stderr, "Error: could not read Matrix Market file banner\n"); - return -1; - } - if (!mm_is_matrix(*t) || !mm_is_coordinate(*t)) { - fprintf(stderr, "Error: file does not contain matrix in coordinate format\n"); - return -1; - } - if (mm_read_mtx_crd_size(f, &mint, &nint, &nnzint)) { - fprintf(stderr, "Error: could not read matrix dimensions\n"); - return -1; - } - if (!mm_is_pattern(*t) && !mm_is_real(*t) && !mm_is_integer(*t) && !mm_is_complex(*t)) { - fprintf(stderr, "Error: matrix entries are not valid type\n"); - return -1; - } - *m = mint; - *n = nint; - *nnz = nnzint; - - // Find total number of non-zero entries - if (tg && !mm_is_general(*t)) { - // Non-diagonal entries should be counted twice - *nnz *= 2; - - // Diagonal entries should not be double-counted - int st; - for (int i = 0; i < nnzint; ++i) { - // Read matrix entry - // MTX only supports int for row and col idx - int row, col; - double rval, ival; - if (mm_is_pattern(*t)) - st = fscanf(f, "%d %d\n", &row, &col); - else if (mm_is_real(*t) || mm_is_integer(*t)) - st = fscanf(f, "%d %d %lg\n", &row, &col, &rval); - else // Complex matrix - st = fscanf(f, "%d %d %lg %lg\n", &row, &col, &rval, &ival); - if (ferror(f) || (st == EOF)) { - fprintf(stderr, "Error: error %d reading Matrix Market file (entry %d)\n", st, i + 1); - return -1; - } - - // Check if entry is diagonal - if (row == col) --(*nnz); - } - } - - return 0; -} - -/// Read Matrix Market file and convert to COO format matrix -/** Matrix Market file is assumed to be a sparse matrix in coordinate - * format. - * - * @param f File stream for Matrix Market file. - * @param tg Boolean indicating whether to convert matrix to general - * format (from symmetric, Hermitian, or skew symmetric format). - * @param nnz Number of non-zero matrix entries. - * @param cooRowInd (Output) Row indices for COO matrix. Should have - * at least nnz entries. - * @param cooColInd (Output) Column indices for COO matrix. Should - * have at least nnz entries. - * @param cooRVal (Output) Real component of COO matrix - * entries. Should have at least nnz entries. Ignored if null - * pointer. - * @param cooIVal (Output) Imaginary component of COO matrix - * entries. Should have at least nnz entries. Ignored if null - * pointer. - * @return Zero if matrix was read successfully. Otherwise non-zero. - */ -template -int mm_to_coo(FILE* f, - int tg, - IndexType_ nnz, - IndexType_* cooRowInd, - IndexType_* cooColInd, - ValueType_* cooRVal, - ValueType_* cooIVal) -{ - // Read matrix properties from file - MM_typecode t; - int m, n, nnzOld; - if (fseek(f, 0, SEEK_SET)) { - fprintf(stderr, "Error: could not set position in file\n"); - return -1; - } - if (mm_read_banner(f, &t)) { - fprintf(stderr, "Error: could not read Matrix Market file banner\n"); - return -1; - } - if (!mm_is_matrix(t) || !mm_is_coordinate(t)) { - fprintf(stderr, "Error: file does not contain matrix in coordinate format\n"); - return -1; - } - if (mm_read_mtx_crd_size(f, &m, &n, &nnzOld)) { - fprintf(stderr, "Error: could not read matrix dimensions\n"); - return -1; - } - if (!mm_is_pattern(t) && !mm_is_real(t) && !mm_is_integer(t) && !mm_is_complex(t)) { - fprintf(stderr, "Error: matrix entries are not valid type\n"); - return -1; - } - - // Add each matrix entry in file to COO format matrix - int i; // Entry index in Matrix Market file; can only be int in the MTX format - int j = 0; // Entry index in COO format matrix; can only be int in the MTX format - for (i = 0; i < nnzOld; ++i) { - // Read entry from file - int row, col; - double rval, ival; - int st; - if (mm_is_pattern(t)) { - st = fscanf(f, "%d %d\n", &row, &col); - rval = 1.0; - ival = 0.0; - } else if (mm_is_real(t) || mm_is_integer(t)) { - st = fscanf(f, "%d %d %lg\n", &row, &col, &rval); - ival = 0.0; - } else // Complex matrix - st = fscanf(f, "%d %d %lg %lg\n", &row, &col, &rval, &ival); - if (ferror(f) || (st == EOF)) { - fprintf(stderr, "Error: error %d reading Matrix Market file (entry %d)\n", st, i + 1); - return -1; - } - - // Switch to 0-based indexing - --row; - --col; - - // Record entry - cooRowInd[j] = row; - cooColInd[j] = col; - if (cooRVal != NULL) cooRVal[j] = rval; - if (cooIVal != NULL) cooIVal[j] = ival; - ++j; - - // Add symmetric complement of non-diagonal entries - if (tg && !mm_is_general(t) && (row != col)) { - // Modify entry value if matrix is skew symmetric or Hermitian - if (mm_is_skew(t)) { - rval = -rval; - ival = -ival; - } else if (mm_is_hermitian(t)) { - ival = -ival; - } - - // Record entry - cooRowInd[j] = col; - cooColInd[j] = row; - if (cooRVal != NULL) cooRVal[j] = rval; - if (cooIVal != NULL) cooIVal[j] = ival; - ++j; - } - } - return 0; -} - -int read_binary_vector(FILE* fpin, int n, std::vector& val) -{ - size_t is_read1; - - double* t_storage = new double[n]; - is_read1 = fread(t_storage, sizeof(double), n, fpin); - for (int i = 0; i < n; i++) { - if (t_storage[i] == DBL_MAX) - val[i] = FLT_MAX; - else if (t_storage[i] == -DBL_MAX) - val[i] = -FLT_MAX; - else - val[i] = static_cast(t_storage[i]); - } - delete[] t_storage; - - if (is_read1 != (size_t)n) { - printf("%s", "I/O fail\n"); - return 1; - } - return 0; -} - -int read_binary_vector(FILE* fpin, int n, std::vector& val) -{ - size_t is_read1; - - is_read1 = fread(&val[0], sizeof(double), n, fpin); - - if (is_read1 != (size_t)n) { - printf("%s", "I/O fail\n"); - return 1; - } - return 0; -} - -// FIXME: A similar function could be useful for CSC format -// There are functions above that operate coo -> csr and coo->csc -/** - * @tparam - */ -template -std::unique_ptr> generate_graph_csr_from_mm( - bool& directed, std::string mm_file) -{ - vertex_t number_of_vertices; - edge_t number_of_edges; - - FILE* fpin = fopen(mm_file.c_str(), "r"); - EXPECT_NE(fpin, nullptr); - - vertex_t number_of_columns = 0; - MM_typecode mm_typecode{0}; - EXPECT_EQ(mm_properties( - fpin, 1, &mm_typecode, &number_of_vertices, &number_of_columns, &number_of_edges), - 0); - EXPECT_TRUE(mm_is_matrix(mm_typecode)); - EXPECT_TRUE(mm_is_coordinate(mm_typecode)); - EXPECT_FALSE(mm_is_complex(mm_typecode)); - EXPECT_FALSE(mm_is_skew(mm_typecode)); - - directed = !mm_is_symmetric(mm_typecode); - - // Allocate memory on host - std::vector coo_row_ind(number_of_edges); - std::vector coo_col_ind(number_of_edges); - std::vector coo_val(number_of_edges); - - // Read - EXPECT_EQ((mm_to_coo( - fpin, 1, number_of_edges, &coo_row_ind[0], &coo_col_ind[0], &coo_val[0], NULL)), - 0); - EXPECT_EQ(fclose(fpin), 0); - - cugraph::GraphCOOView cooview( - &coo_row_ind[0], &coo_col_ind[0], &coo_val[0], number_of_vertices, number_of_edges); - - return cugraph::coo_to_csr(cooview); -} - -template -edgelist_from_market_matrix_file_t read_edgelist_from_matrix_market_file( - std::string const& graph_file_full_path) -{ - edgelist_from_market_matrix_file_t ret{}; - - MM_typecode mc{}; - vertex_t m{}; - edge_t nnz{}; - - FILE* file = fopen(graph_file_full_path.c_str(), "r"); - CUGRAPH_EXPECTS(file != nullptr, "fopen failure."); - - edge_t tmp_m{}; - edge_t tmp_k{}; - auto mm_ret = cugraph::test::mm_properties(file, 1, &mc, &tmp_m, &tmp_k, &nnz); - CUGRAPH_EXPECTS(mm_ret == 0, "could not read Matrix Market file properties."); - m = static_cast(tmp_m); - CUGRAPH_EXPECTS(mm_is_matrix(mc) && mm_is_coordinate(mc) && !mm_is_complex(mc) && !mm_is_skew(mc), - "invalid Matrix Market file properties."); - - ret.h_rows.assign(nnz, vertex_t{0}); - ret.h_cols.assign(nnz, vertex_t{0}); - ret.h_weights.assign(nnz, weight_t{0.0}); - ret.number_of_vertices = m; - ret.is_symmetric = mm_is_symmetric(mc); - - mm_ret = cugraph::test::mm_to_coo( - file, 1, nnz, ret.h_rows.data(), ret.h_cols.data(), ret.h_weights.data(), nullptr); - CUGRAPH_EXPECTS(mm_ret == 0, "could not read matrix data"); - - auto file_ret = fclose(file); - CUGRAPH_EXPECTS(file_ret == 0, "fclose failure."); - - return std::move(ret); -} - -template -cugraph::experimental::graph_t -read_graph_from_matrix_market_file(raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted) -{ - auto mm_graph = - read_edgelist_from_matrix_market_file(graph_file_full_path); - edge_t number_of_edges = static_cast(mm_graph.h_rows.size()); - - rmm::device_uvector d_edgelist_rows(number_of_edges, handle.get_stream()); - rmm::device_uvector d_edgelist_cols(number_of_edges, handle.get_stream()); - rmm::device_uvector d_edgelist_weights(test_weighted ? number_of_edges : 0, - handle.get_stream()); - - raft::update_device( - d_edgelist_rows.data(), mm_graph.h_rows.data(), number_of_edges, handle.get_stream()); - raft::update_device( - d_edgelist_cols.data(), mm_graph.h_cols.data(), number_of_edges, handle.get_stream()); - if (test_weighted) { - raft::update_device( - d_edgelist_weights.data(), mm_graph.h_weights.data(), number_of_edges, handle.get_stream()); - } - - cugraph::experimental::edgelist_t edgelist{ - d_edgelist_rows.data(), - d_edgelist_cols.data(), - test_weighted ? d_edgelist_weights.data() : nullptr, - number_of_edges}; - - return cugraph::experimental::graph_t( - handle, - edgelist, - mm_graph.number_of_vertices, - cugraph::experimental::graph_properties_t{mm_graph.is_symmetric, false}, - false, - true); -} - -// explicit instantiations - -template int mm_to_coo( - FILE* f, int tg, int nnz, int* cooRowInd, int* cooColInd, int* cooRVal, int* cooIVal); - -template int mm_to_coo( - FILE* f, int tg, int nnz, int* cooRowInd, int* cooColInd, double* cooRVal, double* cooIVal); - -template int mm_to_coo( - FILE* f, int tg, int nnz, int* cooRowInd, int* cooColInd, float* cooRVal, float* cooIVal); - -template std::unique_ptr> -generate_graph_csr_from_mm(bool& directed, std::string mm_file); - -template std::unique_ptr> generate_graph_csr_from_mm( - bool& directed, std::string mm_file); - -template std::unique_ptr> generate_graph_csr_from_mm( - bool& directed, std::string mm_file); - -template std::unique_ptr> generate_graph_csr_from_mm( - bool& directed, std::string mm_file); - -template cugraph::experimental::graph_t -read_graph_from_matrix_market_file(raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted); - -template cugraph::experimental::graph_t -read_graph_from_matrix_market_file(raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted); - -template cugraph::experimental::graph_t -read_graph_from_matrix_market_file(raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted); - -template cugraph::experimental::graph_t -read_graph_from_matrix_market_file( - raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted); - -template cugraph::experimental::graph_t -read_graph_from_matrix_market_file(raft::handle_t const& handle, - std::string const& graph_file_full_path, - bool test_weighted); - -template cugraph::experimental::graph_t -read_graph_from_matrix_market_file( - raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted); - -template cugraph::experimental::graph_t -read_graph_from_matrix_market_file( - raft::handle_t const& handle, std::string const& graph_file_full_path, bool test_weighted); - -} // namespace test -} // namespace cugraph diff --git a/cpp/tests/utilities/test_utilities.cu b/cpp/tests/utilities/test_utilities.cu new file mode 100644 index 00000000000..0a7b58b32cd --- /dev/null +++ b/cpp/tests/utilities/test_utilities.cu @@ -0,0 +1,788 @@ +/* + * 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. + */ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +extern "C" { +#include "mmio.h" +} + +#include +#include +#include +#include + +namespace cugraph { +namespace test { + +std::string getFileName(const std::string& s) +{ + char sep = '/'; +#ifdef _WIN32 + sep = '\\'; +#endif + size_t i = s.rfind(sep, s.length()); + if (i != std::string::npos) { return (s.substr(i + 1, s.length() - i)); } + return (""); +} + +/// Read matrix properties from Matrix Market file +/** Matrix Market file is assumed to be a sparse matrix in coordinate + * format. + * + * @param f File stream for Matrix Market file. + * @param tg Boolean indicating whether to convert matrix to general + * format (from symmetric, Hermitian, or skew symmetric format). + * @param t (Output) MM_typecode with matrix properties. + * @param m (Output) Number of matrix rows. + * @param n (Output) Number of matrix columns. + * @param nnz (Output) Number of non-zero matrix entries. + * @return Zero if properties were read successfully. Otherwise + * non-zero. + */ +template +int mm_properties(FILE* f, int tg, MM_typecode* t, IndexType_* m, IndexType_* n, IndexType_* nnz) +{ + // Read matrix properties from file + int mint, nint, nnzint; + if (fseek(f, 0, SEEK_SET)) { + fprintf(stderr, "Error: could not set position in file\n"); + return -1; + } + if (mm_read_banner(f, t)) { + fprintf(stderr, "Error: could not read Matrix Market file banner\n"); + return -1; + } + if (!mm_is_matrix(*t) || !mm_is_coordinate(*t)) { + fprintf(stderr, "Error: file does not contain matrix in coordinate format\n"); + return -1; + } + if (mm_read_mtx_crd_size(f, &mint, &nint, &nnzint)) { + fprintf(stderr, "Error: could not read matrix dimensions\n"); + return -1; + } + if (!mm_is_pattern(*t) && !mm_is_real(*t) && !mm_is_integer(*t) && !mm_is_complex(*t)) { + fprintf(stderr, "Error: matrix entries are not valid type\n"); + return -1; + } + *m = mint; + *n = nint; + *nnz = nnzint; + + // Find total number of non-zero entries + if (tg && !mm_is_general(*t)) { + // Non-diagonal entries should be counted twice + *nnz *= 2; + + // Diagonal entries should not be double-counted + int st; + for (int i = 0; i < nnzint; ++i) { + // Read matrix entry + // MTX only supports int for row and col idx + int row, col; + double rval, ival; + if (mm_is_pattern(*t)) + st = fscanf(f, "%d %d\n", &row, &col); + else if (mm_is_real(*t) || mm_is_integer(*t)) + st = fscanf(f, "%d %d %lg\n", &row, &col, &rval); + else // Complex matrix + st = fscanf(f, "%d %d %lg %lg\n", &row, &col, &rval, &ival); + if (ferror(f) || (st == EOF)) { + fprintf(stderr, "Error: error %d reading Matrix Market file (entry %d)\n", st, i + 1); + return -1; + } + + // Check if entry is diagonal + if (row == col) --(*nnz); + } + } + + return 0; +} + +/// Read Matrix Market file and convert to COO format matrix +/** Matrix Market file is assumed to be a sparse matrix in coordinate + * format. + * + * @param f File stream for Matrix Market file. + * @param tg Boolean indicating whether to convert matrix to general + * format (from symmetric, Hermitian, or skew symmetric format). + * @param nnz Number of non-zero matrix entries. + * @param cooRowInd (Output) Row indices for COO matrix. Should have + * at least nnz entries. + * @param cooColInd (Output) Column indices for COO matrix. Should + * have at least nnz entries. + * @param cooRVal (Output) Real component of COO matrix + * entries. Should have at least nnz entries. Ignored if null + * pointer. + * @param cooIVal (Output) Imaginary component of COO matrix + * entries. Should have at least nnz entries. Ignored if null + * pointer. + * @return Zero if matrix was read successfully. Otherwise non-zero. + */ +template +int mm_to_coo(FILE* f, + int tg, + IndexType_ nnz, + IndexType_* cooRowInd, + IndexType_* cooColInd, + ValueType_* cooRVal, + ValueType_* cooIVal) +{ + // Read matrix properties from file + MM_typecode t; + int m, n, nnzOld; + if (fseek(f, 0, SEEK_SET)) { + fprintf(stderr, "Error: could not set position in file\n"); + return -1; + } + if (mm_read_banner(f, &t)) { + fprintf(stderr, "Error: could not read Matrix Market file banner\n"); + return -1; + } + if (!mm_is_matrix(t) || !mm_is_coordinate(t)) { + fprintf(stderr, "Error: file does not contain matrix in coordinate format\n"); + return -1; + } + if (mm_read_mtx_crd_size(f, &m, &n, &nnzOld)) { + fprintf(stderr, "Error: could not read matrix dimensions\n"); + return -1; + } + if (!mm_is_pattern(t) && !mm_is_real(t) && !mm_is_integer(t) && !mm_is_complex(t)) { + fprintf(stderr, "Error: matrix entries are not valid type\n"); + return -1; + } + + // Add each matrix entry in file to COO format matrix + int i; // Entry index in Matrix Market file; can only be int in the MTX format + int j = 0; // Entry index in COO format matrix; can only be int in the MTX format + for (i = 0; i < nnzOld; ++i) { + // Read entry from file + int row, col; + double rval, ival; + int st; + if (mm_is_pattern(t)) { + st = fscanf(f, "%d %d\n", &row, &col); + rval = 1.0; + ival = 0.0; + } else if (mm_is_real(t) || mm_is_integer(t)) { + st = fscanf(f, "%d %d %lg\n", &row, &col, &rval); + ival = 0.0; + } else // Complex matrix + st = fscanf(f, "%d %d %lg %lg\n", &row, &col, &rval, &ival); + if (ferror(f) || (st == EOF)) { + fprintf(stderr, "Error: error %d reading Matrix Market file (entry %d)\n", st, i + 1); + return -1; + } + + // Switch to 0-based indexing + --row; + --col; + + // Record entry + cooRowInd[j] = row; + cooColInd[j] = col; + if (cooRVal != NULL) cooRVal[j] = rval; + if (cooIVal != NULL) cooIVal[j] = ival; + ++j; + + // Add symmetric complement of non-diagonal entries + if (tg && !mm_is_general(t) && (row != col)) { + // Modify entry value if matrix is skew symmetric or Hermitian + if (mm_is_skew(t)) { + rval = -rval; + ival = -ival; + } else if (mm_is_hermitian(t)) { + ival = -ival; + } + + // Record entry + cooRowInd[j] = col; + cooColInd[j] = row; + if (cooRVal != NULL) cooRVal[j] = rval; + if (cooIVal != NULL) cooIVal[j] = ival; + ++j; + } + } + return 0; +} + +// FIXME: A similar function could be useful for CSC format +// There are functions above that operate coo -> csr and coo->csc +/** + * @tparam + */ +template +std::unique_ptr> generate_graph_csr_from_mm( + bool& directed, std::string mm_file) +{ + vertex_t number_of_vertices; + edge_t number_of_edges; + + FILE* fpin = fopen(mm_file.c_str(), "r"); + CUGRAPH_EXPECTS(fpin != nullptr, "fopen (%s) failure.", mm_file.c_str()); + + vertex_t number_of_columns = 0; + MM_typecode mm_typecode{0}; + CUGRAPH_EXPECTS( + mm_properties( + fpin, 1, &mm_typecode, &number_of_vertices, &number_of_columns, &number_of_edges) == 0, + "mm_properties query failure."); + CUGRAPH_EXPECTS(mm_is_matrix(mm_typecode), "Invalid input file."); + CUGRAPH_EXPECTS(mm_is_coordinate(mm_typecode), "Invalid input file."); + CUGRAPH_EXPECTS(!mm_is_complex(mm_typecode), "Invalid input file."); + CUGRAPH_EXPECTS(!mm_is_skew(mm_typecode), "Invalid input file."); + + directed = !mm_is_symmetric(mm_typecode); + + // Allocate memory on host + std::vector coo_row_ind(number_of_edges); + std::vector coo_col_ind(number_of_edges); + std::vector coo_val(number_of_edges); + + // Read + CUGRAPH_EXPECTS( + (mm_to_coo( + fpin, 1, number_of_edges, &coo_row_ind[0], &coo_col_ind[0], &coo_val[0], NULL)) == 0, + "file read failure."); + CUGRAPH_EXPECTS(fclose(fpin) == 0, "fclose failure."); + + cugraph::GraphCOOView cooview( + &coo_row_ind[0], &coo_col_ind[0], &coo_val[0], number_of_vertices, number_of_edges); + + return cugraph::coo_to_csr(cooview); +} + +template +std::tuple, + rmm::device_uvector, + rmm::device_uvector, + vertex_t, + bool> +read_edgelist_from_matrix_market_file(raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted) +{ + MM_typecode mc{}; + vertex_t m{}; + size_t nnz{}; + + FILE* file = fopen(graph_file_full_path.c_str(), "r"); + CUGRAPH_EXPECTS(file != nullptr, "fopen failure."); + + size_t tmp_m{}; + size_t tmp_k{}; + auto mm_ret = cugraph::test::mm_properties(file, 1, &mc, &tmp_m, &tmp_k, &nnz); + CUGRAPH_EXPECTS(mm_ret == 0, "could not read Matrix Market file properties."); + m = static_cast(tmp_m); + CUGRAPH_EXPECTS(mm_is_matrix(mc) && mm_is_coordinate(mc) && !mm_is_complex(mc) && !mm_is_skew(mc), + "invalid Matrix Market file properties."); + + vertex_t number_of_vertices = m; + bool is_symmetric = mm_is_symmetric(mc); + + std::vector h_rows(nnz); + std::vector h_cols(nnz); + std::vector h_weights(nnz); + + mm_ret = cugraph::test::mm_to_coo( + file, 1, nnz, h_rows.data(), h_cols.data(), h_weights.data(), static_cast(nullptr)); + CUGRAPH_EXPECTS(mm_ret == 0, "could not read matrix data"); + + auto file_ret = fclose(file); + CUGRAPH_EXPECTS(file_ret == 0, "fclose failure."); + + rmm::device_uvector d_edgelist_rows(h_rows.size(), handle.get_stream()); + rmm::device_uvector d_edgelist_cols(h_cols.size(), handle.get_stream()); + rmm::device_uvector d_edgelist_weights(test_weighted ? h_weights.size() : size_t{0}, + handle.get_stream()); + + raft::update_device(d_edgelist_rows.data(), h_rows.data(), h_rows.size(), handle.get_stream()); + raft::update_device(d_edgelist_cols.data(), h_cols.data(), h_cols.size(), handle.get_stream()); + if (test_weighted) { + raft::update_device( + d_edgelist_weights.data(), h_weights.data(), h_weights.size(), handle.get_stream()); + } + + return std::make_tuple(std::move(d_edgelist_rows), + std::move(d_edgelist_cols), + std::move(d_edgelist_weights), + number_of_vertices, + is_symmetric); +} + +namespace detail { + +template +std::enable_if_t< + multi_gpu, + std::tuple< + cugraph::experimental::graph_t, + rmm::device_uvector>> +read_graph_from_matrix_market_file(raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber) +{ + CUGRAPH_EXPECTS(renumber, "renumber should be true if multi_gpu is true."); + + // 1. read from the matrix market file + + rmm::device_uvector d_edgelist_rows(0, handle.get_stream()); + rmm::device_uvector d_edgelist_cols(0, handle.get_stream()); + rmm::device_uvector d_edgelist_weights(0, handle.get_stream()); + vertex_t number_of_vertices{}; + bool is_symmetric{}; + std::tie(d_edgelist_rows, d_edgelist_cols, d_edgelist_weights, number_of_vertices, is_symmetric) = + read_edgelist_from_matrix_market_file( + handle, graph_file_full_path, test_weighted); + + rmm::device_uvector d_vertices(number_of_vertices, handle.get_stream()); + thrust::sequence(rmm::exec_policy(handle.get_stream())->on(handle.get_stream()), + d_vertices.begin(), + d_vertices.end(), + vertex_t{0}); + + // 2. filter non-local vertices & edges + + auto& comm = handle.get_comms(); + auto const comm_size = comm.get_size(); + auto const comm_rank = comm.get_rank(); + auto& row_comm = handle.get_subcomm(cugraph::partition_2d::key_naming_t().row_name()); + auto const row_comm_size = row_comm.get_size(); + auto& col_comm = handle.get_subcomm(cugraph::partition_2d::key_naming_t().col_name()); + auto const col_comm_size = col_comm.get_size(); + + auto vertex_key_func = + cugraph::experimental::detail::compute_gpu_id_from_vertex_t{comm_size}; + d_vertices.resize( + thrust::distance( + d_vertices.begin(), + thrust::remove_if(rmm::exec_policy(handle.get_stream())->on(handle.get_stream()), + d_vertices.begin(), + d_vertices.end(), + [comm_rank, key_func = vertex_key_func] __device__(auto val) { + return key_func(val) != comm_rank; + })), + handle.get_stream()); + d_vertices.shrink_to_fit(handle.get_stream()); + + auto edge_key_func = cugraph::experimental::detail::compute_gpu_id_from_edge_t{ + false, comm_size, row_comm_size, col_comm_size}; + size_t number_of_local_edges{}; + if (test_weighted) { + auto edge_first = thrust::make_zip_iterator(thrust::make_tuple( + d_edgelist_rows.begin(), d_edgelist_cols.begin(), d_edgelist_weights.begin())); + number_of_local_edges = thrust::distance( + edge_first, + thrust::remove_if(rmm::exec_policy(handle.get_stream())->on(handle.get_stream()), + edge_first, + edge_first + d_edgelist_rows.size(), + [comm_rank, key_func = edge_key_func] __device__(auto e) { + auto major = store_transposed ? thrust::get<1>(e) : thrust::get<0>(e); + auto minor = store_transposed ? thrust::get<0>(e) : thrust::get<1>(e); + return key_func(major, minor) != comm_rank; + })); + } else { + auto edge_first = thrust::make_zip_iterator( + thrust::make_tuple(d_edgelist_rows.begin(), d_edgelist_cols.begin())); + number_of_local_edges = thrust::distance( + edge_first, + thrust::remove_if(rmm::exec_policy(handle.get_stream())->on(handle.get_stream()), + edge_first, + edge_first + d_edgelist_rows.size(), + [comm_rank, key_func = edge_key_func] __device__(auto e) { + auto major = store_transposed ? thrust::get<1>(e) : thrust::get<0>(e); + auto minor = store_transposed ? thrust::get<0>(e) : thrust::get<1>(e); + return key_func(major, minor) != comm_rank; + })); + } + + d_edgelist_rows.resize(number_of_local_edges, handle.get_stream()); + d_edgelist_rows.shrink_to_fit(handle.get_stream()); + d_edgelist_cols.resize(number_of_local_edges, handle.get_stream()); + d_edgelist_cols.shrink_to_fit(handle.get_stream()); + if (test_weighted) { + d_edgelist_weights.resize(number_of_local_edges, handle.get_stream()); + d_edgelist_weights.shrink_to_fit(handle.get_stream()); + } + + // 3. renumber + + rmm::device_uvector renumber_map_labels(0, handle.get_stream()); + cugraph::experimental::partition_t partition{}; + vertex_t aggregate_number_of_vertices{}; + edge_t number_of_edges{}; + // FIXME: set do_expensive_check to false once validated + std::tie(renumber_map_labels, partition, aggregate_number_of_vertices, number_of_edges) = + cugraph::experimental::renumber_edgelist( + handle, + d_vertices.data(), + static_cast(d_vertices.size()), + store_transposed ? d_edgelist_cols.data() : d_edgelist_rows.data(), + store_transposed ? d_edgelist_rows.data() : d_edgelist_cols.data(), + d_edgelist_rows.size(), + false, + true); + assert(aggregate_number_of_vertices == number_of_vertices); + + // 4. create a graph + + return std::make_tuple( + cugraph::experimental::graph_t( + handle, + std::vector>{ + cugraph::experimental::edgelist_t{ + d_edgelist_rows.data(), + d_edgelist_cols.data(), + test_weighted ? d_edgelist_weights.data() : nullptr, + static_cast(d_edgelist_rows.size())}}, + partition, + number_of_vertices, + number_of_edges, + cugraph::experimental::graph_properties_t{is_symmetric, false}, + true, + true), + std::move(renumber_map_labels)); +} + +template +std::enable_if_t< + !multi_gpu, + std::tuple< + cugraph::experimental::graph_t, + rmm::device_uvector>> +read_graph_from_matrix_market_file(raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber) +{ + rmm::device_uvector d_edgelist_rows(0, handle.get_stream()); + rmm::device_uvector d_edgelist_cols(0, handle.get_stream()); + rmm::device_uvector d_edgelist_weights(0, handle.get_stream()); + vertex_t number_of_vertices{}; + bool is_symmetric{}; + std::tie(d_edgelist_rows, d_edgelist_cols, d_edgelist_weights, number_of_vertices, is_symmetric) = + read_edgelist_from_matrix_market_file( + handle, graph_file_full_path, test_weighted); + + rmm::device_uvector d_vertices(number_of_vertices, handle.get_stream()); + thrust::sequence(rmm::exec_policy(handle.get_stream())->on(handle.get_stream()), + d_vertices.begin(), + d_vertices.end(), + vertex_t{0}); + + // FIXME: set do_expensive_check to false once validated + auto renumber_map_labels = + renumber ? cugraph::experimental::renumber_edgelist( + handle, + d_vertices.data(), + static_cast(d_vertices.size()), + store_transposed ? d_edgelist_cols.data() : d_edgelist_rows.data(), + store_transposed ? d_edgelist_rows.data() : d_edgelist_cols.data(), + static_cast(d_edgelist_rows.size()), + true) + : rmm::device_uvector(0, handle.get_stream()); + + // FIXME: set do_expensive_check to false once validated + return std::make_tuple( + cugraph::experimental::graph_t( + handle, + cugraph::experimental::edgelist_t{ + d_edgelist_rows.data(), + d_edgelist_cols.data(), + test_weighted ? d_edgelist_weights.data() : nullptr, + static_cast(d_edgelist_rows.size())}, + number_of_vertices, + cugraph::experimental::graph_properties_t{is_symmetric, false}, + renumber ? true : false, + true), + std::move(renumber_map_labels)); +} + +} // namespace detail + +template +std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file(raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber) +{ + return detail:: + read_graph_from_matrix_market_file( + handle, graph_file_full_path, test_weighted, renumber); +} +// explicit instantiations + +template int32_t mm_to_coo(FILE* f, + int32_t tg, + int32_t nnz, + int32_t* cooRowInd, + int32_t* cooColInd, + int32_t* cooRVal, + int32_t* cooIVal); + +template int32_t mm_to_coo(FILE* f, + int32_t tg, + int32_t nnz, + int32_t* cooRowInd, + int32_t* cooColInd, + double* cooRVal, + double* cooIVal); + +template int32_t mm_to_coo(FILE* f, + int32_t tg, + int32_t nnz, + int32_t* cooRowInd, + int32_t* cooColInd, + float* cooRVal, + float* cooIVal); + +template std::unique_ptr> generate_graph_csr_from_mm( + bool& directed, std::string mm_file); + +template std::unique_ptr> generate_graph_csr_from_mm( + bool& directed, std::string mm_file); + +template std::unique_ptr> generate_graph_csr_from_mm( + bool& directed, std::string mm_file); + +template std::unique_ptr> generate_graph_csr_from_mm( + bool& directed, std::string mm_file); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +template std::tuple, + rmm::device_uvector> +read_graph_from_matrix_market_file( + raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted, + bool renumber); + +} // namespace test +} // namespace cugraph diff --git a/cpp/tests/utilities/test_utilities.hpp b/cpp/tests/utilities/test_utilities.hpp index 406f09048e0..4b5517271f5 100644 --- a/cpp/tests/utilities/test_utilities.hpp +++ b/cpp/tests/utilities/test_utilities.hpp @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -77,10 +79,6 @@ int mm_to_coo(FILE* f, ValueType_* cooRVal, ValueType_* cooIVal); -int read_binary_vector(FILE* fpin, int n, std::vector& val); - -int read_binary_vector(FILE* fpin, int n, std::vector& val); - // FIXME: A similar function could be useful for CSC format // There are functions above that operate coo -> csr and coo->csc /** @@ -108,24 +106,29 @@ static const std::string& get_rapids_dataset_root_dir() return rdrd; } +// returns a tuple of (rows, columns, weights, number_of_vertices, is_symmetric) template -struct edgelist_from_market_matrix_file_t { - std::vector h_rows{}; - std::vector h_cols{}; - std::vector h_weights{}; - vertex_t number_of_vertices{}; - bool is_symmetric{}; -}; - -template -edgelist_from_market_matrix_file_t read_edgelist_from_matrix_market_file( - std::string const& graph_file_full_path); - -template -cugraph::experimental::graph_t +std::tuple, + rmm::device_uvector, + rmm::device_uvector, + vertex_t, + bool> +read_edgelist_from_matrix_market_file(raft::handle_t const& handle, + std::string const& graph_file_full_path, + bool test_weighted); + +// renumber must be true if multi_gpu is true +template +std::tuple, + rmm::device_uvector> read_graph_from_matrix_market_file(raft::handle_t const& handle, std::string const& graph_file_full_path, - bool test_weighted); + bool test_weighted, + bool renumber); } // namespace test } // namespace cugraph