[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

details Parallel Processing VIGRA

Classes

class  ParallelOptions
 Option base class for parallel algorithms. More...
 
class  ThreadPool
 Thread pool class to manage a set of parallel workers. More...
 

Functions

template<class F >
threading::future< void > enqueue (F &&f)
 
template<class F >
auto enqueueReturning (F &&f) -> threading::future< decltype(f(0))>
 
template<... >
void parallel_foreach (...)
 Apply a functor to all items in a range in parallel. More...
 
 ~ThreadPool ()
 

Detailed Description

See Also
These algorithms and data structures also support parallel processing:
labelMultiArrayBlockwise (...)
unionFindWatershedsBlockwise (...)
gaussianGradientMagnitude (..., BlockwiseConvolutionOptions)
ChunkedArray
ChunkedArrayFull
ChunkedArrayLazy
ChunkedArrayCompressed
ChunkedArrayTmpFile
ChunkedArrayHDF5
gaussianSmoothMultiArray (..., BlockwiseConvolutionOptions)
gaussianGradientMultiArray (..., BlockwiseConvolutionOptions)
symmetricGradientMultiArray (..., BlockwiseConvolutionOptions)
laplacianOfGaussianMultiArray (..., BlockwiseConvolutionOptions)
gaussianDivergenceMultiArray (..., BlockwiseConvolutionOptions)
hessianOfGaussianMultiArray (..., BlockwiseConvolutionOptions)
structureTensorMultiArray (..., BlockwiseConvolutionOptions)

Function Documentation

void vigra::parallel_foreach (   ...)

Apply a functor to all items in a range in parallel.

Declarations:

namespace vigra {
// pass the desired number of threads or ParallelOptions::Auto
// (creates an internal thread pool accordingly)
template<class ITER, class F>
void parallel_foreach(int64_t nThreads,
ITER begin, ITER end,
F && f,
const uint64_t nItems = 0);
// use an existing thread pool
template<class ITER, class F>
void parallel_foreach(ThreadPool & pool,
ITER begin, ITER end,
F && f,
const uint64_t nItems = 0);
// pass the integers from 0 ... (nItems-1) to the functor f,
// using the given number of threads or ParallelOptions::Auto
template<class F>
void parallel_foreach(int64_t nThreads,
uint64_t nItems,
F && f);
// likewise with an existing thread pool
template<class F>
void parallel_foreach(ThreadPool & threadpool,
uint64_t nItems,
F && f);
}

Create a thread pool (or use an existing one) to apply the functor

  • f to all items in the range [begin, end) in parallel.
  • f must be callable with two arguments of type size_t and T, where the first argument is the thread index (starting at 0) and T is convertible from the iterator's reference_type (i.e. the result of *begin).

If the iterators are forward iterators (std::forward_iterator_tag), you can provide the optional argument nItems to avoid the a std::distance(begin, end) call to compute the range's length.

Parameter nThreads controls the number of threads. parallel_foreach will split the work into about three times as many parallel tasks. If nThreads = ParallelOptions::Auto, the number of threads is set to the machine default (std::thread::hardware_concurrency()).

If nThreads = 0, the function will not use threads, but will call the functor sequentially. This can also be enforced by setting the preprocessor flag VIGRA_SINGLE_THREADED, ignoring the value of nThreads (useful for debugging).

Usage:

#include <iostream>
#include <algorithm>
#include <vector>
#include <vigra/threadpool.hxx>
using namespace std;
using namespace vigra;
int main()
{
size_t const n_threads = 4;
size_t const n = 2000;
vector<int> input(n);
auto iter = input.begin(),
end = input.end();
// fill input with 0, 1, 2, ...
iota(iter, end, 0);
// compute the sum of the elements in the input vector.
// (each thread computes the partial sum of the items it sees
// and stores the sum at the appropriate index of 'results')
vector<int> results(n_threads, 0);
parallel_foreach(n_threads, iter, end,
// the functor to be executed, defined as a lambda function
// (first argument: thread ID, second argument: result of *iter)
[&results](size_t thread_id, int items)
{
results[thread_id] += items;
}
);
// collect the partial sums of all threads
int sum = accumulate(results.begin(), results.end(), 0);
cout << "The sum " << sum << " should be equal to " << (n*(n-1))/2 << endl;
}
~ThreadPool ( )

The destructor joins all threads.

auto enqueueReturning ( F &&  f) -> threading::future<decltype(f(0))>

Enqueue a task that will be executed by the thread pool. The task result can be obtained using the get() function of the returned future. If the task throws an exception, it will be raised on the call to get().

threading::future< void > enqueue ( F &&  f)

Enqueue function for tasks without return value. This is a special case of the enqueueReturning template function, but some compilers fail on std::result_of<F(int)>::type for void(int) functions.

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.11.1 (Fri May 19 2017)