snail-map-reduce 0.0.2 → 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.
@@ -0,0 +1,66 @@
1
+ require 'rubygems'
2
+ require 'statsample'
3
+ require './matrix_block_mixin'
4
+ require './map_reduce'
5
+ require 'benchmark'
6
+
7
+ class Matrix
8
+ def each_column
9
+ self.column_vectors.each {|column_vector| yield(column_vector)}
10
+ end
11
+ def each_row
12
+ self.row_vectors.each {|row_vector| yield(row_vector)}
13
+ end
14
+ end
15
+
16
+ def pair_up(key, value)
17
+ inputs = []
18
+ a = value[:a]
19
+ b = value[:b]
20
+
21
+ row = 0
22
+ a.each_column do |a_column|
23
+ column = 0
24
+ b.row_vectors[row].each do |e|
25
+ inputs << {:key => column.to_s, :value => {:scalar => e, :vector => a_column}}
26
+ column += 1
27
+ end
28
+ row += 1
29
+ end
30
+ inputs
31
+ end
32
+
33
+ def multiply(key, value)
34
+ [{ :key => key, :value => value[:vector].collect {|vc| vc * value[:scalar]}}]
35
+ end
36
+
37
+ def add_reduce(key, values)
38
+ empty = Array.new(values.first.size)
39
+ empty.fill(0)
40
+ v = values.inject(Vector.elements(empty)) {|sum, v| sum + v}
41
+ [{:key => 'X', :value => v}]
42
+ end
43
+
44
+ def append_reduce(key, values)
45
+ [{:key => 'result', :value => Matrix.columns(values)}]
46
+ end
47
+
48
+ def m(order)
49
+ Matrix.build(order, order) {|row, col| rand(20) }
50
+ end
51
+
52
+ order = 8
53
+ mappings = reductions = (Math.log2(order) - 1).to_i
54
+ m1 = m(order)
55
+ m2 = m(order)
56
+
57
+ operations = []
58
+ operations << Mapper.new {|k,v| pair_up(k,v)}
59
+ operations << Mapper.new {|k,v| multiply(k,v)}
60
+ operations << Reducer.new {|k,vs| add_reduce(k,vs)}
61
+ operations << Reducer.new {|k,vs| append_reduce(k,vs)}
62
+
63
+ result = MapReduceRunner.new(operations).run([{:key => "X", :value => {:a => m1, :b => m2}}])
64
+
65
+ puts m1*m2 == result[0][:value]
66
+
@@ -4,13 +4,13 @@ require './matrix_block_mixin'
4
4
  require './map_reduce'
5
5
  require 'benchmark'
6
6
 
7
- def setup(key, value)
7
+ def map(key, value)
8
8
  inputs = []
9
9
  a = value[:a]
10
10
  b = value[:b]
11
11
  if a.row_size == 2
12
12
  inputs << {:key=> key, :a => a, :b => b}
13
- return
13
+ return inputs
14
14
  end
15
15
  inputs << {:key => key + "00A", :value => {:a => a.block(0,0), :b => b.block(0,0)}}
16
16
  inputs << {:key => key + "00B", :value => {:a => a.block(0,1), :b => b.block(1,0)}}
@@ -45,40 +45,39 @@ def block_join_reduce(key, values)
45
45
  p01 = values[values.index {|v| v[:identity] == '01'}][:matrix]
46
46
  p10 = values[values.index {|v| v[:identity] == '10'}][:matrix]
47
47
  p11 = values[values.index {|v| v[:identity] == '11'}][:matrix]
48
- {:key => key[0..-2], :value => {:identity => key[-1], :matrix => Matrix.rows(join(p00, p01) + join(p10, p11))}}
48
+ [{:key => key[0..-2], :value => {:identity => key[-1], :matrix => Matrix.rows(join(p00, p01) + join(p10, p11))}}]
49
49
  end
50
50
 
51
51
  def block_matrix_sum(key, values)
52
52
  sum = Matrix.zero(values.first[:matrix].row_size)
53
53
  values.each {|m| sum += m[:matrix]}
54
- {:key => key[0..-3], :value => {:matrix => sum, :identity => key[-2..-1]}}
54
+ [{:key => key[0..-3], :value => {:matrix => sum, :identity => key[-2..-1]}}]
55
55
  end
