# CompTree: Parallel Computation Tree

**URL:** <https://www.ruby-forum.com/t/comptree-parallel-computation-tree/148097>\
**Category:** Ruby\
**Created:** [September 9, 2008, 9:10am UTC](https://www.ruby-forum.com/t/comptree-parallel-computation-tree/148097 "2008-09-09T09:10:45Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [September 9, 2008, 9:10am UTC](https://www.ruby-forum.com/t/comptree-parallel-computation-tree/148097/1 "2008-09-09T09:10:45Z")

</div>

= CompTree: Parallel Computation Tree

== Synopsis

require ‘comp\_tree’

CompTree::Driver.new { |driver|

```
# Define a function named 'area' taking these three arguments.
driver.define_area(:width, :height, :offset) { |width, height,

```

offset|  
width\*height - offset  
}

```
# Define a function 'width' which takes a 'border' argument.
driver.define_width(:border) { |border|
  2 + border
}

# Ditto for 'height'.
driver.define_height(:border) { |border|
  3 + border
}

# Define a constant function 'border'.
driver.define_border {
  5
}

# Ditto for 'offset'.
driver.define_offset {
  7
}

# Compute the area using four parallel threads.
area = driver.compute(:area, :threads => 4)

# We've done this computation.
if area == (2 + 5)*(3 + 5) - 7
  puts "It worked!"
else
  puts "Send bug report to ..."
end

```

}

=== Alternative Forms for Function Definitions

This form evals a lambda, saving you the repeat parameter list:

driver.define\_area :width, :height, :offset, %{  
width\*height - offset  
}

driver.define\_width :border, %{  
2 + border  
}

Notice the ‘%’ before the brace. The lambda is created just once,  
during the time of definition.

Finally there is the raw form which uses no +eval+ or  
+method\_missing+ tricks:

driver.define(:area, :width, :height, :offset) { |width, height,  
offset|  
width\*height - offset  
}

driver.define(:width, :border) { |border|  
2 + border  
}

== Important Notes

The user should have a basic understanding of functional programming  
(see for example [Functional programming - Wikipedia](http://en.wikipedia.org/wiki/Functional_programming))  
and the meaning of side effects.

CompTree requires the user to adopt a functional style. Every  
function you define must explicitly depend on the data it uses.

# 

# BAD example: depending on state – offset not listed as a

parameter

# 

driver.define\_area(:width, :height) { |width, height|  
width\*height - offset  
}

Unless offset is really a constant, the result of  
driver.compute(:area, :num\_threads =\> n) is not well-defined for n\>1.

Just as depending on some changeable state is bad, it is likewise bad  
to affect a state (to produce a side effect).

# 

# BAD example: affecting state

# 

driver.define\_area(:width, :height, :offset) { |width, height,  
offset|  
ACCUMULATOR.add “more data”  
width\*height - offset  
}

Given a tree where nodes are modifying _ACCUMULATOR_, the end state of  
_ACCUMULATOR_ is not well-defined. Moreover if _ACCUMULATOR_ is not  
thread-safe, the result will be even worse.

Note however it is OK affect a state as long as no other function  
depends on that state. This is the principle under which +comp\_tree+  
parallelizes Rake tasks ([http://drake.rubyforge.org](http://drake.rubyforge.org)).

== Install

% gem install comp\_tree

Or for the regular (non-gem) .tgz package,

% ruby install.rb [–uninstall]

== Links

- Download: [http://rubyforge.org/frs/?group\_id=6917](http://rubyforge.org/frs/?group_id=6917)
- Rubyforge home: [http://rubyforge.org/projects/comptree](http://rubyforge.org/projects/comptree)
- Repository: [GitHub - quix/comp\_tree: A simple framework for automatic parallelism.](http://github.com/quix/comp_tree)

== Author

- James M. Lawrence [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
