comp_tree 0.7.2 → 0.7.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.
- data/CHANGES.rdoc +4 -0
- data/README.rdoc +4 -3
- data/Rakefile +1 -1
- data/devel/jumpstart.rb +39 -25
- data/install.rb +1 -1
- data/lib/comp_tree/algorithm.rb +35 -32
- data/lib/comp_tree/driver.rb +2 -4
- data/lib/comp_tree/error.rb +0 -4
- data/lib/comp_tree/node.rb +2 -2
- data/lib/comp_tree/queue.rb +1 -0
- data/lib/comp_tree/queue_new.rb +33 -0
- data/lib/comp_tree/queue_old.rb +34 -0
- data/lib/comp_tree.rb +2 -2
- data/test/common.rb +1 -1
- data/test/test_basic.rb +1 -1
- data/test/test_circular.rb +1 -1
- data/test/test_drain.rb +1 -1
- data/test/test_exception.rb +1 -1
- data/test/test_flood.rb +1 -1
- data/test/test_grind.rb +7 -5
- data/test/test_sequential.rb +1 -1
- metadata +8 -5
data/CHANGES.rdoc
CHANGED
data/README.rdoc
CHANGED
@@ -5,7 +5,8 @@
|
|
5
5
|
|
6
6
|
== Summary
|
7
7
|
|
8
|
-
Automatic parallelism and lazy evaluation
|
8
|
+
Automatic parallelism and lazy evaluation via pure functional
|
9
|
+
programming.
|
9
10
|
|
10
11
|
== Synopsis
|
11
12
|
|
@@ -52,7 +53,7 @@ Or for the (non-gem) .tgz package,
|
|
52
53
|
|
53
54
|
== Description
|
54
55
|
|
55
|
-
|
56
|
+
CompTree is a framework for parallelizing interrelated computations.
|
56
57
|
|
57
58
|
The user should have a basic understanding of <em>functional
|
58
59
|
programming</em> (see for example
|
@@ -103,7 +104,7 @@ depends on that state</em>. This is the principle under which
|
|
103
104
|
|
104
105
|
== License
|
105
106
|
|
106
|
-
Copyright (c) 2008 James M. Lawrence. All rights reserved.
|
107
|
+
Copyright (c) 2008, 2009 James M. Lawrence. All rights reserved.
|
107
108
|
|
108
109
|
Permission is hereby granted, free of charge, to any person
|
109
110
|
obtaining a copy of this software and associated documentation files
|
data/Rakefile
CHANGED
data/devel/jumpstart.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
$LOAD_PATH.unshift File.dirname(__FILE__) +
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require 'ostruct'
|
@@ -10,9 +10,9 @@ require 'rake/clean'
|
|
10
10
|
|
11
11
|
require 'rdoc/rdoc'
|
12
12
|
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
13
|
+
require 'jumpstart/ruby'
|
14
|
+
require 'jumpstart/lazy_attribute'
|
15
|
+
require 'jumpstart/simple_installer'
|
16
16
|
|
17
17
|
class Jumpstart
|
18
18
|
include LazyAttribute
|
@@ -112,7 +112,19 @@ class Jumpstart
|
|
112
112
|
end
|
113
113
|
|
114
114
|
attribute :files do
|
115
|
-
|
115
|
+
if File.exist?(manifest = "Manifest.txt")
|
116
|
+
File.read(manifest).split("\n")
|
117
|
+
elsif File.directory? ".git"
|
118
|
+
`git ls-files`.split("\n")
|
119
|
+
elsif File.directory? ".svn"
|
120
|
+
`svn status --verbose`.split("\n").map { |t|
|
121
|
+
t.split[3]
|
122
|
+
}.select { |t|
|
123
|
+
t and File.file?(t)
|
124
|
+
}
|
125
|
+
else
|
126
|
+
[]
|
127
|
+
end
|
116
128
|
end
|
117
129
|
|
118
130
|
attribute :rdoc_files do
|
@@ -302,7 +314,7 @@ class Jumpstart
|
|
302
314
|
run_ruby_on_each(*spec_files)
|
303
315
|
end
|
304
316
|
|
305
|
-
task :prerelease => :spec_deps
|
317
|
+
task :prerelease => [:spec, :spec_deps]
|
306
318
|
task :default => :spec
|
307
319
|
|
308
320
|
CLEAN.include spec_output
|
@@ -337,7 +349,7 @@ class Jumpstart
|
|
337
349
|
run_ruby_on_each(*test_files)
|
338
350
|
end
|
339
351
|
|
340
|
-
task :prerelease => :test_deps
|
352
|
+
task :prerelease => [:test, :test_deps]
|
341
353
|
task :default => :test
|
342
354
|
|
343
355
|
CLEAN.include rcov_dir
|
@@ -417,7 +429,7 @@ class Jumpstart
|
|
417
429
|
def debug_info(enable)
|
418
430
|
Find.find("lib", "test") { |path|
|
419
431
|
if path =~ %r!\.rb\Z!
|
420
|
-
replace_file(path) { |contents|
|
432
|
+
Jumpstart.replace_file(path) { |contents|
|
421
433
|
result = comment_regions(!enable, contents, "debug")
|
422
434
|
comment_lines(!enable, result, "trace")
|
423
435
|
}
|
@@ -539,17 +551,6 @@ class Jumpstart
|
|
539
551
|
sh(*([browser].flatten + files))
|
540
552
|
end
|
541
553
|
|
542
|
-
def replace_file(file)
|
543
|
-
old_contents = File.read(file)
|
544
|
-
yield(old_contents).tap { |new_contents|
|
545
|
-
if old_contents != new_contents
|
546
|
-
File.open(file, "wb") { |output|
|
547
|
-
output.print(new_contents)
|
548
|
-
}
|
549
|
-
end
|
550
|
-
}
|
551
|
-
end
|
552
|
-
|
553
554
|
def write_file(file)
|
554
555
|
yield.tap { |contents|
|
555
556
|
File.open(file, "wb") { |out|
|
@@ -568,12 +569,25 @@ class Jumpstart
|
|
568
569
|
str.split('_').map { |t| t.capitalize }.join
|
569
570
|
end
|
570
571
|
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
572
|
+
class << self
|
573
|
+
def replace_file(file)
|
574
|
+
old_contents = File.read(file)
|
575
|
+
yield(old_contents).tap { |new_contents|
|
576
|
+
if old_contents != new_contents
|
577
|
+
File.open(file, "wb") { |output|
|
578
|
+
output.print(new_contents)
|
579
|
+
}
|
580
|
+
end
|
581
|
+
}
|
582
|
+
end
|
583
|
+
end
|
584
|
+
end
|
585
|
+
|
586
|
+
unless respond_to? :tap
|
587
|
+
class Object
|
588
|
+
def tap
|
589
|
+
yield self
|
590
|
+
self
|
577
591
|
end
|
578
592
|
end
|
579
593
|
end
|
data/install.rb
CHANGED
data/lib/comp_tree/algorithm.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
|
2
|
+
require 'comp_tree/queue'
|
3
|
+
|
2
4
|
module CompTree
|
3
5
|
module Algorithm
|
4
6
|
module_function
|
@@ -6,52 +8,53 @@ module CompTree
|
|
6
8
|
def compute_parallel(root, num_threads)
|
7
9
|
to_workers = Queue.new
|
8
10
|
from_workers = Queue.new
|
9
|
-
|
10
|
-
node_to_worker = nil
|
11
|
-
node_from_worker = nil
|
12
|
-
|
13
|
-
num_working = 0
|
14
|
-
finished = nil
|
11
|
+
final_node = nil
|
15
12
|
|
16
13
|
workers = (1..num_threads).map {
|
17
14
|
Thread.new {
|
18
|
-
until (node = to_workers.pop) ==
|
15
|
+
until (node = to_workers.pop) == nil
|
19
16
|
node.compute
|
20
17
|
from_workers.push node
|
21
18
|
end
|
22
19
|
}
|
23
20
|
}
|
24
21
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
22
|
+
Thread.new {
|
23
|
+
node_to_worker = nil
|
24
|
+
node_from_worker = nil
|
25
|
+
num_working = 0
|
26
|
+
while true
|
27
|
+
if num_working == num_threads or
|
28
|
+
not (node_to_worker = find_node(root))
|
29
|
+
#
|
30
|
+
# maxed out or no nodes available -- wait for results
|
31
|
+
#
|
32
|
+
node_from_worker = from_workers.pop
|
33
|
+
node_from_worker.unlock
|
34
|
+
num_working -= 1
|
35
|
+
if node_from_worker == root or
|
36
|
+
node_from_worker.computed.is_a? Exception
|
37
|
+
final_node = node_from_worker
|
38
|
+
break
|
39
|
+
end
|
40
|
+
elsif node_to_worker
|
41
|
+
#
|
42
|
+
# found a node
|
43
|
+
#
|
44
|
+
to_workers.push node_to_worker
|
45
|
+
num_working += 1
|
46
|
+
node_to_worker = nil
|
37
47
|
end
|
38
|
-
elsif node_to_worker
|
39
|
-
#
|
40
|
-
# found a node
|
41
|
-
#
|
42
|
-
to_workers.push node_to_worker
|
43
|
-
num_working += 1
|
44
|
-
node_to_worker = nil
|
45
48
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
+
num_threads.times { to_workers.push nil }
|
50
|
+
}.join
|
51
|
+
|
49
52
|
workers.each { |t| t.join }
|
50
53
|
|
51
|
-
if
|
52
|
-
raise
|
54
|
+
if final_node.computed.is_a? Exception
|
55
|
+
raise final_node.computed
|
53
56
|
else
|
54
|
-
|
57
|
+
final_node.result
|
55
58
|
end
|
56
59
|
end
|
57
60
|
|
data/lib/comp_tree/driver.rb
CHANGED
@@ -3,8 +3,6 @@ require 'comp_tree/algorithm'
|
|
3
3
|
require 'comp_tree/node'
|
4
4
|
require 'comp_tree/error'
|
5
5
|
|
6
|
-
require 'thread'
|
7
|
-
|
8
6
|
module CompTree
|
9
7
|
#
|
10
8
|
# Driver is the main interface to the computation tree. It is
|
@@ -14,7 +12,7 @@ module CompTree
|
|
14
12
|
include Algorithm
|
15
13
|
|
16
14
|
#
|
17
|
-
# See CompTree.build
|
15
|
+
# See CompTree.build
|
18
16
|
#
|
19
17
|
def initialize(opts = nil) #:nodoc:
|
20
18
|
@node_class =
|
@@ -34,7 +32,7 @@ module CompTree
|
|
34
32
|
#
|
35
33
|
# _name_ -- unique node identifier (for example a symbol).
|
36
34
|
#
|
37
|
-
# _child_names_ -- unique node identifiers
|
35
|
+
# _child_names_ -- unique node identifiers of children.
|
38
36
|
#
|
39
37
|
# Define a computation node.
|
40
38
|
#
|
data/lib/comp_tree/error.rb
CHANGED
data/lib/comp_tree/node.rb
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
require "comp_tree/queue_" + (RUBY_VERSION < "1.9.0" ? "old" : "new")
|
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
module CompTree
|
3
|
+
#
|
4
|
+
# minimal version of standard Queue
|
5
|
+
#
|
6
|
+
class Queue
|
7
|
+
def initialize
|
8
|
+
@queue = []
|
9
|
+
@waiting = []
|
10
|
+
@mutex = Mutex.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def push(object)
|
14
|
+
@mutex.synchronize {
|
15
|
+
@queue.push object
|
16
|
+
thread = @waiting.shift and thread.wakeup
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def pop
|
21
|
+
@mutex.synchronize {
|
22
|
+
while true
|
23
|
+
if @queue.empty?
|
24
|
+
@waiting.push Thread.current
|
25
|
+
@mutex.sleep
|
26
|
+
else
|
27
|
+
return @queue.shift
|
28
|
+
end
|
29
|
+
end
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
require 'thread'
|
3
|
+
|
4
|
+
module CompTree
|
5
|
+
#
|
6
|
+
# minimal version of standard Queue
|
7
|
+
#
|
8
|
+
class Queue
|
9
|
+
def initialize
|
10
|
+
@queue = []
|
11
|
+
@waiting = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def push(object)
|
15
|
+
Thread.critical = true
|
16
|
+
@queue.push object
|
17
|
+
begin
|
18
|
+
thread = @waiting.shift and thread.wakeup
|
19
|
+
ensure
|
20
|
+
Thread.critical = false
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def pop
|
25
|
+
while (Thread.critical = true; @queue.empty?)
|
26
|
+
@waiting.push Thread.current
|
27
|
+
Thread.stop
|
28
|
+
end
|
29
|
+
@queue.shift
|
30
|
+
ensure
|
31
|
+
Thread.critical = false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/comp_tree.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2008 James M. Lawrence. All rights reserved.
|
2
|
+
# Copyright (c) 2008, 2009 James M. Lawrence. All rights reserved.
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -28,7 +28,7 @@ require 'comp_tree/driver'
|
|
28
28
|
# See README.rdoc.
|
29
29
|
#
|
30
30
|
module CompTree
|
31
|
-
VERSION = "0.7.
|
31
|
+
VERSION = "0.7.3"
|
32
32
|
|
33
33
|
class << self
|
34
34
|
#
|
data/test/common.rb
CHANGED
data/test/test_basic.rb
CHANGED
data/test/test_circular.rb
CHANGED
data/test/test_drain.rb
CHANGED
data/test/test_exception.rb
CHANGED
data/test/test_flood.rb
CHANGED
data/test/test_grind.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
-
require File.dirname(__FILE__) +
|
1
|
+
require File.dirname(__FILE__) + '/common'
|
2
2
|
|
3
3
|
class TestGrind < Test::Unit::TestCase
|
4
4
|
include TestCommon
|
5
5
|
|
6
6
|
GENERATOR_DATA = {
|
7
|
-
:level_range => 1..
|
8
|
-
:children_range => 1..
|
7
|
+
:level_range => 1..5,
|
8
|
+
:children_range => 1..5,
|
9
9
|
:thread_range => 1..10,
|
10
10
|
:drain_iterations => 30,
|
11
11
|
}
|
12
12
|
|
13
13
|
ROOT = 'a'
|
14
|
+
RETURN_FLAG = rand
|
14
15
|
|
15
16
|
def test_grind
|
16
17
|
run_generated_tree(GENERATOR_DATA)
|
@@ -28,6 +29,7 @@ class TestGrind < Test::Unit::TestCase
|
|
28
29
|
drain = lambda { |*args|
|
29
30
|
drain_iterations.times {
|
30
31
|
}
|
32
|
+
RETURN_FLAG
|
31
33
|
}
|
32
34
|
build_tree = lambda { |parent, children, level|
|
33
35
|
#trace "building #{parent} --> #{children.join(' ')}"
|
@@ -44,7 +46,7 @@ class TestGrind < Test::Unit::TestCase
|
|
44
46
|
}
|
45
47
|
end
|
46
48
|
}
|
47
|
-
build_tree.call(ROOT, pick_names.call,
|
49
|
+
build_tree.call(ROOT, pick_names.call, 0)
|
48
50
|
driver
|
49
51
|
}
|
50
52
|
end
|
@@ -69,7 +71,7 @@ class TestGrind < Test::Unit::TestCase
|
|
69
71
|
#}
|
70
72
|
result = driver.compute(ROOT, threads)
|
71
73
|
#bench_output bench
|
72
|
-
assert_equal(result,
|
74
|
+
assert_equal(result, RETURN_FLAG)
|
73
75
|
}
|
74
76
|
}
|
75
77
|
}
|
data/test/test_sequential.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: comp_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- James M. Lawrence
|
@@ -9,11 +9,11 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-04-
|
12
|
+
date: 2009-04-25 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description:
|
16
|
+
description: CompTree is a framework for parallelizing interrelated computations.
|
17
17
|
email:
|
18
18
|
- quixoticsycophant@gmail.com
|
19
19
|
executables: []
|
@@ -36,6 +36,9 @@ files:
|
|
36
36
|
- lib/comp_tree/driver.rb
|
37
37
|
- lib/comp_tree/error.rb
|
38
38
|
- lib/comp_tree/node.rb
|
39
|
+
- lib/comp_tree/queue.rb
|
40
|
+
- lib/comp_tree/queue_new.rb
|
41
|
+
- lib/comp_tree/queue_old.rb
|
39
42
|
- test/common.rb
|
40
43
|
- test/test_basic.rb
|
41
44
|
- test/test_circular.rb
|
@@ -51,7 +54,7 @@ rdoc_options:
|
|
51
54
|
- --main
|
52
55
|
- README.rdoc
|
53
56
|
- --title
|
54
|
-
- "comp_tree: Automatic parallelism and lazy evaluation."
|
57
|
+
- "comp_tree: Automatic parallelism and lazy evaluation via pure functional programming."
|
55
58
|
- --exclude
|
56
59
|
- CHANGES.rdoc
|
57
60
|
- --exclude
|
@@ -104,6 +107,6 @@ rubyforge_project: comptree
|
|
104
107
|
rubygems_version: 1.3.1
|
105
108
|
signing_key:
|
106
109
|
specification_version: 2
|
107
|
-
summary: Automatic parallelism and lazy evaluation.
|
110
|
+
summary: Automatic parallelism and lazy evaluation via pure functional programming.
|
108
111
|
test_files: []
|
109
112
|
|