Skip to content

Commit

Permalink
Fix compilation error
Browse files Browse the repository at this point in the history
  • Loading branch information
Naim committed Feb 2, 2024
1 parent 4895f74 commit 85d9ebc
Show file tree
Hide file tree
Showing 7 changed files with 302 additions and 14 deletions.
6 changes: 6 additions & 0 deletions cpp/examples/graph2.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
3 4 34
3 5 35
4 3 43
4 5 45
5 3 53
5 4 54
7 changes: 3 additions & 4 deletions cpp/examples/graph_partitioning/graph_partition_examples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@

#include <thrust/for_each.h>

#include "iostream"
#include "string"
using namespace std;
#include <iostream>
#include <string>

void initialize_mpi_and_set_device(int argc, char** argv)
{
Expand Down Expand Up @@ -59,7 +58,7 @@ std::unique_ptr<raft::handle_t> initialize_mg_handle(std::string const& allocati
<< std::endl;
std::for_each(possible_allocation_modes.cbegin(),
possible_allocation_modes.cend(),
[](string mode) { std::cout << mode << std::endl; });
[](std::string mode) { std::cout << mode << std::endl; });
}
RAFT_MPI_TRY(MPI_Finalize());

Expand Down
266 changes: 266 additions & 0 deletions cpp/examples/graph_partitioning/graph_partition_examples.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,266 @@
/*
* Copyright (c) 2024, 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 <../tests/utilities/base_fixture.hpp>
#include <../tests/utilities/test_utilities.hpp>

// #include <prims/update_edge_src_dst_property.cuh>
// #include <cugraph/edge_property.hpp>
// #include <cugraph/edge_src_dst_property.hpp>

#include <cugraph/algorithms.hpp>

#include <raft/comms/mpi_comms.hpp>
#include <raft/core/comms.hpp>
#include <raft/core/handle.hpp>
#include <raft/random/rng_state.hpp>

#include <thrust/for_each.h>

#include <iostream>
#include <string>
#include <system_error>
using namespace std;

void initialize_mpi_and_set_device(int argc, char** argv)
{
RAFT_MPI_TRY(MPI_Init(&argc, &argv));

int comm_rank{};
RAFT_MPI_TRY(MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank));

int comm_size{};
RAFT_MPI_TRY(MPI_Comm_size(MPI_COMM_WORLD, &comm_size));

int num_gpus_per_node{};
RAFT_CUDA_TRY(cudaGetDeviceCount(&num_gpus_per_node));
RAFT_CUDA_TRY(cudaSetDevice(comm_rank % num_gpus_per_node));
}

std::unique_ptr<raft::handle_t> initialize_mg_handle(std::string const& allocation_mode = "cuda")
{
int comm_rank{};
RAFT_MPI_TRY(MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank));

std::set<std::string> possible_allocation_modes = {"cuda", "pool", "binning", "managed"};

if (possible_allocation_modes.find(allocation_mode) == possible_allocation_modes.end()) {
if (!comm_rank) {
std::cout << "'" << allocation_mode
<< "' is not a valid allocation mode. It must be one of the followings -"
<< std::endl;
std::for_each(possible_allocation_modes.cbegin(),
possible_allocation_modes.cend(),
[](std::string mode) { std::cout << mode << std::endl; });
}
RAFT_MPI_TRY(MPI_Finalize());

exit(0);
}

if (!comm_rank) {
std::cout << "Using '" << allocation_mode
<< "' allocation mode to create device memory resources." << std::endl;
}
std::shared_ptr<rmm::mr::device_memory_resource> resource =
cugraph::test::create_memory_resource(allocation_mode);
rmm::mr::set_current_device_resource(resource.get());

std::unique_ptr<raft::handle_t> handle =
std::make_unique<raft::handle_t>(rmm::cuda_stream_per_thread, resource);

raft::comms::initialize_mpi_comms(handle.get(), MPI_COMM_WORLD);
auto& comm = handle->get_comms();
auto const comm_size = comm.get_size();

auto gpu_row_comm_size = static_cast<int>(sqrt(static_cast<double>(comm_size)));
while (comm_size % gpu_row_comm_size != 0) {
--gpu_row_comm_size;
}

cugraph::partition_manager::init_subcomm(*handle, gpu_row_comm_size);

return std::move(handle);
}

/**
* @brief This function reads graph from an input csv file and
* display vertex and edge partitions.
*/

