Skip to content

Commit

Permalink
add unit tests for the compress_results option
Browse files Browse the repository at this point in the history
  • Loading branch information
ChuckHastings committed Feb 16, 2022
1 parent 7595067 commit db88891
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 18 deletions.
6 changes: 3 additions & 3 deletions cpp/include/cugraph_c/algorithms.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,12 +377,12 @@ cugraph_type_erased_device_array_view_t* cugraph_random_walk_result_get_weights(
cugraph_random_walk_result_t* result);

/**
* @brief If the random walk result is compressed, get the offsets
* @brief If the random walk result is compressed, get the path sizes
*
* @param [in] result The result from a random walk algorithm
* @return type erased array pointing to the edge offsets in device memory
* @return type erased array pointing to the path sizes in device memory
*/
cugraph_type_erased_device_array_view_t* cugraph_random_walk_result_get_offsets(
cugraph_type_erased_device_array_view_t* cugraph_random_walk_result_get_path_sizes(
cugraph_random_walk_result_t* result);

/**
Expand Down
11 changes: 6 additions & 5 deletions cpp/src/c_api/random_walks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct cugraph_random_walk_result_t {
size_t max_path_length_;
cugraph_type_erased_device_array_t* paths_;
cugraph_type_erased_device_array_t* weights_;
cugraph_type_erased_device_array_t* offsets_;
cugraph_type_erased_device_array_t* sizes_;
};

struct node2vec_functor : public abstract_functor {
Expand Down Expand Up @@ -112,7 +112,7 @@ struct node2vec_functor : public abstract_functor {
// FIXME: Forcing this to edge_t for now. What should it really be?
// Seems like it should be the smallest size that can accommodate
// max_depth_ * sources_->size_
auto [paths, weights, offsets] = cugraph::random_walks(
auto [paths, weights, sizes] = cugraph::random_walks(
handle_,
graph_view,
sources.data(),
Expand All @@ -127,7 +127,7 @@ struct node2vec_functor : public abstract_functor {
max_depth_,
new cugraph_type_erased_device_array_t(paths, graph_->vertex_type_),
new cugraph_type_erased_device_array_t(weights, graph_->weight_type_),
new cugraph_type_erased_device_array_t(offsets, graph_->vertex_type_)};
new cugraph_type_erased_device_array_t(sizes, graph_->vertex_type_)};
}
}
};
Expand Down Expand Up @@ -203,18 +203,19 @@ cugraph_type_erased_device_array_view_t* cugraph_random_walk_result_get_weights(
internal_pointer->weights_->view());
}

cugraph_type_erased_device_array_view_t* cugraph_random_walk_result_get_offsets(
cugraph_type_erased_device_array_view_t* cugraph_random_walk_result_get_path_sizes(
cugraph_random_walk_result_t* result)
{
auto internal_pointer = reinterpret_cast<cugraph::c_api::cugraph_random_walk_result_t*>(result);
return reinterpret_cast<cugraph_type_erased_device_array_view_t*>(
internal_pointer->offsets_->view());
internal_pointer->sizes_->view());
}

void cugraph_random_walk_result_free(cugraph_random_walk_result_t* result)
{
auto internal_pointer = reinterpret_cast<cugraph::c_api::cugraph_random_walk_result_t*>(result);
delete internal_pointer->paths_;
delete internal_pointer->sizes_;
delete internal_pointer->weights_;
delete internal_pointer;
}
83 changes: 73 additions & 10 deletions cpp/tests/c_api/node2vec_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ int generic_node2vec_test(vertex_t* h_src,
vertex_t* h_dst,
weight_t* h_wgt,
vertex_t* h_seeds,
size_t num_vertices,
size_t num_edges,
size_t num_seeds,
size_t max_depth,
bool_t compressed_result,
double p,
double q,
bool_t store_transposed)
Expand Down Expand Up @@ -67,10 +69,11 @@ int generic_node2vec_test(vertex_t* h_src,
TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "src copy_from_host failed.");

ret_code = cugraph_node2vec(
p_handle, p_graph, p_source_view, max_depth, FALSE, p, q, &p_result, &ret_error);
p_handle, p_graph, p_source_view, max_depth, compressed_result, p, q, &p_result, &ret_error);
TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "node2vec failed failed.");

cugraph_type_erased_device_array_view_t* paths;
cugraph_type_erased_device_array_view_t* path_sizes;
cugraph_type_erased_device_array_view_t* weights;
size_t max_path_length;

Expand All @@ -92,7 +95,6 @@ int generic_node2vec_test(vertex_t* h_src,
// We can easily validate that the results of node2vec
// are feasible by converting the sparse (h_src,h_dst,h_wgt)
// into a dense host matrix and check each path.
int num_vertices = 5;
weight_t M[num_vertices][num_vertices];

for (int i = 0; i < num_vertices; ++i)
Expand All @@ -102,13 +104,39 @@ int generic_node2vec_test(vertex_t* h_src,
for (int i = 0; i < num_edges; ++i)
M[h_src[i]][h_dst[i]] = h_wgt[i];

for (int i = 0; (i < num_seeds) && (test_ret_value == 0); ++i) {
for (int j = 0; (j < (max_path_length-1)) && (test_ret_value == 0); ++j) {
TEST_ASSERT(test_ret_value,
nearlyEqual(h_weights[i * (max_path_length - 1)],
M[h_paths[i * max_path_length]][h_paths[i * max_path_length + 1]],
EPSILON),
"node2vec weights don't match");
if (compressed_result) {
path_sizes = cugraph_random_walk_result_get_path_sizes(p_result);

edge_t h_path_sizes[num_seeds];
edge_t h_path_offsets[num_seeds + 1];

ret_code = cugraph_type_erased_device_array_view_copy_to_host(
p_handle, (byte_t*)h_path_sizes, path_sizes, &ret_error);
TEST_ASSERT(test_ret_value, ret_code == CUGRAPH_SUCCESS, "copy_to_host failed.");

h_path_offsets[0] = 0;
for (int i = 0; i < num_seeds; ++i)
h_path_offsets[i + 1] = h_path_offsets[i] + h_path_sizes[i];

for (int i = 0; (i < num_seeds) && (test_ret_value == 0); ++i) {
for (int j = h_path_offsets[i]; j < (h_path_offsets[i + 1] - 1); ++j) {
TEST_ASSERT(test_ret_value,
nearlyEqual(h_weights[j - i], M[h_paths[j]][h_paths[j + 1]], EPSILON),
"node2vec weights don't match");
}
}
} else {
for (int i = 0; (i < num_seeds) && (test_ret_value == 0); ++i) {
for (int j = 0; (j < (max_path_length - 1)) && (test_ret_value == 0); ++j) {
if (h_paths[i * max_path_length + j + 1] != num_vertices) {
TEST_ASSERT(
test_ret_value,
nearlyEqual(h_weights[i * (max_path_length - 1) + j],
M[h_paths[i * max_path_length + j]][h_paths[i * max_path_length + j + 1]],
EPSILON),
"node2vec weights don't match");
}
}
}
}

Expand All @@ -126,12 +154,47 @@ int test_node2vec()
vertex_t seeds[] = {0, 0};
size_t max_depth = 4;

return generic_node2vec_test(src, dst, wgt, seeds, num_edges, 2, max_depth, 0.8, 0.5, FALSE);
return generic_node2vec_test(
src, dst, wgt, seeds, num_vertices, num_edges, 2, max_depth, FALSE, 0.8, 0.5, FALSE);
}

int test_node2vec_short_dense()
{
size_t num_edges = 8;
size_t num_vertices = 6;

vertex_t src[] = {0, 1, 1, 2, 2, 2, 3, 4};
vertex_t dst[] = {1, 3, 4, 0, 1, 3, 5, 5};
weight_t wgt[] = {0.1f, 2.1f, 1.1f, 5.1f, 3.1f, 4.1f, 7.2f, 3.2f};
vertex_t seeds[] = {2, 3};
size_t max_depth = 4;

return generic_node2vec_test(
src, dst, wgt, seeds, num_vertices, num_edges, 2, max_depth, FALSE, 0.8, 0.5, FALSE);
}

int test_node2vec_short_sparse()
{
size_t num_edges = 8;
size_t num_vertices = 6;

vertex_t src[] = {0, 1, 1, 2, 2, 2, 3, 4};
vertex_t dst[] = {1, 3, 4, 0, 1, 3, 5, 5};
weight_t wgt[] = {0.1f, 2.1f, 1.1f, 5.1f, 3.1f, 4.1f, 7.2f, 3.2f};
vertex_t seeds[] = {2, 3};
size_t max_depth = 4;

// FIXME: max_depth seems to be off by 1. It's counting vertices
// instead of edges.
return generic_node2vec_test(
src, dst, wgt, seeds, num_vertices, num_edges, 2, max_depth, TRUE, 0.8, 0.5, FALSE);
}

int main(int argc, char** argv)
{
int result = 0;
result |= RUN_TEST(test_node2vec);
result |= RUN_TEST(test_node2vec_short_dense);
result |= RUN_TEST(test_node2vec_short_sparse);
return result;
}

0 comments on commit db88891

Please sign in to comment.