elaine 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.ruby-version +1 -0
- data/Gemfile +3 -0
- data/README.md +90 -0
- data/Rakefile +3 -0
- data/autotest/discover.rb +1 -0
- data/elaine.gemspec +29 -0
- data/examples/.gitignore +1 -0
- data/examples/erdos-renyi-N_1000-E_0.2.egonets +1000 -0
- data/lib/elaine.rb +30 -0
- data/lib/elaine/coordinator.rb +33 -0
- data/lib/elaine/distributed.rb +11 -0
- data/lib/elaine/distributed/coordinator.rb +134 -0
- data/lib/elaine/distributed/post_office.rb +80 -0
- data/lib/elaine/distributed/vertex.rb +52 -0
- data/lib/elaine/distributed/worker.rb +85 -0
- data/lib/elaine/version.rb +3 -0
- data/lib/elaine/vertex.rb +41 -0
- data/lib/elaine/worker.rb +25 -0
- data/spec/coordinator_spec.rb +95 -0
- data/spec/distributed_coordinator_spec.rb +143 -0
- data/spec/distributed_helper.rb +196 -0
- data/spec/distributed_page_rank_vertex.rb +23 -0
- data/spec/distributed_triad_census_vertex.rb +41 -0
- data/spec/helper.rb +10 -0
- data/spec/test_add_vertex.rb +7 -0
- data/spec/test_coordinator_node.rb +12 -0
- data/spec/test_worker_node1.rb +12 -0
- data/spec/test_worker_node2.rb +12 -0
- data/spec/vertex_spec.rb +56 -0
- data/spec/worker_spec.rb +61 -0
- metadata +173 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
require 'elaine/distributed'
|
3
|
+
class DistributedPageRankVertex < Elaine::Distributed::Vertex
|
4
|
+
def compute
|
5
|
+
# puts "Working on supserstep: #{superstep}"
|
6
|
+
if superstep >= 1
|
7
|
+
# sum = messages.inject(0) {|total,msg| total += msg; total }
|
8
|
+
# sum = messages.reduce(0, :+)
|
9
|
+
sum = messages.reduce(0) do |total, msg|
|
10
|
+
raise "Got an out-of-step message! current superstep: #{superstep}, message from superstep: #{msg[:superstep]}" if msg[:superstep] != (superstep - 1)
|
11
|
+
total += msg[:value]
|
12
|
+
|
13
|
+
end
|
14
|
+
@value = (0.15 / 3) + 0.85 * sum
|
15
|
+
end
|
16
|
+
|
17
|
+
if superstep < 30
|
18
|
+
deliver_to_all_neighbors({value: @value / neighbors.size, superstep: superstep})
|
19
|
+
else
|
20
|
+
halt
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
require 'elaine/distributed'
|
3
|
+
class DistributedTriadCensusVertex < Elaine::Distributed::Vertex
|
4
|
+
def compute
|
5
|
+
# puts "Working on supserstep: #{superstep}"
|
6
|
+
if superstep == 1
|
7
|
+
deliver_to_all_neighbors({source: id; neighborhood: @outedges})
|
8
|
+
elsif superstep == 2
|
9
|
+
# sum = messages.inject(0) {|total,msg| total += msg; total }
|
10
|
+
# sum = messages.reduce(0, :+)
|
11
|
+
@value = {type2: 0, type3: 0 }
|
12
|
+
|
13
|
+
u = id.to_s.plit("_")[1].to_i
|
14
|
+
messages.each(0) do |msg|
|
15
|
+
# raise "Got an out-of-step message! current superstep: #{superstep}, message from superstep: #{msg[:superstep]}" if msg[:superstep] != (superstep - 1)
|
16
|
+
v = msg[:source].to_s.split("_")[1].to_i
|
17
|
+
if u < v
|
18
|
+
|
19
|
+
msg[:neighborhood].each do |node_w|
|
20
|
+
w = node_w.to_s.split("_")[1].to_i
|
21
|
+
if v < w
|
22
|
+
num_edges = 2
|
23
|
+
if @outedges.include? node_w
|
24
|
+
num_edges += 1
|
25
|
+
end
|
26
|
+
|
27
|
+
@value[:type2] += 1 if num_edges == 2
|
28
|
+
@value[:type3] += 1 if num_edges == 3
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
else
|
36
|
+
vote_to_stop
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
data/spec/helper.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'elaine'
|
2
|
+
require 'elaine/distributed'
|
3
|
+
require 'dcell'
|
4
|
+
# require 'test_add_vertex'
|
5
|
+
|
6
|
+
load File.expand_path("../test_add_vertex.rb", __FILE__)
|
7
|
+
load File.expand_path("../distributed_page_rank_vertex.rb", __FILE__)
|
8
|
+
|
9
|
+
DCell.start id: "test.elaine.coordinator", addr: "tcp://127.0.0.1:8090"
|
10
|
+
|
11
|
+
Elaine::Distributed::Coordinator.supervise_as :coordinator
|
12
|
+
sleep
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'elaine'
|
2
|
+
require 'elaine/distributed'
|
3
|
+
require 'dcell'
|
4
|
+
|
5
|
+
load File.expand_path("../test_add_vertex.rb", __FILE__)
|
6
|
+
load File.expand_path("../distributed_page_rank_vertex.rb", __FILE__)
|
7
|
+
|
8
|
+
DCell.start id: "test.elaine.worker1", addr: "tcp://127.0.0.1:8091"
|
9
|
+
|
10
|
+
Elaine::Distributed::Worker.supervise_as :worker, coordinator_node: "test.elaine.coordinator"
|
11
|
+
Elaine::Distributed::PostOffice.supervise_as :postoffice
|
12
|
+
sleep
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'elaine'
|
2
|
+
require 'elaine/distributed'
|
3
|
+
require 'dcell'
|
4
|
+
|
5
|
+
load File.expand_path("../test_add_vertex.rb", __FILE__)
|
6
|
+
load File.expand_path("../distributed_page_rank_vertex.rb", __FILE__)
|
7
|
+
|
8
|
+
DCell.start id: "test.elaine.worker2", addr: "tcp://127.0.0.1:8092"
|
9
|
+
|
10
|
+
Elaine::Distributed::Worker.supervise_as :worker, coordinator_node: "test.elaine.coordinator"
|
11
|
+
Elaine::Distributed::PostOffice.supervise_as :postoffice
|
12
|
+
sleep
|
data/spec/vertex_spec.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Vertex do
|
4
|
+
it 'should create a vertex with id, value, and edges' do
|
5
|
+
lambda { Vertex.new(:a, 10, :b) }.should_not raise_error
|
6
|
+
lambda { Vertex.new(:a, 10, :b, :c) }.should_not raise_error
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:v) { Vertex.new(:a, 10, :b, :c) }
|
10
|
+
|
11
|
+
it 'should report new vertex as active' do
|
12
|
+
v.active?.should be_true
|
13
|
+
|
14
|
+
v.halt
|
15
|
+
v.active?.should be_false
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should contain a modifiable value' do
|
19
|
+
v.value = 20
|
20
|
+
v.value.should == 20
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should keep track of the current superstep' do
|
24
|
+
v.superstep.should == 0
|
25
|
+
v.step
|
26
|
+
v.superstep.should == 1
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should allow iterating over out-edges' do
|
30
|
+
v.edges.size.should == 2
|
31
|
+
v.edges.each {|e| [:b, :c].should include e }
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should allow arbitrary type for edge' do
|
35
|
+
lambda do
|
36
|
+
Vertex.new(:a, 10, {id: 1, weight:10}, {id: 2, weight:20})
|
37
|
+
end.should_not raise_error
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should allow a user defined compute' do
|
41
|
+
class V < Vertex
|
42
|
+
def compute; @value = 20; end
|
43
|
+
end
|
44
|
+
|
45
|
+
v = V.new(:a, 10)
|
46
|
+
v.compute
|
47
|
+
v.value.should == 20
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should have an inbox for incoming messages' do
|
51
|
+
v.messages.size.should == 0
|
52
|
+
v.messages = [:a, :b]
|
53
|
+
v.messages.size.should == 2
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
data/spec/worker_spec.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Worker do
|
4
|
+
|
5
|
+
let(:graph) do
|
6
|
+
[
|
7
|
+
AddVertex.new(:igvita, 1, :wikipedia),
|
8
|
+
AddVertex.new(:wikipedia, 2, :google),
|
9
|
+
AddVertex.new(:google, 1, :wikipedia)
|
10
|
+
]
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:worker) do
|
14
|
+
Worker.new(graph)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should accept non-zero number of nodes' do
|
18
|
+
lambda { Worker.new([]) }.should raise_error
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should partition graphs with variable worker sizes' do
|
22
|
+
graph = [
|
23
|
+
Vertex.new(:igvita, 1, :wikipedia),
|
24
|
+
Vertex.new(:wikipedia, 2, :google),
|
25
|
+
Vertex.new(:google, 1, :wikipedia)
|
26
|
+
]
|
27
|
+
|
28
|
+
c = Coordinator.new(graph)
|
29
|
+
c.workers.size.should == 1
|
30
|
+
|
31
|
+
c = Coordinator.new(graph, partitions: 2)
|
32
|
+
c.workers.size.should == 2
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should execute an async superstep' do
|
36
|
+
# TODO: simulate async message delivery to worker by returning
|
37
|
+
# a thread per message
|
38
|
+
worker.superstep.should be_an_instance_of Thread
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should perform single iteration on the graph' do
|
42
|
+
# TODO: reuse a threadpool within worker for each partition
|
43
|
+
worker.superstep.join
|
44
|
+
worker.vertices.first.value.should == 2
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should return the number of active vertices for next superstep' do
|
48
|
+
worker.superstep.join
|
49
|
+
worker.active.should > 0
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should deliver messages to vertices at beginning of each superstep' do
|
53
|
+
PostOffice.instance.deliver(:igvita, 'hello')
|
54
|
+
worker.superstep.join
|
55
|
+
|
56
|
+
ig = worker.vertices.find {|v| v.id == :igvita }
|
57
|
+
ig.messages.size.should == 1
|
58
|
+
ig.messages.first.should == 'hello'
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
metadata
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: elaine
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeremy Blackburn
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-11-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: celluloid-io
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: dcell
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: thor
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: activesupport
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Distribtuted implementation of Google's Pregel framework for large-scale
|
98
|
+
graph processing. Forked from http://github.com/igrigorik/pregel
|
99
|
+
email:
|
100
|
+
- jeremy.blackburn@gmail.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- .gitignore
|
106
|
+
- .ruby-version
|
107
|
+
- Gemfile
|
108
|
+
- README.md
|
109
|
+
- Rakefile
|
110
|
+
- autotest/discover.rb
|
111
|
+
- elaine.gemspec
|
112
|
+
- examples/.gitignore
|
113
|
+
- examples/erdos-renyi-N_1000-E_0.2.egonets
|
114
|
+
- lib/elaine.rb
|
115
|
+
- lib/elaine/coordinator.rb
|
116
|
+
- lib/elaine/distributed.rb
|
117
|
+
- lib/elaine/distributed/coordinator.rb
|
118
|
+
- lib/elaine/distributed/post_office.rb
|
119
|
+
- lib/elaine/distributed/vertex.rb
|
120
|
+
- lib/elaine/distributed/worker.rb
|
121
|
+
- lib/elaine/version.rb
|
122
|
+
- lib/elaine/vertex.rb
|
123
|
+
- lib/elaine/worker.rb
|
124
|
+
- spec/coordinator_spec.rb
|
125
|
+
- spec/distributed_coordinator_spec.rb
|
126
|
+
- spec/distributed_helper.rb
|
127
|
+
- spec/distributed_page_rank_vertex.rb
|
128
|
+
- spec/distributed_triad_census_vertex.rb
|
129
|
+
- spec/helper.rb
|
130
|
+
- spec/test_add_vertex.rb
|
131
|
+
- spec/test_coordinator_node.rb
|
132
|
+
- spec/test_worker_node1.rb
|
133
|
+
- spec/test_worker_node2.rb
|
134
|
+
- spec/vertex_spec.rb
|
135
|
+
- spec/worker_spec.rb
|
136
|
+
homepage: http://bitbucket.org/worst/elaine
|
137
|
+
licenses: []
|
138
|
+
metadata: {}
|
139
|
+
post_install_message:
|
140
|
+
rdoc_options: []
|
141
|
+
require_paths:
|
142
|
+
- lib
|
143
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
+
requirements:
|
145
|
+
- - '>='
|
146
|
+
- !ruby/object:Gem::Version
|
147
|
+
version: '0'
|
148
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
requirements: []
|
154
|
+
rubyforge_project: elaine
|
155
|
+
rubygems_version: 2.0.6
|
156
|
+
signing_key:
|
157
|
+
specification_version: 4
|
158
|
+
summary: Distribtuted implementation of Google's Pregel framework for large-scale
|
159
|
+
graph processing. Forked from http://github.com/igrigorik/pregel
|
160
|
+
test_files:
|
161
|
+
- spec/coordinator_spec.rb
|
162
|
+
- spec/distributed_coordinator_spec.rb
|
163
|
+
- spec/distributed_helper.rb
|
164
|
+
- spec/distributed_page_rank_vertex.rb
|
165
|
+
- spec/distributed_triad_census_vertex.rb
|
166
|
+
- spec/helper.rb
|
167
|
+
- spec/test_add_vertex.rb
|
168
|
+
- spec/test_coordinator_node.rb
|
169
|
+
- spec/test_worker_node1.rb
|
170
|
+
- spec/test_worker_node2.rb
|
171
|
+
- spec/vertex_spec.rb
|
172
|
+
- spec/worker_spec.rb
|
173
|
+
has_rdoc:
|