#include #include #include #include #include #include #include #include #include #include "../common/CycleTimer.h" #include "../common/graph.h" #include "../common/grade.h" #include "page_rank.h" #define USE_BINARY_GRAPH 1 #define PageRankDampening 0.3f #define PageRankConvergence 1e-7d void reference_pageRank(Graph g, double* solution, double damping, double convergence); void usage(const char* binary_name) { std::cout << "Usage: " << binary_name << " [options] graphdir" << std::endl; std::cout << std::endl; std::cout << "Options:" << std::endl; std::cout << " -n INT number of threads" << std::endl; std::cout << " -r INT number of runs" << std::endl; std::cout << " -h this commandline help message" << std::endl; } graph* load_graph(std::string graph_filename) { graph* g; if (USE_BINARY_GRAPH) { g = load_graph_binary(graph_filename.c_str()); } else { g = load_graph(graph_filename); printf("storing binary form of graph!\n"); store_graph_binary(graph_filename.append(".bin").c_str(), g); delete g; exit(1); } return g; } double run_on_graph(graph* g, int num_threads, int num_runs, std::string graph_name) { double* sol_stu = new double[g->num_nodes]; double* sol_ref = new double[g->num_nodes]; omp_set_num_threads(num_threads); double start, time; //Run implementation double stu_time = std::numeric_limits::max(); for (int r = 0; r < num_runs; r++) { start = CycleTimer::currentSeconds(); pageRank(g, sol_stu, PageRankDampening, PageRankConvergence); time = CycleTimer::currentSeconds() - start; stu_time = std::min(stu_time, time); } //Run reference implementation double ref_time = std::numeric_limits::max(); for (int r = 0; r < num_runs; r++) { start = CycleTimer::currentSeconds(); reference_pageRank(g, sol_ref, PageRankDampening, PageRankConvergence); time = CycleTimer::currentSeconds() - start; ref_time = std::min(ref_time, time); } bool correct = compareApprox(g, sol_ref, sol_stu); delete(sol_stu); delete(sol_ref); if (!correct) { std::cout << "Page rank incorrect" << std::endl; } else { std::cout << "ref_time: " << ref_time << "s" << std::endl; std::cout << "stu_time: " << stu_time << "s" << std::endl; } bool small = false; if ((graph_name == "grid1000x1000.graph") || (graph_name == "soc-livejournal1_68m.graph")) small = true; double max_score = (small) ? 1 : 6; double max_perf_score = 0.8 * max_score; //(small) ? 1.6 : 3.2; double correctness_score = 0.2 * max_score; //(small) ? 0.4 : 0.8; correctness_score = (correct) ? correctness_score : 0; double ratio = (ref_time/stu_time); double slope = max_perf_score/(0.7 - 0.3); //(small) ? 4 : 8; double offset = 0.3 * slope; //(small) ? 1.2 : 2.4; double perf_score = (correct) ? ratio*slope - offset : 0; if (perf_score < 0) perf_score = 0; if (perf_score > max_perf_score) perf_score = max_perf_score; return (correctness_score + perf_score); } void print_separator_line() { for (int i = 0; i < 43; i++) { std::cout<<"-"; } std::cout< grade_graphs, std::vector scores) { std::cout.precision(5); std::cout.setf(std::ios::fixed, std:: ios::floatfield); std::cout< grade_graphs = { "grid1000x1000.graph", "soc-livejournal1_68m.graph", "com-orkut_117m.graph", "random_500m.graph", "rmat_200m.graph"}; std::vector scores(grade_graphs.size()); int i = 0; for (auto& graph_name: grade_graphs) { graph* g = load_graph(graph_dir + '/' + graph_name); std::cout << "\nGraph: " << graph_name << std::endl; scores[i] = run_on_graph(g, num_threads, num_runs, graph_name); delete g; i++; } print_scores(grade_graphs, scores); return 0; }