56
56
 
57
57
  def primitive_map(key, value)
58
58
  [{:key => key[0..-2], :value => {:matrix => value[:a] * value[:b], :identity => key[0..-2]}}]
59
59
  end
60
60
 
61
- order = 64
61
+ order = 16
62
62
  mappings = reductions = (Math.log2(order) - 1).to_i
63
63
  m1 = m(order)
64
64
  m2 = m(order)
65
65
 
66
- mappers = []
66
+ operations = []
67
67
  mappings.times do
68
- mappers << ->(k,v) {setup(k,v)}
68
+ operations << Mapper.new {|k,v| map(k,v)}
69
69
  end
70
70
 
71
- mappers << ->(k,v) {primitive_map(k,v)}
72
- reducers = []
71
+ operations << Mapper.new {|k,v| primitive_map(k,v)}
73
72
 
74
73
  reductions.times do
75
- reducers << ->(k,v) {block_matrix_sum(k,v)}
76
- reducers << ->(k,v) {block_join_reduce(k,v)}
74
+ operations << Reducer.new {|k,v| block_matrix_sum(k,v)}
75
+ operations << Reducer.new {|k,v| block_join_reduce(k,v)}
77
76
  end
78
77
 
79
78
  result = []
80
79
  mr_time = Benchmark.measure do
81
- result = MapReduceRunner.new(mappers, reducers).run([{:key => "X", :value => {:a => m1, :b => m2}}])
80
+ result = MapReduceRunner.new(operations).run([{:key => "X", :value => {:a => m1, :b => m2}}])
82
81
  end
83
82
  plain_time = Benchmark.measure do
84
83
  m1*m2
data/map_reduce.rb CHANGED
@@ -11,38 +11,42 @@ class Partitioner
11
11
  end
12
12
 
13
13
  class Reducer
14
- def run(partitions)
14
+ def initialize(&block)
15
+ @function = block
16
+ end
17
+
18
+ def run(pairs)
19
+ partitions = Partitioner.new.run(pairs)
15
20
  space = []
16
21
  partitions.each_pair do |k,v|
17
- space << yield(k,v)
22
+ space += @function.call(k,v)
18
23
  end
19
24
  space
20
25
  end
21
26
  end
22
27
 
23
28
  class Mapper
29
+ def initialize(&block)
30
+ @function = block
31
+ end
32
+
24
33
  def run(pairs)
25
34
  mapped_pairs = []
26
35
  pairs.each do |pair|
27
- mapped_pairs += yield(pair[:key], pair[:value])
36
+ mapped_pairs += @function.call(pair[:key], pair[:value])
28
37
  end
29
38
  mapped_pairs
30
39
  end
31
40
  end
32
41
 
33
42
  class MapReduceRunner
34
- def initialize(mappers, reducers)
35
- @mappers = mappers
36
- @reducers = reducers
43
+ def initialize(operations)
44
+ @operations = operations
37
45
  end
38
46
 
39
47
  def run(pairs)
40
48
  results = []
41
- @mappers.each {|mapper| pairs = Mapper.new.run(pairs) {|k,v| mapper.call(k,v)}}
42
- @reducers.each do |reducer|
43
- partitions = Partitioner.new.run(pairs)
44
- pairs = Reducer.new.run(partitions) {|k,v| reducer.call(k,v)}
45
- end
49
+ @operations.each {|operation| pairs = operation.run(pairs)}
46
50
  pairs
47
51
  end
48
52
  end
data/snail.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  spec = Gem::Specification.new do |s|
2
2
  s.name = "snail-map-reduce"
3
- s.version = "0.0.2"
3
+ s.version = "0.0.3"
4
4
  s.author = "Avishek Sen Gupta"
5
5
  s.email = "avishek.sen.gupta@gmail.com"
6
6
  s.homepage = "http://avishek.net/blog"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: snail-map-reduce
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -19,6 +19,7 @@ extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
21
  - .gitignore
22
+ - MapReduceLinearMatrixProduct.rb
22
23
  - MapReduceMatrixProduct.rb
23
24
  - README
24
25
  - map_reduce.rb