template <typename vertex_t, typename edge_t, typename weight_t, bool multi_gpu>
void look_into_vertex_and_edge_partitions(raft::handle_t const& handle,
std::string const& csv_graph_file_path)
{
auto const comm_rank = handle.get_comms().get_rank();
auto const comm_size = handle.get_comms().get_size();

std::cout << "Rank_" << comm_rank << ", reading graph from " << csv_graph_file_path << std::endl;

bool renumber = true; // must be true for distributed graph.

// Read a graph (along with edge properties e.g. edge weights, if provided) from
// the input csv file

auto [graph, edge_weights, renumber_map] =
cugraph::test::read_graph_from_csv_file<vertex_t, edge_t, weight_t, false, multi_gpu>(
handle, csv_graph_file_path, true, renumber);

// Meta of the non-owning view of the graph object store vertex/edge partitioning map
auto graph_view = graph.view();

// Non-owning of the edge edge_weights object
auto edge_weight_view = edge_weights ? std::make_optional((*edge_weights).view()) : std::nullopt;

// Total number of vertices
vertex_t global_number_of_vertices = graph_view.number_of_vertices();

//
// Look into vertex partitions
//

// Number of vertices mapped to this process, ie the size of
// the vertex partition assigned to this process

vertex_t size_of_the_vertex_partition_assigned_to_this_process =
graph_view.local_vertex_partition_range_size();

// NOTE: The `renumber_map` contains the vertices assigned to this process.

// Print verties mapped to this process
RAFT_CUDA_TRY(cudaDeviceSynchronize());
if (renumber_map) {
auto vertex_partition_title = std::string("vertices@rank_").append(std::to_string(comm_rank));
raft::print_device_vector(
vertex_partition_title.c_str(), (*renumber_map).data(), (*renumber_map).size(), std::cout);
}

std::vector<vertex_t> h_vertices_in_this_proces((*renumber_map).size());

raft::update_host(h_vertices_in_this_proces.data(),
(*renumber_map).data(),
(*renumber_map).size(),
handle.get_stream());
handle.sync_stream();

assert(size_of_the_vertex_partition_assigned_to_this_process == (*renumber_map).size());

// The position of a vertex in the `renumber_map` is indicative of its new (aka renumberd)
// vertex id. The new (aka renumbered) id of the first vertex, ie the vertex at position 0
// of `renumber_map`, assigned to this process

vertex_t renumber_vertex_id_of_local_first = graph_view.local_vertex_partition_range_first();

// The new (aka renumbered) id of the last vertex, ie the vertex at position
// `size_of_the_vertex_partition_assigned_to_this_process` - 1 of `renumber_map`,
// assigned to this process

vertex_t renumber_vertex_id_of_local_last = graph_view.local_vertex_partition_range_last();

// Print original vertex ids, new (aka renumbered) vertex ids and the ranks of the owner processes

if (renumber_map) {
thrust::for_each(
thrust::host,
thrust::make_zip_iterator(
thrust::make_tuple(h_vertices_in_this_proces.begin(),
thrust::make_counting_iterator(renumber_vertex_id_of_local_first))),
thrust::make_zip_iterator(
thrust::make_tuple(h_vertices_in_this_proces.end(),
thrust::make_counting_iterator(renumber_vertex_id_of_local_last))),
[comm_rank](auto old_and_new_id_pair) {
auto old_id = thrust::get<0>(old_and_new_id_pair);
auto new_id = thrust::get<1>(old_and_new_id_pair);
printf("owner rank = %d, original vertex id %d -----> new (renumbered) vertex id %d\n",
comm_rank,
static_cast<int>(old_id),
static_cast<int>(new_id));
});
}

//
// Look into edge partitions and their associated edge properties (if any)
//

for (size_t ep_idx = 0; ep_idx < graph_view.number_of_local_edge_partitions(); ++ep_idx) {
// Toplogy
auto edge_partition = graph_view.local_edge_partition_view(ep_idx);

auto number_of_edges = edge_partition.number_of_edges();
auto offsets = edge_partition.offsets();
auto indices = edge_partition.indices();

auto offsets_title = std::string("offsets_")
.append(std::to_string(comm_rank))
.append("_")
.append(std::to_string(ep_idx));
RAFT_CUDA_TRY(cudaDeviceSynchronize());
raft::print_device_vector(offsets_title.c_str(), offsets.begin(), offsets.size(), std::cout);

auto indices_title = std::string("indices_")
.append(std::to_string(comm_rank))
.append("_")
.append(std::to_string(ep_idx));
RAFT_CUDA_TRY(cudaDeviceSynchronize());
raft::print_device_vector(indices_title.c_str(), indices.begin(), indices.size(), std::cout);

// Edge property values
if (edge_weight_view) {
auto value_firsts = edge_weight_view->value_firsts();
auto edge_counts = edge_weight_view->edge_counts();

assert(number_of_edges == edge_counts[ep_idx]);

RAFT_CUDA_TRY(cudaDeviceSynchronize());
auto weights_title = std::string("weights_")
.append(std::to_string(comm_rank))
.append("_")
.append(std::to_string(ep_idx));
raft::print_device_vector(
weights_title.c_str(), value_firsts[ep_idx], edge_counts[ep_idx], std::cout);
}
}

// using graph_view_t = cugraph::graph_view_t<vertex_t, edge_t, false, multi_gpu>;

// cugraph::edge_src_property_t<graph_view_t, weight_t> src_vertex_props(handle, graph_view);
}

