comp_tree 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES.rdoc CHANGED
@@ -1,6 +1,10 @@
1
1
 
2
2
  = CompTree ChangeLog
3
3
 
4
+ == Version 0.7.3
5
+
6
+ * replace standard Queue class
7
+
4
8
  == Version 0.7.2
5
9
 
6
10
  * check for number of threads < 1
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
- A computation tree for pure functional programming in Ruby.
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
@@ -1,4 +1,4 @@
1
- $LOAD_PATH.unshift "devel"
1
+ $LOAD_PATH.unshift 'devel'
2
2
 
3
3
  require 'jumpstart'
4
4
 
data/devel/jumpstart.rb CHANGED
@@ -1,4 +1,4 @@
1
- $LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
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 "jumpstart/ruby"
14
- require "jumpstart/lazy_attribute"
15
- require "jumpstart/simple_installer"
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
- `git ls-files`.split("\n")
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
- unless respond_to? :tap
572
- class Object
573
- def tap
574
- yield self
575
- self
576
- end
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
@@ -1,3 +1,3 @@
1
- $LOAD_PATH.unshift "rakelib"
1
+ $LOAD_PATH.unshift 'rakelib'
2
2
  require 'jumpstart/simple_installer'
3
3
  Jumpstart::SimpleInstaller.new.run
@@ -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) == :finished
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
- while true
26
- if num_working == num_threads or not (node_to_worker = find_node(root))
27
- #
28
- # max computations running or no nodes available -- wait for results
29
- #
30
- node_from_worker = from_workers.pop
31
- node_from_worker.unlock
32
- num_working -= 1
33
- if node_from_worker == root or
34
- node_from_worker.computed.is_a? Exception
35
- finished = node_from_worker
36
- break
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
- end
47
-
48
- num_threads.times { to_workers.push :finished }
49
+ num_threads.times { to_workers.push nil }
50
+ }.join
51
+
49
52
  workers.each { |t| t.join }
50
53
 
51
- if finished.computed.is_a? Exception
52
- raise finished.computed
54
+ if final_node.computed.is_a? Exception
55
+ raise final_node.computed
53
56
  else
54
- finished.result
57
+ final_node.result
55
58
  end
56
59
  end
57
60
 
@@ -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 for children.
35
+ # _child_names_ -- unique node identifiers of children.
38
36
  #
39
37
  # Define a computation node.
40
38
  #
@@ -13,8 +13,4 @@ module CompTree
13
13
 
14
14
  # Encountered a node without a function during a computation.
15
15
  class NoFunctionError < Error ; end
16
-
17
- #debug {
18
- # class AssertionFailedError < Error ; end
19
- #}
20
16
  end
@@ -105,8 +105,8 @@ module CompTree
105
105
  end
106
106
  @result = @function.call(*@children_results)
107
107
  @computed = true
108
- rescue Exception => e
109
- @computed = e
108
+ rescue Exception => exception
109
+ @computed = exception
110
110
  end
111
111
  @result
112
112
  end
@@ -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.2"
31
+ VERSION = "0.7.3"
32
32
 
33
33
  class << self
34
34
  #
data/test/common.rb CHANGED
@@ -1,4 +1,4 @@
1
- $LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
1
+ $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
2
2
 
3
3
  require 'test/unit'
4
4
  require 'comp_tree'
data/test/test_basic.rb CHANGED
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/common"
1
+ require File.dirname(__FILE__) + '/common'
2
2
 
3
3
  class TestBasic < Test::Unit::TestCase
4
4
  def test_define
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/common"
1
+ require File.dirname(__FILE__) + '/common'
2
2
 
3
3
  class TestCircular < Test::Unit::TestCase
4
4
  def test_circular
data/test/test_drain.rb CHANGED
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/common"
1
+ require File.dirname(__FILE__) + '/common'
2
2
 
3
3
  class TestDrain < Test::Unit::TestCase
4
4
  include TestCommon
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/common"
1
+ require File.dirname(__FILE__) + '/common'
2
2
 
3
3
  class TestException < Test::Unit::TestCase
4
4
  def test_exception
data/test/test_flood.rb CHANGED
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/common"
1
+ require File.dirname(__FILE__) + '/common'
2
2
 
3
3
  class TestFlood < Test::Unit::TestCase
4
4
  def test_thread_flood
data/test/test_grind.rb CHANGED
@@ -1,16 +1,17 @@
1
- require File.dirname(__FILE__) + "/common"
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..10,
8
- :children_range => 1..10,
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, drain_iterations)
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, args[:drain_iterations])
74
+ assert_equal(result, RETURN_FLAG)
73
75
  }
74
76
  }
75
77
  }
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + "/common"
1
+ require File.dirname(__FILE__) + '/common'
2
2
 
3
3
  class TestSequential < Test::Unit::TestCase
4
4
  def test_sequential
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.2
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-20 00:00:00 -04:00
12
+ date: 2009-04-25 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
16
- description: A computation tree for pure functional programming in Ruby.
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