diff --git a/.travis.yml b/.travis.yml index c869cd1..005fcb6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,8 @@ os: - linux julia: - - 0.6 - + - 1.0 + - nightly notifications: email: false @@ -27,10 +27,10 @@ matrix: # uncomment the following lines to override the default test script script: - - julia -e 'Pkg.clone(pwd()); Pkg.build("Graph500"); Pkg.test("Graph500"; coverage=true)' + - julia -e 'using Pkg; Pkg.clone(pwd()); Pkg.build("Graph500"); Pkg.test("Graph500"; coverage=true)' after_success: # push coverage results to Coveralls # - julia -e 'cd(Pkg.dir("Graph500")); Pkg.add("Coverage"); using Coverage; Coveralls.submit(Coveralls.process_folder())' # push coverage results to Codecov - - julia -e 'cd(Pkg.dir("Graph500")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())' + - julia -e 'using Pkg; cd(Pkg.dir("Graph500")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())' diff --git a/REQUIRE b/REQUIRE index 6e29c66..c6207ad 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,4 +1,4 @@ -julia 0.6 -LightGraphs 0.10.0 -StatsBase 0.8.2 +julia 0.7 +LightGraphs 1.0 +StatsBase ProgressMeter diff --git a/src/Graph500.jl b/src/Graph500.jl index 80c6792..20ec653 100644 --- a/src/Graph500.jl +++ b/src/Graph500.jl @@ -1,4 +1,3 @@ -__precompile__(true) module Graph500 # Dependencies @@ -6,6 +5,11 @@ module Graph500 using StatsBase using ProgressMeter import LightGraphs.sample + using Distributed: @everywhere, @spawnat, @distributed, nprocs, myid + using Markdown: @doc_str + using Random + using Statistics: std + export # kronecker_generator diff --git a/src/driver.jl b/src/driver.jl index dfcfc6e..d4aa209 100644 --- a/src/driver.jl +++ b/src/driver.jl @@ -10,7 +10,7 @@ end ### required for initialising Dict{Graph{T},Graph500Results}() constructor Graph500Results() = Graph500Results(0, 0, 0.0, zeros(0), zeros(0)) -@doc_str """ +doc""" driver(scale, edgefactor; replicate, seed) Run Graph500 benchmark(http://graph500.org/?page_id=12) on a graph with `2^scale` vertices and @@ -29,9 +29,8 @@ function driver( ij = kronecker_generator(scale, edgefactor; replicate=replicate, seed=seed) # generate edge list println("Starting Kernel 1.") - tic() - g = kernel_1(ij) # kernel1 - kernel_1_time = toq() + + g, kernel_1_time = @timed kernel_1(ij) # kernel1 T = eltype(g) search_key = key_sampling(g) # sample min(nv(g),64) vertices for dfs @@ -41,9 +40,7 @@ function driver( ### kernel_2 @showprogress 1 "Kernel 2: " for (k, key) in enumerate(search_key) - tic() - parent_ = kernel_2(g, key) - kernel_2_time[k] = toq() + parent_, kernel_2_time[k] = @timed kernel_2(g, key) err = validate(g, parent_, ij, key) err <= 0 && error("BFS ", k, " from search key ", key, " failed to validate: ", err) diff --git a/src/kernel_1.jl b/src/kernel_1.jl index 994cf80..9e9eb4d 100644 --- a/src/kernel_1.jl +++ b/src/kernel_1.jl @@ -1,4 +1,4 @@ -@doc_str """ +""" get_next_type(T) Return a data with a Integer Datatype twice the size of `T` """ @@ -9,7 +9,7 @@ function get_next_type(T::DataType) (T== UInt64) && return (UInt128,64) end -@doc_str """ +""" kernel_1(ij) Create Graph from edge list `ij` based on kernel_1 benchmark(http://graph500.org/?page_id=12#sec-4) Return `LightGraphs.SimpleGraph` structure diff --git a/src/kernel_2.jl b/src/kernel_2.jl index a3cfbb8..e9fd55b 100644 --- a/src/kernel_2.jl +++ b/src/kernel_2.jl @@ -1,4 +1,4 @@ -@doc_str """ +doc""" key_sampling(g) Sample `min(nv(g), 64)` keys in `[1,nv(g)]` Returns a vector of randomly sampled keys @@ -25,7 +25,7 @@ function key_sampling( return keys end -@doc_str """ +doc""" kernel_2(g, s) Perform bfs on graph `g` starting at vertex `s` Returns vector containing parent info for each vertex diff --git a/src/kronecker_generator.jl b/src/kronecker_generator.jl index ae73431..e127c29 100644 --- a/src/kronecker_generator.jl +++ b/src/kronecker_generator.jl @@ -50,17 +50,26 @@ function kronecker_generator( T_two = T(2) # seeding the processors if replicate is true - if replicate - for i in 1:nprocs() - @spawnat i srand(seed[i]) - end - end + # if replicate + # for i in 1:nprocs() + # if replicate + # @spawnat i rng = MersenneTwister(seed[i]) + # else + # @spawnat i rng = MersenneTwister() + # end + # end + # end - temp = @parallel (+) for ib in 1:T(scale) + temp = @distributed (+) for ib in 1:T(scale) # Compare with probabilities and set bits of indices. + if replicate + rng = Random.seed!(seed[myid()]) + else + rng = Random.seed!() + end random_bits = falses(2, M) - random_bits[1, :] = rand(M) .> (ab) - random_bits[2, :] = rand(M) .> ( c_norm.*(random_bits[1, :]) + a_norm.*.!(random_bits[1, :]) ) + random_bits[1, :] = rand(rng, M) .> (ab) + random_bits[2, :] = rand(rng, M) .> ( c_norm.*(random_bits[1, :]) + a_norm.*.!(random_bits[1, :]) ) T_two^(ib-T_one).*random_bits end diff --git a/src/output.jl b/src/output.jl index 0bb2c57..33dac2e 100644 --- a/src/output.jl +++ b/src/output.jl @@ -1,56 +1,57 @@ -@doc_str """ +doc""" output(result, nv, ne) Print Graph500 Benchmark statistics(http://graph500.org/?page_id=12#sec-9_3) """ function output(result::Graph500Results,nv::Integer,ne::Integer) - print_with_color(:green, "\n", "Benchmark Info", "\n") - println("Scale : ", result.scale) - println("Number of vertices : ", nv) - println("Number of Edges : ", ne) - println("Number of Bfs : ", result.nbfs, "\n") - - # kernel 1 Construction time - print_with_color(:green, "\n", "Graph construction time", "\n") - println("Graph Construction Time : ", result.kernel_1_time, "\n") - - # bfs time statistics - bfs_time_stats = summarystats(result.kernel_2_time) - print_with_color(:green, "\n", "BFS time statistics", "\n") - println("BFS min time : ", bfs_time_stats.min) - println("BFS first quartile time : ", bfs_time_stats.q25) - println("BFS median time : ", bfs_time_stats.median) - println("BFS third quartile time : ", bfs_time_stats.q75) - println("BFS max time : ", bfs_time_stats.max) - println("BFS mean time : ", bfs_time_stats.mean) - println("BFS standard deviation time : ", std(result.kernel_2_time), "\n") - - # bfs statistics based on number of edges - bfs_edgetraversed_stats = summarystats(result.kernel_2_nedge) - print_with_color(:green, "\n", "Edges traversed per BFS statistics", "\n") - println("BFS min nedge : ", bfs_edgetraversed_stats.min) - println("BFS first quartile nedge : ", bfs_edgetraversed_stats.q25) - println("BFS median nedge : ", bfs_edgetraversed_stats.median) - println("BFS third quartile nedge : ", bfs_edgetraversed_stats.q75) - println("BFS max nedge : ", bfs_edgetraversed_stats.max) - println("BFS mean nedge : ", bfs_edgetraversed_stats.mean) - println("BFS standard deviation nedge : ", std(result.kernel_2_nedge), "\n") - - # statistics on traversed edges per second(teps) - bfs_teps = result.kernel_2_nedge ./ result.kernel_2_time - bfs_n = length(bfs_teps) - teps_stats = summarystats(bfs_teps) - print_with_color(:green, "\n", "Edges traversed per second statistics", "\n") - println("BFS min TEPS : ", teps_stats.min) - println("BFS first quartile TEPS : ", teps_stats.q25) - println("BFS median TEPS : ", teps_stats.median) - println("BFS third quartile TEPS : ", teps_stats.q75) - println("BFS max TEPS : ", teps_stats.max) - - # harmomnic mean of teps - k2tmp = 1.0 ./ bfs_teps - k2tmp = k2tmp - (1/harmmean(bfs_teps)) - harmonic_std = (sqrt(sum(k2tmp.^2)) / (bfs_n-1)) * harmmean(bfs_teps)^2 - println("BFS harmonic mean TEPS : ", harmmean(bfs_teps)) - println("BFS harmonic standard deviation TEPS : ", harmonic_std, "\n") - end + io = IOContext(stdout, :color=>true) + printstyled(io, "\n", "Benchmark Info", "\n", color=:green) + println("Scale : ", result.scale) + println("Number of vertices : ", nv) + println("Number of Edges : ", ne) + println("Number of Bfs : ", result.nbfs, "\n") + + # kernel 1 Construction time + printstyled(io, "\n", "Graph construction time", "\n", color=:green) + println("Graph Construction Time : ", result.kernel_1_time, "\n") + + # bfs time statistics + bfs_time_stats = summarystats(result.kernel_2_time) + printstyled(io, "\n", "BFS time statistics", "\n", color=:green) + println("BFS min time : ", bfs_time_stats.min) + println("BFS first quartile time : ", bfs_time_stats.q25) + println("BFS median time : ", bfs_time_stats.median) + println("BFS third quartile time : ", bfs_time_stats.q75) + println("BFS max time : ", bfs_time_stats.max) + println("BFS mean time : ", bfs_time_stats.mean) + println("BFS standard deviation time : ", std(result.kernel_2_time), "\n") + + # bfs statistics based on number of edges + bfs_edgetraversed_stats = summarystats(result.kernel_2_nedge) + printstyled(io, "\n", "Edges traversed per BFS statistics", "\n", color=:green) + println("BFS min nedge : ", bfs_edgetraversed_stats.min) + println("BFS first quartile nedge : ", bfs_edgetraversed_stats.q25) + println("BFS median nedge : ", bfs_edgetraversed_stats.median) + println("BFS third quartile nedge : ", bfs_edgetraversed_stats.q75) + println("BFS max nedge : ", bfs_edgetraversed_stats.max) + println("BFS mean nedge : ", bfs_edgetraversed_stats.mean) + println("BFS standard deviation nedge : ", std(result.kernel_2_nedge), "\n") + + # statistics on traversed edges per second(teps) + bfs_teps = result.kernel_2_nedge ./ result.kernel_2_time + bfs_n = length(bfs_teps) + teps_stats = summarystats(bfs_teps) + printstyled(io, "\n", "Edges traversed per second statistics", "\n", color=:green) + println("BFS min TEPS : ", teps_stats.min) + println("BFS first quartile TEPS : ", teps_stats.q25) + println("BFS median TEPS : ", teps_stats.median) + println("BFS third quartile TEPS : ", teps_stats.q75) + println("BFS max TEPS : ", teps_stats.max) + + # harmomnic mean of teps + k2tmp = 1.0 ./ bfs_teps + k2tmp = k2tmp .- (1/harmmean(bfs_teps)) + harmonic_std = (sqrt(sum(k2tmp.^2)) / (bfs_n-1)) * harmmean(bfs_teps)^2 + println("BFS harmonic mean TEPS : ", harmmean(bfs_teps)) + println("BFS harmonic standard deviation TEPS : ", harmonic_std, "\n") +end diff --git a/src/validation.jl b/src/validation.jl index fe5401a..0a674f7 100644 --- a/src/validation.jl +++ b/src/validation.jl @@ -1,4 +1,4 @@ -@doc_str """ +doc""" validate(g, parent_, ij, search_key) validate `parent_` info for bfs on graph `g` with key `search_key` based on Graph500 result validation(http://graph500.org/?page_id=12#sec-8) @@ -20,16 +20,16 @@ function validate( end N = nv(g) - slice = find(x->(x > zero(T)), parent_) + slice = findall(x->(x > zero(T)), parent_) #Compute levels and check for cycles. level_ = zeros(T, length(parent_)) - level_[slice] = 1 + level_[slice] .= 1 P = parent_[slice] mask = (P .!= search_key) k = 0 while any(mask) - level_[slice[mask]] = level_[slice[mask]] + 1 + level_[slice[mask]] .+= 1 P = parent_[P] mask = (P .!= search_key) k = k + 1 diff --git a/test/runtests.jl b/test/runtests.jl index 8b313b0..408ef4e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,5 +1,5 @@ using Graph500 -using Base.Test +using Test @testset begin include("kronecker_generator.jl")