int main(int argc, char** argv)
{
if (argc < 2) {
std::cout << "Usage: ./sg_examples path_to_your_csv_graph_file [memory allocation mode]"
<< std::endl;
exit(0);
}

std::string const& csv_graph_file_path = argv[1];
std::string const& allocation_mode = argc < 3 ? "cuda" : argv[2];

initialize_mpi_and_set_device(argc, argv);
std::unique_ptr<raft::handle_t> handle = initialize_mg_handle(allocation_mode);

auto const comm_rank = handle->get_comms().get_rank();
auto const comm_size = handle->get_comms().get_size();

using vertex_t = int32_t;
using edge_t = int32_t;
using weight_t = float;
constexpr bool multi_gpu = true;

look_into_vertex_and_edge_partitions<vertex_t, edge_t, weight_t, multi_gpu>(*handle,
csv_graph_file_path);
}
7 changes: 3 additions & 4 deletions cpp/examples/multi_gpu/mg_examples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@
#include <raft/core/handle.hpp>
#include <raft/random/rng_state.hpp>

#include "iostream"
#include "string"
using namespace std;
#include <iostream>
#include <string>

void initialize_mpi_and_set_device(int argc, char** argv)
{
Expand Down Expand Up @@ -57,7 +56,7 @@ std::unique_ptr<raft::handle_t> initialize_mg_handle(std::string const& allocati
<< std::endl;
std::for_each(possible_allocation_modes.cbegin(),
possible_allocation_modes.cend(),
[](string mode) { std::cout << mode << std::endl; });
[](std::string mode) { std::cout << mode << std::endl; });
}
RAFT_MPI_TRY(MPI_Finalize());

Expand Down
20 changes: 20 additions & 0 deletions cpp/examples/output.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Using 'cuda' allocation mode to create device memory resources.
Rank_1, reading graph from graph2.csv
Rank_0, reading graph from graph2.csv
vertices@rank_0=[5];
owned by rank 0, original vertex id 5 --- becomes --> 0
offsets_0_0=[0,0];
indices_0_0=[];
weights_0_0=[];
offsets_0_1=[0,1,2];
indices_0_1=[0,0];
weights_0_1=[35,45];
vertices@rank_1=[3,4];
owned by rank 1, original vertex id 3 --- becomes --> 1
owned by rank 1, original vertex id 4 --- becomes --> 2
offsets_1_0=[0,2];
indices_1_0=[1,2];
weights_1_0=[53,54];
offsets_1_1=[0,1,2];
indices_1_1=[2,1];
weights_1_1=[34,43];
7 changes: 3 additions & 4 deletions cpp/examples/single_gpu/sg_examples.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@
#include <raft/core/handle.hpp>
#include <raft/random/rng_state.hpp>

#include "iostream"
#include "string"
using namespace std;
#include <iostream>
#include <string>

std::unique_ptr<raft::handle_t> initialize_sg_handle(std::string const& allocation_mode = "cuda")
{
Expand All @@ -36,7 +35,7 @@ std::unique_ptr<raft::handle_t> initialize_sg_handle(std::string const& allocati
<< std::endl;
std::for_each(possible_allocation_modes.cbegin(),
possible_allocation_modes.cend(),
[](string mode) { std::cout << mode << std::endl; });
[](std::string mode) { std::cout << mode << std::endl; });

exit(0);
}
Expand Down
3 changes: 1 addition & 2 deletions cpp/examples/work_with_vertex_edge_partitions/main.cu
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@

#include <iostream>
#include <string>
using namespace std;

void initialize_mpi_and_set_device(int argc, char** argv)
{
Expand Down Expand Up @@ -59,7 +58,7 @@ std::unique_ptr<raft::handle_t> initialize_mg_handle(std::string const& allocati
<< std::endl;
std::for_each(possible_allocation_modes.cbegin(),
possible_allocation_modes.cend(),
[](string mode) { std::cout << mode << std::endl; });
[](std::string mode) { std::cout << mode << std::endl; });
}
RAFT_MPI_TRY(MPI_Finalize());

Expand Down

0 comments on commit 85d9ebc

Please sign in to comment.