From 67eab859ed34d5c9e1cbc65140e2d5fa0966dd01 Mon Sep 17 00:00:00 2001 From: Alexander Frolov Date: Tue, 19 Jul 2016 18:19:01 +0300 Subject: [PATCH 1/6] HPCC RandomAccess benchmark added. --- hpcc/CMakeLists.txt | 4 ++ hpcc/hpcc_random_access.cpp | 114 ++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 hpcc/CMakeLists.txt create mode 100644 hpcc/hpcc_random_access.cpp diff --git a/hpcc/CMakeLists.txt b/hpcc/CMakeLists.txt new file mode 100644 index 000000000..507133341 --- /dev/null +++ b/hpcc/CMakeLists.txt @@ -0,0 +1,4 @@ +#set(SOURCES main.cpp common.hpp) + + add_grappa_application(hpcc_random_access.exe hpcc_random_access.cpp) + diff --git a/hpcc/hpcc_random_access.cpp b/hpcc/hpcc_random_access.cpp new file mode 100644 index 000000000..e707c5b7f --- /dev/null +++ b/hpcc/hpcc_random_access.cpp @@ -0,0 +1,114 @@ +// to run, do something like +// make -j demo-hpcc_random_access +// bin/grappa_run --ppn 8 --nnode 12 -- demo-hpcc_random_access.exe + +#include +#include + +using namespace Grappa; + +// define command-line flags (third-party 'gflags' library) +DEFINE_int64( scale, 20, "table size = 2 ^ scale * sizeof(uint64_t) * number of PEs" ); +DEFINE_int64( iters, 4, "Number of iterations" ); + +// define custom statistics which are logged by the runtime +// (here we're not using these features, just printing them ourselves) +GRAPPA_DEFINE_METRIC( SimpleMetric, gups_runtime, 0.0 ); +GRAPPA_DEFINE_METRIC( SimpleMetric, gups_throughput, 0.0 ); + +#define POLY 0x0000000000000007ULL +#define PERIOD 1317624576693539401LL + +typedef double time_type; +std::string print_time(time_type t) +{ + std::ostringstream out; + out << std::setiosflags(std::ios::fixed) << std::setprecision(2) << t; + return out.str(); +} + + +uint64_t N; +uint64_t HPCC_starts(int64_t n); + +double run_random_access() { + LOG(INFO) << "HPCC RandomAccess" << std::endl; + N = (1 << FLAGS_scale) * cores(); + + // create target array that we'll be updating + auto hpcc_table = global_alloc(N); + Grappa::memset( hpcc_table, 0, N); + + double tstart = walltime(); + + on_all_cores([hpcc_table] { + uint64_t key = HPCC_starts(FLAGS_iters * mycore() * N / cores()); + for(int k = 0; k < FLAGS_iters; k++) + for(uint64_t i = 0; i < N / cores(); i++) { + key = key << 1 ^ ((int64_t) key < 0 ? POLY : 0); + auto addr = hpcc_table + (key & N - 1); + //auto core = key >> (int)log2((double)(N / cores())) & cores() - 1; + delegate::call(addr.core(), [addr, key] { + //uint64_t offset = key & (N / cores() - 1); + *(addr.pointer()) ^= key; + }); + } + }); + + double tend = walltime(); + + LOG(INFO) << "\tTime elapsed " << (double)(tend - tstart) << " sec" << std::endl; + + global_free(hpcc_table); + + return (double)(tend - tstart); +} + +uint64_t HPCC_starts(int64_t n) { + int i, j; + uint64_t m2[64]; + uint64_t temp, ran; + while (n < 0) n += PERIOD; + while (n > PERIOD) n -= PERIOD; + if (n == 0) return 0x1; + temp = 0x1; + for (i = 0; i < 64; i++) { + m2[i] = temp; + temp = temp << 1 ^ ((int64_t) temp < 0 ? POLY : 0); + temp = temp << 1 ^ ((int64_t) temp < 0 ? POLY : 0); + } + for (i = 62; i >= 0; i--) + if (n >> i & 1) + break; + + ran = 0x2; + while (i > 0) { + temp = 0; + for (j = 0; j < 64; j++) + if (ran >> j & 1) + temp ^= m2[j]; + ran = temp; + i -= 1; + if (n >> i & 1) + ran = ran << 1 ^ ((int64_t) ran < 0 ? POLY : 0); + } + return ran; +} + + +int main(int argc, char * argv[]) { + init( &argc, &argv ); + run([]{ + + LOG(INFO) << "\tGlobal table size = 2^" << FLAGS_scale << " * " << cores() << " = " << (1 << FLAGS_scale) * cores() << " words\n"; + LOG(INFO) << "\tNumber of processes = " << cores() << std::endl; + LOG(INFO) << "\tNumber of updates = " << FLAGS_iters * (1 << FLAGS_scale) * cores() << std::endl; + + gups_runtime = run_random_access(); + gups_throughput = 1e-9 * FLAGS_iters * N / gups_runtime; + + LOG(INFO) << "[Final] CPU time used " << print_time(gups_runtime.value()) << " seconds, " << print_time(gups_throughput.value()) << " GUPS\n"; + + }); + finalize(); +} From 15f34eadfe4818087d46b393084fbd5dea61437d Mon Sep 17 00:00:00 2001 From: Alexander Frolov Date: Wed, 20 Jul 2016 14:04:03 +0300 Subject: [PATCH 2/6] hpcc folder moved to application, CMakeList.txt fixed --- applications/CMakeLists.txt | 1 + {hpcc => applications/hpcc}/CMakeLists.txt | 0 {hpcc => applications/hpcc}/hpcc_random_access.cpp | 0 3 files changed, 1 insertion(+) rename {hpcc => applications/hpcc}/CMakeLists.txt (100%) rename {hpcc => applications/hpcc}/hpcc_random_access.cpp (100%) diff --git a/applications/CMakeLists.txt b/applications/CMakeLists.txt index ddcf18d40..725d605a0 100644 --- a/applications/CMakeLists.txt +++ b/applications/CMakeLists.txt @@ -8,3 +8,4 @@ add_subdirectory(join) add_subdirectory(isopath) add_subdirectory(graphlab) add_subdirectory(util) +add_subdirectory(hpcc) diff --git a/hpcc/CMakeLists.txt b/applications/hpcc/CMakeLists.txt similarity index 100% rename from hpcc/CMakeLists.txt rename to applications/hpcc/CMakeLists.txt diff --git a/hpcc/hpcc_random_access.cpp b/applications/hpcc/hpcc_random_access.cpp similarity index 100% rename from hpcc/hpcc_random_access.cpp rename to applications/hpcc/hpcc_random_access.cpp From 66644f5afd26628b9326bf8e1f728d4feb597f91 Mon Sep 17 00:00:00 2001 From: Alexander Frolov Date: Wed, 20 Jul 2016 15:06:27 +0300 Subject: [PATCH 3/6] hpcc randomaccess modified (gce added to monitor completion of updates) --- applications/hpcc/hpcc_random_access.cpp | 60 +++++++++++++----------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/applications/hpcc/hpcc_random_access.cpp b/applications/hpcc/hpcc_random_access.cpp index e707c5b7f..c1bd2dd89 100644 --- a/applications/hpcc/hpcc_random_access.cpp +++ b/applications/hpcc/hpcc_random_access.cpp @@ -31,38 +31,44 @@ std::string print_time(time_type t) uint64_t N; uint64_t HPCC_starts(int64_t n); -double run_random_access() { - LOG(INFO) << "HPCC RandomAccess" << std::endl; - N = (1 << FLAGS_scale) * cores(); - - // create target array that we'll be updating - auto hpcc_table = global_alloc(N); - Grappa::memset( hpcc_table, 0, N); - - double tstart = walltime(); - - on_all_cores([hpcc_table] { - uint64_t key = HPCC_starts(FLAGS_iters * mycore() * N / cores()); - for(int k = 0; k < FLAGS_iters; k++) - for(uint64_t i = 0; i < N / cores(); i++) { - key = key << 1 ^ ((int64_t) key < 0 ? POLY : 0); - auto addr = hpcc_table + (key & N - 1); - //auto core = key >> (int)log2((double)(N / cores())) & cores() - 1; - delegate::call(addr.core(), [addr, key] { - //uint64_t offset = key & (N / cores() - 1); - *(addr.pointer()) ^= key; +Grappa::GlobalCompletionEvent randomaccess_gce; + +template + double run_random_access() { + LOG(INFO) << "HPCC RandomAccess" << std::endl; + N = (1 << FLAGS_scale) * cores(); + + // create target array that we'll be updating + auto hpcc_table = global_alloc(N); + Grappa::memset( hpcc_table, 0, N); + + double tstart = walltime(); + + on_all_cores([hpcc_table] { + //for(int k = 0; k < FLAGS_iters; k++) + //forall_here(0, FLAGS_iters, [=](uint64_t k) { + forall_here(0, FLAGS_iters, [=](int64_t k) { + uint64_t key = HPCC_starts((FLAGS_iters + k)* mycore() * N / cores()); + for(uint64_t i = 0; i < N / cores(); i++) { + key = key << 1 ^ ((int64_t) key < 0 ? POLY : 0); + auto addr = hpcc_table + (key & N - 1); + //auto core = key >> (int)log2((double)(N / cores())) & cores() - 1; + delegate::call(addr.core(), [addr, key] { + //uint64_t offset = key & (N / cores() - 1); + *(addr.pointer()) ^= key; + }); + } }); - } - }); + }); - double tend = walltime(); + double tend = walltime(); - LOG(INFO) << "\tTime elapsed " << (double)(tend - tstart) << " sec" << std::endl; + LOG(INFO) << "\tTime elapsed " << (double)(tend - tstart) << " sec" << std::endl; - global_free(hpcc_table); + global_free(hpcc_table); - return (double)(tend - tstart); -} + return (double)(tend - tstart); + } uint64_t HPCC_starts(int64_t n) { int i, j; From e2431248a23c25da1fcc9f8f31057c677876d627 Mon Sep 17 00:00:00 2001 From: Alexander Frolov Date: Thu, 21 Jul 2016 15:42:02 +0300 Subject: [PATCH 4/6] Minor fixes in HPCC RandomAccess. --- applications/hpcc/hpcc_random_access.cpp | 63 +++++++++++------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/applications/hpcc/hpcc_random_access.cpp b/applications/hpcc/hpcc_random_access.cpp index c1bd2dd89..49a07cd75 100644 --- a/applications/hpcc/hpcc_random_access.cpp +++ b/applications/hpcc/hpcc_random_access.cpp @@ -31,44 +31,41 @@ std::string print_time(time_type t) uint64_t N; uint64_t HPCC_starts(int64_t n); -Grappa::GlobalCompletionEvent randomaccess_gce; - -template - double run_random_access() { - LOG(INFO) << "HPCC RandomAccess" << std::endl; - N = (1 << FLAGS_scale) * cores(); - - // create target array that we'll be updating - auto hpcc_table = global_alloc(N); - Grappa::memset( hpcc_table, 0, N); - - double tstart = walltime(); - - on_all_cores([hpcc_table] { - //for(int k = 0; k < FLAGS_iters; k++) - //forall_here(0, FLAGS_iters, [=](uint64_t k) { - forall_here(0, FLAGS_iters, [=](int64_t k) { - uint64_t key = HPCC_starts((FLAGS_iters + k)* mycore() * N / cores()); - for(uint64_t i = 0; i < N / cores(); i++) { - key = key << 1 ^ ((int64_t) key < 0 ? POLY : 0); - auto addr = hpcc_table + (key & N - 1); - //auto core = key >> (int)log2((double)(N / cores())) & cores() - 1; - delegate::call(addr.core(), [addr, key] { - //uint64_t offset = key & (N / cores() - 1); - *(addr.pointer()) ^= key; - }); - } +Grappa::GlobalCompletionEvent gce; + +double run_random_access() { + LOG(INFO) << "HPCC RandomAccess" << std::endl; + N = (1 << FLAGS_scale) * cores(); + + // create target array that we'll be updating + auto hpcc_table = global_alloc(N); + Grappa::memset( hpcc_table, 0, N); + + double tstart = walltime(); + + on_all_cores([hpcc_table] { + uint64_t key = HPCC_starts(FLAGS_iters * mycore() * N / cores()); + for(int k = 0; k < FLAGS_iters; k++) + for(uint64_t i = 0; i < N / cores(); i++) { + key = key << 1 ^ ((int64_t) key < 0 ? POLY : 0); + auto addr = hpcc_table + (key & N - 1); + //auto core = key >> (int)log2((double)(N / cores())) & cores() - 1; + delegate::call(addr.core(), [addr, key] { + //uint64_t offset = key & (N / cores() - 1); + *(addr.pointer()) ^= key; }); - }); + } + }); + gce.wait(); - double tend = walltime(); + double tend = walltime(); - LOG(INFO) << "\tTime elapsed " << (double)(tend - tstart) << " sec" << std::endl; + LOG(INFO) << "\tTime elapsed " << (double)(tend - tstart) << " sec" << std::endl; - global_free(hpcc_table); + global_free(hpcc_table); - return (double)(tend - tstart); - } + return (double)(tend - tstart); +} uint64_t HPCC_starts(int64_t n) { int i, j; From e1ce6caf99e47a6cb75089d0e12cfb9915860173 Mon Sep 17 00:00:00 2001 From: Alexander Frolov Date: Fri, 22 Jul 2016 00:37:28 +0300 Subject: [PATCH 5/6] Bug fixed in HPCC RandomAccess. --- applications/hpcc/hpcc_random_access.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/applications/hpcc/hpcc_random_access.cpp b/applications/hpcc/hpcc_random_access.cpp index 49a07cd75..0b7b3f9ad 100644 --- a/applications/hpcc/hpcc_random_access.cpp +++ b/applications/hpcc/hpcc_random_access.cpp @@ -35,7 +35,7 @@ Grappa::GlobalCompletionEvent gce; double run_random_access() { LOG(INFO) << "HPCC RandomAccess" << std::endl; - N = (1 << FLAGS_scale) * cores(); + N = (1LL << FLAGS_scale) * cores(); // create target array that we'll be updating auto hpcc_table = global_alloc(N); @@ -44,6 +44,7 @@ double run_random_access() { double tstart = walltime(); on_all_cores([hpcc_table] { + N = (1LL << FLAGS_scale) * cores(); uint64_t key = HPCC_starts(FLAGS_iters * mycore() * N / cores()); for(int k = 0; k < FLAGS_iters; k++) for(uint64_t i = 0; i < N / cores(); i++) { @@ -103,9 +104,9 @@ int main(int argc, char * argv[]) { init( &argc, &argv ); run([]{ - LOG(INFO) << "\tGlobal table size = 2^" << FLAGS_scale << " * " << cores() << " = " << (1 << FLAGS_scale) * cores() << " words\n"; + LOG(INFO) << "\tGlobal table size = 2^" << FLAGS_scale << " * " << cores() << " = " << (1LL << FLAGS_scale) * cores() << " words\n"; LOG(INFO) << "\tNumber of processes = " << cores() << std::endl; - LOG(INFO) << "\tNumber of updates = " << FLAGS_iters * (1 << FLAGS_scale) * cores() << std::endl; + LOG(INFO) << "\tNumber of updates = " << FLAGS_iters * (1LL << FLAGS_scale) * cores() << std::endl; gups_runtime = run_random_access(); gups_throughput = 1e-9 * FLAGS_iters * N / gups_runtime; From 1c706d72e11807aaaea350756a3010d72c4565f8 Mon Sep 17 00:00:00 2001 From: Alexander Frolov Date: Wed, 3 Aug 2016 18:51:14 +0300 Subject: [PATCH 6/6] parallel_search branch added. --- applications/nativegraph/CMakeLists.txt | 1 + .../parallel_search/CMakeLists.txt | 3 + .../nativegraph/parallel_search/common.hpp | 39 +++++++ .../nativegraph/parallel_search/igor_bfs.rb | 51 +++++++++ .../nativegraph/parallel_search/main.cpp | 95 ++++++++++++++++ .../parallel_search/parallel_search.cpp | 102 ++++++++++++++++++ 6 files changed, 291 insertions(+) create mode 100644 applications/nativegraph/parallel_search/CMakeLists.txt create mode 100644 applications/nativegraph/parallel_search/common.hpp create mode 100755 applications/nativegraph/parallel_search/igor_bfs.rb create mode 100644 applications/nativegraph/parallel_search/main.cpp create mode 100644 applications/nativegraph/parallel_search/parallel_search.cpp diff --git a/applications/nativegraph/CMakeLists.txt b/applications/nativegraph/CMakeLists.txt index 6f6842906..2fb623a4c 100644 --- a/applications/nativegraph/CMakeLists.txt +++ b/applications/nativegraph/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(bfs) add_subdirectory(cc) add_subdirectory(sssp) +add_subdirectory(parallel_search) diff --git a/applications/nativegraph/parallel_search/CMakeLists.txt b/applications/nativegraph/parallel_search/CMakeLists.txt new file mode 100644 index 000000000..f565a3dc1 --- /dev/null +++ b/applications/nativegraph/parallel_search/CMakeLists.txt @@ -0,0 +1,3 @@ +set(SOURCES main.cpp common.hpp) + +add_grappa_application(parallel_search.exe parallel_search.cpp ${SOURCES}) diff --git a/applications/nativegraph/parallel_search/common.hpp b/applications/nativegraph/parallel_search/common.hpp new file mode 100644 index 000000000..feadaf395 --- /dev/null +++ b/applications/nativegraph/parallel_search/common.hpp @@ -0,0 +1,39 @@ +#include +#include +#include +#include "../verifier.hpp" + +using namespace Grappa; + +// additional data to attach to each vertex in the graph +struct BFSData { + int64_t parent; + int64_t level; + bool seen; + + void init() { + parent = -1; + level = 0; + seen = false; + } +}; + +using G = Graph; + +extern int64_t nedge_traversed; + +void bfs(GlobalAddress g, int nbfs, TupleGraph tg); + +template< typename V, typename E > +inline int64_t choose_root(GlobalAddress> g) { + int64_t root; + do { + root = random() % g->nv; + } while (delegate::call(g->vs+root,[](typename G::Vertex& v){ return v.nadj; }) == 0); + return root; +} + +inline int64_t verify(TupleGraph tg, GlobalAddress g, int64_t root) { + return VerificatorBase::verify(tg, g, root); +} + diff --git a/applications/nativegraph/parallel_search/igor_bfs.rb b/applications/nativegraph/parallel_search/igor_bfs.rb new file mode 100755 index 000000000..8900973dc --- /dev/null +++ b/applications/nativegraph/parallel_search/igor_bfs.rb @@ -0,0 +1,51 @@ +#!/usr/bin/env ruby +require 'igor' + +# inherit parser, sbatch_flags +require_relative '../../util/igor_common.rb' + +Igor do + include Isolatable + + database '~/osdi.sqlite', :bfs + + # isolate everything needed for the executable so we can sbcast them for local execution + isolate(['bfs_bags.exe']) + + GFLAGS.merge!({ + path: '/pic/projects/grappa/twitter/bintsv4/twitter-all.bintsv4', + format: 'bintsv4', + nbfs: 3, + beamer_alpha: 20.0, + beamer_beta: 20.0, + }) + GFLAGS.delete :flat_combining + + params.merge!(GFLAGS) + + @c = ->{ %Q[ %{tdir}/grappa_srun --no-freeze-on-error + -- %{tdir}/bfs_bags.exe --metrics --max_degree_source --vmodule bfs_bags=1 + #{GFLAGS.expand} + ].gsub(/\s+/,' ') } + command @c[] + + sbatch_flags << "--time=30:00" + + params { + grappa_version 'beamer' + nnode 16 + ppn 32 + loop_threshold 1024 + num_starting_workers 512 + # aggregator_autoflush_ticks 3e6.to_i + # periodic_poll_ticks 2e5.to_i + shared_pool_chunk_size 2**15 + global_heap_fraction 0.25 + } + + expect :total_time + @cols << :total_time_mean + @order = :total_time_mean + + interact # enter interactive mode +end diff --git a/applications/nativegraph/parallel_search/main.cpp b/applications/nativegraph/parallel_search/main.cpp new file mode 100644 index 000000000..87898a57e --- /dev/null +++ b/applications/nativegraph/parallel_search/main.cpp @@ -0,0 +1,95 @@ +//////////////////////////////////////////////////////////////////////// +// Copyright (c) 2010-2015, University of Washington and Battelle +// Memorial Institute. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above +// copyright notice, this list of conditions and the following +// disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials +// provided with the distribution. +// * Neither the name of the University of Washington, Battelle +// Memorial Institute, or the names of their contributors may be +// used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// UNIVERSITY OF WASHINGTON OR BATTELLE MEMORIAL INSTITUTE BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// Simon Kahan's 3-phase Connected Components (for Grappa Graph) +//////////////////////////////////////////////////////////////////////// + +#include +#include "common.hpp" + +DEFINE_bool( metrics, false, "Dump metrics"); + +DEFINE_int32(scale, 10, "Log2 number of vertices."); +DEFINE_int32(edgefactor, 16, "Average number of edges per vertex."); +DEFINE_int32(nbfs, 1, "Number of BFS traversals to do."); + +DEFINE_string(path, "", "Path to graph source file."); +DEFINE_string(format, "bintsv4", "Format of graph source file."); + +GRAPPA_DEFINE_METRIC(SimpleMetric, init_time, 0); +GRAPPA_DEFINE_METRIC(SimpleMetric, tuple_time, 0); +GRAPPA_DEFINE_METRIC(SimpleMetric, construction_time, 0); + +GRAPPA_DEFINE_METRIC(SummarizingMetric, bfs_mteps, 0); +GRAPPA_DEFINE_METRIC(SummarizingMetric, total_time, 0); +GRAPPA_DEFINE_METRIC(SimpleMetric, bfs_nedge, 0); +GRAPPA_DEFINE_METRIC(SimpleMetric, verify_time, 0); + +int64_t nedge_traversed; + +int main(int argc, char* argv[]) { + init(&argc, &argv); + run([]{ + + TupleGraph tg; + + GRAPPA_TIME_REGION(tuple_time) { + if (FLAGS_path.empty()) { + int64_t NE = (1L << FLAGS_scale) * FLAGS_edgefactor; + tg = TupleGraph::Kronecker(FLAGS_scale, NE, 111, 222); + } else { + LOG(INFO) << "loading " << FLAGS_path; + tg = TupleGraph::Load(FLAGS_path, FLAGS_format); + } + } + LOG(INFO) << tuple_time; + LOG(INFO) << "constructing graph"; + + double t = walltime(); + + // construct the compact graph representation (roughly CSR) + auto g = G::Undirected( tg ); + + construction_time = (walltime()-t); + LOG(INFO) << construction_time; + + bfs(g, FLAGS_nbfs, tg); + + LOG(INFO) << "\n" << bfs_nedge << "\n" << total_time << "\n" << bfs_mteps; + if (FLAGS_metrics) Metrics::merge_and_print(); + Metrics::merge_and_dump_to_file(); + }); + finalize(); +} diff --git a/applications/nativegraph/parallel_search/parallel_search.cpp b/applications/nativegraph/parallel_search/parallel_search.cpp new file mode 100644 index 000000000..f05d811a8 --- /dev/null +++ b/applications/nativegraph/parallel_search/parallel_search.cpp @@ -0,0 +1,102 @@ +//////////////////////////////////////////////////////////////////////// +// Copyright (c) 2010-2015, University of Washington and Battelle +// Memorial Institute. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above +// copyright notice, this list of conditions and the following +// disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials +// provided with the distribution. +// * Neither the name of the University of Washington, Battelle +// Memorial Institute, or the names of their contributors may be +// used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// UNIVERSITY OF WASHINGTON OR BATTELLE MEMORIAL INSTITUTE BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT +// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +// USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +// DAMAGE. +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +/// This mini-app demonstrates a breadth-first-search of the built-in +/// graph data structure. This implement's Graph500's BFS benchmark: +/// - Uses the Graph500 Specification Kronecker graph generator with +/// numVertices = 2^scale (--scale specified on command-line) +/// - Uses the builtin hybrid compressed-sparse-row graph format +/// - Computes the 'parent' tree given a root, and does this a number +/// of times (specified by --nbfs). +//////////////////////////////////////////////////////////////////////// + +#include "common.hpp" + +GRAPPA_DECLARE_METRIC(SummarizingMetric, bfs_mteps); +GRAPPA_DECLARE_METRIC(SummarizingMetric, total_time); +GRAPPA_DECLARE_METRIC(SimpleMetric, bfs_nedge); +GRAPPA_DECLARE_METRIC(SimpleMetric, graph_create_time); +GRAPPA_DECLARE_METRIC(SimpleMetric, verify_time); + +Grappa::GlobalCompletionEvent gce; + +void bfs(GlobalAddress g, int nbfs, TupleGraph tg) { + bool verified = false; + double t; + + auto frontier = GlobalVector::create(g->nv); + auto next = GlobalVector::create(g->nv); + + // do BFS from multiple different roots and average their times + for (int root_idx = 0; root_idx < nbfs; root_idx++) { + + // intialize parent to -1 + forall(g, [](G::Vertex& v){ v->init(); }); + + int64_t root = choose_root(g); + VLOG(1) << "root => " << root; + + std::function update = [&](G::Vertex& v){ + if (v->parent == -1) { + VLOG(1) << &v << ": updated\n"; + v->parent = 0;//FIXME: here parent must be used + forall(adj(g,v), [=](G::Edge& e) { + VLOG(1) << "call update\n"; + delegate::call(e.ga, update); + }); + } + }; + + // setup 'root' as the parent of itself + delegate::call(g->vs+root, update); + + gce.wait(); + + double this_total_time = walltime() - t; + LOG(INFO) << "(root=" << root << ", time=" << this_total_time << ")"; + total_time += this_total_time; + + /*if (!verified) { + // only verify the first one to save time + t = walltime(); + bfs_nedge = verify(tg, g, root); + verify_time = (walltime()-t); + LOG(INFO) << verify_time; + verified = true; + }*/ + + bfs_mteps += bfs_nedge / this_total_time / 1.0e6; + } +}