Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/torch/threads-ffi.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornicholas-leonard <nick@nikopia.org>2015-01-09 19:43:12 +0300
committernicholas-leonard <nick@nikopia.org>2015-01-09 21:06:48 +0300
commit86b4ae0cee9654d2f48ffdc000e87fa31d958fde (patch)
tree66f75a565db57ba0f498f1dc33555ca585bb4bc2 /README.md
parenta3c358105350ace8bcc61e94c4bc028f3aaa3e02 (diff)
Example lua code + library documentation
Diffstat (limited to 'README.md')
-rw-r--r--README.md144
1 files changed, 107 insertions, 37 deletions
diff --git a/README.md b/README.md
index c7fc923..f9bdfb4 100644
--- a/README.md
+++ b/README.md
@@ -21,8 +21,9 @@ The magic of the *threads* package lies in the seven following points:
# Installation #
-At this time *threads* relies on two other packages: *torch* (for
-serialization) and *SDL2* for threads.
+At this time *threads* relies on two other packages:
+ * [Torch7](torch.ch) (for serialization) ; and
+ * [SDL2](https://github.com/torch/sdl2-ffi/blob/master/README.md) for threads.
One could certainly port easily this package to other threading API
(pthreads, Windows threads...), but as SDL2 is really easy to install, and
@@ -30,8 +31,8 @@ very portable, I believe this dependency should not be a problem. If there
are enough requests, I might propose alternatives to SDL2 threads.
Torch is used for full serialization. One could easily get inspired from
-Torch serialization system to adapt the package to its own needs. Soon
-(with torch9), Torch should be straighforward to install, so this
+Torch serialization system to adapt the package to its own needs.
+Torch should be straighforward to install, so this
dependency should be minor too.
At this time, if you have torch7 installed:
@@ -40,9 +41,9 @@ luarocks install https://raw.github.com/torch/sdl2-ffi/master/rocks/sdl2-scm-1.r
luarocks install https://raw.github.com/torch/threads-ffi/master/rocks/threads-scm-1.rockspec
```
-# Example Usage #
+# Examples #
-An example is better than convoluted explanations.
+A [simple example](example/simple.md) is better than convoluted explanations:
```lua
local Threads = require 'threads'
@@ -61,41 +62,44 @@ sdl.init(0)
-- the function takes several callbacks as input, which will be executed
-- sequentially on each newly created lua state
local threads = Threads(nthread,
- -- typically the first callback requires modules
- -- necessary to serialize other callbacks
- function()
- gsdl = require 'sdl2'
- end,
-
- -- other callbacks (one is enough in general!) prepare stuff
- -- you need to run your program
- function(idx)
- print('starting a new thread/state number:', idx)
- gmsg = msg -- we copy here an upvalue of the main thread
- end)
+ -- typically the first callback requires modules
+ -- necessary to serialize other callbacks
+ function()
+ gsdl = require 'sdl2'
+ end,
+
+ -- other callbacks (one is enough in general!) prepare stuff
+ -- you need to run your program
+ function(idx)
+ print('starting a new thread/state number:', idx)
+ gmsg = msg -- we copy here an upvalue of the main thread
+ end
+)
-- now add jobs
local jobdone = 0
for i=1,njob do
threads:addjob(
- -- the job callback
- function()
- local id = tonumber(gsdl.threadID())
- print(string.format('%s -- thread ID is %x', gmsg, id))
-
- -- return a value to the end callback
- return id
- end,
-
- -- the end callback
- -- ran in the main thread
- function(id)
- print(string.format("task %d finished (ran on thread ID %x)", i, id))
-
- -- note that we can manipulate upvalues of the main thread
- -- as this callback is ran in the main thread!
- jobdone = jobdone + 1
- end)
+ -- the job callback
+ function()
+ local id = tonumber(gsdl.threadID())
+ -- note that gmsg was intialized in last worker callback
+ print(string.format('%s -- thread ID is %x', gmsg, id))
+
+ -- return a value to the end callback
+ return id
+ end,
+
+ -- the end callback runs in the main thread.
+ -- takes output of the previous function as argument
+ function(id)
+ print(string.format("task %d finished (ran on thread ID %x)", i, id))
+
+ -- note that we can manipulate upvalues of the main thread
+ -- as this callback is ran in the main thread!
+ jobdone = jobdone + 1
+ end
+ )
end
-- wait for all jobs to finish
@@ -139,7 +143,73 @@ task 10 finished (ran on thread ID cec8000)
10 jobs done
```
-# Advanced Example #
+## Advanced Example ##
See a neural network [threaded training example](benchmark/README.md) for a
more advanced usage of `threads`.
+
+# Library #
+
+## Threads ##
+This class is used to manage a set of worker threads. The class is
+returned upon requiring the package:
+
+```lua
+Threads = require 'threads'
+```
+
+### Threads(N,[f1,f2,...]) ###
+Argument `N` of this constructor specifies the number of worker threads
+that will be spawned. The optional arguments `f1,f2,...` can be a list
+of functions to execute in each worker thread. To be clear, all of
+these functions will be executed in each thread. However, each optional
+function `f` takes an argument `threadIdx` which is a number between
+`1` and `N` identifying each thread. This could be used to make each
+thread have different behaviour.
+
+Example:
+```lua
+Threads(4,
+ function(threadIdx)
+ print("Initializing thread " .. threadIdx)
+ end
+)
+```
+
+### Threads:addjob(callback, [endcallback, ...]) ###
+This method is used to queue the execution of jobs in the worker threads.
+The `callback` is function that will be executed in each worker thread.
+It arguments are the optional `...`.
+The `endcallback` is a function that will be executed in the main thread
+(the one calling this method).
+
+Before being executed in the worker thread, the `callback` is serialized
+by the main thread and unserialized by the worker. The main thread can
+thus transfer data to the worker by using upvalues:
+```lua
+local upvalue = 10
+threads:addjob(
+ function()
+ workervalue = upvalue
+ return 1
+ end,
+ function(inc)
+ upvalue = upvalue + inc
+ end
+)
+```
+In the above example, each worker will have a global variable `workervalue`
+which will contain a copy of the main thread's `upvalue`. Note that
+if the main thread's upvalue were global, as opposed to `local`
+it would not be an upvalue, and therefore would not be serialized along
+with the `callback`. In which case, `workervalue` would be `nil`.
+
+In the same example, the worker also communicates a value to the main thread.
+This is accomplished by having the `callback` return one ore many values which
+will be serialized and unserialized as arguments to the `endcallback` function.
+In this case a value of `1` is received by the main thread as argument `inc` to the
+`endcallback` function, which then uses it to increment `upvalue`. This
+demonstrates how communication between threads is easily achieved using
+the `addjob` method.
+
+### Threads:dojob(