public class LoopBuilder<T> extends Object
LoopBuilder
provides an easy way to write fast loops on
RandomAccessibleInterval
s. For example, this is a loop that
calculates the sum of two images:
RandomAccessibleInterval<DoubleType> imageA = ...
RandomAccessibleInterval<DoubleType> imageB = ...
RandomAccessibleInterval<DoubleType> sum = ...
LoopBuilder.setImages(imageA, imageB, sum).forEachPixel(
(a, b, s) -> {
s.setReal(a.getRealDouble() + b.getRealDouble());
}
);
The RandomAccessibleInterval
s imageA
, imageB
and
sum
must have equal dimensions, but the bounds of there
Intervals
can differ.
Modifier and Type | Class and Description |
---|---|
static interface |
LoopBuilder.Chunk<T> |
static interface |
LoopBuilder.FiveConsumer<A,B,C,D,E> |
static interface |
LoopBuilder.FourConsumer<A,B,C,D> |
static interface |
LoopBuilder.SixConsumer<A,B,C,D,E,F> |
static interface |
LoopBuilder.TriConsumer<A,B,C> |
public static <A> LoopBuilder<Consumer<A>> setImages(RandomAccessibleInterval<A> a)
LoopBuilder
public static <A,B> LoopBuilder<BiConsumer<A,B>> setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b)
LoopBuilder
public static <A,B,C> LoopBuilder<LoopBuilder.TriConsumer<A,B,C>> setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b, RandomAccessibleInterval<C> c)
LoopBuilder
public static <A,B,C,D> LoopBuilder<LoopBuilder.FourConsumer<A,B,C,D>> setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b, RandomAccessibleInterval<C> c, RandomAccessibleInterval<D> d)
LoopBuilder
public static <A,B,C,D,E> LoopBuilder<LoopBuilder.FiveConsumer<A,B,C,D,E>> setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b, RandomAccessibleInterval<C> c, RandomAccessibleInterval<D> d, RandomAccessibleInterval<E> e)
LoopBuilder
public static <A,B,C,D,E,F> LoopBuilder<LoopBuilder.SixConsumer<A,B,C,D,E,F>> setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b, RandomAccessibleInterval<C> c, RandomAccessibleInterval<D> d, RandomAccessibleInterval<E> e, RandomAccessibleInterval<F> f)
LoopBuilder
public void forEachPixel(T action)
LoopBuilder
public <R> List<R> forEachChunk(Function<LoopBuilder.Chunk<T>,R> action)
forEachPixel(T)
but more flexible when multi threading is used.
The following example calculates the sum of the pixel values of an image.
Multi threading is used to improve performance. The image is split into chunks.
The chunks are processed in parallel by multiple threads. A variable
of IntType
is used to calculate the sum, but IntType
is not thread safe.
It's therefore necessary to have one sum variable per chunk. This can be realized as follows:
List<IntType> listOfSums = LoopBuilder.setImages( image ).multithreaded().forEachChunk(
chunk -> {
IntType sum = new IntType();
chunk.forEach( pixel -> sum.add( pixel ) ):
return sum;
}
);
IntType totalSum = new IntType();
listOfSums.forEach( sum -> totalSum.add( sum );
return totalSum;
public LoopBuilder<T> multiThreaded()
LoopBuilder
runs the loop without multi-threading.
Calling this method allows LoopBuilder
to use multi-threading for optimal performance.
Usually, if this method is used, LoopBuilder
will indeed
use multi-threading. But that's not always the case.
The Parallelization
class can still be used to explicitly run the
code single-threaded.
Here is a small example for a copy method with enabled multi-threading.
public void copy( RandomAccessibleInterval<T> source, RandomAccessibleInterval<T> target)
{
LoopBuilder.setImages( source, target ).multiThreaded().forEachPixel( ( s, t ) -> t.set( s ) );
}
This method usually runs multi-threaded. Which means good performance.
But sometimes, a user might want to run the code single-threaded.
There's no need to write a second single-threaded version of our copy method.
The Parallelization
class allows the user to run the code single-threaded:
Parallelization.runSingleThreaded( () -> {
copy( source, target );
} );
WARNING: You need to make sure that the action passed to forEachPixel(T)
is thread safe.Parallelization
public LoopBuilder<T> multiThreaded(boolean multiThreaded)
public LoopBuilder<T> multiThreaded(TaskExecutor taskExecutor)
LoopBuilder
runs the loop without multi-threading.
Calling this method causes LoopBuilder to use the given TaskExecutor
for multi-threading.
WARNING: You need to make sure that your operation is thread safe.
public LoopBuilder<T> flatIterationOrder()
LoopBuilder
might use any iteration order to execute
the loop. Calling this method will cause LoopBuilder
to use flat iteration order, when executing the loop.
WARNING: Don't use multi-threading if you want to have flat iteration order.
public LoopBuilder<T> flatIterationOrder(boolean value)
LoopBuilder
might use any iteration order
to execute the loop.
If true, LoopBuilder
will use
flat iteration order, and multi threading is disabled.
WARNING: Don't use multi-threading if you want to have flat iteration order.
FlatIterationOrder
Copyright © 2015–2022 ImgLib2. All rights reserved.