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 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